midenc_debug/
felt.rs

1use std::collections::VecDeque;
2
3use miden_core::{FieldElement, StarkField, Word};
4use miden_processor::Felt as RawFelt;
5use midenc_hir::{smallvec, SmallVec};
6use proptest::{
7    arbitrary::Arbitrary,
8    strategy::{BoxedStrategy, Strategy},
9};
10use serde::Deserialize;
11
12pub trait ToMidenRepr {
13    /// Convert this type into its raw byte representation
14    ///
15    /// The order of bytes in the resulting vector should be little-endian, i.e. the least
16    /// significant bytes come first.
17    fn to_bytes(&self) -> SmallVec<[u8; 16]>;
18    /// Convert this type into one or more field elements, where the order of the elements is such
19    /// that the byte representation of `self` is in little-endian order, i.e. the least significant
20    /// bytes come first.
21    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
22        let bytes = self.to_bytes();
23        let num_felts = bytes.len().next_multiple_of(4) / 4;
24        let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(num_felts);
25        let mut chunks = bytes.into_iter().array_chunks::<4>();
26        for chunk in chunks.by_ref() {
27            felts.push(RawFelt::new(u32::from_ne_bytes(chunk) as u64));
28        }
29        if let Some(remainder) = chunks.into_remainder().filter(|r| r.len() > 0) {
30            let mut chunk = [0u8; 4];
31            for (i, byte) in remainder.enumerate() {
32                chunk[i] = byte;
33            }
34            felts.push(RawFelt::new(u32::from_ne_bytes(chunk) as u64));
35        }
36        felts
37    }
38    /// Convert this type into one or more words, zero-padding as needed, such that:
39    ///
40    /// * The field elements within each word is in little-endian order, i.e. the least significant
41    ///   bytes of come first.
42    /// * Each word, if pushed on the operand stack element-by-element, would leave the element
43    ///   with the most significant bytes on top of the stack (including padding)
44    fn to_words(&self) -> SmallVec<[Word; 1]> {
45        let felts = self.to_felts();
46        let num_words = felts.len().next_multiple_of(4) / 4;
47        let mut words = SmallVec::<[Word; 1]>::with_capacity(num_words);
48        let mut chunks = felts.into_iter().array_chunks::<4>();
49        for mut word in chunks.by_ref() {
50            word.reverse();
51            words.push(word);
52        }
53        if let Some(remainder) = chunks.into_remainder().filter(|r| r.len() > 0) {
54            let mut word = [RawFelt::ZERO; 4];
55            for (i, felt) in remainder.enumerate() {
56                word[i] = felt;
57            }
58            word.reverse();
59            words.push(word);
60        }
61        words
62    }
63
64    /// Push this value on the given operand stack using [Self::to_felts] representation
65    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
66        let felts = self.to_felts();
67        for felt in felts.into_iter().rev() {
68            stack.push(felt);
69        }
70    }
71
72    /// Push this value in its [Self::to_words] representation, on the given stack.
73    ///
74    /// This function is designed for encoding values that will be placed on the advice stack and
75    /// copied into Miden VM memory by the compiler-emitted test harness.
76    ///
77    /// Returns the number of words that were pushed on the stack
78    fn push_words_to_advice_stack(&self, stack: &mut Vec<RawFelt>) -> usize {
79        let words = self.to_words();
80        let num_words = words.len();
81        for word in words.into_iter().rev() {
82            for felt in word.into_iter() {
83                stack.push(felt);
84            }
85        }
86        num_words
87    }
88}
89
90pub trait FromMidenRepr: Sized {
91    /// Returns the size of this type as encoded by [ToMidenRepr::to_felts]
92    fn size_in_felts() -> usize;
93    /// Extract a value of this type from `bytes`, where:
94    ///
95    /// * It is assumed that bytes is always padded out to 4 byte alignment
96    /// * It is assumed that the bytes are in little-endian order, as encoded by [ToMidenRepr]
97    fn from_bytes(bytes: &[u8]) -> Self;
98    /// Extract a value of this type as encoded in a vector of field elements, where:
99    ///
100    /// * The order of the field elements is little-endian, i.e. the element holding the least
101    ///   significant bytes comes first.
102    fn from_felts(felts: &[RawFelt]) -> Self {
103        let mut bytes = SmallVec::<[u8; 16]>::with_capacity(felts.len() * 4);
104        for felt in felts {
105            let chunk = (felt.as_int() as u32).to_ne_bytes();
106            bytes.extend(chunk);
107        }
108        Self::from_bytes(&bytes)
109    }
110    /// Extract a value of this type as encoded in a vector of words, where:
111    ///
112    /// * The order of the words is little-endian, i.e. the word holding the least significant
113    ///   bytes comes first.
114    /// * The order of the field elements in each word is in big-endian order, i.e. the element
115    ///   with the most significant byte is at the start of the word, and the element with the
116    ///   least significant byte is at the end of the word. This corresponds to the order in
117    ///   which elements are placed on the operand stack when preparing to read or write them
118    ///   from Miden's memory.
119    fn from_words(words: &[Word]) -> Self {
120        let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(words.len() * 4);
121        for word in words {
122            for felt in word.iter().copied().rev() {
123                felts.push(felt);
124            }
125        }
126        Self::from_felts(&felts)
127    }
128
129    /// Pop a value of this type from `stack` based on the canonical representation of this type
130    /// on the operand stack when writing it to memory (and as read from memory).
131    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
132        let needed = Self::size_in_felts();
133        let mut felts = SmallVec::<[RawFelt; 4]>::with_capacity(needed);
134        for _ in 0..needed {
135            felts.push(stack.pop().unwrap());
136        }
137        Self::from_felts(&felts)
138    }
139}
140
141impl ToMidenRepr for bool {
142    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
143        smallvec![*self as u8]
144    }
145
146    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
147        smallvec![RawFelt::new(*self as u64)]
148    }
149
150    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
151        stack.push(RawFelt::new(*self as u64));
152    }
153}
154
155impl FromMidenRepr for bool {
156    #[inline(always)]
157    fn size_in_felts() -> usize {
158        1
159    }
160
161    fn from_bytes(bytes: &[u8]) -> Self {
162        match bytes[0] {
163            0 => false,
164            1 => true,
165            n => panic!("invalid byte representation for boolean: {n:0x}"),
166        }
167    }
168
169    fn from_felts(felts: &[RawFelt]) -> Self {
170        match felts[0].as_int() {
171            0 => false,
172            1 => true,
173            n => panic!("invalid byte representation for boolean: {n:0x}"),
174        }
175    }
176
177    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
178        match stack.pop().unwrap().as_int() {
179            0 => false,
180            1 => true,
181            n => panic!("invalid byte representation for boolean: {n:0x}"),
182        }
183    }
184}
185
186impl ToMidenRepr for u8 {
187    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
188        smallvec![*self]
189    }
190
191    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
192        smallvec![RawFelt::new(*self as u64)]
193    }
194
195    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
196        stack.push(RawFelt::new(*self as u64));
197    }
198}
199
200impl FromMidenRepr for u8 {
201    #[inline(always)]
202    fn size_in_felts() -> usize {
203        1
204    }
205
206    #[inline(always)]
207    fn from_bytes(bytes: &[u8]) -> Self {
208        bytes[0]
209    }
210
211    fn from_felts(felts: &[RawFelt]) -> Self {
212        felts[0].as_int() as u8
213    }
214
215    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
216        stack.pop().unwrap().as_int() as u8
217    }
218}
219
220impl ToMidenRepr for i8 {
221    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
222        smallvec![*self as u8]
223    }
224
225    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
226        smallvec![RawFelt::new(*self as u8 as u64)]
227    }
228
229    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
230        stack.push(RawFelt::new(*self as u8 as u64));
231    }
232}
233
234impl FromMidenRepr for i8 {
235    #[inline(always)]
236    fn size_in_felts() -> usize {
237        1
238    }
239
240    #[inline(always)]
241    fn from_bytes(bytes: &[u8]) -> Self {
242        bytes[0] as i8
243    }
244
245    fn from_felts(felts: &[RawFelt]) -> Self {
246        felts[0].as_int() as u8 as i8
247    }
248
249    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
250        stack.pop().unwrap().as_int() as u8 as i8
251    }
252}
253
254impl ToMidenRepr for u16 {
255    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
256        SmallVec::from_slice(&self.to_ne_bytes())
257    }
258
259    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
260        smallvec![RawFelt::new(*self as u64)]
261    }
262
263    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
264        stack.push(RawFelt::new(*self as u64));
265    }
266}
267
268impl FromMidenRepr for u16 {
269    #[inline(always)]
270    fn size_in_felts() -> usize {
271        1
272    }
273
274    fn from_bytes(bytes: &[u8]) -> Self {
275        assert!(bytes.len() >= 2);
276        u16::from_ne_bytes([bytes[0], bytes[1]])
277    }
278
279    fn from_felts(felts: &[RawFelt]) -> Self {
280        felts[0].as_int() as u16
281    }
282
283    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
284        stack.pop().unwrap().as_int() as u16
285    }
286}
287
288impl ToMidenRepr for i16 {
289    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
290        SmallVec::from_slice(&self.to_ne_bytes())
291    }
292
293    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
294        smallvec![RawFelt::new(*self as u16 as u64)]
295    }
296
297    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
298        stack.push(RawFelt::new(*self as u16 as u64));
299    }
300}
301
302impl FromMidenRepr for i16 {
303    #[inline(always)]
304    fn size_in_felts() -> usize {
305        1
306    }
307
308    fn from_bytes(bytes: &[u8]) -> Self {
309        assert!(bytes.len() >= 2);
310        i16::from_ne_bytes([bytes[0], bytes[1]])
311    }
312
313    fn from_felts(felts: &[RawFelt]) -> Self {
314        felts[0].as_int() as u16 as i16
315    }
316
317    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
318        stack.pop().unwrap().as_int() as u16 as i16
319    }
320}
321
322impl ToMidenRepr for u32 {
323    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
324        SmallVec::from_slice(&self.to_ne_bytes())
325    }
326
327    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
328        smallvec![RawFelt::new(*self as u64)]
329    }
330
331    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
332        stack.push(RawFelt::new(*self as u64));
333    }
334}
335
336impl FromMidenRepr for u32 {
337    #[inline(always)]
338    fn size_in_felts() -> usize {
339        1
340    }
341
342    fn from_bytes(bytes: &[u8]) -> Self {
343        assert!(bytes.len() >= 4);
344        u32::from_ne_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
345    }
346
347    fn from_felts(felts: &[RawFelt]) -> Self {
348        felts[0].as_int() as u32
349    }
350
351    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
352        stack.pop().unwrap().as_int() as u32
353    }
354}
355
356impl ToMidenRepr for i32 {
357    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
358        SmallVec::from_slice(&self.to_ne_bytes())
359    }
360
361    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
362        smallvec![RawFelt::new(*self as u32 as u64)]
363    }
364
365    fn push_to_operand_stack(&self, stack: &mut Vec<RawFelt>) {
366        stack.push(RawFelt::new(*self as u32 as u64));
367    }
368}
369
370impl FromMidenRepr for i32 {
371    #[inline(always)]
372    fn size_in_felts() -> usize {
373        1
374    }
375
376    fn from_bytes(bytes: &[u8]) -> Self {
377        assert!(bytes.len() >= 4);
378        i32::from_ne_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
379    }
380
381    fn from_felts(felts: &[RawFelt]) -> Self {
382        felts[0].as_int() as u32 as i32
383    }
384
385    fn pop_from_stack(stack: &mut Vec<RawFelt>) -> Self {
386        stack.pop().unwrap().as_int() as u32 as i32
387    }
388}
389
390impl ToMidenRepr for u64 {
391    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
392        SmallVec::from_slice(&self.to_be_bytes())
393    }
394
395    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
396        let bytes = self.to_be_bytes();
397        let hi = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
398        let lo = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
399        smallvec![RawFelt::new(hi as u64), RawFelt::new(lo as u64)]
400    }
401}
402
403impl FromMidenRepr for u64 {
404    #[inline(always)]
405    fn size_in_felts() -> usize {
406        2
407    }
408
409    fn from_bytes(bytes: &[u8]) -> Self {
410        assert!(bytes.len() >= 8);
411        u64::from_be_bytes([
412            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
413        ])
414    }
415
416    fn from_felts(felts: &[RawFelt]) -> Self {
417        assert!(felts.len() >= 2);
418        let hi = (felts[0].as_int() as u32).to_be_bytes();
419        let lo = (felts[1].as_int() as u32).to_be_bytes();
420        u64::from_be_bytes([hi[0], hi[1], hi[2], hi[3], lo[0], lo[1], lo[2], lo[3]])
421    }
422}
423
424impl ToMidenRepr for i64 {
425    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
426        SmallVec::from_slice(&self.to_be_bytes())
427    }
428
429    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
430        (*self as u64).to_felts()
431    }
432}
433
434impl FromMidenRepr for i64 {
435    #[inline(always)]
436    fn size_in_felts() -> usize {
437        2
438    }
439
440    fn from_bytes(bytes: &[u8]) -> Self {
441        u64::from_bytes(bytes) as i64
442    }
443
444    fn from_felts(felts: &[RawFelt]) -> Self {
445        u64::from_felts(felts) as i64
446    }
447}
448
449impl ToMidenRepr for u128 {
450    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
451        SmallVec::from_slice(&self.to_be_bytes())
452    }
453
454    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
455        let bytes = self.to_be_bytes();
456        let hi_h =
457            RawFelt::new(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as u64);
458        let hi_l =
459            RawFelt::new(u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]) as u64);
460        let lo_h =
461            RawFelt::new(u32::from_be_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]) as u64);
462        let lo_l =
463            RawFelt::new(u32::from_be_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]) as u64);
464        smallvec![hi_h, hi_l, lo_h, lo_l]
465    }
466}
467
468impl FromMidenRepr for u128 {
469    #[inline(always)]
470    fn size_in_felts() -> usize {
471        4
472    }
473
474    fn from_bytes(bytes: &[u8]) -> Self {
475        assert!(bytes.len() >= 16);
476        u128::from_be_bytes([
477            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
478            bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
479        ])
480    }
481
482    fn from_felts(felts: &[RawFelt]) -> Self {
483        assert!(felts.len() >= 4);
484        let hi_h = (felts[0].as_int() as u32).to_be_bytes();
485        let hi_l = (felts[1].as_int() as u32).to_be_bytes();
486        let lo_h = (felts[2].as_int() as u32).to_be_bytes();
487        let lo_l = (felts[3].as_int() as u32).to_be_bytes();
488        u128::from_be_bytes([
489            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],
490            lo_h[1], lo_h[2], lo_h[3], lo_l[0], lo_l[1], lo_l[2], lo_l[3],
491        ])
492    }
493}
494
495impl ToMidenRepr for i128 {
496    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
497        SmallVec::from_slice(&self.to_be_bytes())
498    }
499
500    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
501        (*self as u128).to_felts()
502    }
503}
504
505impl FromMidenRepr for i128 {
506    #[inline(always)]
507    fn size_in_felts() -> usize {
508        4
509    }
510
511    fn from_bytes(bytes: &[u8]) -> Self {
512        u128::from_bytes(bytes) as i128
513    }
514
515    fn from_felts(felts: &[RawFelt]) -> Self {
516        u128::from_felts(felts) as i128
517    }
518}
519
520impl ToMidenRepr for RawFelt {
521    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
522        panic!("field elements have no canonical byte representation")
523    }
524
525    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
526        smallvec![*self]
527    }
528
529    fn to_words(&self) -> SmallVec<[Word; 1]> {
530        let mut word = [RawFelt::ZERO; 4];
531        word[0] = *self;
532        smallvec![word]
533    }
534}
535
536impl FromMidenRepr for RawFelt {
537    #[inline(always)]
538    fn size_in_felts() -> usize {
539        1
540    }
541
542    fn from_bytes(bytes: &[u8]) -> Self {
543        panic!("field elements have no canonical byte representation")
544    }
545
546    #[inline(always)]
547    fn from_felts(felts: &[RawFelt]) -> Self {
548        felts[0]
549    }
550
551    #[inline(always)]
552    fn from_words(words: &[Word]) -> Self {
553        words[0][0]
554    }
555}
556
557impl ToMidenRepr for Felt {
558    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
559        panic!("field elements have no canonical byte representation")
560    }
561
562    fn to_felts(&self) -> SmallVec<[RawFelt; 4]> {
563        smallvec![self.0]
564    }
565
566    fn to_words(&self) -> SmallVec<[Word; 1]> {
567        let mut word = [RawFelt::ZERO; 4];
568        word[0] = self.0;
569        smallvec![word]
570    }
571}
572
573impl FromMidenRepr for Felt {
574    #[inline(always)]
575    fn size_in_felts() -> usize {
576        1
577    }
578
579    fn from_bytes(bytes: &[u8]) -> Self {
580        panic!("field elements have no canonical byte representation")
581    }
582
583    #[inline(always)]
584    fn from_felts(felts: &[RawFelt]) -> Self {
585        Felt(felts[0])
586    }
587
588    #[inline(always)]
589    fn from_words(words: &[Word]) -> Self {
590        Felt(words[0][0])
591    }
592}
593
594impl<const N: usize> ToMidenRepr for [u8; N] {
595    #[inline]
596    fn to_bytes(&self) -> SmallVec<[u8; 16]> {
597        SmallVec::from_slice(self)
598    }
599}
600
601impl<const N: usize> FromMidenRepr for [u8; N] {
602    #[inline(always)]
603    fn size_in_felts() -> usize {
604        N.next_multiple_of(4) / 4
605    }
606
607    fn from_bytes(bytes: &[u8]) -> Self {
608        assert!(bytes.len() >= N, "insufficient bytes");
609        Self::try_from(&bytes[..N]).unwrap()
610    }
611}
612
613/// Convert a byte array to an equivalent vector of words
614///
615/// Given a byte slice laid out like so:
616///
617/// [b0, b1, b2, b3, b4, b5, b6, b7, .., b31]
618///
619/// This will produce a vector of words laid out like so:
620///
621/// [[{b12, ..b15}, {b8..b11}, {b4, ..b7}, {b0, ..b3}], [{b31, ..}, ..]]
622///
623/// In short, it produces words that when placed on the stack and written to memory word-by-word,
624/// the original bytes will be laid out in Miden's memory in the correct order.
625pub fn bytes_to_words(bytes: &[u8]) -> Vec<[RawFelt; 4]> {
626    // 1. Chunk bytes up into felts
627    let mut iter = bytes.iter().array_chunks::<4>();
628    let padded_bytes = bytes.len().next_multiple_of(16);
629    let num_felts = padded_bytes / 4;
630    let mut buf = Vec::with_capacity(num_felts);
631    for chunk in iter.by_ref() {
632        let n = u32::from_ne_bytes([*chunk[0], *chunk[1], *chunk[2], *chunk[3]]);
633        buf.push(n);
634    }
635    // Zero-pad the buffer to nearest whole element
636    if let Some(rest) = iter.into_remainder().filter(|r| r.len() > 0) {
637        let mut n_buf = [0u8; 4];
638        for (i, byte) in rest.into_iter().enumerate() {
639            n_buf[i] = *byte;
640        }
641        buf.push(u32::from_ne_bytes(n_buf));
642    }
643    // Zero-pad the buffer to nearest whole word
644    buf.resize(num_felts, 0);
645    // Chunk into words, and push them in largest-address first order
646    let num_words = num_felts / 4;
647    let mut words = Vec::with_capacity(num_words);
648    let mut iter = buf.into_iter().map(|elem| RawFelt::new(elem as u64)).array_chunks::<4>();
649    for mut word in iter.by_ref() {
650        word.reverse();
651        words.push(word);
652    }
653    if let Some(extra) = iter.into_remainder().filter(|r| r.len() > 0) {
654        let mut word = [RawFelt::ZERO; 4];
655        for (i, felt) in extra.enumerate() {
656            word[i] = felt;
657        }
658        word.reverse();
659        words.push(word);
660    }
661    words
662}
663
664/// Wrapper around `miden_processor::Felt` that implements useful traits that are not implemented
665/// for that type.
666#[derive(Debug, Copy, Clone, PartialEq, Eq)]
667pub struct Felt(pub RawFelt);
668impl Felt {
669    #[inline]
670    pub fn new(value: u64) -> Self {
671        Self(RawFelt::new(value))
672    }
673}
674
675impl<'de> Deserialize<'de> for Felt {
676    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
677    where
678        D: serde::Deserializer<'de>,
679    {
680        u64::deserialize(deserializer).and_then(|n| {
681            if n > RawFelt::MODULUS {
682                Err(serde::de::Error::custom(
683                    "invalid field element value: exceeds the field modulus",
684                ))
685            } else {
686                RawFelt::try_from(n).map(Felt).map_err(|err| {
687                    serde::de::Error::custom(format!("invalid field element value: {err}"))
688                })
689            }
690        })
691    }
692}
693
694impl clap::builder::ValueParserFactory for Felt {
695    type Parser = FeltParser;
696
697    fn value_parser() -> Self::Parser {
698        FeltParser
699    }
700}
701
702#[doc(hidden)]
703#[derive(Clone)]
704pub struct FeltParser;
705impl clap::builder::TypedValueParser for FeltParser {
706    type Value = Felt;
707
708    fn parse_ref(
709        &self,
710        _cmd: &clap::Command,
711        _arg: Option<&clap::Arg>,
712        value: &std::ffi::OsStr,
713    ) -> Result<Self::Value, clap::error::Error> {
714        use clap::error::{Error, ErrorKind};
715
716        let value = value.to_str().ok_or_else(|| Error::new(ErrorKind::InvalidUtf8))?.trim();
717        value.parse().map_err(|err| Error::raw(ErrorKind::ValueValidation, err))
718    }
719}
720
721impl core::str::FromStr for Felt {
722    type Err = String;
723
724    fn from_str(s: &str) -> Result<Self, Self::Err> {
725        let value = if let Some(value) = s.strip_prefix("0x") {
726            u64::from_str_radix(value, 16)
727                .map_err(|err| format!("invalid field element value: {err}"))?
728        } else {
729            s.parse::<u64>().map_err(|err| format!("invalid field element value: {err}"))?
730        };
731
732        if value > RawFelt::MODULUS {
733            Err("invalid field element value: exceeds the field modulus".to_string())
734        } else {
735            RawFelt::try_from(value).map(Felt)
736        }
737    }
738}
739
740impl From<Felt> for miden_processor::Felt {
741    fn from(f: Felt) -> Self {
742        f.0
743    }
744}
745
746impl From<bool> for Felt {
747    fn from(b: bool) -> Self {
748        Self(RawFelt::from(b as u32))
749    }
750}
751
752impl From<u8> for Felt {
753    fn from(t: u8) -> Self {
754        Self(t.into())
755    }
756}
757
758impl From<i8> for Felt {
759    fn from(t: i8) -> Self {
760        Self((t as u8).into())
761    }
762}
763
764impl From<i16> for Felt {
765    fn from(t: i16) -> Self {
766        Self((t as u16).into())
767    }
768}
769
770impl From<u16> for Felt {
771    fn from(t: u16) -> Self {
772        Self(t.into())
773    }
774}
775
776impl From<i32> for Felt {
777    fn from(t: i32) -> Self {
778        Self((t as u32).into())
779    }
780}
781
782impl From<u32> for Felt {
783    fn from(t: u32) -> Self {
784        Self(t.into())
785    }
786}
787
788impl From<u64> for Felt {
789    fn from(t: u64) -> Self {
790        Self(RawFelt::new(t))
791    }
792}
793
794impl From<i64> for Felt {
795    fn from(t: i64) -> Self {
796        Self(RawFelt::new(t as u64))
797    }
798}
799
800// Reverse Felt to Rust types conversion
801
802impl From<Felt> for bool {
803    fn from(f: Felt) -> Self {
804        f.0.as_int() != 0
805    }
806}
807
808impl From<Felt> for u8 {
809    fn from(f: Felt) -> Self {
810        f.0.as_int() as u8
811    }
812}
813
814impl From<Felt> for i8 {
815    fn from(f: Felt) -> Self {
816        f.0.as_int() as i8
817    }
818}
819
820impl From<Felt> for u16 {
821    fn from(f: Felt) -> Self {
822        f.0.as_int() as u16
823    }
824}
825
826impl From<Felt> for i16 {
827    fn from(f: Felt) -> Self {
828        f.0.as_int() as i16
829    }
830}
831
832impl From<Felt> for u32 {
833    fn from(f: Felt) -> Self {
834        f.0.as_int() as u32
835    }
836}
837
838impl From<Felt> for i32 {
839    fn from(f: Felt) -> Self {
840        f.0.as_int() as i32
841    }
842}
843
844impl From<Felt> for u64 {
845    fn from(f: Felt) -> Self {
846        f.0.as_int()
847    }
848}
849
850impl From<Felt> for i64 {
851    fn from(f: Felt) -> Self {
852        f.0.as_int() as i64
853    }
854}
855
856impl Arbitrary for Felt {
857    type Parameters = ();
858    type Strategy = BoxedStrategy<Self>;
859
860    fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
861        use miden_core::StarkField;
862        (0u64..RawFelt::MODULUS).prop_map(|v| Felt(RawFelt::new(v))).boxed()
863    }
864}
865
866#[cfg(test)]
867mod tests {
868    use std::collections::VecDeque;
869
870    use super::{bytes_to_words, FromMidenRepr, ToMidenRepr};
871
872    #[test]
873    fn bool_roundtrip() {
874        let encoded = true.to_bytes();
875        let decoded = <bool as FromMidenRepr>::from_bytes(&encoded);
876        assert!(decoded);
877
878        let encoded = true.to_felts();
879        let decoded = <bool as FromMidenRepr>::from_felts(&encoded);
880        assert!(decoded);
881
882        let encoded = true.to_words();
883        let decoded = <bool as FromMidenRepr>::from_words(&encoded);
884        assert!(decoded);
885
886        let mut stack = Vec::default();
887        true.push_to_operand_stack(&mut stack);
888        let popped = <bool as FromMidenRepr>::pop_from_stack(&mut stack);
889        assert!(popped);
890    }
891
892    #[test]
893    fn u8_roundtrip() {
894        let encoded = u8::MAX.to_bytes();
895        let decoded = <u8 as FromMidenRepr>::from_bytes(&encoded);
896        assert_eq!(decoded, u8::MAX);
897
898        let encoded = u8::MAX.to_felts();
899        let decoded = <u8 as FromMidenRepr>::from_felts(&encoded);
900        assert_eq!(decoded, u8::MAX);
901
902        let encoded = u8::MAX.to_words();
903        let decoded = <u8 as FromMidenRepr>::from_words(&encoded);
904        assert_eq!(decoded, u8::MAX);
905
906        let mut stack = Vec::default();
907        u8::MAX.push_to_operand_stack(&mut stack);
908        let popped = <u8 as FromMidenRepr>::pop_from_stack(&mut stack);
909        assert_eq!(popped, u8::MAX);
910    }
911
912    #[test]
913    fn u16_roundtrip() {
914        let encoded = u16::MAX.to_bytes();
915        let decoded = <u16 as FromMidenRepr>::from_bytes(&encoded);
916        assert_eq!(decoded, u16::MAX);
917
918        let encoded = u16::MAX.to_felts();
919        let decoded = <u16 as FromMidenRepr>::from_felts(&encoded);
920        assert_eq!(decoded, u16::MAX);
921
922        let encoded = u16::MAX.to_words();
923        let decoded = <u16 as FromMidenRepr>::from_words(&encoded);
924        assert_eq!(decoded, u16::MAX);
925
926        let mut stack = Vec::default();
927        u16::MAX.push_to_operand_stack(&mut stack);
928        let popped = <u16 as FromMidenRepr>::pop_from_stack(&mut stack);
929        assert_eq!(popped, u16::MAX);
930    }
931
932    #[test]
933    fn u32_roundtrip() {
934        let encoded = u32::MAX.to_bytes();
935        let decoded = <u32 as FromMidenRepr>::from_bytes(&encoded);
936        assert_eq!(decoded, u32::MAX);
937
938        let encoded = u32::MAX.to_felts();
939        let decoded = <u32 as FromMidenRepr>::from_felts(&encoded);
940        assert_eq!(decoded, u32::MAX);
941
942        let encoded = u32::MAX.to_words();
943        let decoded = <u32 as FromMidenRepr>::from_words(&encoded);
944        assert_eq!(decoded, u32::MAX);
945
946        let mut stack = Vec::default();
947        u32::MAX.push_to_operand_stack(&mut stack);
948        let popped = <u32 as FromMidenRepr>::pop_from_stack(&mut stack);
949        assert_eq!(popped, u32::MAX);
950    }
951
952    #[test]
953    fn u64_roundtrip() {
954        let encoded = u64::MAX.to_bytes();
955        let decoded = <u64 as FromMidenRepr>::from_bytes(&encoded);
956        assert_eq!(decoded, u64::MAX);
957
958        let encoded = u64::MAX.to_felts();
959        let decoded = <u64 as FromMidenRepr>::from_felts(&encoded);
960        assert_eq!(decoded, u64::MAX);
961
962        let encoded = u64::MAX.to_words();
963        let decoded = <u64 as FromMidenRepr>::from_words(&encoded);
964        assert_eq!(decoded, u64::MAX);
965
966        let mut stack = Vec::default();
967        u64::MAX.push_to_operand_stack(&mut stack);
968        let popped = <u64 as FromMidenRepr>::pop_from_stack(&mut stack);
969        assert_eq!(popped, u64::MAX);
970    }
971
972    #[test]
973    fn u128_roundtrip() {
974        let encoded = u128::MAX.to_bytes();
975        let decoded = <u128 as FromMidenRepr>::from_bytes(&encoded);
976        assert_eq!(decoded, u128::MAX);
977
978        let encoded = u128::MAX.to_felts();
979        let decoded = <u128 as FromMidenRepr>::from_felts(&encoded);
980        assert_eq!(decoded, u128::MAX);
981
982        let encoded = u128::MAX.to_words();
983        let decoded = <u128 as FromMidenRepr>::from_words(&encoded);
984        assert_eq!(decoded, u128::MAX);
985
986        let mut stack = Vec::default();
987        u128::MAX.push_to_operand_stack(&mut stack);
988        let popped = <u128 as FromMidenRepr>::pop_from_stack(&mut stack);
989        assert_eq!(popped, u128::MAX);
990    }
991
992    #[test]
993    fn byte_array_roundtrip() {
994        let bytes = [0, 1, 2, 3, 4, 5, 6, 7];
995
996        let encoded = bytes.to_felts();
997        let decoded = <[u8; 8] as FromMidenRepr>::from_felts(&encoded);
998        assert_eq!(decoded, bytes);
999
1000        let encoded = bytes.to_words();
1001        let decoded = <[u8; 8] as FromMidenRepr>::from_words(&encoded);
1002        assert_eq!(decoded, bytes);
1003
1004        let mut stack = Vec::default();
1005        bytes.push_to_operand_stack(&mut stack);
1006        let popped = <[u8; 8] as FromMidenRepr>::pop_from_stack(&mut stack);
1007        assert_eq!(popped, bytes);
1008    }
1009
1010    #[test]
1011    fn bytes_to_words_test() {
1012        let bytes = [
1013            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1014            25, 26, 27, 28, 29, 30, 31, 32,
1015        ];
1016        let words = bytes_to_words(&bytes);
1017        assert_eq!(words.len(), 2);
1018        // Words should be in little-endian order, elements of the word should be in big-endian
1019        assert_eq!(words[0][3].as_int() as u32, u32::from_ne_bytes([1, 2, 3, 4]));
1020        assert_eq!(words[0][2].as_int() as u32, u32::from_ne_bytes([5, 6, 7, 8]));
1021        assert_eq!(words[0][1].as_int() as u32, u32::from_ne_bytes([9, 10, 11, 12]));
1022        assert_eq!(words[0][0].as_int() as u32, u32::from_ne_bytes([13, 14, 15, 16]));
1023
1024        // Make sure bytes_to_words and to_words agree
1025        let to_words_output = bytes.to_words();
1026        assert_eq!(words.as_slice(), to_words_output.as_slice());
1027    }
1028
1029    #[test]
1030    fn bytes_from_words_test() {
1031        let bytes = [
1032            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1033            25, 26, 27, 28, 29, 30, 31, 32,
1034        ];
1035        let words = bytes_to_words(&bytes);
1036        let out = <[u8; 32] as FromMidenRepr>::from_words(&words);
1037        assert_eq!(&out, &bytes);
1038    }
1039}