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