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>) {
65 let felts = self.to_felts();
66 for felt in felts.into_iter().rev() {
67 stack.push(felt);
68 }
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_int() 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_int() {
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_int() {
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_int() as u8
212 }
213
214 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
215 stack.pop().unwrap().as_int() 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_int() as u8 as i8
246 }
247
248 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
249 stack.pop().unwrap().as_int() 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_int() as u16
280 }
281
282 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
283 stack.pop().unwrap().as_int() 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_int() as u16 as i16
314 }
315
316 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
317 stack.pop().unwrap().as_int() 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_int() as u32
348 }
349
350 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
351 stack.pop().unwrap().as_int() 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_int() as u32 as i32
382 }
383
384 fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
385 stack.pop().unwrap().as_int() 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_be_bytes())
392 }
393
394 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
395 let bytes = self.to_be_bytes();
396 let hi = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
397 let lo = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
398 smallvec![RawFelt::new(hi as u64), RawFelt::new(lo as u64)]
399 }
400}
401
402impl FromMidenRepr for u64 {
403 #[inline(always)]
404 fn size_in_felts() -> usize {
405 2
406 }
407
408 fn from_bytes(bytes: &[u8]) -> Self {
409 assert!(bytes.len() >= 8);
410 u64::from_be_bytes([
411 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
412 ])
413 }
414
415 fn from_felts(felts: &[RawFelt]) -> Self {
416 assert!(felts.len() >= 2);
417 let hi = (felts[0].as_int() as u32).to_be_bytes();
418 let lo = (felts[1].as_int() as u32).to_be_bytes();
419 u64::from_be_bytes([hi[0], hi[1], hi[2], hi[3], lo[0], lo[1], lo[2], lo[3]])
420 }
421}
422
423impl ToMidenRepr for i64 {
424 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
425 SmallVec::from_slice(&self.to_be_bytes())
426 }
427
428 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
429 (*self as u64).to_felts()
430 }
431}
432
433impl FromMidenRepr for i64 {
434 #[inline(always)]
435 fn size_in_felts() -> usize {
436 2
437 }
438
439 fn from_bytes(bytes: &[u8]) -> Self {
440 u64::from_bytes(bytes) as i64
441 }
442
443 fn from_felts(felts: &[RawFelt]) -> Self {
444 u64::from_felts(felts) as i64
445 }
446}
447
448impl ToMidenRepr for u128 {
449 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
450 SmallVec::from_slice(&self.to_be_bytes())
451 }
452
453 fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
454 let bytes = self.to_be_bytes();
455 let hi_h =
456 RawFelt::new(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as u64);
457 let hi_l =
458 RawFelt::new(u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]) as u64);
459 let lo_h =
460 RawFelt::new(u32::from_be_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]) as u64);
461 let lo_l =
462 RawFelt::new(u32::from_be_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]) as u64);
463
464 smallvec![lo_h, lo_l, hi_h, hi_l]
467 }
468}
469
470impl FromMidenRepr for u128 {
471 #[inline(always)]
472 fn size_in_felts() -> usize {
473 4
474 }
475
476 fn from_bytes(bytes: &[u8]) -> Self {
477 assert!(bytes.len() >= 16);
478 u128::from_be_bytes([
479 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
480 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
481 ])
482 }
483
484 fn from_felts(felts: &[RawFelt]) -> Self {
485 assert!(felts.len() >= 4);
486 let hi_h = (felts[0].as_int() as u32).to_be_bytes();
487 let hi_l = (felts[1].as_int() as u32).to_be_bytes();
488 let lo_h = (felts[2].as_int() as u32).to_be_bytes();
489 let lo_l = (felts[3].as_int() as u32).to_be_bytes();
490 u128::from_be_bytes([
491 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],
492 lo_h[1], lo_h[2], lo_h[3], lo_l[0], lo_l[1], lo_l[2], lo_l[3],
493 ])
494 }
495}
496
497impl ToMidenRepr for i128 {
498 fn to_bytes(&self) -> SmallVec<[u8; 16]> {
499 SmallVec::from_slice(&self.to_be_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.next_multiple_of(4) / 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),
670 RawFelt::new(chunk[2] as u64),
671 RawFelt::new(chunk[1] as u64),
672 RawFelt::new(chunk[0] as u64),
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);
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))
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::MODULUS {
704 Err(serde::de::Error::custom(
705 "invalid field element value: exceeds the field modulus",
706 ))
707 } else {
708 RawFelt::try_from(n).map(Felt).map_err(|err| {
709 serde::de::Error::custom(format!("invalid field element value: {err}"))
710 })
711 }
712 })
713 }
714}
715
716impl clap::builder::ValueParserFactory for Felt {
717 type Parser = FeltParser;
718
719 fn value_parser() -> Self::Parser {
720 FeltParser
721 }
722}
723
724#[doc(hidden)]
725#[derive(Clone)]
726pub struct FeltParser;
727impl clap::builder::TypedValueParser for FeltParser {
728 type Value = Felt;
729
730 fn parse_ref(
731 &self,
732 _cmd: &clap::Command,
733 _arg: Option<&clap::Arg>,
734 value: &std::ffi::OsStr,
735 ) -> Result<Self::Value, clap::error::Error> {
736 use clap::error::{Error, ErrorKind};
737
738 let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?.trim();
739 value.parse().map_err(|err| Error::raw(ErrorKind::ValueValidation, err))
740 }
741}
742
743impl core::str::FromStr for Felt {
744 type Err = String;
745
746 fn from_str(s: &str) -> Result<Self, Self::Err> {
747 let value = if let Some(value) = s.strip_prefix("0x") {
748 u64::from_str_radix(value, 16)
749 .map_err(|err| format!("invalid field element value: {err}"))?
750 } else {
751 s.parse::<u64>().map_err(|err| format!("invalid field element value: {err}"))?
752 };
753
754 if value > RawFelt::MODULUS {
755 Err("invalid field element value: exceeds the field modulus".to_string())
756 } else {
757 RawFelt::try_from(value).map(Felt)
758 }
759 }
760}
761
762impl From<Felt> for miden_processor::Felt {
763 fn from(f: Felt) -> Self {
764 f.0
765 }
766}
767
768impl From<bool> for Felt {
769 fn from(b: bool) -> Self {
770 Self(RawFelt::from(b as u32))
771 }
772}
773
774impl From<u8> for Felt {
775 fn from(t: u8) -> Self {
776 Self(t.into())
777 }
778}
779
780impl From<i8> for Felt {
781 fn from(t: i8) -> Self {
782 Self((t as u8).into())
783 }
784}
785
786impl From<i16> for Felt {
787 fn from(t: i16) -> Self {
788 Self((t as u16).into())
789 }
790}
791
792impl From<u16> for Felt {
793 fn from(t: u16) -> Self {
794 Self(t.into())
795 }
796}
797
798impl From<i32> for Felt {
799 fn from(t: i32) -> Self {
800 Self((t as u32).into())
801 }
802}
803
804impl From<u32> for Felt {
805 fn from(t: u32) -> Self {
806 Self(t.into())
807 }
808}
809
810impl From<u64> for Felt {
811 fn from(t: u64) -> Self {
812 Self(RawFelt::new(t))
813 }
814}
815
816impl From<i64> for Felt {
817 fn from(t: i64) -> Self {
818 Self(RawFelt::new(t as u64))
819 }
820}
821
822impl From<Felt> for bool {
825 fn from(f: Felt) -> Self {
826 f.0.as_int() != 0
827 }
828}
829
830impl From<Felt> for u8 {
831 fn from(f: Felt) -> Self {
832 f.0.as_int() as u8
833 }
834}
835
836impl From<Felt> for i8 {
837 fn from(f: Felt) -> Self {
838 f.0.as_int() as i8
839 }
840}
841
842impl From<Felt> for u16 {
843 fn from(f: Felt) -> Self {
844 f.0.as_int() as u16
845 }
846}
847
848impl From<Felt> for i16 {
849 fn from(f: Felt) -> Self {
850 f.0.as_int() as i16
851 }
852}
853
854impl From<Felt> for u32 {
855 fn from(f: Felt) -> Self {
856 f.0.as_int() as u32
857 }
858}
859
860impl From<Felt> for i32 {
861 fn from(f: Felt) -> Self {
862 f.0.as_int() as i32
863 }
864}
865
866impl From<Felt> for u64 {
867 fn from(f: Felt) -> Self {
868 f.0.as_int()
869 }
870}
871
872impl From<Felt> for i64 {
873 fn from(f: Felt) -> Self {
874 f.0.as_int() as i64
875 }
876}
877
878#[cfg(feature = "proptest")]
879impl Arbitrary for Felt {
880 type Parameters = ();
881 type Strategy = BoxedStrategy<Self>;
882
883 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
884 use miden_core::StarkField;
885 (0u64..RawFelt::MODULUS).prop_map(|v| Felt(RawFelt::new(v))).boxed()
886 }
887}
888
889#[cfg(test)]
890mod tests {
891 use miden_core::Word;
892
893 use super::{FromMidenRepr, ToMidenRepr, bytes_to_words};
894
895 #[test]
896 fn bool_roundtrip() {
897 let encoded = true.to_bytes();
898 let decoded = <bool as FromMidenRepr>::from_bytes(&encoded);
899 assert!(decoded);
900
901 let encoded = true.to_felts();
902 let decoded = <bool as FromMidenRepr>::from_felts(&encoded);
903 assert!(decoded);
904
905 let encoded = true.to_words();
906 let decoded = <bool as FromMidenRepr>::from_words(&encoded);
907 assert!(decoded);
908
909 let mut stack = Vec::default();
910 true.push_to_operand_stack(&mut stack);
911 let popped = <bool as FromMidenRepr>::pop_from_stack(&mut stack);
912 assert!(popped);
913 }
914
915 #[test]
916 fn u8_roundtrip() {
917 let encoded = u8::MAX.to_bytes();
918 let decoded = <u8 as FromMidenRepr>::from_bytes(&encoded);
919 assert_eq!(decoded, u8::MAX);
920
921 let encoded = u8::MAX.to_felts();
922 let decoded = <u8 as FromMidenRepr>::from_felts(&encoded);
923 assert_eq!(decoded, u8::MAX);
924
925 let encoded = u8::MAX.to_words();
926 let decoded = <u8 as FromMidenRepr>::from_words(&encoded);
927 assert_eq!(decoded, u8::MAX);
928
929 let mut stack = Vec::default();
930 u8::MAX.push_to_operand_stack(&mut stack);
931 let popped = <u8 as FromMidenRepr>::pop_from_stack(&mut stack);
932 assert_eq!(popped, u8::MAX);
933 }
934
935 #[test]
936 fn u16_roundtrip() {
937 let encoded = u16::MAX.to_bytes();
938 let decoded = <u16 as FromMidenRepr>::from_bytes(&encoded);
939 assert_eq!(decoded, u16::MAX);
940
941 let encoded = u16::MAX.to_felts();
942 let decoded = <u16 as FromMidenRepr>::from_felts(&encoded);
943 assert_eq!(decoded, u16::MAX);
944
945 let encoded = u16::MAX.to_words();
946 let decoded = <u16 as FromMidenRepr>::from_words(&encoded);
947 assert_eq!(decoded, u16::MAX);
948
949 let mut stack = Vec::default();
950 u16::MAX.push_to_operand_stack(&mut stack);
951 let popped = <u16 as FromMidenRepr>::pop_from_stack(&mut stack);
952 assert_eq!(popped, u16::MAX);
953 }
954
955 #[test]
956 fn u32_roundtrip() {
957 let encoded = u32::MAX.to_bytes();
958 let decoded = <u32 as FromMidenRepr>::from_bytes(&encoded);
959 assert_eq!(decoded, u32::MAX);
960
961 let encoded = u32::MAX.to_felts();
962 let decoded = <u32 as FromMidenRepr>::from_felts(&encoded);
963 assert_eq!(decoded, u32::MAX);
964
965 let encoded = u32::MAX.to_words();
966 let decoded = <u32 as FromMidenRepr>::from_words(&encoded);
967 assert_eq!(decoded, u32::MAX);
968
969 let mut stack = Vec::default();
970 u32::MAX.push_to_operand_stack(&mut stack);
971 let popped = <u32 as FromMidenRepr>::pop_from_stack(&mut stack);
972 assert_eq!(popped, u32::MAX);
973 }
974
975 #[test]
976 fn u64_roundtrip() {
977 let encoded = u64::MAX.to_bytes();
978 let decoded = <u64 as FromMidenRepr>::from_bytes(&encoded);
979 assert_eq!(decoded, u64::MAX);
980
981 let encoded = u64::MAX.to_felts();
982 let decoded = <u64 as FromMidenRepr>::from_felts(&encoded);
983 assert_eq!(decoded, u64::MAX);
984
985 let encoded = u64::MAX.to_words();
986 let decoded = <u64 as FromMidenRepr>::from_words(&encoded);
987 assert_eq!(decoded, u64::MAX);
988
989 let mut stack = Vec::default();
990 u64::MAX.push_to_operand_stack(&mut stack);
991 let popped = <u64 as FromMidenRepr>::pop_from_stack(&mut stack);
992 assert_eq!(popped, u64::MAX);
993 }
994
995 #[test]
996 fn u128_roundtrip() {
997 let encoded = u128::MAX.to_bytes();
998 let decoded = <u128 as FromMidenRepr>::from_bytes(&encoded);
999 assert_eq!(decoded, u128::MAX);
1000
1001 let encoded = u128::MAX.to_felts();
1002 let decoded = <u128 as FromMidenRepr>::from_felts(&encoded);
1003 assert_eq!(decoded, u128::MAX);
1004
1005 let encoded = u128::MAX.to_words();
1006 let decoded = <u128 as FromMidenRepr>::from_words(&encoded);
1007 assert_eq!(decoded, u128::MAX);
1008
1009 let mut stack = Vec::default();
1010 u128::MAX.push_to_operand_stack(&mut stack);
1011 let popped = <u128 as FromMidenRepr>::pop_from_stack(&mut stack);
1012 assert_eq!(popped, u128::MAX);
1013 }
1014
1015 #[test]
1016 fn byte_array_roundtrip() {
1017 let bytes = [0, 1, 2, 3, 4, 5, 6, 7];
1018
1019 let encoded = bytes.to_felts();
1020 let decoded = <[u8; 8] as FromMidenRepr>::from_felts(&encoded);
1021 assert_eq!(decoded, bytes);
1022
1023 let encoded = bytes.to_words();
1024 let decoded = <[u8; 8] as FromMidenRepr>::from_words(&encoded);
1025 assert_eq!(decoded, bytes);
1026
1027 let mut stack = Vec::default();
1028 bytes.push_to_operand_stack(&mut stack);
1029 let popped = <[u8; 8] as FromMidenRepr>::pop_from_stack(&mut stack);
1030 assert_eq!(popped, bytes);
1031 }
1032
1033 #[test]
1034 fn bytes_to_words_test() {
1035 let bytes = [
1036 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1037 25, 26, 27, 28, 29, 30, 31, 32,
1038 ];
1039 let words = bytes_to_words(&bytes);
1040 assert_eq!(words.len(), 2);
1041 assert_eq!(words[0][3].as_int() as u32, u32::from_ne_bytes([1, 2, 3, 4]));
1043 assert_eq!(words[0][2].as_int() as u32, u32::from_ne_bytes([5, 6, 7, 8]));
1044 assert_eq!(words[0][1].as_int() as u32, u32::from_ne_bytes([9, 10, 11, 12]));
1045 assert_eq!(words[0][0].as_int() as u32, u32::from_ne_bytes([13, 14, 15, 16]));
1046
1047 let to_words_output = bytes.to_words();
1049 assert_eq!(Word::new(words[0]), to_words_output[0]);
1050 }
1051
1052 #[test]
1053 fn bytes_from_words_test() {
1054 let bytes = [
1055 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1056 25, 26, 27, 28, 29, 30, 31, 32,
1057 ];
1058 let words_as_bytes = bytes_to_words(&bytes);
1059
1060 let words = vec![Word::new(words_as_bytes[0]), Word::new(words_as_bytes[1])];
1061
1062 let out = <[u8; 32] as FromMidenRepr>::from_words(&words);
1063
1064 assert_eq!(&out, &bytes);
1065 }
1066}