Skip to main content

sonobe_primitives/utils/
null.rs

1//! This module defines a zero-cost placeholder type that have well-defined
2//! arithmetic operations.
3
4use ark_ff::Field;
5use ark_r1cs_std::{
6    GR1CSVar,
7    alloc::{AllocVar, AllocationMode},
8};
9use ark_relations::gr1cs::{ConstraintSystemRef, Namespace, SynthesisError};
10use ark_std::{
11    borrow::Borrow,
12    fmt::Debug,
13    iter::Sum,
14    ops::{Add, Mul},
15};
16
17/// [`Null`] is a zero-sized type that absorbs any arithmetic and always returns
18/// itself.
19///
20/// It also has itself as its in-circuit representation, which does not allocate
21/// any variables or require any constraints.
22#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
23pub struct Null;
24
25impl<F> Add<F> for Null {
26    type Output = Null;
27
28    fn add(self, _: F) -> Null {
29        Null
30    }
31}
32
33impl<F> Add<F> for &Null {
34    type Output = Null;
35
36    fn add(self, _: F) -> Null {
37        Null
38    }
39}
40
41impl<F> Mul<F> for Null {
42    type Output = Self;
43
44    fn mul(self, _: F) -> Null {
45        Null
46    }
47}
48
49impl<F> Mul<F> for &Null {
50    type Output = Null;
51
52    fn mul(self, _: F) -> Null {
53        Null
54    }
55}
56
57impl Sum for Null {
58    fn sum<I: Iterator<Item = Self>>(_: I) -> Self {
59        Null
60    }
61}
62
63impl<F: Field> AllocVar<Null, F> for Null {
64    fn new_variable<T: Borrow<Null>>(
65        _cs: impl Into<Namespace<F>>,
66        _f: impl FnOnce() -> Result<T, SynthesisError>,
67        _mode: AllocationMode,
68    ) -> Result<Self, SynthesisError> {
69        Ok(Self)
70    }
71}
72
73impl<F: Field> GR1CSVar<F> for Null {
74    type Value = Null;
75
76    fn cs(&self) -> ConstraintSystemRef<F> {
77        ConstraintSystemRef::None
78    }
79
80    fn value(&self) -> Result<Self::Value, SynthesisError> {
81        Ok(Null)
82    }
83}