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