From 90eb6759d09c85df44e9d490bec9c7b94023814c Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Mon, 13 Jul 2026 17:42:06 +0300 Subject: [PATCH 1/5] feat: add `u64_widen` helper function --- simf/lib/point/general.simf | 0 simf/lib/u64.simf | 5 +++++ simf/u64_test.simf | 13 +++++++++---- tests/u64_test.rs | 39 +++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 simf/lib/point/general.simf diff --git a/simf/lib/point/general.simf b/simf/lib/point/general.simf new file mode 100644 index 0000000..e69de29 diff --git a/simf/lib/u64.simf b/simf/lib/u64.simf index 77fc4aa..a626359 100644 --- a/simf/lib/u64.simf +++ b/simf/lib/u64.simf @@ -67,3 +67,8 @@ pub fn gt_64(a: u64, b: u64) -> bool { pub fn ge_64(a: u64, b: u64) -> bool { jet::le_64(b, a) } + +/// Widen `u64` to a `u256` scalar. +pub fn u64_widen(val: u64) -> u256 { + <(u64, u64, u64, u64)>::into((0, 0, 0, val)) +} diff --git a/simf/u64_test.simf b/simf/u64_test.simf index 82c605b..8a9d443 100644 --- a/simf/u64_test.simf +++ b/simf/u64_test.simf @@ -1,4 +1,7 @@ -use crate::lib::u64::{checked_add_64, safe_add_64, checked_sub_64, safe_sub_64, checked_mul_64, safe_mul_64, checked_div_64, safe_div_64, gt_64, ge_64}; +use crate::lib::u64::{ + checked_add_64, safe_add_64, checked_sub_64, safe_sub_64, checked_mul_64, safe_mul_64, checked_div_64, safe_div_64, + gt_64, ge_64, u64_widen, +}; use crate::lib::asserts::{assert_none_64, assert_eq_64}; use crate::lib::logical_operations::not; use crate::helper::if_test_this_function; @@ -29,6 +32,9 @@ fn main() { let b: u64 = witness::SECOND_ARG; let expected: Option = witness::EXPECTED; + let expected_widen: u256 = witness::EXPECTED_WIDEN; + + // add match if_test_this_function(0, fn_idx) { true => { assert_eq_opt(checked_add_64(a, b), expected); }, false => (), }; match if_test_this_function(1, fn_idx) { true => { assert!(jet::eq_64(safe_add_64(a, b), unwrap(expected))); }, false => (), }; @@ -45,7 +51,6 @@ fn main() { match if_test_this_function(6, fn_idx) { true => { assert_eq_opt(checked_div_64(a, b), expected); }, false => (), }; match if_test_this_function(7, fn_idx) { true => { assert!(jet::eq_64(safe_div_64(a, b), unwrap(expected))); }, false => (), }; - // gt, ge - match if_test_this_function(8, fn_idx) { true => { assert_bool_by_opt(gt_64(a, b), expected); }, false => (), }; - match if_test_this_function(9, fn_idx) { true => { assert_bool_by_opt(ge_64(a, b), expected); }, false => (), }; + // Custom + match if_test_this_function(192, fn_idx) { true => { assert_eq_opt(checked_div_64(a, b), expected); }, false => (), }; } diff --git a/tests/u64_test.rs b/tests/u64_test.rs index e354846..d932384 100644 --- a/tests/u64_test.rs +++ b/tests/u64_test.rs @@ -5,6 +5,8 @@ use common::uint::TestUint; use simplicityhl_std::artifacts::u64_test::U64TestProgram; use simplicityhl_std::artifacts::u64_test::derived_u64_test::{U64TestArguments, U64TestWitness}; +use crate::common::uint::CUSTOM_BASE; + // The only per-width code for the common operations. impl TestUint for u64 { type Program = U64TestProgram; @@ -26,13 +28,50 @@ impl TestUint for u64 { first_arg: a, second_arg: b, expected, + ..Default::default() } } } +enum FunctionToTest { + U64Widen, +} + +#[inline] +fn op(o: FunctionToTest) -> u8 { + o as u8 + CUSTOM_BASE +} + mod u64_tests { + use rand::Rng as _; + + use crate::{ + FunctionToTest::U64Widen, + common::core::{Expect, run}, + }; + use super::*; // Stamps the 16 `#[simplex::test]` entry points for u64. Logic lives in common::uint. uint_tests!(u64); + + #[simplex::test] + fn u64_widen(context: simplex::TestContext) -> anyhow::Result<()> { + let a = rand::thread_rng().gen_range(0..=u64::MAX); + + let mut expected_widen: [u8; 32] = [0u8; 32]; + expected_widen[24..32].copy_from_slice(&a.to_be_bytes()); + + run( + &context, + ::program(), + U64TestWitness { + function_index: op(U64Widen), + first_arg: a, + expected_widen, + ..Default::default() + }, + Expect::Ok, + ) + } } From 116cce1677809efdbf1f24b695e30712c624d65e Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Fri, 17 Jul 2026 16:07:18 +0300 Subject: [PATCH 2/5] feat: add ec operations and test them, add asserts for u1 --- Cargo.lock | 69 +++-- Cargo.toml | 3 + simf/asserts_test.simf | 34 ++- simf/ec_ops_test.simf | 35 +++ simf/lib/asserts.simf | 12 +- simf/lib/ec/ops.simf | 109 ++++++++ tests/asserts_test.rs | 52 ++++ tests/ec_tests.rs | 570 +++++++++++++++++++++++++++++++++++++++++ tests/u64_test.rs | 6 +- 9 files changed, 853 insertions(+), 37 deletions(-) create mode 100644 simf/ec_ops_test.simf create mode 100644 simf/lib/ec/ops.simf create mode 100644 tests/ec_tests.rs diff --git a/Cargo.lock b/Cargo.lock index 924c45f..edcffcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.32.101" +version = "0.32.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed8ccb78a9ff7a6fbb90e2fb9b8588b4a9928d49d8af3cb789108a84ea6b0ce" +checksum = "bb0ce8bd5baaa0d303a19915a6d93afed161f528654e42da2a7a97d05c59499a" dependencies = [ "base58ck", "base64 0.21.7", @@ -273,9 +273,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bitvec" @@ -360,18 +360,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.1" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "dd059f9da4f5c36b3787f65d38ccaab1cc315f07b01f89abc8359ee6a8205011" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" dependencies = [ "anstream", "anstyle", @@ -683,14 +683,14 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +checksum = "e47d37d2ae4464254884b60ab7071be2b876a9c35b696bd018ddcc76847309cd" dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.15", + "regex-automata 0.4.16", "regex-syntax 0.8.11", ] @@ -700,7 +700,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "ignore", "walkdir", ] @@ -772,15 +772,15 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adf14691c72bcfc1058740436a35bdd3ae9c07d1a941ef00b749e9ea16aefa7" +checksum = "7b009b6744c1445efd7244084e25e498636412effb6760b55067553baa925cc7" dependencies = [ "crossbeam-deque", "globset", "log", "memchr", - "regex-automata 0.4.15", + "regex-automata 0.4.16", "same-file", "walkdir", "winapi-util", @@ -971,6 +971,34 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "num-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "object" version = "0.37.3" @@ -1166,9 +1194,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" dependencies = [ "aho-corasick", "memchr", @@ -1213,7 +1241,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -1226,7 +1254,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys 0.12.1", @@ -1447,8 +1475,11 @@ name = "simplicityhl-std" version = "0.1.0" dependencies = [ "anyhow", + "num-bigint", + "num-traits", "primitive-types", "rand", + "secp256k1-zkp", "smplx-std", ] diff --git a/Cargo.toml b/Cargo.toml index 36ad43c..d757165 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,6 @@ smplx-std = "0.0.8" anyhow = { version = "1.0.101" } rand = { version = "0.8.6" } primitive-types = { version = "0.14" } +num-bigint = { version = "0.5.1" } +num-traits = { version = "0.2.19" } +secp256k1-zkp = { version = "0.11.0", features = ["rand"] } diff --git a/simf/asserts_test.simf b/simf/asserts_test.simf index bcaf598..2f33693 100644 --- a/simf/asserts_test.simf +++ b/simf/asserts_test.simf @@ -1,9 +1,15 @@ -use crate::lib::asserts::{assert_eq_8, assert_eq_16, assert_eq_32, assert_eq_64,assert_eq_128, assert_eq_256, assert_none_8, assert_none_16, assert_none_32, assert_none_64, assert_none_128, assert_none_256}; +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, + assert_none_1, assert_none_8, assert_none_16, assert_none_32, assert_none_64, assert_none_128, assert_none_256 +}; use crate::helper::if_test_this_function; fn main() { let fn_idx: u8 = witness::FUNCTION_INDEX; + let a_u1: Option = witness::FIRST_ARG_U1; + let b_u1: Option = witness::SECOND_ARG_U1; + let a_u8: Option = witness::FIRST_ARG_U8; let b_u8: Option = witness::SECOND_ARG_U8; @@ -23,18 +29,20 @@ fn main() { let b_u256: Option = witness::SECOND_ARG_U256; // Assert Eq - match if_test_this_function(0, fn_idx) { true => { assert_eq_8(unwrap(a_u8), unwrap(b_u8)); }, false => (), }; - match if_test_this_function(1, fn_idx) { true => { assert_eq_16(unwrap(a_u16), unwrap(b_u16)); }, false => (), }; - match if_test_this_function(2, fn_idx) { true => { assert_eq_32(unwrap(a_u32), unwrap(b_u32)); }, false => (), }; - match if_test_this_function(3, fn_idx) { true => { assert_eq_64(unwrap(a_u64), unwrap(b_u64)); }, false => (), }; - match if_test_this_function(4, fn_idx) { true => { assert_eq_128(unwrap(a_u128), unwrap(b_u128)); }, false => (), }; - match if_test_this_function(5, fn_idx) { true => { assert_eq_256(unwrap(a_u256), unwrap(b_u256)); }, false => (), }; + match if_test_this_function(0, fn_idx) { true => { assert_eq_1(unwrap(a_u1), unwrap(b_u1)); }, false => (), }; + match if_test_this_function(1, fn_idx) { true => { assert_eq_8(unwrap(a_u8), unwrap(b_u8)); }, false => (), }; + match if_test_this_function(2, fn_idx) { true => { assert_eq_16(unwrap(a_u16), unwrap(b_u16)); }, false => (), }; + match if_test_this_function(3, fn_idx) { true => { assert_eq_32(unwrap(a_u32), unwrap(b_u32)); }, false => (), }; + match if_test_this_function(4, fn_idx) { true => { assert_eq_64(unwrap(a_u64), unwrap(b_u64)); }, false => (), }; + match if_test_this_function(5, fn_idx) { true => { assert_eq_128(unwrap(a_u128), unwrap(b_u128)); }, false => (), }; + match if_test_this_function(6, fn_idx) { true => { assert_eq_256(unwrap(a_u256), unwrap(b_u256)); }, false => (), }; // Assert None - match if_test_this_function(6, fn_idx) { true => { assert_none_8(a_u8); }, false => (), }; - match if_test_this_function(7, fn_idx) { true => { assert_none_16(a_u16); }, false => (), }; - match if_test_this_function(8, fn_idx) { true => { assert_none_32(a_u32); }, false => (), }; - match if_test_this_function(9, fn_idx) { true => { assert_none_64(a_u64); }, false => (), }; - match if_test_this_function(10, fn_idx) { true => { assert_none_128(a_u128); }, false => (), }; - match if_test_this_function(11, fn_idx) { true => { assert_none_256(a_u256); }, false => (), }; + match if_test_this_function(7, fn_idx) { true => { assert_none_1(a_u1); }, false => (), }; + match if_test_this_function(8, fn_idx) { true => { assert_none_8(a_u8); }, false => (), }; + match if_test_this_function(9, fn_idx) { true => { assert_none_16(a_u16); }, false => (), }; + match if_test_this_function(10, fn_idx) { true => { assert_none_32(a_u32); }, false => (), }; + match if_test_this_function(11, fn_idx) { true => { assert_none_64(a_u64); }, false => (), }; + match if_test_this_function(12, fn_idx) { true => { assert_none_128(a_u128); }, false => (), }; + match if_test_this_function(13, fn_idx) { true => { assert_none_256(a_u256); }, false => (), }; } diff --git a/simf/ec_ops_test.simf b/simf/ec_ops_test.simf new file mode 100644 index 0000000..8d73f2d --- /dev/null +++ b/simf/ec_ops_test.simf @@ -0,0 +1,35 @@ +use crate::lib::ec::ops::{ + ge_to_point, point_to_gej, fe_sub, scalar_sub, gej_sub, + fe_eq, scalar_eq, ge_eq, gej_point_eq, safe_gej_normalize, + assert_fe_eq, assert_scalar_eq, assert_ge_eq, assert_point_eq, assert_gej_point_eq, assert_gej_eq +}; +use crate::helper::if_test_this_function; + +fn main() { + let fn_idx: u8 = witness::FUNCTION_INDEX; + + // Interpreted as Fe or Scalar depending on the function index + let uint_a: u256 = witness::FIRST_UINT; + let uint_b: u256 = witness::SECOND_UINT; + let ge_a: Ge = witness::FIRST_GE; + let ge_b: Ge = witness::SECOND_GE; + let gej_a: Gej = witness::FIRST_GEJ; + let gej_b: Gej = witness::SECOND_GEJ; + let point_a: Point = witness::FIRST_POINT; + + let exp_uint: u256 = witness::EXPECTED_UINT; + let exp_ge: Ge = witness::EXPECTED_GE; + let exp_gej: Gej = witness::EXPECTED_GEJ; + let exp_point: Point = witness::EXPECTED_POINT; + + match if_test_this_function(0, fn_idx) { true => { assert_point_eq(ge_to_point(ge_a), exp_point); }, false => (), }; + match if_test_this_function(1, fn_idx) { true => { assert_gej_point_eq(point_to_gej(point_a), exp_point); }, false => (), }; + match if_test_this_function(2, fn_idx) { true => { assert_fe_eq(fe_sub(uint_a, uint_b), exp_uint); }, false => (), }; + match if_test_this_function(3, fn_idx) { true => { assert_scalar_eq(scalar_sub(uint_a, uint_b), exp_uint); }, false => (), }; + match if_test_this_function(4, fn_idx) { true => { assert_gej_eq(gej_sub(gej_a, gej_b), exp_gej); }, false => (), }; + match if_test_this_function(5, fn_idx) { true => { assert!(fe_eq(uint_a, uint_b)); }, false => (), }; + match if_test_this_function(6, fn_idx) { true => { assert!(scalar_eq(uint_a, uint_b)); }, false => (), }; + match if_test_this_function(7, fn_idx) { true => { assert!(ge_eq(ge_a, ge_b)); }, false => (), }; + match if_test_this_function(8, fn_idx) { true => { assert!(gej_point_eq(gej_a, point_a)); }, false => (), }; + match if_test_this_function(9, fn_idx) { true => { assert_ge_eq(safe_gej_normalize(gej_a), exp_ge); }, false => (), }; +} diff --git a/simf/lib/asserts.simf b/simf/lib/asserts.simf index 6714e6d..60c577c 100644 --- a/simf/lib/asserts.simf +++ b/simf/lib/asserts.simf @@ -1,4 +1,9 @@ -use crate::lib::u128::{eq_128}; +use crate::lib::u128::eq_128; + +/// Asserts that two `u1` are equal +pub fn assert_eq_1(a: u1, b: u1) { + assert!(jet::eq_1(a, b)) +} /// Asserts that two u8 are equal pub fn assert_eq_8(a: u8, b: u8) { @@ -30,6 +35,11 @@ pub fn assert_eq_256(a: u256, b: u256) { assert!(jet::eq_256(a, b)); } +/// Asserts that provided `Option` value is a `None` +pub fn assert_none_1(val: Option) { + assert!(is_none::(val)); +} + /// Asserts that provided u8 Option value is a None pub fn assert_none_8(val: Option) { assert!(is_none::(val)); diff --git a/simf/lib/ec/ops.simf b/simf/lib/ec/ops.simf new file mode 100644 index 0000000..809b46f --- /dev/null +++ b/simf/lib/ec/ops.simf @@ -0,0 +1,109 @@ +use crate::lib::logical_operations::and; +use crate::lib::asserts::{assert_eq_1, assert_eq_256}; + +/// Compress an affine point to `(parity, x)`, where `parity = 1` iff `y` is odd. +pub fn ge_to_point(p: Ge) -> Point { + let (x, y): (Fe, Fe) = p; + + match jet::fe_is_odd(y) { + true => (1, x), + false => (0, x), + } +} + +/// Decompress a `Point` into a Jacobian point with `z = 1`. +pub fn point_to_gej(p: Point) -> Gej { + (unwrap(jet::decompress(p)), 1) +} + +/// Convert the point into affine coordinates. +pub fn safe_gej_normalize(p: Gej) -> Ge { + unwrap(jet::gej_normalize(p)) +} + +/// Subtract two field elements. +pub fn fe_sub(a: Fe, b: Fe) -> Fe { + jet::fe_add(a, jet::fe_negate(b)) +} + +/// Subtract two scalars. +pub fn scalar_sub(a: Scalar, b: Scalar) -> Scalar { + jet::scalar_add(a, jet::scalar_negate(b)) +} + +/// Subtract two points. +pub fn gej_sub(p: Gej, q: Gej) -> Gej { + jet::gej_add(p, jet::gej_negate(q)) +} + +/// Field equality modulo `p`. +pub fn fe_eq(a: Fe, b: Fe) -> bool { + jet::fe_is_zero(fe_sub(a, b)) +} + +/// Scalar equality modulo `n`. +pub fn scalar_eq(a: Scalar, b: Scalar) -> bool { + jet::scalar_is_zero(scalar_sub(a, b)) +} + +/// Affine point equality. +pub fn ge_eq(a: Ge, b: Ge) -> bool { + let (ax, ay): (Fe, Fe) = a; + let (bx, by): (Fe, Fe) = b; + and(fe_eq(ax, bx), fe_eq(ay, by)) +} + +/// Check if two points are equal. +pub fn point_point_eq(a: Point, b: Point) -> bool { + let (ap, ax): (u1, u256) = a; + let (bp, bx): (u1, u256) = b; + and(jet::eq_256(ax, bx), jet::eq_1(ap, bp)) +} + +/// Check if two points represent the same point +pub fn gej_point_eq(a: Gej, p: Point) -> bool { + jet::gej_ge_equiv(a, unwrap(jet::decompress(p))) +} + +/// Field equality modulo `p`. +pub fn assert_fe_eq(a: Fe, b: Fe) { + assert!(fe_eq(a, b)); +} + +/// Scalar equality modulo `n`. +pub fn assert_scalar_eq(a: Scalar, b: Scalar) { + assert!(scalar_eq(a, b)); +} + +/// Affine point equality. +pub fn assert_ge_eq(a: Ge, b: Ge) { + let (ax, ay): (Fe, Fe) = a; + let (bx, by): (Fe, Fe) = b; + + assert_fe_eq(ax, bx); + assert_fe_eq(ay, by); +} + +/// Check if two points are equal. +pub fn assert_point_eq(a: Point, b: Point) { + let (ap, ax): (u1, u256) = a; + let (bp, bx): (u1, u256) = b; + + assert_eq_256(ax, bx); + assert_eq_1(ap, bp); +} + +/// Check if two points represent the same point. +pub fn assert_gej_point_eq(a: Gej, p: Point) { + assert!(gej_point_eq(a, p)); +} + +/// Check if two points represent the same point. +pub fn assert_gej_eq(a: Gej, b: Gej) { + assert!(jet::gej_equiv(a, b)); +} + +/// Check if two points represent the same point. +pub fn assert_gej_ge_eq(a: Gej, b: Ge) { + assert!(jet::gej_ge_equiv(a, b)); +} diff --git a/tests/asserts_test.rs b/tests/asserts_test.rs index ab8790c..f53519e 100644 --- a/tests/asserts_test.rs +++ b/tests/asserts_test.rs @@ -12,12 +12,15 @@ use simplicityhl_std::artifacts::asserts_test::derived_asserts_test::{ // Dispatch indices — must match the `if_test_this_function(N, ..)` arms in // simf/asserts_test.simf. enum FunctionToTest { + AssertEq1, AssertEq8, AssertEq16, AssertEq32, AssertEq64, AssertEq128, AssertEq256, + + AssertNone1, AssertNone8, AssertNone16, AssertNone32, @@ -64,6 +67,8 @@ pub fn generate_uints_in_one_range(same: bool, min_val: u128, max_val: u128) -> fn build_witness(function: FunctionToTest, same: bool, none: bool) -> AssertsTestWitness { let mut witness = AssertsTestWitness { function_index: 0, + first_arg_u1: DEFAULT_SOME_U8, + second_arg_u1: DEFAULT_SOME_U8, first_arg_u8: DEFAULT_SOME_U8, second_arg_u8: DEFAULT_SOME_U8, first_arg_u16: DEFAULT_SOME_U16, @@ -79,6 +84,10 @@ fn build_witness(function: FunctionToTest, same: bool, none: bool) -> AssertsTes }; match function { + FunctionToTest::AssertEq1 => { + let (a, b) = generate_uints_in_one_range(same, 0, 1u128); + (witness.first_arg_u1, witness.second_arg_u1) = (Some(a as u8), Some(b as u8)); + } FunctionToTest::AssertEq8 => { let (a, b) = generate_uints_in_one_range(same, 0, u8::MAX as u128); (witness.first_arg_u8, witness.second_arg_u8) = (Some(a as u8), Some(b as u8)); @@ -104,6 +113,11 @@ fn build_witness(function: FunctionToTest, same: bool, none: bool) -> AssertsTes (witness.first_arg_u256, witness.second_arg_u256) = (Some([a as u8; 32]), Some([b as u8; 32])); } + FunctionToTest::AssertNone1 => { + if none { + witness.first_arg_u1 = None; + } + } FunctionToTest::AssertNone8 => { if none { witness.first_arg_u8 = None; @@ -159,6 +173,22 @@ mod asserts_test { use super::*; // ---------- assert_eq: happy = equal args, unhappy = distinct args ---------- + #[simplex::test] + fn assert_eq_1_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + run_assert(&context, FunctionToTest::AssertEq1, true, false, Expect::Ok) + } + + #[simplex::test] + fn assert_eq_1_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { + run_assert( + &context, + FunctionToTest::AssertEq1, + false, + false, + Expect::AssertFailed, + ) + } + #[simplex::test] fn assert_eq_8_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { run_assert(&context, FunctionToTest::AssertEq8, true, false, Expect::Ok) @@ -286,6 +316,28 @@ mod asserts_test { } // ---------- assert_none: happy = None arg, unhappy = Some arg ---------- + #[simplex::test] + fn assert_none_1_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + run_assert( + &context, + FunctionToTest::AssertNone1, + false, + true, + Expect::Ok, + ) + } + + #[simplex::test] + fn assert_none_1_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { + run_assert( + &context, + FunctionToTest::AssertNone1, + false, + false, + Expect::AssertFailed, + ) + } + #[simplex::test] fn assert_none_8_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { run_assert( diff --git a/tests/ec_tests.rs b/tests/ec_tests.rs new file mode 100644 index 0000000..b9f2589 --- /dev/null +++ b/tests/ec_tests.rs @@ -0,0 +1,570 @@ +mod common; + +//use hex_literal::hex; +use num_bigint::BigUint; +use num_traits::Zero; +use rand::{RngCore, rngs::OsRng}; +use secp256k1_zkp::{PublicKey, Secp256k1, SecretKey, rand::rngs::OsRng as SecpOsRng}; + +use common::core::{Expect, run}; + +use simplicityhl_std::artifacts::ec_ops_test::EcOpsTestProgram; +use simplicityhl_std::artifacts::ec_ops_test::derived_ec_ops_test::{ + EcOpsTestArguments, EcOpsTestWitness, +}; + +enum FunctionToTest { + GeToPoint, + PointToGej, + FeSub, + ScalarSub, + GejSub, + FeEq, + ScalarEq, + GeEq, + GejPointEq, + SafeGejNormalize, +} + +#[inline] +fn op(o: FunctionToTest) -> u8 { + o as u8 +} + +const DEFAULT_UINT: [u8; 32] = [0u8; 32]; +const DEFAULT_GE: ([u8; 32], [u8; 32]) = ([0u8; 32], [0u8; 32]); +const DEFAULT_GEJ: (([u8; 32], [u8; 32]), [u8; 32]) = (([0u8; 32], [0u8; 32]), [0u8; 32]); +const DEFAULT_POINT: (u8, [u8; 32]) = (0, [0u8; 32]); + +// FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +const SECP_P: [u8; 32] = [ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, +]; + +// FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +const SECP_N: [u8; 32] = [ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41, +]; + +fn program() -> EcOpsTestProgram { + EcOpsTestProgram::new(EcOpsTestArguments {}) +} + +#[allow(clippy::too_many_arguments)] +fn build_witness( + function: u8, + first_uint: [u8; 32], + second_uint: [u8; 32], + first_ge: ([u8; 32], [u8; 32]), + second_ge: ([u8; 32], [u8; 32]), + first_gej: (([u8; 32], [u8; 32]), [u8; 32]), + second_gej: (([u8; 32], [u8; 32]), [u8; 32]), + first_point: (u8, [u8; 32]), + expected_uint: [u8; 32], + expected_ge: ([u8; 32], [u8; 32]), + expected_gej: (([u8; 32], [u8; 32]), [u8; 32]), + expected_point: (u8, [u8; 32]), +) -> EcOpsTestWitness { + EcOpsTestWitness { + function_index: function, + first_uint, + second_uint, + first_ge, + second_ge, + first_gej, + second_gej, + first_point, + expected_uint, + expected_ge, + expected_gej, + expected_point, + } +} + +fn secp_p() -> BigUint { + BigUint::from_bytes_be(&SECP_P) +} +fn secp_n() -> BigUint { + BigUint::from_bytes_be(&SECP_N) +} + +fn to_32_be(x: &BigUint) -> [u8; 32] { + let b = x.to_bytes_be(); + + let mut out = [0u8; 32]; + out[32 - b.len()..].copy_from_slice(&b); + + out +} + +fn mod_p(x: &BigUint) -> BigUint { + x % secp_p() +} +fn mod_n(x: &BigUint) -> BigUint { + x % secp_n() +} + +fn fe_sub_ref(a: [u8; 32], b: [u8; 32]) -> [u8; 32] { + let p = secp_p(); + let a = BigUint::from_bytes_be(&a) % &p; + let b = BigUint::from_bytes_be(&b) % &p; + + to_32_be(&((a + &p - b) % &p)) +} + +fn scalar_sub_ref(a: [u8; 32], b: [u8; 32]) -> [u8; 32] { + let n = secp_n(); + let a = BigUint::from_bytes_be(&a) % &n; + let b = BigUint::from_bytes_be(&b) % &n; + + to_32_be(&((a + &n - b) % &n)) +} + +fn fe_negate_ref(a: [u8; 32]) -> [u8; 32] { + let p = secp_p(); + let a = BigUint::from_bytes_be(&a) % &p; + + if a.is_zero() { + [0u8; 32] + } else { + to_32_be(&(&p - &a)) + } +} + +fn fe_mul_ref(a: [u8; 32], b: [u8; 32]) -> [u8; 32] { + let p = secp_p(); + let a = BigUint::from_bytes_be(&a); + let b = BigUint::from_bytes_be(&b); + + to_32_be(&((a * b) % &p)) +} + +// Randomness helpers +fn random_uint_bytes() -> [u8; 32] { + let mut b = [0u8; 32]; + OsRng.fill_bytes(&mut b); + + b +} + +fn random_fe_bytes() -> [u8; 32] { + to_32_be(&mod_p(&BigUint::from_bytes_be(&random_uint_bytes()))) +} + +fn random_scalar_bytes() -> [u8; 32] { + to_32_be(&mod_n(&BigUint::from_bytes_be(&random_uint_bytes()))) +} + +fn random_ge_bytes() -> ([u8; 32], [u8; 32]) { + let secp = Secp256k1::new(); + let sk = SecretKey::new(&mut SecpOsRng); + let pk = PublicKey::from_secret_key(&secp, &sk); + let ser = pk.serialize_uncompressed(); // 0x04 || x(32) || y(32) + + let mut x = [0u8; 32]; + x.copy_from_slice(&ser[1..33]); + + let mut y = [0u8; 32]; + y.copy_from_slice(&ser[33..65]); + + (x, y) +} + +fn ge_to_gej(ge: ([u8; 32], [u8; 32])) -> (([u8; 32], [u8; 32]), [u8; 32]) { + let mut one = [0u8; 32]; + one[31] = 1; + + (ge, one) +} + +fn compress(ge: ([u8; 32], [u8; 32])) -> (u8, [u8; 32]) { + (ge.1[31] & 1, ge.0) +} + +fn pk_to_gej(pk: &PublicKey) -> (([u8; 32], [u8; 32]), [u8; 32]) { + let ser = pk.serialize_uncompressed(); + + let mut x = [0u8; 32]; + x.copy_from_slice(&ser[1..33]); + + let mut y = [0u8; 32]; + y.copy_from_slice(&ser[33..65]); + + ge_to_gej((x, y)) +} + +mod ec_ops_tests { + use super::*; + + // 0. ge_to_point + #[simplex::test] + fn ge_to_point_matches_parity(context: simplex::TestContext) -> anyhow::Result<()> { + // Sample one on-curve point; whatever parity it has, that's what we expect + // ge_to_point to produce. Covers both parities across repeated runs. + let ge = random_ge_bytes(); + let expected_parity = ge.1[31] & 1; // 0 (even y) or 1 (odd y) + + run( + &context, + program(), + build_witness( + op(FunctionToTest::GeToPoint), + DEFAULT_UINT, + DEFAULT_UINT, + ge, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + (expected_parity, ge.0), + ), + Expect::Ok, + ) + } + + // 1. point_to_gej + #[simplex::test] + fn point_to_gej_roundtrip(context: simplex::TestContext) -> anyhow::Result<()> { + let ge = random_ge_bytes(); + let point = compress(ge); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::PointToGej), + DEFAULT_UINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + point, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + point, + ), + Expect::Ok, + ) + } + + // 2. fe_sub + #[simplex::test] + fn fe_sub_self_is_zero(context: simplex::TestContext) -> anyhow::Result<()> { + let a = random_fe_bytes(); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::FeSub), + a, + a, + DEFAULT_GE, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + [0u8; 32], + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + #[simplex::test] + fn fe_sub_matches_reference(context: simplex::TestContext) -> anyhow::Result<()> { + let a = random_fe_bytes(); + let b = random_fe_bytes(); + let exp = fe_sub_ref(a, b); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::FeSub), + a, + b, + DEFAULT_GE, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + exp, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + // 3. scalar_sub + #[simplex::test] + fn scalar_sub_matches_reference(context: simplex::TestContext) -> anyhow::Result<()> { + let a = random_scalar_bytes(); + let b = random_scalar_bytes(); + let exp = scalar_sub_ref(a, b); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::ScalarSub), + a, + b, + DEFAULT_GE, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + exp, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + // 4. gej_sub + #[simplex::test] + fn gej_sub_matches_reference(context: simplex::TestContext) -> anyhow::Result<()> { + let secp = Secp256k1::new(); + let sk_p = SecretKey::new(&mut SecpOsRng); + let sk_q = SecretKey::new(&mut SecpOsRng); + + let p = PublicKey::from_secret_key(&secp, &sk_p); + let q = PublicKey::from_secret_key(&secp, &sk_q); + let diff = p.combine(&q.negate(&secp)).expect("p - q non-infinity"); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::GejSub), + DEFAULT_UINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GE, + pk_to_gej(&p), + pk_to_gej(&q), + DEFAULT_POINT, + DEFAULT_UINT, + DEFAULT_GE, + pk_to_gej(&diff), + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + // 5. fe_eq + #[simplex::test] + fn fe_eq_reflexive(context: simplex::TestContext) -> anyhow::Result<()> { + let a = random_fe_bytes(); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::FeEq), + a, + a, + DEFAULT_GE, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + #[simplex::test] + fn fe_eq_zero_and_p_are_equal(context: simplex::TestContext) -> anyhow::Result<()> { + run( + &context, + program(), + build_witness( + op(FunctionToTest::FeEq), + [0u8; 32], + SECP_P, + DEFAULT_GE, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + // 6. scalar_eq + #[simplex::test] + fn scalar_eq_s_and_s_plus_n_are_equal(context: simplex::TestContext) -> anyhow::Result<()> { + // s = 5. s + n has no carry past the low byte. + let mut s = [0u8; 32]; + s[31] = 5; + + let mut s_plus_n = SECP_N; + s_plus_n[31] = s_plus_n[31].wrapping_add(5); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::ScalarEq), + s, + s_plus_n, + DEFAULT_GE, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + // 7. ge_eq + #[simplex::test] + fn ge_eq_rejects_negation(context: simplex::TestContext) -> anyhow::Result<()> { + let ge = random_ge_bytes(); + let neg_y = fe_negate_ref(ge.1); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::GeEq), + DEFAULT_UINT, + DEFAULT_UINT, + ge, + (ge.0, neg_y), + DEFAULT_GEJ, + DEFAULT_GEJ, + DEFAULT_POINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::AssertFailed, + ) + } + + // 8. gej_point_eq + #[simplex::test] + fn gej_point_eq_rescaled(context: simplex::TestContext) -> anyhow::Result<()> { + // (λ²X, λ³Y, λZ) is the same affine point as (X, Y, 1). + let ge = random_ge_bytes(); + let lambda = random_fe_bytes(); + let l2 = fe_mul_ref(lambda, lambda); + let l3 = fe_mul_ref(l2, lambda); + let g = ((fe_mul_ref(ge.0, l2), fe_mul_ref(ge.1, l3)), lambda); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::GejPointEq), + DEFAULT_UINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GE, + g, + DEFAULT_GEJ, + compress(ge), + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } + + #[simplex::test] + fn gej_point_eq_rejects_negation(context: simplex::TestContext) -> anyhow::Result<()> { + // Property under test: gej_point_eq(P, -P) == false. + // + // Construction: + // ge = random on-curve point P = (x, y) + // (parity, x) = compressed form of +P + // ge_to_gej(ge) = Gej encoding of +P + // (parity ^ 1, x) = compressed form of -P + // + // decompress((parity ^ 1, x)) inside gej_point_eq recovers (x, -y) = -P. + // Since P ≠ -P on secp256k1, the equivalence must return false. + // expected_bool = false locks that in. + let ge = random_ge_bytes(); + let (parity, x) = compress(ge); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::GejPointEq), + DEFAULT_UINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GE, + ge_to_gej(ge), + DEFAULT_GEJ, + (parity ^ 1, x), + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::AssertFailed, + ) + } + + // 9. safe_gej_normalize + #[simplex::test] + fn safe_gej_normalize_roundtrip(context: simplex::TestContext) -> anyhow::Result<()> { + let ge = random_ge_bytes(); + + run( + &context, + program(), + build_witness( + op(FunctionToTest::SafeGejNormalize), + DEFAULT_UINT, + DEFAULT_UINT, + DEFAULT_GE, + DEFAULT_GE, + ge_to_gej(ge), + DEFAULT_GEJ, + DEFAULT_POINT, + DEFAULT_UINT, + ge, + DEFAULT_GEJ, + DEFAULT_POINT, + ), + Expect::Ok, + ) + } +} diff --git a/tests/u64_test.rs b/tests/u64_test.rs index d932384..0eea865 100644 --- a/tests/u64_test.rs +++ b/tests/u64_test.rs @@ -45,10 +45,8 @@ fn op(o: FunctionToTest) -> u8 { mod u64_tests { use rand::Rng as _; - use crate::{ - FunctionToTest::U64Widen, - common::core::{Expect, run}, - }; + use crate::FunctionToTest::U64Widen; + use crate::common::core::{Expect, run}; use super::*; From 935a5d54dda2cc4a83010f66153d2ab0f4d8071f Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Fri, 17 Jul 2026 16:36:27 +0300 Subject: [PATCH 3/5] refactor: delete unused file --- simf/lib/point/general.simf | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 simf/lib/point/general.simf diff --git a/simf/lib/point/general.simf b/simf/lib/point/general.simf deleted file mode 100644 index e69de29..0000000 From 83536bcde864174f9fc9451fa6d45a928574661c Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Fri, 17 Jul 2026 16:44:08 +0300 Subject: [PATCH 4/5] refactor(u64): restore gt and ge in u64_test.simf --- simf/u64_test.simf | 4 ++++ tests/asserts_test.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/simf/u64_test.simf b/simf/u64_test.simf index 8a9d443..f5777da 100644 --- a/simf/u64_test.simf +++ b/simf/u64_test.simf @@ -51,6 +51,10 @@ fn main() { match if_test_this_function(6, fn_idx) { true => { assert_eq_opt(checked_div_64(a, b), expected); }, false => (), }; match if_test_this_function(7, fn_idx) { true => { assert!(jet::eq_64(safe_div_64(a, b), unwrap(expected))); }, false => (), }; + // gt, ge + match if_test_this_function(8, fn_idx) { true => { assert_bool_by_opt(gt_64(a, b), expected); }, false => (), }; + match if_test_this_function(9, fn_idx) { true => { assert_bool_by_opt(ge_64(a, b), expected); }, false => (), }; + // Custom match if_test_this_function(192, fn_idx) { true => { assert_eq_opt(checked_div_64(a, b), expected); }, false => (), }; } diff --git a/tests/asserts_test.rs b/tests/asserts_test.rs index f53519e..fad2ee3 100644 --- a/tests/asserts_test.rs +++ b/tests/asserts_test.rs @@ -67,7 +67,7 @@ pub fn generate_uints_in_one_range(same: bool, min_val: u128, max_val: u128) -> fn build_witness(function: FunctionToTest, same: bool, none: bool) -> AssertsTestWitness { let mut witness = AssertsTestWitness { function_index: 0, - first_arg_u1: DEFAULT_SOME_U8, + first_arg_u1: DEFAULT_SOME_U8, // u1 in Simplicity is represented as u8 second_arg_u1: DEFAULT_SOME_U8, first_arg_u8: DEFAULT_SOME_U8, second_arg_u8: DEFAULT_SOME_U8, From 244bc8272ad882782b56ea572fc5e43fa2397ae2 Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Fri, 17 Jul 2026 16:51:31 +0300 Subject: [PATCH 5/5] refactor: naming for elliptic curve operations --- .../{ec/ops.simf => secp256k1/operations.simf} | 0 ...test.simf => secp256k1_operations_test.simf} | 2 +- tests/ec_tests.rs | 17 ++++++++--------- 3 files changed, 9 insertions(+), 10 deletions(-) rename simf/lib/{ec/ops.simf => secp256k1/operations.simf} (100%) rename simf/{ec_ops_test.simf => secp256k1_operations_test.simf} (98%) diff --git a/simf/lib/ec/ops.simf b/simf/lib/secp256k1/operations.simf similarity index 100% rename from simf/lib/ec/ops.simf rename to simf/lib/secp256k1/operations.simf diff --git a/simf/ec_ops_test.simf b/simf/secp256k1_operations_test.simf similarity index 98% rename from simf/ec_ops_test.simf rename to simf/secp256k1_operations_test.simf index 8d73f2d..991eae8 100644 --- a/simf/ec_ops_test.simf +++ b/simf/secp256k1_operations_test.simf @@ -1,4 +1,4 @@ -use crate::lib::ec::ops::{ +use crate::lib::secp256k1::operations::{ ge_to_point, point_to_gej, fe_sub, scalar_sub, gej_sub, fe_eq, scalar_eq, ge_eq, gej_point_eq, safe_gej_normalize, assert_fe_eq, assert_scalar_eq, assert_ge_eq, assert_point_eq, assert_gej_point_eq, assert_gej_eq diff --git a/tests/ec_tests.rs b/tests/ec_tests.rs index b9f2589..08b5b87 100644 --- a/tests/ec_tests.rs +++ b/tests/ec_tests.rs @@ -1,6 +1,5 @@ mod common; -//use hex_literal::hex; use num_bigint::BigUint; use num_traits::Zero; use rand::{RngCore, rngs::OsRng}; @@ -8,9 +7,9 @@ use secp256k1_zkp::{PublicKey, Secp256k1, SecretKey, rand::rngs::OsRng as SecpOs use common::core::{Expect, run}; -use simplicityhl_std::artifacts::ec_ops_test::EcOpsTestProgram; -use simplicityhl_std::artifacts::ec_ops_test::derived_ec_ops_test::{ - EcOpsTestArguments, EcOpsTestWitness, +use simplicityhl_std::artifacts::secp256k1_operations_test::Secp256k1OperationsTestProgram; +use simplicityhl_std::artifacts::secp256k1_operations_test::derived_secp256k1_operations_test::{ + Secp256k1OperationsTestArguments, Secp256k1OperationsTestWitness, }; enum FunctionToTest { @@ -48,8 +47,8 @@ const SECP_N: [u8; 32] = [ 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41, ]; -fn program() -> EcOpsTestProgram { - EcOpsTestProgram::new(EcOpsTestArguments {}) +fn program() -> Secp256k1OperationsTestProgram { + Secp256k1OperationsTestProgram::new(Secp256k1OperationsTestArguments {}) } #[allow(clippy::too_many_arguments)] @@ -66,8 +65,8 @@ fn build_witness( expected_ge: ([u8; 32], [u8; 32]), expected_gej: (([u8; 32], [u8; 32]), [u8; 32]), expected_point: (u8, [u8; 32]), -) -> EcOpsTestWitness { - EcOpsTestWitness { +) -> Secp256k1OperationsTestWitness { + Secp256k1OperationsTestWitness { function_index: function, first_uint, second_uint, @@ -195,7 +194,7 @@ fn pk_to_gej(pk: &PublicKey) -> (([u8; 32], [u8; 32]), [u8; 32]) { ge_to_gej((x, y)) } -mod ec_ops_tests { +mod secp256k1_operations_tests { use super::*; // 0. ge_to_point