arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/crypto-primitives/src/signature/schnorr/constraints.rs
crypto-primitives/src/signature/schnorr/constraints.rsRaw
  1use crate::Vec;
  2use algebra_core::{Field, ProjectiveCurve};
  3use r1cs_core::{Namespace, SynthesisError};
  4use r1cs_std::prelude::*;
  5
  6use crate::signature::SigRandomizePkGadget;
  7
  8use core::{borrow::Borrow, marker::PhantomData};
  9
 10use crate::signature::schnorr::{Parameters, PublicKey, Schnorr};
 11use digest::Digest;
 12
 13type ConstraintF<C> = <<C as ProjectiveCurve>::BaseField as Field>::BasePrimeField;
 14
 15#[derive(Clone)]
 16pub struct ParametersVar<C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>>
 17where
 18    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
 19{
 20    generator: GC,
 21    _curve: PhantomData<C>,
 22}
 23
 24#[derive(Derivative)]
 25#[derivative(
 26    Debug(bound = "C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>"),
 27    Clone(bound = "C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>")
 28)]
 29pub struct PublicKeyVar<C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>>
 30where
 31    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
 32{
 33    pub_key: GC,
 34    #[doc(hidden)]
 35    _group: PhantomData<*const C>,
 36}
 37
 38pub struct SchnorrRandomizePkGadget<C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>>
 39where
 40    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
 41{
 42    #[doc(hidden)]
 43    _group: PhantomData<*const C>,
 44    #[doc(hidden)]
 45    _group_gadget: PhantomData<*const GC>,
 46}
 47
 48impl<C, GC, D> SigRandomizePkGadget<Schnorr<C, D>, ConstraintF<C>>
 49    for SchnorrRandomizePkGadget<C, GC>
 50where
 51    C: ProjectiveCurve,
 52    GC: CurveVar<C, ConstraintF<C>>,
 53    D: Digest + Send + Sync,
 54    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
 55{
 56    type ParametersVar = ParametersVar<C, GC>;
 57    type PublicKeyVar = PublicKeyVar<C, GC>;
 58
 59    fn randomize(
 60        parameters: &Self::ParametersVar,
 61        public_key: &Self::PublicKeyVar,
 62        randomness: &[UInt8<ConstraintF<C>>],
 63    ) -> Result<Self::PublicKeyVar, SynthesisError> {
 64        let base = parameters.generator.clone();
 65        let randomness = randomness
 66            .iter()
 67            .flat_map(|b| b.into_bits_le())
 68            .collect::<Vec<_>>();
 69        let rand_pk = &public_key.pub_key + &base.mul_bits(randomness.iter())?;
 70        Ok(PublicKeyVar {
 71            pub_key: rand_pk,
 72            _group: PhantomData,
 73        })
 74    }
 75}
 76
 77impl<C, GC, D> AllocVar<Parameters<C, D>, ConstraintF<C>> for ParametersVar<C, GC>
 78where
 79    C: ProjectiveCurve,
 80    GC: CurveVar<C, ConstraintF<C>>,
 81    D: Digest,
 82    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
 83{
 84    fn new_variable<T: Borrow<Parameters<C, D>>>(
 85        cs: impl Into<Namespace<ConstraintF<C>>>,
 86        f: impl FnOnce() -> Result<T, SynthesisError>,
 87        mode: AllocationMode,
 88    ) -> Result<Self, SynthesisError> {
 89        let generator = GC::new_variable(cs, || f().map(|g| g.borrow().generator), mode)?;
 90        Ok(Self {
 91            generator,
 92            _curve: PhantomData,
 93        })
 94    }
 95}
 96
 97impl<C, GC> AllocVar<PublicKey<C>, ConstraintF<C>> for PublicKeyVar<C, GC>
 98where
 99    C: ProjectiveCurve,
100    GC: CurveVar<C, ConstraintF<C>>,
101    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
102{
103    fn new_variable<T: Borrow<PublicKey<C>>>(
104        cs: impl Into<Namespace<ConstraintF<C>>>,
105        f: impl FnOnce() -> Result<T, SynthesisError>,
106        mode: AllocationMode,
107    ) -> Result<Self, SynthesisError> {
108        let pub_key = GC::new_variable(cs, f, mode)?;
109        Ok(Self {
110            pub_key,
111            _group: PhantomData,
112        })
113    }
114}
115
116impl<C, GC> EqGadget<ConstraintF<C>> for PublicKeyVar<C, GC>
117where
118    C: ProjectiveCurve,
119    GC: CurveVar<C, ConstraintF<C>>,
120    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
121{
122    #[inline]
123    fn is_eq(&self, other: &Self) -> Result<Boolean<ConstraintF<C>>, SynthesisError> {
124        self.pub_key.is_eq(&other.pub_key)
125    }
126
127    #[inline]
128    fn conditional_enforce_equal(
129        &self,
130        other: &Self,
131        condition: &Boolean<ConstraintF<C>>,
132    ) -> Result<(), SynthesisError> {
133        self.pub_key
134            .conditional_enforce_equal(&other.pub_key, condition)
135    }
136
137    #[inline]
138    fn conditional_enforce_not_equal(
139        &self,
140        other: &Self,
141        condition: &Boolean<ConstraintF<C>>,
142    ) -> Result<(), SynthesisError> {
143        self.pub_key
144            .conditional_enforce_not_equal(&other.pub_key, condition)
145    }
146}
147
148impl<C, GC> ToBytesGadget<ConstraintF<C>> for PublicKeyVar<C, GC>
149where
150    C: ProjectiveCurve,
151    GC: CurveVar<C, ConstraintF<C>>,
152    for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
153{
154    fn to_bytes(&self) -> Result<Vec<UInt8<ConstraintF<C>>>, SynthesisError> {
155        self.pub_key.to_bytes()
156    }
157}