1use miden_core::{Word, field::PrimeField64};
2pub use miden_processor::Felt as RawFelt;
3#[cfg(feature = "proptest")]
4use proptest::{
5 arbitrary::Arbitrary,
6 strategy::{BoxedStrategy, Strategy},
7};
8use serde::Deserialize;
9use smallvec::{SmallVec, smallvec};
10
11pub trait ToMidenRepr {
12 fn to_bytes(&self) -> SmallVec<[u8; 16]>;
17 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
21 let bytes = self.to_bytes();
22 let num_felts = bytes.len().div_ceil(4);
23 let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(num_felts);
24 let (chunks, remainder) = bytes.as_chunks::<4>();
25 for chunk in chunks {
26 felts.push(
27 RawFelt::new(u32::from_ne_bytes(*chunk) as u64)
28 .expect("value exceeds field modulus"),
29 );
30 }
31 if !remainder.is_empty() {
32 let mut chunk = [0u8; 4];
33 for (i, byte) in remainder.iter().enumerate() {
34 chunk[i] = *byte;
35 }
36 felts.push(
37 RawFelt::new(u32::from_ne_bytes(chunk) as u64)
38 .expect("value exceeds field modulus"),
39 );
40 }
41 felts
42 }
43 fn to_words(&self) -> SmallVec<[Word; 1]> {
50 let felts = self.to_felts();
51 let num_words = felts.len().div_ceil(4);
52 let mut words = SmallVec::<[Word; 1]>::with_capacity(num_words);
53 let (chunks, remainder) = felts.as_chunks::<4>();
54 for mut word in chunks.iter().copied() {
55 word.reverse();
56 words.push(Word::new(word));
57 }
58 if !remainder.is_empty() {
59 let mut word = [RawFelt::ZERO; 4];
60 for (i, felt) in remainder.iter().enumerate() {
61 word[i] = *felt;
62 }
63 word.reverse();
64 words.push(Word::new(word));
65 }
66 words
67 }
68
69 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
74 stack.extend(self.to_felts());
75 }
76
77 fn push_words_to_advice_stack(&self, stack: &mut Vec<RawFelt>) -> usize {
84 let words = self.to_words();
85 let num_words = words.len();
86 for word in words.into_iter().rev() {
87 for felt in word.into_iter() {
88 stack.push(felt);
89 }
90 }
91 num_words
92 }
93}
94
95pub trait FromMidenRepr: Sized {
96 fn size_in_felts() -> usize;
98 fn from_bytes(bytes: &[u8]) -> Self;
103 fn from_felts(felts: &[RawFelt]) -> Self {
108 let mut bytes = SmallVec::<[u8; 16]>::with_capacity(felts.len() * 4);
109 for felt in felts {
110 let chunk = (felt.as_canonical_u64() as u32).to_ne_bytes();
111 bytes.extend(chunk);
112 }
113 Self::from_bytes(&bytes)
114 }
115 fn from_words(words: &[Word]) -> Self {
125 let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(words.len() * 4);
126 for word in words {
127 for felt in word.iter().copied().rev() {
128 felts.push(felt);
129 }
130 }
131 Self::from_felts(&felts)
132 }
133
134 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
137 let needed = Self::size_in_felts();
138 let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(needed);
139 for _ in 0..needed {
140 felts.push(stack.pop().unwrap());
141 }
142 Self::from_felts(&felts)
143 }
144}
145
146impl ToMidenRepr for bool {
147 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
148 smallvec![*self as u8]
149 }
150
151 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
152 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
153 }
154
155 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
156 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
157 }
158}
159
160impl FromMidenRepr for bool {
161 #[inline(always)]
162 fn size_in_felts() -> usize {
163 1
164 }
165
166 fn from_bytes(bytes: &[u8]) -> Self {
167 match bytes[0] {
168 0 => false,
169 1 => true,
170 n => panic!("invalid byte representation for boolean: {n:0x}"),
171 }
172 }
173
174 fn from_felts(felts: &[RawFelt]) -> Self {
175 match felts[0].as_canonical_u64() {
176 0 => false,
177 1 => true,
178 n => panic!("invalid byte representation for boolean: {n:0x}"),
179 }
180 }
181
182 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
183 match stack.pop().unwrap().as_canonical_u64() {
184 0 => false,
185 1 => true,
186 n => panic!("invalid byte representation for boolean: {n:0x}"),
187 }
188 }
189}
190
191impl ToMidenRepr for u8 {
192 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
193 smallvec![*self]
194 }
195
196 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
197 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
198 }
199
200 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
201 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
202 }
203}
204
205impl FromMidenRepr for u8 {
206 #[inline(always)]
207 fn size_in_felts() -> usize {
208 1
209 }
210
211 #[inline(always)]
212 fn from_bytes(bytes: &[u8]) -> Self {
213 bytes[0]
214 }
215
216 fn from_felts(felts: &[RawFelt]) -> Self {
217 felts[0].as_canonical_u64() as u8
218 }
219
220 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
221 stack.pop().unwrap().as_canonical_u64() as u8
222 }
223}
224
225impl ToMidenRepr for i8 {
226 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
227 smallvec![*self as u8]
228 }
229
230 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
231 smallvec![RawFelt::new(*self as u8 as u64).expect("value exceeds field modulus")]
232 }
233
234 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
235 stack.push(RawFelt::new(*self as u8 as u64).expect("value exceeds field modulus"));
236 }
237}
238
239impl FromMidenRepr for i8 {
240 #[inline(always)]
241 fn size_in_felts() -> usize {
242 1
243 }
244
245 #[inline(always)]
246 fn from_bytes(bytes: &[u8]) -> Self {
247 bytes[0] as i8
248 }
249
250 fn from_felts(felts: &[RawFelt]) -> Self {
251 felts[0].as_canonical_u64() as u8 as i8
252 }
253
254 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
255 stack.pop().unwrap().as_canonical_u64() as u8 as i8
256 }
257}
258
259impl ToMidenRepr for u16 {
260 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
261 SmallVec::from_slice(&self.to_ne_bytes())
262 }
263
264 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
265 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
266 }
267
268 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
269 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
270 }
271}
272
273impl FromMidenRepr for u16 {
274 #[inline(always)]
275 fn size_in_felts() -> usize {
276 1
277 }
278
279 fn from_bytes(bytes: &[u8]) -> Self {
280 assert!(bytes.len() >= 2);
281 u16::from_ne_bytes([bytes[0], bytes[1]])
282 }
283
284 fn from_felts(felts: &[RawFelt]) -> Self {
285 felts[0].as_canonical_u64() as u16
286 }
287
288 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
289 stack.pop().unwrap().as_canonical_u64() as u16
290 }
291}
292
293impl ToMidenRepr for i16 {
294 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
295 SmallVec::from_slice(&self.to_ne_bytes())
296 }
297
298 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
299 smallvec![RawFelt::new(*self as u16 as u64).expect("value exceeds field modulus")]
300 }
301
302 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
303 stack.push(RawFelt::new(*self as u16 as u64).expect("value exceeds field modulus"));
304 }
305}
306
307impl FromMidenRepr for i16 {
308 #[inline(always)]
309 fn size_in_felts() -> usize {
310 1
311 }
312
313 fn from_bytes(bytes: &[u8]) -> Self {
314 assert!(bytes.len() >= 2);
315 i16::from_ne_bytes([bytes[0], bytes[1]])
316 }
317
318 fn from_felts(felts: &[RawFelt]) -> Self {
319 felts[0].as_canonical_u64() as u16 as i16
320 }
321
322 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
323 stack.pop().unwrap().as_canonical_u64() as u16 as i16
324 }
325}
326
327impl ToMidenRepr for u32 {
328 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
329 SmallVec::from_slice(&self.to_ne_bytes())
330 }
331
332 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
333 smallvec![RawFelt::new(*self as u64).expect("value exceeds field modulus")]
334 }
335
336 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
337 stack.push(RawFelt::new(*self as u64).expect("value exceeds field modulus"));
338 }
339}
340
341impl FromMidenRepr for u32 {
342 #[inline(always)]
343 fn size_in_felts() -> usize {
344 1
345 }
346
347 fn from_bytes(bytes: &[u8]) -> Self {
348 assert!(bytes.len() >= 4);
349 u32::from_ne_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
350 }
351
352 fn from_felts(felts: &[RawFelt]) -> Self {
353 felts[0].as_canonical_u64() as u32
354 }
355
356 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
357 stack.pop().unwrap().as_canonical_u64() as u32
358 }
359}
360
361impl ToMidenRepr for i32 {
362 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
363 SmallVec::from_slice(&self.to_ne_bytes())
364 }
365
366 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
367 smallvec![RawFelt::new(*self as u32 as u64).expect("value exceeds field modulus")]
368 }
369
370 fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
371 stack.push(RawFelt::new(*self as u32 as u64).expect("value exceeds field modulus"));
372 }
373}
374
375impl FromMidenRepr for i32 {
376 #[inline(always)]
377 fn size_in_felts() -> usize {
378 1
379 }
380
381 fn from_bytes(bytes: &[u8]) -> Self {
382 assert!(bytes.len() >= 4);
383 i32::from_ne_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
384 }
385
386 fn from_felts(felts: &[RawFelt]) -> Self {
387 felts[0].as_canonical_u64() as u32 as i32
388 }
389
390 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
391 stack.pop().unwrap().as_canonical_u64() as u32 as i32
392 }
393}
394
395impl ToMidenRepr for u64 {
396 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
397 SmallVec::from_slice(&self.to_le_bytes())
398 }
399
400 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
401 let lo = (*self as u32) as u64;
402 let hi = *self >> 32;
403 smallvec![
404 RawFelt::new(lo).expect("value exceeds field modulus"),
405 RawFelt::new(hi).expect("value exceeds field modulus"),
406 ]
407 }
408}
409
410impl FromMidenRepr for u64 {
411 #[inline(always)]
412 fn size_in_felts() -> usize {
413 2
414 }
415
416 fn from_bytes(bytes: &[u8]) -> Self {
417 assert!(bytes.len() >= 8);
418 u64::from_le_bytes([
419 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
420 ])
421 }
422
423 fn from_felts(felts: &[RawFelt]) -> Self {
424 assert!(felts.len() >= 2);
425 let lo = felts[0].as_canonical_u64() as u32 as u64;
426 let hi = felts[1].as_canonical_u64() as u32 as u64;
427 lo | (hi << 32)
428 }
429}
430
431impl ToMidenRepr for i64 {
432 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
433 SmallVec::from_slice(&self.to_le_bytes())
434 }
435
436 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
437 (*self as u64).to_felts()
438 }
439}
440
441impl FromMidenRepr for i64 {
442 #[inline(always)]
443 fn size_in_felts() -> usize {
444 2
445 }
446
447 fn from_bytes(bytes: &[u8]) -> Self {
448 u64::from_bytes(bytes) as i64
449 }
450
451 fn from_felts(felts: &[RawFelt]) -> Self {
452 u64::from_felts(felts) as i64
453 }
454}
455
456impl ToMidenRepr for u128 {
457 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
458 SmallVec::from_slice(&self.to_le_bytes())
459 }
460
461 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
462 let lo_lo = RawFelt::new((*self as u32) as u64).expect("value exceeds field modulus");
463 let lo_hi =
464 RawFelt::new(((*self >> 32) as u32) as u64).expect("value exceeds field modulus");
465 let hi_lo =
466 RawFelt::new(((*self >> 64) as u32) as u64).expect("value exceeds field modulus");
467 let hi_hi =
468 RawFelt::new(((*self >> 96) as u32) as u64).expect("value exceeds field modulus");
469 smallvec![lo_lo, lo_hi, hi_lo, hi_hi]
470 }
471}
472
473impl FromMidenRepr for u128 {
474 #[inline(always)]
475 fn size_in_felts() -> usize {
476 4
477 }
478
479 fn from_bytes(bytes: &[u8]) -> Self {
480 assert!(bytes.len() >= 16);
481 u128::from_le_bytes([
482 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
483 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
484 ])
485 }
486
487 fn from_felts(felts: &[RawFelt]) -> Self {
488 assert!(felts.len() >= 4);
489 let lo_lo = felts[0].as_canonical_u64() as u32 as u128;
490 let lo_hi = felts[1].as_canonical_u64() as u32 as u128;
491 let hi_lo = felts[2].as_canonical_u64() as u32 as u128;
492 let hi_hi = felts[3].as_canonical_u64() as u32 as u128;
493 lo_lo | (lo_hi << 32) | (hi_lo << 64) | (hi_hi << 96)
494 }
495}
496
497impl ToMidenRepr for i128 {
498 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
499 SmallVec::from_slice(&self.to_le_bytes())
500 }
501
502 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
503 (*self as u128).to_felts()
504 }
505}
506
507impl FromMidenRepr for i128 {
508 #[inline(always)]
509 fn size_in_felts() -> usize {
510 4
511 }
512
513 fn from_bytes(bytes: &[u8]) -> Self {
514 u128::from_bytes(bytes) as i128
515 }
516
517 fn from_felts(felts: &[RawFelt]) -> Self {
518 u128::from_felts(felts) as i128
519 }
520}
521
522impl ToMidenRepr for RawFelt {
523 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
524 panic!("field elements have no canonical byte representation")
525 }
526
527 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
528 smallvec![*self]
529 }
530
531 fn to_words(&self) -> SmallVec<[Word; 1]> {
532 let mut word = [RawFelt::ZERO; 4];
533 word[0] = *self;
534 smallvec![Word::new(word)]
535 }
536}
537
538impl FromMidenRepr for RawFelt {
539 #[inline(always)]
540 fn size_in_felts() -> usize {
541 1
542 }
543
544 fn from_bytes(_bytes: &[u8]) -> Self {
545 panic!("field elements have no canonical byte representation")
546 }
547
548 #[inline(always)]
549 fn from_felts(felts: &[RawFelt]) -> Self {
550 felts[0]
551 }
552
553 #[inline(always)]
554 fn from_words(words: &[Word]) -> Self {
555 words[0][0]
556 }
557}
558
559impl ToMidenRepr for Felt {
560 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
561 panic!("field elements have no canonical byte representation")
562 }
563
564 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
565 smallvec![self.0]
566 }
567
568 fn to_words(&self) -> SmallVec<[Word; 1]> {
569 let mut word = [RawFelt::ZERO; 4];
570 word[0] = self.0;
571 smallvec![Word::new(word)]
572 }
573}
574
575impl FromMidenRepr for Felt {
576 #[inline(always)]
577 fn size_in_felts() -> usize {
578 1
579 }
580
581 fn from_bytes(_bytes: &[u8]) -> Self {
582 panic!("field elements have no canonical byte representation")
583 }
584
585 #[inline(always)]
586 fn from_felts(felts: &[RawFelt]) -> Self {
587 Felt(felts[0])
588 }
589
590 #[inline(always)]
591 fn from_words(words: &[Word]) -> Self {
592 Felt(words[0][0])
593 }
594}
595
596impl<const N: usize> ToMidenRepr for [u8; N] {
597 #[inline]
598 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
599 SmallVec::from_slice(self)
600 }
601}
602
603impl<const N: usize> FromMidenRepr for [u8; N] {
604 #[inline(always)]
605 fn size_in_felts() -> usize {
606 N.div_ceil(4)
607 }
608
609 fn from_bytes(bytes: &[u8]) -> Self {
610 assert!(bytes.len() >= N, "insufficient bytes");
611 Self::try_from(&bytes[..N]).unwrap()
612 }
613}
614
615impl FromMidenRepr for [Felt; 4] {
616 #[inline(always)]
617 fn size_in_felts() -> usize {
618 4
619 }
620
621 fn from_bytes(_bytes: &[u8]) -> Self {
622 panic!("field elements have no canonical byte representation")
623 }
624
625 #[inline(always)]
626 fn from_felts(felts: &[RawFelt]) -> Self {
627 [Felt(felts[0]), Felt(felts[1]), Felt(felts[2]), Felt(felts[3])]
628 }
629}
630
631pub fn bytes_to_words(bytes: &[u8]) -> Vec<[RawFelt; 4]> {
644 let (chunks, remainder) = bytes.as_chunks::<4>();
646 let padded_bytes = bytes.len().next_multiple_of(16);
647 let num_felts = padded_bytes / 4;
648 let mut buf = Vec::with_capacity(num_felts);
649 for chunk in chunks {
650 let n = u32::from_ne_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]);
651 buf.push(n);
652 }
653 if !remainder.is_empty() {
655 let mut n_buf = [0u8; 4];
656 for (i, byte) in remainder.iter().enumerate() {
657 n_buf[i] = *byte;
658 }
659 buf.push(u32::from_ne_bytes(n_buf));
660 }
661 buf.resize(num_felts, 0);
663 let num_words = num_felts / 4;
665 let mut words = Vec::with_capacity(num_words);
666 let (chunks, remainder) = buf.as_chunks::<4>();
667 for chunk in chunks {
668 words.push([
669 RawFelt::new(chunk[3] as u64).expect("value exceeds field modulus"),
670 RawFelt::new(chunk[2] as u64).expect("value exceeds field modulus"),
671 RawFelt::new(chunk[1] as u64).expect("value exceeds field modulus"),
672 RawFelt::new(chunk[0] as u64).expect("value exceeds field modulus"),
673 ]);
674 }
675 if !remainder.is_empty() {
676 let mut word = [RawFelt::ZERO; 4];
677 for (i, n) in remainder.iter().enumerate() {
678 word[i] = RawFelt::new(*n as u64).expect("value exceeds field modulus");
679 }
680 word.reverse();
681 words.push(word);
682 }
683 words
684}
685
686#[derive(Debug, Copy, Clone, PartialEq, Eq)]
689pub struct Felt(pub RawFelt);
690impl Felt {
691 #[inline]
692 pub fn new(value: u64) -> Self {
693 Self(RawFelt::new(value).expect("value exceeds field modulus"))
694 }
695}
696
697impl<'de> Deserialize<'de> for Felt {
698 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
699 where
700 D: serde::Deserializer<'de>,
701 {
702 u64::deserialize(deserializer).and_then(|n| {
703 if n >= RawFelt::ORDER_U64 {
704 Err(serde::de::Error::custom(
705 "invalid field element value: exceeds the field modulus",
706 ))
707 } else {
708 Ok(Felt(RawFelt::new(n).expect("value exceeds field modulus")))
709 }
710 })
711 }
712}
713
714impl clap::builder::ValueParserFactory for Felt {
715 type Parser = FeltParser;
716
717 fn value_parser() -> Self::Parser {
718 FeltParser
719 }
720}
721
722#[doc(hidden)]
723#[derive(Clone)]
724pub struct FeltParser;
725impl clap::builder::TypedValueParser for FeltParser {
726 type Value = Felt;
727
728 fn parse_ref(
729 &self,
730 _cmd: &clap::Command,
731 _arg: Option<&clap::Arg>,
732 value: &std::ffi::OsStr,
733 ) -> Result<Self::Value, clap::error::Error> {
734 use clap::error::{Error, ErrorKind};
735
736 let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?.trim();
737 value.parse().map_err(|err| Error::raw(ErrorKind::ValueValidation, err))
738 }
739}
740
741impl core::str::FromStr for Felt {
742 type Err = String;
743
744 fn from_str(s: &str) -> Result<Self, Self::Err> {
745 let value = if let Some(value) = s.strip_prefix("0x") {
746 u64::from_str_radix(value, 16)
747 .map_err(|err| format!("invalid field element value: {err}"))?
748 } else {
749 s.parse::<u64>().map_err(|err| format!("invalid field element value: {err}"))?
750 };
751
752 if value >= RawFelt::ORDER_U64 {
753 Err("invalid field element value: exceeds the field modulus".to_string())
754 } else {
755 Ok(Felt(RawFelt::new(value).expect("value exceeds field modulus")))
756 }
757 }
758}
759
760impl From<Felt> for miden_processor::Felt {
761 fn from(f: Felt) -> Self {
762 f.0
763 }
764}
765
766impl From<bool> for Felt {
767 fn from(b: bool) -> Self {
768 Self(RawFelt::new(b as u64).expect("value exceeds field modulus"))
769 }
770}
771
772impl From<u8> for Felt {
773 fn from(t: u8) -> Self {
774 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
775 }
776}
777
778impl From<i8> for Felt {
779 fn from(t: i8) -> Self {
780 Self(RawFelt::new(t as u8 as u64).expect("value exceeds field modulus"))
781 }
782}
783
784impl From<i16> for Felt {
785 fn from(t: i16) -> Self {
786 Self(RawFelt::new(t as u16 as u64).expect("value exceeds field modulus"))
787 }
788}
789
790impl From<u16> for Felt {
791 fn from(t: u16) -> Self {
792 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
793 }
794}
795
796impl From<i32> for Felt {
797 fn from(t: i32) -> Self {
798 Self(RawFelt::new(t as u32 as u64).expect("value exceeds field modulus"))
799 }
800}
801
802impl From<u32> for Felt {
803 fn from(t: u32) -> Self {
804 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
805 }
806}
807
808impl From<u64> for Felt {
809 fn from(t: u64) -> Self {
810 Self(RawFelt::new(t).expect("value exceeds field modulus"))
811 }
812}
813
814impl From<i64> for Felt {
815 fn from(t: i64) -> Self {
816 Self(RawFelt::new(t as u64).expect("value exceeds field modulus"))
817 }
818}
819
820impl From<Felt> for bool {
823 fn from(f: Felt) -> Self {
824 f.0.as_canonical_u64() != 0
825 }
826}
827
828impl From<Felt> for u8 {
829 fn from(f: Felt) -> Self {
830 f.0.as_canonical_u64() as u8
831 }
832}
833
834impl From<Felt> for i8 {
835 fn from(f: Felt) -> Self {
836 f.0.as_canonical_u64() as i8
837 }
838}
839
840impl From<Felt> for u16 {
841 fn from(f: Felt) -> Self {
842 f.0.as_canonical_u64() as u16
843 }
844}
845
846impl From<Felt> for i16 {
847 fn from(f: Felt) -> Self {
848 f.0.as_canonical_u64() as i16
849 }
850}
851
852impl From<Felt> for u32 {
853 fn from(f: Felt) -> Self {
854 f.0.as_canonical_u64() as u32
855 }
856}
857
858impl From<Felt> for i32 {
859 fn from(f: Felt) -> Self {
860 f.0.as_canonical_u64() as i32
861 }
862}
863
864impl From<Felt> for u64 {
865 fn from(f: Felt) -> Self {
866 f.0.as_canonical_u64()
867 }
868}
869
870impl From<Felt> for i64 {
871 fn from(f: Felt) -> Self {
872 f.0.as_canonical_u64() as i64
873 }
874}
875
876#[cfg(feature = "proptest")]
877impl Arbitrary for Felt {
878 type Parameters = ();
879 type Strategy = BoxedStrategy<Self>;
880
881 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
882 (0u64..RawFelt::ORDER_U64)
883 .prop_map(|v| Felt(RawFelt::new(v).expect("value exceeds field modulus")))
884 .boxed()
885 }
886}
887
888pub fn push_wasm_ty_to_operand_stack<T>(value: T, stack: &mut Vec<RawFelt>)
893where
894 T: ToMidenRepr + num_traits::PrimInt,
895{
896 let ty_size = std::mem::size_of::<T>();
897 if ty_size > 2 {
898 value.push_to_operand_stack(stack);
899 return;
900 }
901
902 let is_signed = T::min_value() < T::zero();
903 let value_u32 = if is_signed {
905 value.to_i32().unwrap() as u32
906 } else {
907 value.to_u32().unwrap()
908 };
909 value_u32.push_to_operand_stack(stack);
910}
911
912#[cfg(test)]
913mod tests {
914 use miden_core::Word;
915
916 use super::{FromMidenRepr, ToMidenRepr, bytes_to_words, push_wasm_ty_to_operand_stack};
917
918 #[test]
919 fn bool_roundtrip() {
920 let encoded = true.to_bytes();
921 let decoded = <bool as FromMidenRepr>::from_bytes(&encoded);
922 assert!(decoded);
923
924 let encoded = true.to_felts();
925 let decoded = <bool as FromMidenRepr>::from_felts(&encoded);
926 assert!(decoded);
927
928 let encoded = true.to_words();
929 let decoded = <bool as FromMidenRepr>::from_words(&encoded);
930 assert!(decoded);
931
932 let mut stack = Vec::default();
933 true.push_to_operand_stack(&mut stack);
934 assert_eq!(stack.as_slice(), true.to_felts().as_slice());
935
936 stack.reverse();
937 let popped = <bool as FromMidenRepr>::pop_from_stack(&mut stack);
938 assert!(popped);
939 }
940
941 #[test]
942 fn u8_roundtrip() {
943 let encoded = u8::MAX.to_bytes();
944 let decoded = <u8 as FromMidenRepr>::from_bytes(&encoded);
945 assert_eq!(decoded, u8::MAX);
946
947 let encoded = u8::MAX.to_felts();
948 let decoded = <u8 as FromMidenRepr>::from_felts(&encoded);
949 assert_eq!(decoded, u8::MAX);
950
951 let encoded = u8::MAX.to_words();
952 let decoded = <u8 as FromMidenRepr>::from_words(&encoded);
953 assert_eq!(decoded, u8::MAX);
954
955 let mut stack = Vec::default();
956 u8::MAX.push_to_operand_stack(&mut stack);
957 assert_eq!(stack.as_slice(), u8::MAX.to_felts().as_slice());
958
959 stack.reverse();
960 let popped = <u8 as FromMidenRepr>::pop_from_stack(&mut stack);
961 assert_eq!(popped, u8::MAX);
962 }
963
964 #[test]
965 fn u16_roundtrip() {
966 let encoded = u16::MAX.to_bytes();
967 let decoded = <u16 as FromMidenRepr>::from_bytes(&encoded);
968 assert_eq!(decoded, u16::MAX);
969
970 let encoded = u16::MAX.to_felts();
971 let decoded = <u16 as FromMidenRepr>::from_felts(&encoded);
972 assert_eq!(decoded, u16::MAX);
973
974 let encoded = u16::MAX.to_words();
975 let decoded = <u16 as FromMidenRepr>::from_words(&encoded);
976 assert_eq!(decoded, u16::MAX);
977
978 let mut stack = Vec::default();
979 u16::MAX.push_to_operand_stack(&mut stack);
980 assert_eq!(stack.as_slice(), u16::MAX.to_felts().as_slice());
981
982 stack.reverse();
983 let popped = <u16 as FromMidenRepr>::pop_from_stack(&mut stack);
984 assert_eq!(popped, u16::MAX);
985 }
986
987 #[test]
988 fn u32_roundtrip() {
989 let encoded = u32::MAX.to_bytes();
990 let decoded = <u32 as FromMidenRepr>::from_bytes(&encoded);
991 assert_eq!(decoded, u32::MAX);
992
993 let encoded = u32::MAX.to_felts();
994 let decoded = <u32 as FromMidenRepr>::from_felts(&encoded);
995 assert_eq!(decoded, u32::MAX);
996
997 let encoded = u32::MAX.to_words();
998 let decoded = <u32 as FromMidenRepr>::from_words(&encoded);
999 assert_eq!(decoded, u32::MAX);
1000
1001 let mut stack = Vec::default();
1002 u32::MAX.push_to_operand_stack(&mut stack);
1003 assert_eq!(stack.as_slice(), u32::MAX.to_felts().as_slice());
1004
1005 stack.reverse();
1006 let popped = <u32 as FromMidenRepr>::pop_from_stack(&mut stack);
1007 assert_eq!(popped, u32::MAX);
1008 }
1009
1010 #[test]
1011 fn u64_roundtrip() {
1012 let encoded = u64::MAX.to_bytes();
1013 let decoded = <u64 as FromMidenRepr>::from_bytes(&encoded);
1014 assert_eq!(decoded, u64::MAX);
1015
1016 let encoded = u64::MAX.to_felts();
1017 let decoded = <u64 as FromMidenRepr>::from_felts(&encoded);
1018 assert_eq!(decoded, u64::MAX);
1019
1020 let encoded = u64::MAX.to_words();
1021 let decoded = <u64 as FromMidenRepr>::from_words(&encoded);
1022 assert_eq!(decoded, u64::MAX);
1023
1024 let mut stack = Vec::default();
1025 u64::MAX.push_to_operand_stack(&mut stack);
1026 assert_eq!(stack.as_slice(), u64::MAX.to_felts().as_slice());
1027
1028 stack.reverse();
1029 let popped = <u64 as FromMidenRepr>::pop_from_stack(&mut stack);
1030 assert_eq!(popped, u64::MAX);
1031 }
1032
1033 #[test]
1034 fn u128_roundtrip() {
1035 let encoded = u128::MAX.to_bytes();
1036 let decoded = <u128 as FromMidenRepr>::from_bytes(&encoded);
1037 assert_eq!(decoded, u128::MAX);
1038
1039 let encoded = u128::MAX.to_felts();
1040 let decoded = <u128 as FromMidenRepr>::from_felts(&encoded);
1041 assert_eq!(decoded, u128::MAX);
1042
1043 let encoded = u128::MAX.to_words();
1044 let decoded = <u128 as FromMidenRepr>::from_words(&encoded);
1045 assert_eq!(decoded, u128::MAX);
1046
1047 let mut stack = Vec::default();
1048 u128::MAX.push_to_operand_stack(&mut stack);
1049 assert_eq!(stack.as_slice(), u128::MAX.to_felts().as_slice());
1050
1051 stack.reverse();
1052 let popped = <u128 as FromMidenRepr>::pop_from_stack(&mut stack);
1053 assert_eq!(popped, u128::MAX);
1054 }
1055
1056 #[test]
1057 fn byte_array_roundtrip() {
1058 let bytes = [0, 1, 2, 3, 4, 5, 6, 7];
1059
1060 let encoded = bytes.to_felts();
1061 let decoded = <[u8; 8] as FromMidenRepr>::from_felts(&encoded);
1062 assert_eq!(decoded, bytes);
1063
1064 let encoded = bytes.to_words();
1065 let decoded = <[u8; 8] as FromMidenRepr>::from_words(&encoded);
1066 assert_eq!(decoded, bytes);
1067
1068 let mut stack = Vec::default();
1069 bytes.push_to_operand_stack(&mut stack);
1070 assert_eq!(stack.as_slice(), bytes.to_felts().as_slice());
1071
1072 stack.reverse();
1073 let popped = <[u8; 8] as FromMidenRepr>::pop_from_stack(&mut stack);
1074 assert_eq!(popped, bytes);
1075 }
1076
1077 #[test]
1078 fn bytes_to_words_test() {
1079 let bytes = [
1080 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1081 25, 26, 27, 28, 29, 30, 31, 32,
1082 ];
1083 let words = bytes_to_words(&bytes);
1084 assert_eq!(words.len(), 2);
1085 assert_eq!(words[0][3].as_canonical_u64() as u32, u32::from_ne_bytes([1, 2, 3, 4]));
1087 assert_eq!(words[0][2].as_canonical_u64() as u32, u32::from_ne_bytes([5, 6, 7, 8]));
1088 assert_eq!(words[0][1].as_canonical_u64() as u32, u32::from_ne_bytes([9, 10, 11, 12]));
1089 assert_eq!(words[0][0].as_canonical_u64() as u32, u32::from_ne_bytes([13, 14, 15, 16]));
1090
1091 let to_words_output = bytes.to_words();
1093 assert_eq!(Word::new(words[0]), to_words_output[0]);
1094 }
1095
1096 #[test]
1097 fn bytes_from_words_test() {
1098 let bytes = [
1099 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1100 25, 26, 27, 28, 29, 30, 31, 32,
1101 ];
1102 let words_as_bytes = bytes_to_words(&bytes);
1103
1104 let words = vec![Word::new(words_as_bytes[0]), Word::new(words_as_bytes[1])];
1105
1106 let out = <[u8; 32] as FromMidenRepr>::from_words(&words);
1107
1108 assert_eq!(&out, &bytes);
1109 }
1110
1111 #[test]
1112 fn push_wasm_ty_to_operand_stack_test() {
1113 let mut stack = Vec::default();
1114 push_wasm_ty_to_operand_stack(i8::MIN, &mut stack);
1115 push_wasm_ty_to_operand_stack(i16::MIN, &mut stack);
1116 push_wasm_ty_to_operand_stack(u32::MAX, &mut stack);
1117
1118 assert_eq!(stack[0].as_canonical_u64(), ((i8::MIN as i32) as u32) as u64);
1119 assert_eq!(stack[1].as_canonical_u64(), ((i16::MIN as i32) as u32) as u64);
1120 assert_eq!(stack[2].as_canonical_u64(), u32::MAX as u64);
1121 }
1122}