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