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