halo2_base/safe_types/primitives.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
use std::ops::Deref;
use crate::QuantumCell;
use super::*;
/// SafeType for bool (1 bit).
///
/// This is a separate struct from `CompactSafeType` with the same behavior. Because
/// we know only one [`AssignedValue`] is needed to hold the boolean value, we avoid
/// using `CompactSafeType` to avoid the additional heap allocation from a length 1 vector.
#[derive(Clone, Copy, Debug)]
pub struct SafeBool<F: ScalarField>(pub(super) AssignedValue<F>);
/// SafeType for byte (8 bits).
///
/// This is a separate struct from `CompactSafeType` with the same behavior. Because
/// we know only one [`AssignedValue`] is needed to hold the boolean value, we avoid
/// using `CompactSafeType` to avoid the additional heap allocation from a length 1 vector.
#[derive(Clone, Copy, Debug)]
pub struct SafeByte<F: ScalarField>(pub(super) AssignedValue<F>);
macro_rules! safe_primitive_impls {
($SafePrimitive:ty) => {
impl<F: ScalarField> AsRef<AssignedValue<F>> for $SafePrimitive {
fn as_ref(&self) -> &AssignedValue<F> {
&self.0
}
}
impl<F: ScalarField> Borrow<AssignedValue<F>> for $SafePrimitive {
fn borrow(&self) -> &AssignedValue<F> {
&self.0
}
}
impl<F: ScalarField> Deref for $SafePrimitive {
type Target = AssignedValue<F>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<F: ScalarField> From<$SafePrimitive> for AssignedValue<F> {
fn from(safe_primitive: $SafePrimitive) -> Self {
safe_primitive.0
}
}
impl<F: ScalarField> From<$SafePrimitive> for QuantumCell<F> {
fn from(safe_primitive: $SafePrimitive) -> Self {
QuantumCell::Existing(safe_primitive.0)
}
}
};
}
safe_primitive_impls!(SafeBool<F>);
safe_primitive_impls!(SafeByte<F>);