1use alloc::{
2 string::{String, ToString},
3 vec::Vec,
4};
5
6use miden_core::{Word, field::PrimeField64};
7pub use miden_processor::Felt as RawFelt;
8#[cfg(feature = "proptest")]
9use proptest::{
10 arbitrary::Arbitrary,
11 strategy::{BoxedStrategy, Strategy},
12};
13use serde::Deserialize;
14use smallvec::{SmallVec, smallvec};
15
16pub trait ToMidenRepr {
17 fn to_bytes(&self) -> SmallVec<[u8; 16]>;
22 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
26 let bytes = self.to_bytes();
27 let num_felts = bytes.len().div_ceil(4);
28 let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(num_felts);
29 let (chunks, remainder) = bytes.as_chunks::<4>();
30 for chunk in chunks {
31 felts.push(
32 RawFelt::new(u32::from_ne_bytes(*chunk) as u64)
33 .expect("value exceeds field modulus"),
34 );
35 }
36 if !remainder.is_empty() {
37 let mut chunk = [0u8; 4];
38 for (i, byte) in remainder.iter().enumerate() {
39 chunk[i] = *byte;
40 }
41 felts.push(
42 RawFelt::new(u32::from_ne_bytes(chunk) as u64)
43 .expect("value exceeds field modulus"),
44 );
45 }
46 felts
47 }
48 fn to_words(&self) -> SmallVec<[Word; 1]> {
55 let felts = self.to_felts();
56 let num_words = felts.len().div_ceil(4);
57 let mut words = SmallVec::<[Word; 1]>::with_capacity(num_words);
58 let (chunks, remainder) = felts.as_chunks::<4>();
59 for mut word in chunks.iter().copied() {
60 word.reverse();
61 words.push(Word::new(word));
62 }
63 if !remainder.is_empty() {
64 let mut word = [RawFelt::ZERO; 4];
65 for (i, felt) in remainder.iter().enumerate() {
66 word[i] = *felt;
67 }
68 word.reverse();
69 words.push(Word::new(word));
70 }
71 words
72 }
73
74 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
79 stack.extend(self.to_felts());
80 }
81
82 fn push_words_to_advice_stack(&self, stack: &mut Vec<RawFelt>) -> usize {
89 let words = self.to_words();
90 let num_words = words.len();
91 for word in words.into_iter().rev() {
92 for felt in word.into_iter() {
93 stack.push(felt);
94 }
95 }
96 num_words
97 }
98}
99
100pub trait FromMidenRepr: Sized {
101 fn size_in_felts() -> usize;
103 fn from_bytes(bytes: &[u8]) -> Self;
108 fn from_felts(felts: &[RawFelt]) -> Self {
113 let mut bytes = SmallVec::<[u8; 16]>::with_capacity(felts.len() * 4);
114 for felt in felts {
115 let chunk = (felt.as_canonical_u64() as u32).to_ne_bytes();
116 bytes.extend(chunk);
117 }
118 Self::from_bytes(&bytes)
119 }
120 fn from_words(words: &[Word]) -> Self {
130 let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(words.len() * 4);
131 for word in words {
132 for felt in word.iter().copied().rev() {
133 felts.push(felt);
134 }
135 }
136 Self::from_felts(&felts)
137 }
138
139 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
142 let needed = Self::size_in_felts();
143 let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(needed);
144 for _ in 0..needed {
145 felts.push(stack.pop().unwrap());
146 }
147 Self::from_felts(&felts)
148 }
149}
150
151impl ToMidenRepr for bool {
152 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
153 smallvec![*self as u8]
154 }
155
156 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
157 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
158 }
159
160 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
161 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
162 }
163}
164
165impl FromMidenRepr for bool {
166 #[inline(always)]
167 fn size_in_felts() -> usize {
168 1
169 }
170
171 fn from_bytes(bytes: &[u8]) -> Self {
172 match bytes[0] {
173 0 => false,
174 1 => true,
175 n => panic!("invalid byte representation for boolean: {n:0x}"),
176 }
177 }
178
179 fn from_felts(felts: &[RawFelt]) -> Self {
180 match felts[0].as_canonical_u64() {
181 0 => false,
182 1 => true,
183 n => panic!("invalid byte representation for boolean: {n:0x}"),
184 }
185 }
186
187 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
188 match stack.pop().unwrap().as_canonical_u64() {
189 0 => false,
190 1 => true,
191 n => panic!("invalid byte representation for boolean: {n:0x}"),
192 }
193 }
194}
195
196impl ToMidenRepr for u8 {
197 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
198 smallvec![*self]
199 }
200
201 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
202 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
203 }
204
205 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
206 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
207 }
208}
209
210impl FromMidenRepr for u8 {
211 #[inline(always)]
212 fn size_in_felts() -> usize {
213 1
214 }
215
216 #[inline(always)]
217 fn from_bytes(bytes: &[u8]) -> Self {
218 bytes[0]
219 }
220
221 fn from_felts(felts: &[RawFelt]) -> Self {
222 felts[0].as_canonical_u64() as u8
223 }
224
225 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
226 stack.pop().unwrap().as_canonical_u64() as u8
227 }
228}
229
230impl ToMidenRepr for i8 {
231 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
232 smallvec![*self as u8]
233 }
234
235 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
236 smallvec![RawFelt::new(*self as u8 as u64).expect("value exceeds field modulus")]
237 }
238
239 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
240 stack.push(RawFelt::new(*self as u8 as u64).expect("value exceeds field modulus"));
241 }
242}
243
244impl FromMidenRepr for i8 {
245 #[inline(always)]
246 fn size_in_felts() -> usize {
247 1
248 }
249
250 #[inline(always)]
251 fn from_bytes(bytes: &[u8]) -> Self {
252 bytes[0] as i8
253 }
254
255 fn from_felts(felts: &[RawFelt]) -> Self {
256 felts[0].as_canonical_u64() as u8 as i8
257 }
258
259 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
260 stack.pop().unwrap().as_canonical_u64() as u8 as i8
261 }
262}
263
264impl ToMidenRepr for u16 {
265 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
266 SmallVec::from_slice(&self.to_ne_bytes())
267 }
268
269 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
270 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
271 }
272
273 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
274 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
275 }
276}
277
278impl FromMidenRepr for u16 {
279 #[inline(always)]
280 fn size_in_felts() -> usize {
281 1
282 }
283
284 fn from_bytes(bytes: &[u8]) -> Self {
285 assert!(bytes.len() >= 2);
286 u16::from_ne_bytes([bytes[0], bytes[1]])
287 }
288
289 fn from_felts(felts: &[RawFelt]) -> Self {
290 felts[0].as_canonical_u64() as u16
291 }
292
293 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
294 stack.pop().unwrap().as_canonical_u64() as u16
295 }
296}
297
298impl ToMidenRepr for i16 {
299 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
300 SmallVec::from_slice(&self.to_ne_bytes())
301 }
302
303 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
304 smallvec![RawFelt::new(*self as u16 as u64).expect("value exceeds field modulus")]
305 }
306
307 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
308 stack.push(RawFelt::new(*self as u16 as u64).expect("value exceeds field modulus"));
309 }
310}
311
312impl FromMidenRepr for i16 {
313 #[inline(always)]
314 fn size_in_felts() -> usize {
315 1
316 }
317
318 fn from_bytes(bytes: &[u8]) -> Self {
319 assert!(bytes.len() >= 2);
320 i16::from_ne_bytes([bytes[0], bytes[1]])
321 }
322
323 fn from_felts(felts: &[RawFelt]) -> Self {
324 felts[0].as_canonical_u64() as u16 as i16
325 }
326
327 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
328 stack.pop().unwrap().as_canonical_u64() as u16 as i16
329 }
330}
331
332impl ToMidenRepr for u32 {
333 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
334 SmallVec::from_slice(&self.to_ne_bytes())
335 }
336
337 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
338 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
339 }
340
341 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
342 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
343 }
344}
345
346impl FromMidenRepr for u32 {
347 #[inline(always)]
348 fn size_in_felts() -> usize {
349 1
350 }
351
352 fn from_bytes(bytes: &[u8]) -> Self {
353 assert!(bytes.len() >= 4);
354 u32::from_ne_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
355 }
356
357 fn from_felts(felts: &[RawFelt]) -> Self {
358 felts[0].as_canonical_u64() as u32
359 }
360
361 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
362 stack.pop().unwrap().as_canonical_u64() as u32
363 }
364}
365
366impl ToMidenRepr for i32 {
367 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
368 SmallVec::from_slice(&self.to_ne_bytes())
369 }
370
371 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
372 smallvec![RawFelt::new(*self as u32 as u64).expect("value exceeds field modulus")]
373 }
374
375 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
376 stack.push(RawFelt::new(*self as u32 as u64).expect("value exceeds field modulus"));
377 }
378}
379
380impl FromMidenRepr for i32 {
381 #[inline(always)]
382 fn size_in_felts() -> usize {
383 1
384 }
385
386 fn from_bytes(bytes: &[u8]) -> Self {
387 assert!(bytes.len() >= 4);
388 i32::from_ne_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
389 }
390
391 fn from_felts(felts: &[RawFelt]) -> Self {
392 felts[0].as_canonical_u64() as u32 as i32
393 }
394
395 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
396 stack.pop().unwrap().as_canonical_u64() as u32 as i32
397 }
398}
399
400impl ToMidenRepr for u64 {
401 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
402 SmallVec::from_slice(&self.to_le_bytes())
403 }
404
405 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
406 let lo = (*self as u32) as u64;
407 let hi = *self >> 32;
408 smallvec![
409 RawFelt::new(lo).expect("value exceeds field modulus"),
410 RawFelt::new(hi).expect("value exceeds field modulus"),
411 ]
412 }
413}
414
415impl FromMidenRepr for u64 {
416 #[inline(always)]
417 fn size_in_felts() -> usize {
418 2
419 }
420
421 fn from_bytes(bytes: &[u8]) -> Self {
422 assert!(bytes.len() >= 8);
423 u64::from_le_bytes([
424 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
425 ])
426 }
427
428 fn from_felts(felts: &[RawFelt]) -> Self {
429 assert!(felts.len() >= 2);
430 let lo = felts[0].as_canonical_u64() as u32 as u64;
431 let hi = felts[1].as_canonical_u64() as u32 as u64;
432 lo | (hi << 32)
433 }
434}
435
436impl ToMidenRepr for i64 {
437 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
438 SmallVec::from_slice(&self.to_le_bytes())
439 }
440
441 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
442 (*self as u64).to_felts()
443 }
444}
445
446impl FromMidenRepr for i64 {
447 #[inline(always)]
448 fn size_in_felts() -> usize {
449 2
450 }
451
452 fn from_bytes(bytes: &[u8]) -> Self {
453 u64::from_bytes(bytes) as i64
454 }
455
456 fn from_felts(felts: &[RawFelt]) -> Self {
457 u64::from_felts(felts) as i64
458 }
459}
460
461impl ToMidenRepr for u128 {
462 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
463 SmallVec::from_slice(&self.to_le_bytes())
464 }
465
466 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
467 let lo_lo = RawFelt::new((*self as u32) as u64).expect("value exceeds field modulus");
468 let lo_hi =
469 RawFelt::new(((*self >> 32) as u32) as u64).expect("value exceeds field modulus");
470 let hi_lo =
471 RawFelt::new(((*self >> 64) as u32) as u64).expect("value exceeds field modulus");
472 let hi_hi =
473 RawFelt::new(((*self >> 96) as u32) as u64).expect("value exceeds field modulus");
474 smallvec![lo_lo, lo_hi, hi_lo, hi_hi]
475 }
476}
477
478impl FromMidenRepr for u128 {
479 #[inline(always)]
480 fn size_in_felts() -> usize {
481 4
482 }
483
484 fn from_bytes(bytes: &[u8]) -> Self {
485 assert!(bytes.len() >= 16);
486 u128::from_le_bytes([
487 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
488 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
489 ])
490 }
491
492 fn from_felts(felts: &[RawFelt]) -> Self {
493 assert!(felts.len() >= 4);
494 let lo_lo = felts[0].as_canonical_u64() as u32 as u128;
495 let lo_hi = felts[1].as_canonical_u64() as u32 as u128;
496 let hi_lo = felts[2].as_canonical_u64() as u32 as u128;
497 let hi_hi = felts[3].as_canonical_u64() as u32 as u128;
498 lo_lo | (lo_hi << 32) | (hi_lo << 64) | (hi_hi << 96)
499 }
500}
501
502impl ToMidenRepr for i128 {
503 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
504 SmallVec::from_slice(&self.to_le_bytes())
505 }
506
507 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
508 (*self as u128).to_felts()
509 }
510}
511
512impl FromMidenRepr for i128 {
513 #[inline(always)]
514 fn size_in_felts() -> usize {
515 4
516 }
517
518 fn from_bytes(bytes: &[u8]) -> Self {
519 u128::from_bytes(bytes) as i128
520 }
521
522 fn from_felts(felts: &[RawFelt]) -> Self {
523 u128::from_felts(felts) as i128
524 }
525}
526
527impl ToMidenRepr for RawFelt {
528 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
529 panic!("field elements have no canonical byte representation")
530 }
531
532 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
533 smallvec![*self]
534 }
535
536 fn to_words(&self) -> SmallVec<[Word; 1]> {
537 let mut word = [RawFelt::ZERO; 4];
538 word[0] = *self;
539 smallvec![Word::new(word)]
540 }
541}
542
543impl FromMidenRepr for RawFelt {
544 #[inline(always)]
545 fn size_in_felts() -> usize {
546 1
547 }
548
549 fn from_bytes(_bytes: &[u8]) -> Self {
550 panic!("field elements have no canonical byte representation")
551 }
552
553 #[inline(always)]
554 fn from_felts(felts: &[RawFelt]) -> Self {
555 felts[0]
556 }
557
558 #[inline(always)]
559 fn from_words(words: &[Word]) -> Self {
560 words[0][0]
561 }
562}
563
564impl ToMidenRepr for Felt {
565 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
566 panic!("field elements have no canonical byte representation")
567 }
568
569 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
570 smallvec![self.0]
571 }
572
573 fn to_words(&self) -> SmallVec<[Word; 1]> {
574 let mut word = [RawFelt::ZERO; 4];
575 word[0] = self.0;
576 smallvec![Word::new(word)]
577 }
578}
579
580impl FromMidenRepr for Felt {
581 #[inline(always)]
582 fn size_in_felts() -> usize {
583 1
584 }
585
586 fn from_bytes(_bytes: &[u8]) -> Self {
587 panic!("field elements have no canonical byte representation")
588 }
589
590 #[inline(always)]
591 fn from_felts(felts: &[RawFelt]) -> Self {
592 Felt(felts[0])
593 }
594
595 #[inline(always)]
596 fn from_words(words: &[Word]) -> Self {
597 Felt(words[0][0])
598 }
599}
600
601impl<const N: usize> ToMidenRepr for [u8; N] {
602 #[inline]
603 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
604 SmallVec::from_slice(self)
605 }
606}
607
608impl<const N: usize> FromMidenRepr for [u8; N] {
609 #[inline(always)]
610 fn size_in_felts() -> usize {
611 N.div_ceil(4)
612 }
613
614 fn from_bytes(bytes: &[u8]) -> Self {
615 assert!(bytes.len() >= N, "insufficient bytes");
616 Self::try_from(&bytes[..N]).unwrap()
617 }
618}
619
620impl FromMidenRepr for [Felt; 4] {
621 #[inline(always)]
622 fn size_in_felts() -> usize {
623 4
624 }
625
626 fn from_bytes(_bytes: &[u8]) -> Self {
627 panic!("field elements have no canonical byte representation")
628 }
629
630 #[inline(always)]
631 fn from_felts(felts: &[RawFelt]) -> Self {
632 [Felt(felts[0]), Felt(felts[1]), Felt(felts[2]), Felt(felts[3])]
633 }
634}
635
636pub fn bytes_to_words(bytes: &[u8]) -> Vec<[RawFelt; 4]> {
649 let (chunks, remainder) = bytes.as_chunks::<4>();
651 let padded_bytes = bytes.len().next_multiple_of(16);
652 let num_felts = padded_bytes / 4;
653 let mut buf = Vec::with_capacity(num_felts);
654 for chunk in chunks {
655 let n = u32::from_ne_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]);
656 buf.push(n);
657 }
658 if !remainder.is_empty() {
660 let mut n_buf = [0u8; 4];
661 for (i, byte) in remainder.iter().enumerate() {
662 n_buf[i] = *byte;
663 }
664 buf.push(u32::from_ne_bytes(n_buf));
665 }
666 buf.resize(num_felts, 0);
668 let num_words = num_felts / 4;
670 let mut words = Vec::with_capacity(num_words);
671 let (chunks, remainder) = buf.as_chunks::<4>();
672 for chunk in chunks {
673 words.push([
674 RawFelt::new(chunk[3] as u64).expect("value exceeds field modulus"),
675 RawFelt::new(chunk[2] as u64).expect("value exceeds field modulus"),
676 RawFelt::new(chunk[1] as u64).expect("value exceeds field modulus"),
677 RawFelt::new(chunk[0] as u64).expect("value exceeds field modulus"),
678 ]);
679 }
680 if !remainder.is_empty() {
681 let mut word = [RawFelt::ZERO; 4];
682 for (i, n) in remainder.iter().enumerate() {
683 word[i] = RawFelt::new(*n as u64).expect("value exceeds field modulus");
684 }
685 word.reverse();
686 words.push(word);
687 }
688 words
689}
690
691#[derive(Debug, Copy, Clone, PartialEq, Eq)]
694pub struct Felt(pub RawFelt);
695impl Felt {
696 #[inline]
697 pub fn new(value: u64) -> Self {
698 Self(RawFelt::new(value).expect("value exceeds field modulus"))
699 }
700}
701
702impl<'de> Deserialize<'de> for Felt {
703 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
704 where
705 D: serde::Deserializer<'de>,
706 {
707 u64::deserialize(deserializer).and_then(|n| {
708 if n >= RawFelt::ORDER_U64 {
709 Err(serde::de::Error::custom(
710 "invalid field element value: exceeds the field modulus",
711 ))
712 } else {
713 Ok(Felt(RawFelt::new(n).expect("value exceeds field modulus")))
714 }
715 })
716 }
717}
718
719#[cfg(feature = "std")]
720impl clap::builder::ValueParserFactory for Felt {
721 type Parser = FeltParser;
722
723 fn value_parser() -> Self::Parser {
724 FeltParser
725 }
726}
727
728#[doc(hidden)]
729#[cfg(feature = "std")]
730#[derive(Clone)]
731pub struct FeltParser;
732#[cfg(feature = "std")]
733impl clap::builder::TypedValueParser for FeltParser {
734 type Value = Felt;
735
736 fn parse_ref(
737 &self,
738 _cmd: &clap::Command,
739 _arg: Option<&clap::Arg>,
740 value: &std::ffi::OsStr,
741 ) -> Result<Self::Value, clap::error::Error> {
742 use clap::error::{Error, ErrorKind};
743
744 let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?.trim();
745 value.parse().map_err(|err| Error::raw(ErrorKind::ValueValidation, err))
746 }
747}
748
749impl core::str::FromStr for Felt {
750 type Err = String;
751
752 fn from_str(s: &str) -> Result<Self, Self::Err> {
753 let value = if let Some(value) = s.strip_prefix("0x") {
754 u64::from_str_radix(value, 16)
755 .map_err(|err| format!("invalid field element value: {err}"))?
756 } else {
757 s.parse::<u64>().map_err(|err| format!("invalid field element value: {err}"))?
758 };
759
760 if value >= RawFelt::ORDER_U64 {
761 Err("invalid field element value: exceeds the field modulus".to_string())
762 } else {
763 Ok(Felt(RawFelt::new(value).expect("value exceeds field modulus")))
764 }
765 }
766}
767
768impl From<Felt> for miden_processor::Felt {
769 fn from(f: Felt) -> Self {
770 f.0
771 }
772}
773
774impl From<bool> for Felt {
775 fn from(b: bool) -> Self {
776 Self(RawFelt::new(b as u64).expect("value exceeds field modulus"))
777 }
778}
779
780impl From<u8> for Felt {
781 fn from(t: u8) -> Self {
782 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
783 }
784}
785
786impl From<i8> for Felt {
787 fn from(t: i8) -> Self {
788 Self(RawFelt::new(t as u8 as u64).expect("value exceeds field modulus"))
789 }
790}
791
792impl From<i16> for Felt {
793 fn from(t: i16) -> Self {
794 Self(RawFelt::new(t as u16 as u64).expect("value exceeds field modulus"))
795 }
796}
797
798impl From<u16> for Felt {
799 fn from(t: u16) -> Self {
800 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
801 }
802}
803
804impl From<i32> for Felt {
805 fn from(t: i32) -> Self {
806 Self(RawFelt::new(t as u32 as u64).expect("value exceeds field modulus"))
807 }
808}
809
810impl From<u32> for Felt {
811 fn from(t: u32) -> Self {
812 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
813 }
814}
815
816impl From<u64> for Felt {
817 fn from(t: u64) -> Self {
818 Self(RawFelt::new(t).expect("value exceeds field modulus"))
819 }
820}
821
822impl From<i64> for Felt {
823 fn from(t: i64) -> Self {
824 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
825 }
826}
827
828impl From<Felt> for bool {
831 fn from(f: Felt) -> Self {
832 f.0.as_canonical_u64() != 0
833 }
834}
835
836impl From<Felt> for u8 {
837 fn from(f: Felt) -> Self {
838 f.0.as_canonical_u64() as u8
839 }
840}
841
842impl From<Felt> for i8 {
843 fn from(f: Felt) -> Self {
844 f.0.as_canonical_u64() as i8
845 }
846}
847
848impl From<Felt> for u16 {
849 fn from(f: Felt) -> Self {
850 f.0.as_canonical_u64() as u16
851 }
852}
853
854impl From<Felt> for i16 {
855 fn from(f: Felt) -> Self {
856 f.0.as_canonical_u64() as i16
857 }
858}
859
860impl From<Felt> for u32 {
861 fn from(f: Felt) -> Self {
862 f.0.as_canonical_u64() as u32
863 }
864}
865
866impl From<Felt> for i32 {
867 fn from(f: Felt) -> Self {
868 f.0.as_canonical_u64() as i32
869 }
870}
871
872impl From<Felt> for u64 {
873 fn from(f: Felt) -> Self {
874 f.0.as_canonical_u64()
875 }
876}
877
878impl From<Felt> for i64 {
879 fn from(f: Felt) -> Self {
880 f.0.as_canonical_u64() as i64
881 }
882}
883
884#[cfg(feature = "proptest")]
885impl Arbitrary for Felt {
886 type Parameters = ();
887 type Strategy = BoxedStrategy<Self>;
888
889 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
890 (0u64..RawFelt::ORDER_U64)
891 .prop_map(|v| Felt(RawFelt::new(v).expect("value exceeds field modulus")))
892 .boxed()
893 }
894}
895
896pub fn push_wasm_ty_to_operand_stack<T>(value: T, stack: &mut Vec<RawFelt>)
901where
902 T: ToMidenRepr + num_traits::PrimInt,
903{
904 let ty_size = core::mem::size_of::<T>();
905 if ty_size > 2 {
906 value.push_to_operand_stack(stack);
907 return;
908 }
909
910 let is_signed = T::min_value() < T::zero();
911 let value_u32 = if is_signed {
913 value.to_i32().unwrap() as u32
914 } else {
915 value.to_u32().unwrap()
916 };
917 value_u32.push_to_operand_stack(stack);
918}
919
920#[cfg(test)]
921mod tests;