aztec_pxe/execution/
field_conversion.rs

1//! Field element conversion between aztec-core Fr and ACVM FieldElement.
2//!
3//! Both wrap `ark_bn254::Fr` internally, so conversion is essentially
4//! copying the inner bytes.
5
6use acir::native_types::{Witness, WitnessMap};
7use acir::{AcirField, FieldElement};
8use aztec_core::types::Fr;
9use std::collections::BTreeSet;
10
11/// Convert an ACVM FieldElement to our Fr type.
12pub fn fe_to_fr(fe: &FieldElement) -> Fr {
13    let hex = fe.to_hex();
14    Fr::from_hex(&format!("0x{hex}")).unwrap_or_else(|_| Fr::zero())
15}
16
17/// Convert our Fr type to an ACVM FieldElement.
18pub fn fr_to_fe(fr: &Fr) -> FieldElement {
19    let bytes = fr.to_be_bytes();
20    FieldElement::from_be_bytes_reduce(&bytes)
21}
22
23/// Extract ordered field values from a witness map for the given return witnesses.
24pub fn witness_map_to_frs(
25    witness: &WitnessMap<FieldElement>,
26    return_witnesses: &BTreeSet<Witness>,
27) -> Vec<Fr> {
28    return_witnesses
29        .iter()
30        .filter_map(|w| witness.get(w).map(fe_to_fr))
31        .collect()
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn roundtrip_conversion() {
40        let original = Fr::from(42u64);
41        let fe = fr_to_fe(&original);
42        let back = fe_to_fr(&fe);
43        assert_eq!(original, back);
44    }
45
46    #[test]
47    fn zero_roundtrip() {
48        let zero = Fr::zero();
49        let fe = fr_to_fe(&zero);
50        let back = fe_to_fr(&fe);
51        assert_eq!(zero, back);
52    }
53
54    #[test]
55    fn large_value_roundtrip() {
56        let large = Fr::from(u64::MAX);
57        let fe = fr_to_fe(&large);
58        let back = fe_to_fr(&fe);
59        assert_eq!(large, back);
60    }
61}