mdnt_support/
lib.rs

1//! Support crate for integrating the extractor.
2
3#![deny(rustdoc::broken_intra_doc_links)]
4#![deny(missing_debug_implementations)]
5#![deny(missing_docs)]
6
7use ff::{Field, PrimeField};
8
9use num_bigint::{BigInt, BigUint};
10use num_traits::{Num as _, Signed as _};
11
12use crate::error::Error;
13
14pub mod cells;
15pub mod circuit;
16pub mod error;
17pub mod macros;
18
19pub use haloumi_ir as ir;
20
21/// This trait defines the halo2 types required by this crate.
22/// An implementation of halo2 compatible with this crate must have
23/// some type that implements this trait s.t. it can be passed to traits
24/// and types in this crate.
25pub trait Halo2Types<F: Field> {
26    /// Type for instance columns.
27    type InstanceCol: std::fmt::Debug + Copy + Clone;
28    /// Type for advice columns.
29    type AdviceCol: std::fmt::Debug + Copy + Clone;
30    /// Type for a cell.
31    type Cell: std::fmt::Debug + Copy + Clone;
32    /// Type for an assigned cell.
33    type AssignedCell<V>;
34    /// Region type.
35    type Region<'a>;
36    /// Error type.
37    type Error: Into<crate::error::Error> + From<crate::error::Error>;
38    /// Region index type
39    type RegionIndex: std::hash::Hash + Copy + Eq;
40    /// Expression type
41    type Expression;
42}
43
44/// Parses a value of F from the given string.
45pub fn parse_field<F: PrimeField>(s: &str) -> Result<F, Error> {
46    if s.is_empty() {
47        return Err(Error::FieldParsingError);
48    }
49    let ten = F::from(10);
50    s.chars()
51        .map(|c| c.to_digit(10).ok_or(Error::FieldParsingError))
52        .map(|r| r.map(u64::from))
53        .map(|r| r.map(F::from))
54        .fold(Ok(F::ZERO), |acc, c| Ok(acc? * ten + c?))
55}
56
57/// Returns the modulus of the field as a [`BigUint`].
58fn modulus<F: PrimeField>() -> BigUint {
59    BigUint::from_str_radix(&F::MODULUS[2..], 16).unwrap()
60}
61
62/// Returns the modulus of the field as a [`BigInt`].
63fn modulus_signed<F: PrimeField>() -> BigInt {
64    BigInt::from_str_radix(&F::MODULUS[2..], 16).unwrap()
65}
66
67/// Converts a big unsigned integer into a prime field element.
68pub fn big_to_fe<F: PrimeField>(e: BigUint) -> F {
69    let modulus = modulus::<F>();
70    let e = e % modulus;
71    F::from_str_vartime(&e.to_str_radix(10)[..]).unwrap()
72}
73
74/// Converts a big signed integer into a prime field element.
75/// If the value is negative it wraps around the field's modulus.
76pub fn sbig_to_fe<F: PrimeField>(mut e: BigInt) -> F {
77    let modulus = modulus_signed::<F>();
78    e = (e % modulus).abs();
79    F::from_str_vartime(&e.to_str_radix(10)[..]).unwrap()
80}
81
82/// Converts a prime field element into a big unsigned integer.
83pub fn fe_to_big<F: PrimeField>(fe: F) -> BigUint {
84    BigUint::from_bytes_le(fe.to_repr().as_ref())
85}
86
87/// Creates an [`Expression`] that queries the given cell relative to the
88/// beginning of the cell's region.
89#[macro_export]
90macro_rules! cell_to_expr {
91    ($x:expr, $F:ty) => {{
92        let c = $x.cell();
93        i32::try_from(c.row_offset)
94            .map(midnight_proofs::poly::Rotation)
95            .map(|r| c.column.query_cell::<$F>(r))
96            .map_err($crate::error::Error::from)
97    }};
98}