miden_debug/
felt.rs

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    /// Convert this type into its raw byte representation
13    ///
14    /// The order of bytes in the resulting vector should be little-endian, i.e. the least
15    /// significant bytes come first.
16    fn to_bytes(&self) -> SmallVec<[u8; 16]>;
17    /// Convert this type into one or more field elements, where the order of the elements is such
18    /// that the byte representation of `self` is in little-endian order, i.e. the least significant
19    /// bytes come first.
20    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    /// Convert this type into one or more words, zero-padding as needed, such that:
38    ///
39    /// * The field elements within each word is in little-endian order, i.e. the least significant
40    ///   bytes of come first.
41    /// * Each word, if pushed on the operand stack element-by-element, would leave the element
42    ///   with the most significant bytes on top of the stack (including padding)
43    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    /// Push this value on the given operand stack using [Self::to_felts] representation
64    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    /// Push this value in its [Self::to_words] representation, on the given stack.
72    ///
73    /// This function is designed for encoding values that will be placed on the advice stack and
74    /// copied into Miden VM memory by the compiler-emitted test harness.
75    ///
76    /// Returns the number of words that were pushed on the stack
77    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    /// Returns the size of this type as encoded by [ToMidenRepr::to_felts]
91    fn size_in_felts() -> usize;
92    /// Extract a value of this type from `bytes`, where:
93    ///
94    /// * It is assumed that bytes is always padded out to 4 byte alignment
95    /// * It is assumed that the bytes are in little-endian order, as encoded by [ToMidenRepr]
96    fn from_bytes(bytes: &[u8]) -> Self;
97    /// Extract a value of this type as encoded in a vector of field elements, where:
98    ///
99    /// * The order of the field elements is little-endian, i.e. the element holding the least
100    ///   significant bytes comes first.
101    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    /// Extract a value of this type as encoded in a vector of words, where:
110    ///
111    /// * The order of the words is little-endian, i.e. the word holding the least significant
112    ///   bytes comes first.
113    /// * The order of the field elements in each word is in big-endian order, i.e. the element
114    ///   with the most significant byte is at the start of the word, and the element with the
115    ///   least significant byte is at the end of the word. This corresponds to the order in
116    ///   which elements are placed on the operand stack when preparing to read or write them
117    ///   from Miden's memory.
118    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    /// Pop a value of this type from `stack` based on the canonical representation of this type
129    /// on the operand stack when writing it to memory (and as read from memory).
130    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        // The 64-bit limbs are little endian, (lo, hi), but the 32-bit limbs of those 64-bit
465        // values are big endian, (lo_h, lo_l) and (hi_h, hi_l).
466        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
631/// Convert a byte array to an equivalent vector of words
632///
633/// Given a byte slice laid out like so:
634///
635/// [b0, b1, b2, b3, b4, b5, b6, b7, .., b31]
636///
637/// This will produce a vector of words laid out like so:
638///
639/// [[{b12, ..b15}, {b8..b11}, {b4, ..b7}, {b0, ..b3}], [{b31, ..}, ..]]
640///
641/// In short, it produces words that when placed on the stack and written to memory word-by-word,
642/// the original bytes will be laid out in Miden's memory in the correct order.
643pub fn bytes_to_words(bytes: &[u8]) -> Vec<[RawFelt; 4]> {
644    // 1. Chunk bytes up into felts
645    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    // Zero-pad the buffer to nearest whole element
654    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    // Zero-pad the buffer to nearest whole word
662    buf.resize(num_felts, 0);
663    // Chunk into words, and push them in largest-address first order
664    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/// Wrapper around `miden_processor::Felt` that implements useful traits that are not implemented
687/// for that type.
688#[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
822// Reverse Felt to Rust types conversion
823
824impl 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        // Words should be in little-endian order, elements of the word should be in big-endian
1042        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        // Make sure bytes_to_words and to_words agree
1048        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}