miden_precompiles/math/uint/
domain.rs1use miden_core::Felt;
4
5use super::spec::{Limbs, UintSpec};
6use crate::math::{k1_base::K1Base, k1_scalar::K1Scalar, u256::U256};
7
8pub const U256_BOUND_PTR: u32 = 1;
10pub const K1_BASE_BOUND_PTR: u32 = 2;
12pub const K1_SCALAR_BOUND_PTR: u32 = 3;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum UintDomain {
18 U256,
20 K1Base,
22 K1Scalar,
24}
25
26impl UintDomain {
27 pub const ALL: [Self; 3] = [Self::U256, Self::K1Base, Self::K1Scalar];
29
30 pub fn from_id(id: Felt) -> Option<Self> {
32 match id {
33 id if id == <U256 as UintSpec>::ID => Some(Self::U256),
34 id if id == <K1Base as UintSpec>::ID => Some(Self::K1Base),
35 id if id == <K1Scalar as UintSpec>::ID => Some(Self::K1Scalar),
36 _ => None,
37 }
38 }
39
40 pub fn id(self) -> Felt {
42 match self {
43 Self::U256 => <U256 as UintSpec>::ID,
44 Self::K1Base => <K1Base as UintSpec>::ID,
45 Self::K1Scalar => <K1Scalar as UintSpec>::ID,
46 }
47 }
48
49 pub const fn bound_ptr(self) -> u32 {
51 match self {
52 Self::U256 => U256_BOUND_PTR,
53 Self::K1Base => K1_BASE_BOUND_PTR,
54 Self::K1Scalar => K1_SCALAR_BOUND_PTR,
55 }
56 }
57
58 pub const fn from_bound_ptr(ptr: u32) -> Option<Self> {
60 match ptr {
61 U256_BOUND_PTR => Some(Self::U256),
62 K1_BASE_BOUND_PTR => Some(Self::K1Base),
63 K1_SCALAR_BOUND_PTR => Some(Self::K1Scalar),
64 _ => None,
65 }
66 }
67
68 pub fn encoded_modulus(self) -> Limbs {
70 match self {
71 Self::U256 => <U256 as UintSpec>::ENCODED_MODULUS,
72 Self::K1Base => <K1Base as UintSpec>::ENCODED_MODULUS,
73 Self::K1Scalar => <K1Scalar as UintSpec>::ENCODED_MODULUS,
74 }
75 }
76
77 pub fn is_prime_field(self) -> bool {
79 match self {
80 Self::U256 => <U256 as UintSpec>::IS_PRIME_FIELD,
81 Self::K1Base => <K1Base as UintSpec>::IS_PRIME_FIELD,
82 Self::K1Scalar => <K1Scalar as UintSpec>::IS_PRIME_FIELD,
83 }
84 }
85
86 pub fn is_canonical(self, value: &Limbs) -> bool {
88 match self {
89 Self::U256 => U256::is_canonical(value),
90 Self::K1Base => K1Base::is_canonical(value),
91 Self::K1Scalar => K1Scalar::is_canonical(value),
92 }
93 }
94
95 pub fn add(self, lhs: Limbs, rhs: Limbs) -> Limbs {
97 match self {
98 Self::U256 => U256::add(lhs, rhs),
99 Self::K1Base => K1Base::add(lhs, rhs),
100 Self::K1Scalar => K1Scalar::add(lhs, rhs),
101 }
102 }
103
104 pub fn sub(self, lhs: Limbs, rhs: Limbs) -> Limbs {
106 match self {
107 Self::U256 => U256::sub(lhs, rhs),
108 Self::K1Base => K1Base::sub(lhs, rhs),
109 Self::K1Scalar => K1Scalar::sub(lhs, rhs),
110 }
111 }
112
113 pub fn mul(self, lhs: Limbs, rhs: Limbs) -> Limbs {
115 match self {
116 Self::U256 => U256::mul(lhs, rhs),
117 Self::K1Base => K1Base::mul(lhs, rhs),
118 Self::K1Scalar => K1Scalar::mul(lhs, rhs),
119 }
120 }
121
122 pub fn inv(self, value: Limbs) -> Option<Limbs> {
124 match self {
125 Self::U256 => U256::inv(value),
126 Self::K1Base => K1Base::inv(value),
127 Self::K1Scalar => K1Scalar::inv(value),
128 }
129 }
130
131 pub fn max(self) -> Option<Limbs> {
133 match self {
134 Self::U256 => Some(U256::MAX),
135 _ => None,
136 }
137 }
138
139 pub fn minus_one(self) -> Limbs {
141 match self {
142 Self::U256 => U256::minus_one(),
143 Self::K1Base => K1Base::minus_one(),
144 Self::K1Scalar => K1Scalar::minus_one(),
145 }
146 }
147
148 pub fn half(self) -> Option<Limbs> {
150 match self {
151 Self::U256 => U256::half(),
152 Self::K1Base => K1Base::half(),
153 Self::K1Scalar => K1Scalar::half(),
154 }
155 }
156
157 pub fn pow2_mod(self, exponent: usize) -> Option<Limbs> {
159 match self {
160 Self::U256 => U256::pow2_mod(exponent),
161 Self::K1Base => K1Base::pow2_mod(exponent),
162 Self::K1Scalar => K1Scalar::pow2_mod(exponent),
163 }
164 }
165
166 pub fn field_constants(self) -> Option<[Limbs; 5]> {
168 if self.is_prime_field() {
169 Some([
170 self.minus_one(),
171 self.half()?,
172 self.pow2_mod(128)?,
173 self.pow2_mod(256)?,
174 self.pow2_mod(384)?,
175 ])
176 } else {
177 None
178 }
179 }
180}