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