Skip to main content

miden_stdlib_sys/intrinsics/
felt.rs

1//! Felt-related intrinsics and helpers.
2
3pub use miden_field::{Felt, FeltError};
4
5#[cfg(all(target_family = "wasm", miden))]
6unsafe extern "C" {
7    #[link_name = "intrinsics::felt::assert"]
8    fn extern_assert(a: Felt);
9
10    #[link_name = "intrinsics::felt::assertz"]
11    fn extern_assertz(a: Felt);
12
13    #[link_name = "intrinsics::felt::assert_eq"]
14    fn extern_assert_eq(a: Felt, b: Felt);
15}
16
17/// Fails if `a` != 1.
18#[cfg(all(target_family = "wasm", miden))]
19#[inline(always)]
20pub fn assert(a: Felt) {
21    unsafe { extern_assert(a) }
22}
23
24/// Fails if `a` != 0.
25#[cfg(all(target_family = "wasm", miden))]
26#[inline(always)]
27pub fn assertz(a: Felt) {
28    unsafe { extern_assertz(a) }
29}
30
31/// Fails if `a` != `b`.
32#[cfg(all(target_family = "wasm", miden))]
33#[inline(always)]
34pub fn assert_eq(a: Felt, b: Felt) {
35    unsafe { extern_assert_eq(a, b) }
36}
37
38/// Fails if `a` != 1.
39#[cfg(not(all(target_family = "wasm", miden)))]
40#[inline(always)]
41pub fn assert(a: Felt) {
42    if a != Felt::from_u64_unchecked(1) {
43        panic!("assert: expected 1");
44    }
45}
46
47/// Fails if `a` != 0.
48#[cfg(not(all(target_family = "wasm", miden)))]
49#[inline(always)]
50pub fn assertz(a: Felt) {
51    if a != Felt::from_u64_unchecked(0) {
52        panic!("assertz: expected 0");
53    }
54}
55
56/// Fails if `a` != `b`.
57#[cfg(not(all(target_family = "wasm", miden)))]
58#[inline(always)]
59pub fn assert_eq(a: Felt, b: Felt) {
60    if a != b {
61        panic!("assert_eq: values differ");
62    }
63}
64
65/// Creates a `Felt` from an integer constant checking that it is within the
66/// valid range at compile time.
67#[macro_export]
68macro_rules! felt {
69    // Trigger a compile-time error if the value is not a constant
70    ($value:literal) => {{
71        const VALUE: u64 = $value as u64;
72        // assert!(VALUE <= Felt::M, "Invalid Felt value, must be >= 0 and <= 2^64 - 2^32 + 1");
73        // Temporarily switch to `from_u32` to use `bitcast` and avoid checks.
74        // see https://github.com/0xMiden/compiler/issues/361
75        assert!(VALUE <= u32::MAX as u64, "Invalid value, must be >= 0 and <= 2^32");
76        const VALUE_U32: u32 = $value as u32;
77        $crate::Felt::from_u32(VALUE_U32)
78    }};
79}