mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-30 15:36:39 +01:00
Merge branch 'master' into inline-asm
This commit is contained in:
@@ -13,7 +13,7 @@ problem_files=()
|
|||||||
# collect ill-formatted files
|
# collect ill-formatted files
|
||||||
for file in $(git diff --name-only --cached); do
|
for file in $(git diff --name-only --cached); do
|
||||||
if [ ${file: -3} == ".rs" ]; then
|
if [ ${file: -3} == ".rs" ]; then
|
||||||
rustfmt +nightly --check $file &>/dev/null
|
rustfmt +stable --check $file &>/dev/null
|
||||||
if [ $? != 0 ]; then
|
if [ $? != 0 ]; then
|
||||||
problem_files+=($file)
|
problem_files+=($file)
|
||||||
fi
|
fi
|
||||||
@@ -27,7 +27,7 @@ else
|
|||||||
# reformat the files that need it and re-stage them.
|
# reformat the files that need it and re-stage them.
|
||||||
printf "[pre_commit] the following files were rustfmt'd before commit: \n"
|
printf "[pre_commit] the following files were rustfmt'd before commit: \n"
|
||||||
for file in ${problem_files[@]}; do
|
for file in ${problem_files[@]}; do
|
||||||
rustfmt $file
|
rustfmt +stable $file
|
||||||
git add $file
|
git add $file
|
||||||
printf "\033[0;32m $file\033[0m \n"
|
printf "\033[0;32m $file\033[0m \n"
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use rand::{thread_rng, Rng};
|
|||||||
type TestProofSystem = Gm17<Bls12_377, Bench<Fr>, Fr>;
|
type TestProofSystem = Gm17<Bls12_377, Bench<Fr>, Fr>;
|
||||||
|
|
||||||
struct Bench<F: Field> {
|
struct Bench<F: Field> {
|
||||||
inputs: Vec<Option<F>>,
|
inputs: Vec<Option<F>>,
|
||||||
num_constraints: usize,
|
num_constraints: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ where
|
|||||||
GG: GroupGadget<G, ConstraintF>,
|
GG: GroupGadget<G, ConstraintF>,
|
||||||
IG: InjectiveMapGadget<G, I, ConstraintF, GG>,
|
IG: InjectiveMapGadget<G, I, ConstraintF, GG>,
|
||||||
{
|
{
|
||||||
_compressor: PhantomData<I>,
|
_compressor: PhantomData<I>,
|
||||||
_compressor_gadget: PhantomData<IG>,
|
_compressor_gadget: PhantomData<IG>,
|
||||||
_crh: PedersenCommitmentGadget<G, ConstraintF, GG>,
|
_crh: PedersenCommitmentGadget<G, ConstraintF, GG>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G, I, ConstraintF, GG, IG, W> CommitmentGadget<PedersenCommCompressor<G, I, W>, ConstraintF>
|
impl<G, I, ConstraintF, GG, IG, W> CommitmentGadget<PedersenCommCompressor<G, I, W>, ConstraintF>
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ use algebra_core::groups::Group;
|
|||||||
pub mod constraints;
|
pub mod constraints;
|
||||||
|
|
||||||
pub struct PedersenCommCompressor<G: Group, I: InjectiveMap<G>, W: PedersenWindow> {
|
pub struct PedersenCommCompressor<G: Group, I: InjectiveMap<G>, W: PedersenWindow> {
|
||||||
_group: PhantomData<G>,
|
_group: PhantomData<G>,
|
||||||
_compressor: PhantomData<I>,
|
_compressor: PhantomData<I>,
|
||||||
_comm: PedersenCommitment<G, W>,
|
_comm: PedersenCommitment<G, W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G: Group, I: InjectiveMap<G>, W: PedersenWindow> CommitmentScheme
|
impl<G: Group, I: InjectiveMap<G>, W: PedersenWindow> CommitmentScheme
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ use r1cs_std::prelude::*;
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "G: Group, W: PedersenWindow, ConstraintF: Field"))]
|
#[derivative(Clone(bound = "G: Group, W: PedersenWindow, ConstraintF: Field"))]
|
||||||
pub struct PedersenCommitmentGadgetParameters<G: Group, W: PedersenWindow, ConstraintF: Field> {
|
pub struct PedersenCommitmentGadgetParameters<G: Group, W: PedersenWindow, ConstraintF: Field> {
|
||||||
params: PedersenParameters<G>,
|
params: PedersenParameters<G>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_group: PhantomData<G>,
|
_group: PhantomData<G>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@@ -109,8 +109,8 @@ where
|
|||||||
let parameters = temp.borrow().clone();
|
let parameters = temp.borrow().clone();
|
||||||
|
|
||||||
Ok(PedersenCommitmentGadgetParameters {
|
Ok(PedersenCommitmentGadgetParameters {
|
||||||
params: parameters,
|
params: parameters,
|
||||||
_group: PhantomData,
|
_group: PhantomData,
|
||||||
_engine: PhantomData,
|
_engine: PhantomData,
|
||||||
_window: PhantomData,
|
_window: PhantomData,
|
||||||
})
|
})
|
||||||
@@ -128,8 +128,8 @@ where
|
|||||||
let parameters = temp.borrow().clone();
|
let parameters = temp.borrow().clone();
|
||||||
|
|
||||||
Ok(PedersenCommitmentGadgetParameters {
|
Ok(PedersenCommitmentGadgetParameters {
|
||||||
params: parameters,
|
params: parameters,
|
||||||
_group: PhantomData,
|
_group: PhantomData,
|
||||||
_engine: PhantomData,
|
_engine: PhantomData,
|
||||||
_window: PhantomData,
|
_window: PhantomData,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ pub mod constraints;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PedersenParameters<G: Group> {
|
pub struct PedersenParameters<G: Group> {
|
||||||
pub randomness_generator: Vec<G>,
|
pub randomness_generator: Vec<G>,
|
||||||
pub generators: Vec<Vec<G>>,
|
pub generators: Vec<Vec<G>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PedersenCommitment<G: Group, W: PedersenWindow> {
|
pub struct PedersenCommitment<G: Group, W: PedersenWindow> {
|
||||||
group: PhantomData<G>,
|
group: PhantomData<G>,
|
||||||
window: PhantomData<W>,
|
window: PhantomData<W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ pub struct BoweHopwoodPedersenCRHGadgetParameters<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
GG: GroupGadget<G, ConstraintF>,
|
GG: GroupGadget<G, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
params: BoweHopwoodPedersenParameters<G>,
|
params: BoweHopwoodPedersenParameters<G>,
|
||||||
_group_g: PhantomData<GG>,
|
_group_g: PhantomData<GG>,
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
_window: PhantomData<W>,
|
_window: PhantomData<W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BoweHopwoodPedersenCRHGadget<
|
pub struct BoweHopwoodPedersenCRHGadget<
|
||||||
@@ -32,9 +32,9 @@ pub struct BoweHopwoodPedersenCRHGadget<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
GG: GroupGadget<G, ConstraintF>,
|
GG: GroupGadget<G, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
_group: PhantomData<*const G>,
|
_group: PhantomData<*const G>,
|
||||||
_group_gadget: PhantomData<*const GG>,
|
_group_gadget: PhantomData<*const GG>,
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ConstraintF, G, GG, W> FixedLengthCRHGadget<BoweHopwoodPedersenCRH<G, W>, ConstraintF>
|
impl<ConstraintF, G, GG, W> FixedLengthCRHGadget<BoweHopwoodPedersenCRH<G, W>, ConstraintF>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub struct BoweHopwoodPedersenParameters<G: Group> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct BoweHopwoodPedersenCRH<G: Group, W: PedersenWindow> {
|
pub struct BoweHopwoodPedersenCRH<G: Group, W: PedersenWindow> {
|
||||||
group: PhantomData<G>,
|
group: PhantomData<G>,
|
||||||
window: PhantomData<W>,
|
window: PhantomData<W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,9 +97,9 @@ where
|
|||||||
GG: GroupGadget<G, ConstraintF>,
|
GG: GroupGadget<G, ConstraintF>,
|
||||||
IG: InjectiveMapGadget<G, I, ConstraintF, GG>,
|
IG: InjectiveMapGadget<G, I, ConstraintF, GG>,
|
||||||
{
|
{
|
||||||
_compressor: PhantomData<I>,
|
_compressor: PhantomData<I>,
|
||||||
_compressor_gadget: PhantomData<IG>,
|
_compressor_gadget: PhantomData<IG>,
|
||||||
_crh: PedersenCRHGadget<G, ConstraintF, GG>,
|
_crh: PedersenCRHGadget<G, ConstraintF, GG>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G, I, ConstraintF, GG, IG, W> FixedLengthCRHGadget<PedersenCRHCompressor<G, I, W>, ConstraintF>
|
impl<G, I, ConstraintF, GG, IG, W> FixedLengthCRHGadget<PedersenCRHCompressor<G, I, W>, ConstraintF>
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ impl<P: TEModelParameters> InjectiveMap<TEProjective<P>> for TECompressor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct PedersenCRHCompressor<G: Group, I: InjectiveMap<G>, W: PedersenWindow> {
|
pub struct PedersenCRHCompressor<G: Group, I: InjectiveMap<G>, W: PedersenWindow> {
|
||||||
_group: PhantomData<G>,
|
_group: PhantomData<G>,
|
||||||
_compressor: PhantomData<I>,
|
_compressor: PhantomData<I>,
|
||||||
_crh: PedersenCRH<G, W>,
|
_crh: PedersenCRH<G, W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G: Group, I: InjectiveMap<G>, W: PedersenWindow> FixedLengthCRH
|
impl<G: Group, I: InjectiveMap<G>, W: PedersenWindow> FixedLengthCRH
|
||||||
|
|||||||
@@ -18,19 +18,19 @@ pub struct PedersenCRHGadgetParameters<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
GG: GroupGadget<G, ConstraintF>,
|
GG: GroupGadget<G, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
params: PedersenParameters<G>,
|
params: PedersenParameters<G>,
|
||||||
_group_g: PhantomData<GG>,
|
_group_g: PhantomData<GG>,
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
_window: PhantomData<W>,
|
_window: PhantomData<W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PedersenCRHGadget<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
pub struct PedersenCRHGadget<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
||||||
#[doc(hideen)]
|
#[doc(hideen)]
|
||||||
_group: PhantomData<*const G>,
|
_group: PhantomData<*const G>,
|
||||||
#[doc(hideen)]
|
#[doc(hideen)]
|
||||||
_group_gadget: PhantomData<*const GG>,
|
_group_gadget: PhantomData<*const GG>,
|
||||||
#[doc(hideen)]
|
#[doc(hideen)]
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ConstraintF, G, GG, W> FixedLengthCRHGadget<PedersenCRH<G, W>, ConstraintF>
|
impl<ConstraintF, G, GG, W> FixedLengthCRHGadget<PedersenCRH<G, W>, ConstraintF>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub struct PedersenParameters<G: Group> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct PedersenCRH<G: Group, W: PedersenWindow> {
|
pub struct PedersenCRH<G: Group, W: PedersenWindow> {
|
||||||
group: PhantomData<G>,
|
group: PhantomData<G>,
|
||||||
window: PhantomData<W>,
|
window: PhantomData<W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ impl<P: MerkleTreeConfig> MerkleTreePath<P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct MerkleHashTree<P: MerkleTreeConfig> {
|
pub struct MerkleHashTree<P: MerkleTreeConfig> {
|
||||||
tree: Vec<<P::H as FixedLengthCRH>::Output>,
|
tree: Vec<<P::H as FixedLengthCRH>::Output>,
|
||||||
padding_tree: Vec<(
|
padding_tree: Vec<(
|
||||||
<P::H as FixedLengthCRH>::Output,
|
<P::H as FixedLengthCRH>::Output,
|
||||||
<P::H as FixedLengthCRH>::Output,
|
<P::H as FixedLengthCRH>::Output,
|
||||||
)>,
|
)>,
|
||||||
parameters: <P::H as FixedLengthCRH>::Parameters,
|
parameters: <P::H as FixedLengthCRH>::Parameters,
|
||||||
root: Option<<P::H as FixedLengthCRH>::Output>,
|
root: Option<<P::H as FixedLengthCRH>::Output>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: MerkleTreeConfig> MerkleHashTree<P> {
|
impl<P: MerkleTreeConfig> MerkleHashTree<P> {
|
||||||
@@ -248,7 +248,7 @@ impl core::fmt::Display for MerkleTreeError {
|
|||||||
let msg = match self {
|
let msg = match self {
|
||||||
MerkleTreeError::IncorrectLeafIndex(index) => {
|
MerkleTreeError::IncorrectLeafIndex(index) => {
|
||||||
format!("incorrect leaf index: {}", index)
|
format!("incorrect leaf index: {}", index)
|
||||||
},
|
}
|
||||||
MerkleTreeError::IncorrectPathLength(len) => format!("incorrect path length: {}", len),
|
MerkleTreeError::IncorrectPathLength(len) => format!("incorrect path length: {}", len),
|
||||||
};
|
};
|
||||||
write!(f, "{}", msg)
|
write!(f, "{}", msg)
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ pub struct VerifyingKeyGadget<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
P: PairingGadget<PairingE, ConstraintF>,
|
P: PairingGadget<PairingE, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
pub h_g2: P::G2Gadget,
|
pub h_g2: P::G2Gadget,
|
||||||
pub g_alpha_g1: P::G1Gadget,
|
pub g_alpha_g1: P::G1Gadget,
|
||||||
pub h_beta_g2: P::G2Gadget,
|
pub h_beta_g2: P::G2Gadget,
|
||||||
pub g_gamma_g1: P::G1Gadget,
|
pub g_gamma_g1: P::G1Gadget,
|
||||||
pub h_gamma_g2: P::G2Gadget,
|
pub h_gamma_g2: P::G2Gadget,
|
||||||
pub query: Vec<P::G1Gadget>,
|
pub query: Vec<P::G1Gadget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<PairingE: PairingEngine, ConstraintF: Field, P: PairingGadget<PairingE, ConstraintF>>
|
impl<PairingE: PairingEngine, ConstraintF: Field, P: PairingGadget<PairingE, ConstraintF>>
|
||||||
@@ -72,14 +72,14 @@ pub struct PreparedVerifyingKeyGadget<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
P: PairingGadget<PairingE, ConstraintF>,
|
P: PairingGadget<PairingE, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
pub g_alpha: P::G1Gadget,
|
pub g_alpha: P::G1Gadget,
|
||||||
pub h_beta: P::G2Gadget,
|
pub h_beta: P::G2Gadget,
|
||||||
pub g_alpha_pc: P::G1PreparedGadget,
|
pub g_alpha_pc: P::G1PreparedGadget,
|
||||||
pub h_beta_pc: P::G2PreparedGadget,
|
pub h_beta_pc: P::G2PreparedGadget,
|
||||||
pub g_gamma_pc: P::G1PreparedGadget,
|
pub g_gamma_pc: P::G1PreparedGadget,
|
||||||
pub h_gamma_pc: P::G2PreparedGadget,
|
pub h_gamma_pc: P::G2PreparedGadget,
|
||||||
pub h_pc: P::G2PreparedGadget,
|
pub h_pc: P::G2PreparedGadget,
|
||||||
pub query: Vec<P::G1Gadget>,
|
pub query: Vec<P::G1Gadget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Gm17VerifierGadget<PairingE, ConstraintF, P>
|
pub struct Gm17VerifierGadget<PairingE, ConstraintF, P>
|
||||||
@@ -89,7 +89,7 @@ where
|
|||||||
P: PairingGadget<PairingE, ConstraintF>,
|
P: PairingGadget<PairingE, ConstraintF>,
|
||||||
{
|
{
|
||||||
_pairing_engine: PhantomData<PairingE>,
|
_pairing_engine: PhantomData<PairingE>,
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
_pairing_gadget: PhantomData<P>,
|
_pairing_gadget: PhantomData<P>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +412,7 @@ mod test {
|
|||||||
type TestVkGadget = VerifyingKeyGadget<Bls12_377, Fq, Bls12_377PairingGadget>;
|
type TestVkGadget = VerifyingKeyGadget<Bls12_377, Fq, Bls12_377PairingGadget>;
|
||||||
|
|
||||||
struct Bench<F: Field> {
|
struct Bench<F: Field> {
|
||||||
inputs: Vec<Option<F>>,
|
inputs: Vec<Option<F>>,
|
||||||
num_constraints: usize,
|
num_constraints: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ mod test_recursive {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Bench<F: Field> {
|
struct Bench<F: Field> {
|
||||||
inputs: Vec<Option<F>>,
|
inputs: Vec<Option<F>>,
|
||||||
num_constraints: usize,
|
num_constraints: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +612,7 @@ mod test_recursive {
|
|||||||
struct Wrapper {
|
struct Wrapper {
|
||||||
inputs: Vec<Option<MNT4Fq>>,
|
inputs: Vec<Option<MNT4Fq>>,
|
||||||
params: Parameters<MNT6_298>,
|
params: Parameters<MNT6_298>,
|
||||||
proof: Proof<MNT6_298>,
|
proof: Proof<MNT6_298>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstraintSynthesizer<MNT6Fq> for Wrapper {
|
impl ConstraintSynthesizer<MNT6Fq> for Wrapper {
|
||||||
@@ -709,7 +709,7 @@ mod test_recursive {
|
|||||||
let c = Wrapper {
|
let c = Wrapper {
|
||||||
inputs: inputs.clone(),
|
inputs: inputs.clone(),
|
||||||
params: inner_params.clone(),
|
params: inner_params.clone(),
|
||||||
proof: inner_proof.clone(),
|
proof: inner_proof.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
generate_random_parameters(c, rng).unwrap()
|
generate_random_parameters(c, rng).unwrap()
|
||||||
@@ -722,7 +722,7 @@ mod test_recursive {
|
|||||||
let c = Wrapper {
|
let c = Wrapper {
|
||||||
inputs: inputs.clone(),
|
inputs: inputs.clone(),
|
||||||
params: inner_params.clone(),
|
params: inner_params.clone(),
|
||||||
proof: inner_proof.clone(),
|
proof: inner_proof.clone(),
|
||||||
};
|
};
|
||||||
// Create a groth16 proof with our parameters.
|
// Create a groth16 proof with our parameters.
|
||||||
create_random_proof(c, ¶ms, rng).unwrap()
|
create_random_proof(c, ¶ms, rng).unwrap()
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ pub struct Gm17<
|
|||||||
V: ToConstraintField<E::Fr> + ?Sized,
|
V: ToConstraintField<E::Fr> + ?Sized,
|
||||||
> {
|
> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_engine: PhantomData<E>,
|
_engine: PhantomData<E>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_circuit: PhantomData<C>,
|
_circuit: PhantomData<C>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_verifier_input: PhantomData<V>,
|
_verifier_input: PhantomData<V>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ pub struct VerifyingKeyGadget<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
P: PairingGadget<PairingE, ConstraintF>,
|
P: PairingGadget<PairingE, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
pub alpha_g1: P::G1Gadget,
|
pub alpha_g1: P::G1Gadget,
|
||||||
pub beta_g2: P::G2Gadget,
|
pub beta_g2: P::G2Gadget,
|
||||||
pub gamma_g2: P::G2Gadget,
|
pub gamma_g2: P::G2Gadget,
|
||||||
pub delta_g2: P::G2Gadget,
|
pub delta_g2: P::G2Gadget,
|
||||||
pub gamma_abc_g1: Vec<P::G1Gadget>,
|
pub gamma_abc_g1: Vec<P::G1Gadget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,9 +78,9 @@ pub struct PreparedVerifyingKeyGadget<
|
|||||||
P: PairingGadget<PairingE, ConstraintF>,
|
P: PairingGadget<PairingE, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
pub alpha_g1_beta_g2: P::GTGadget,
|
pub alpha_g1_beta_g2: P::GTGadget,
|
||||||
pub gamma_g2_neg_pc: P::G2PreparedGadget,
|
pub gamma_g2_neg_pc: P::G2PreparedGadget,
|
||||||
pub delta_g2_neg_pc: P::G2PreparedGadget,
|
pub delta_g2_neg_pc: P::G2PreparedGadget,
|
||||||
pub gamma_abc_g1: Vec<P::G1Gadget>,
|
pub gamma_abc_g1: Vec<P::G1Gadget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Groth16VerifierGadget<PairingE, ConstraintF, P>
|
pub struct Groth16VerifierGadget<PairingE, ConstraintF, P>
|
||||||
@@ -90,7 +90,7 @@ where
|
|||||||
P: PairingGadget<PairingE, ConstraintF>,
|
P: PairingGadget<PairingE, ConstraintF>,
|
||||||
{
|
{
|
||||||
_pairing_engine: PhantomData<PairingE>,
|
_pairing_engine: PhantomData<PairingE>,
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
_pairing_gadget: PhantomData<P>,
|
_pairing_gadget: PhantomData<P>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +359,7 @@ mod test {
|
|||||||
type TestVkGadget = VerifyingKeyGadget<Bls12_377, Fq, Bls12_377PairingGadget>;
|
type TestVkGadget = VerifyingKeyGadget<Bls12_377, Fq, Bls12_377PairingGadget>;
|
||||||
|
|
||||||
struct Bench<F: Field> {
|
struct Bench<F: Field> {
|
||||||
inputs: Vec<Option<F>>,
|
inputs: Vec<Option<F>>,
|
||||||
num_constraints: usize,
|
num_constraints: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ mod test_recursive {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Bench<F: Field> {
|
struct Bench<F: Field> {
|
||||||
inputs: Vec<Option<F>>,
|
inputs: Vec<Option<F>>,
|
||||||
num_constraints: usize,
|
num_constraints: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,7 +559,7 @@ mod test_recursive {
|
|||||||
struct Wrapper {
|
struct Wrapper {
|
||||||
inputs: Vec<Option<MNT4Fq>>,
|
inputs: Vec<Option<MNT4Fq>>,
|
||||||
params: Parameters<MNT6_298>,
|
params: Parameters<MNT6_298>,
|
||||||
proof: Proof<MNT6_298>,
|
proof: Proof<MNT6_298>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstraintSynthesizer<MNT6Fq> for Wrapper {
|
impl ConstraintSynthesizer<MNT6Fq> for Wrapper {
|
||||||
@@ -656,7 +656,7 @@ mod test_recursive {
|
|||||||
let c = Wrapper {
|
let c = Wrapper {
|
||||||
inputs: inputs.clone(),
|
inputs: inputs.clone(),
|
||||||
params: inner_params.clone(),
|
params: inner_params.clone(),
|
||||||
proof: inner_proof.clone(),
|
proof: inner_proof.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
generate_random_parameters(c, rng).unwrap()
|
generate_random_parameters(c, rng).unwrap()
|
||||||
@@ -669,7 +669,7 @@ mod test_recursive {
|
|||||||
let c = Wrapper {
|
let c = Wrapper {
|
||||||
inputs: inputs.clone(),
|
inputs: inputs.clone(),
|
||||||
params: inner_params.clone(),
|
params: inner_params.clone(),
|
||||||
proof: inner_proof.clone(),
|
proof: inner_proof.clone(),
|
||||||
};
|
};
|
||||||
// Create a groth16 proof with our parameters.
|
// Create a groth16 proof with our parameters.
|
||||||
create_random_proof(c, ¶ms, rng).unwrap()
|
create_random_proof(c, ¶ms, rng).unwrap()
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ pub struct Groth16<
|
|||||||
V: ToConstraintField<E::Fr> + ?Sized,
|
V: ToConstraintField<E::Fr> + ?Sized,
|
||||||
> {
|
> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_engine: PhantomData<E>,
|
_engine: PhantomData<E>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_circuit: PhantomData<C>,
|
_circuit: PhantomData<C>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_verifier_input: PhantomData<V>,
|
_verifier_input: PhantomData<V>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,17 +67,17 @@ mod test {
|
|||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct R1CSCircuit {
|
struct R1CSCircuit {
|
||||||
x: Option<Fr>,
|
x: Option<Fr>,
|
||||||
sum: Option<Fr>,
|
sum: Option<Fr>,
|
||||||
w: Option<Fr>,
|
w: Option<Fr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl R1CSCircuit {
|
impl R1CSCircuit {
|
||||||
pub(super) fn new(x: Fr, sum: Fr, w: Fr) -> Self {
|
pub(super) fn new(x: Fr, sum: Fr, w: Fr) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: Some(x),
|
x: Some(x),
|
||||||
sum: Some(sum),
|
sum: Some(sum),
|
||||||
w: Some(w),
|
w: Some(w),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -664,14 +664,14 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
Boolean::Is(b) => {
|
Boolean::Is(b) => {
|
||||||
assert!(s.next().unwrap() == b.get_value().unwrap());
|
assert!(s.next().unwrap() == b.get_value().unwrap());
|
||||||
},
|
}
|
||||||
Boolean::Not(b) => {
|
Boolean::Not(b) => {
|
||||||
assert!(s.next().unwrap() != b.get_value().unwrap());
|
assert!(s.next().unwrap() != b.get_value().unwrap());
|
||||||
},
|
}
|
||||||
Boolean::Constant(b) => {
|
Boolean::Constant(b) => {
|
||||||
assert!(input_len == 0);
|
assert!(input_len == 0);
|
||||||
assert!(s.next().unwrap() == b);
|
assert!(s.next().unwrap() == b);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,17 +30,17 @@ impl PRF for Blake2s {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Blake2sWithParameterBlock {
|
pub struct Blake2sWithParameterBlock {
|
||||||
pub digest_length: u8,
|
pub digest_length: u8,
|
||||||
pub key_length: u8,
|
pub key_length: u8,
|
||||||
pub fan_out: u8,
|
pub fan_out: u8,
|
||||||
pub depth: u8,
|
pub depth: u8,
|
||||||
pub leaf_length: u32,
|
pub leaf_length: u32,
|
||||||
pub node_offset: u32,
|
pub node_offset: u32,
|
||||||
pub xof_digest_length: u16,
|
pub xof_digest_length: u16,
|
||||||
pub node_depth: u8,
|
pub node_depth: u8,
|
||||||
pub inner_length: u8,
|
pub inner_length: u8,
|
||||||
pub salt: [u8; 8],
|
pub salt: [u8; 8],
|
||||||
pub personalization: [u8; 8],
|
pub personalization: [u8; 8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Blake2sWithParameterBlock {
|
impl Blake2sWithParameterBlock {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ use digest::Digest;
|
|||||||
pub struct SchnorrSigGadgetParameters<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>>
|
pub struct SchnorrSigGadgetParameters<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>>
|
||||||
{
|
{
|
||||||
generator: GG,
|
generator: GG,
|
||||||
_group: PhantomData<*const G>,
|
_group: PhantomData<*const G>,
|
||||||
_engine: PhantomData<*const ConstraintF>,
|
_engine: PhantomData<*const ConstraintF>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> Clone
|
impl<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> Clone
|
||||||
@@ -22,8 +22,8 @@ impl<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> Clone
|
|||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
generator: self.generator.clone(),
|
generator: self.generator.clone(),
|
||||||
_group: PhantomData,
|
_group: PhantomData,
|
||||||
_engine: PhantomData,
|
_engine: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,18 +38,18 @@ impl<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> Clone
|
|||||||
pub struct SchnorrSigGadgetPk<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
pub struct SchnorrSigGadgetPk<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
||||||
pub_key: GG,
|
pub_key: GG,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_group: PhantomData<*const G>,
|
_group: PhantomData<*const G>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_engine: PhantomData<*const ConstraintF>,
|
_engine: PhantomData<*const ConstraintF>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SchnorrRandomizePkGadget<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
pub struct SchnorrRandomizePkGadget<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_group: PhantomData<*const G>,
|
_group: PhantomData<*const G>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_group_gadget: PhantomData<*const GG>,
|
_group_gadget: PhantomData<*const GG>,
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_engine: PhantomData<*const ConstraintF>,
|
_engine: PhantomData<*const ConstraintF>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G, GG, D, ConstraintF> SigRandomizePkGadget<SchnorrSignature<G, D>, ConstraintF>
|
impl<G, GG, D, ConstraintF> SigRandomizePkGadget<SchnorrSignature<G, D>, ConstraintF>
|
||||||
@@ -81,7 +81,7 @@ where
|
|||||||
)?;
|
)?;
|
||||||
Ok(SchnorrSigGadgetPk {
|
Ok(SchnorrSigGadgetPk {
|
||||||
pub_key: rand_pk,
|
pub_key: rand_pk,
|
||||||
_group: PhantomData,
|
_group: PhantomData,
|
||||||
_engine: PhantomData,
|
_engine: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ pub mod constraints;
|
|||||||
|
|
||||||
pub struct SchnorrSignature<G: Group, D: Digest> {
|
pub struct SchnorrSignature<G: Group, D: Digest> {
|
||||||
_group: PhantomData<G>,
|
_group: PhantomData<G>,
|
||||||
_hash: PhantomData<D>,
|
_hash: PhantomData<D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "G: Group, H: Digest"))]
|
#[derivative(Clone(bound = "G: Group, H: Digest"))]
|
||||||
pub struct SchnorrSigParameters<G: Group, H: Digest> {
|
pub struct SchnorrSigParameters<G: Group, H: Digest> {
|
||||||
_hash: PhantomData<H>,
|
_hash: PhantomData<H>,
|
||||||
pub generator: G,
|
pub generator: G,
|
||||||
pub salt: [u8; 32],
|
pub salt: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SchnorrPublicKey<G> = G;
|
pub type SchnorrPublicKey<G> = G;
|
||||||
@@ -42,7 +42,7 @@ impl<G: Group> ToBytes for SchnorrSecretKey<G> {
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "G: Group"), Default(bound = "G: Group"))]
|
#[derivative(Clone(bound = "G: Group"), Default(bound = "G: Group"))]
|
||||||
pub struct SchnorrSig<G: Group> {
|
pub struct SchnorrSig<G: Group> {
|
||||||
pub prover_response: G::ScalarField,
|
pub prover_response: G::ScalarField,
|
||||||
pub verifier_challenge: G::ScalarField,
|
pub verifier_challenge: G::ScalarField,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let new_sig = SchnorrSig {
|
let new_sig = SchnorrSig {
|
||||||
prover_response: *prover_response - &(*verifier_challenge * &multiplier),
|
prover_response: *prover_response - &(*verifier_challenge * &multiplier),
|
||||||
verifier_challenge: *verifier_challenge,
|
verifier_challenge: *verifier_challenge,
|
||||||
};
|
};
|
||||||
end_timer!(rand_signature_time);
|
end_timer!(rand_signature_time);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use r1cs_core::{ConstraintSystem, ConstraintVar, LinearCombination, SynthesisErr
|
|||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct AllocatedBit {
|
pub struct AllocatedBit {
|
||||||
variable: Variable,
|
variable: Variable,
|
||||||
value: Option<bool>,
|
value: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AllocatedBit {
|
impl AllocatedBit {
|
||||||
@@ -69,7 +69,7 @@ impl AllocatedBit {
|
|||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
variable: result_var,
|
variable: result_var,
|
||||||
value: result_value,
|
value: result_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ impl AllocatedBit {
|
|||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
variable: result_var,
|
variable: result_var,
|
||||||
value: result_value,
|
value: result_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ impl AllocatedBit {
|
|||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
variable: result_var,
|
variable: result_var,
|
||||||
value: result_value,
|
value: result_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ impl AllocatedBit {
|
|||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
variable: result_var,
|
variable: result_var,
|
||||||
value: result_value,
|
value: result_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@ impl AllocatedBit {
|
|||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
variable: result_var,
|
variable: result_var,
|
||||||
value: result_value,
|
value: result_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,7 +362,7 @@ fn cond_select_helper<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
value: result_val,
|
value: result_val,
|
||||||
variable: result_var,
|
variable: result_var,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -400,11 +400,11 @@ impl Boolean {
|
|||||||
} else {
|
} else {
|
||||||
LinearCombination::<ConstraintF>::zero()
|
LinearCombination::<ConstraintF>::zero()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Boolean::Is(ref v) => (coeff, v.get_variable()).into(),
|
Boolean::Is(ref v) => (coeff, v.get_variable()).into(),
|
||||||
Boolean::Not(ref v) => {
|
Boolean::Not(ref v) => {
|
||||||
LinearCombination::<ConstraintF>::zero() + (coeff, one) - (coeff, v.get_variable())
|
LinearCombination::<ConstraintF>::zero() + (coeff, one) - (coeff, v.get_variable())
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,12 +458,12 @@ impl Boolean {
|
|||||||
(is @ &Boolean::Is(_), not @ &Boolean::Not(_))
|
(is @ &Boolean::Is(_), not @ &Boolean::Not(_))
|
||||||
| (not @ &Boolean::Not(_), is @ &Boolean::Is(_)) => {
|
| (not @ &Boolean::Not(_), is @ &Boolean::Is(_)) => {
|
||||||
Ok(Boolean::xor(cs, is, ¬.not())?.not())
|
Ok(Boolean::xor(cs, is, ¬.not())?.not())
|
||||||
},
|
}
|
||||||
// a XOR b = (NOT a) XOR (NOT b)
|
// a XOR b = (NOT a) XOR (NOT b)
|
||||||
(&Boolean::Is(ref a), &Boolean::Is(ref b))
|
(&Boolean::Is(ref a), &Boolean::Is(ref b))
|
||||||
| (&Boolean::Not(ref a), &Boolean::Not(ref b)) => {
|
| (&Boolean::Not(ref a), &Boolean::Not(ref b)) => {
|
||||||
Ok(Boolean::Is(AllocatedBit::xor(cs, a, b)?))
|
Ok(Boolean::Is(AllocatedBit::xor(cs, a, b)?))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,16 +477,16 @@ impl Boolean {
|
|||||||
(&Boolean::Constant(false), x) | (x, &Boolean::Constant(false)) => Ok(*x),
|
(&Boolean::Constant(false), x) | (x, &Boolean::Constant(false)) => Ok(*x),
|
||||||
(&Boolean::Constant(true), _) | (_, &Boolean::Constant(true)) => {
|
(&Boolean::Constant(true), _) | (_, &Boolean::Constant(true)) => {
|
||||||
Ok(Boolean::Constant(true))
|
Ok(Boolean::Constant(true))
|
||||||
},
|
}
|
||||||
// a OR b = NOT ((NOT a) AND b)
|
// a OR b = NOT ((NOT a) AND b)
|
||||||
(a @ &Boolean::Is(_), b @ &Boolean::Not(_))
|
(a @ &Boolean::Is(_), b @ &Boolean::Not(_))
|
||||||
| (b @ &Boolean::Not(_), a @ &Boolean::Is(_))
|
| (b @ &Boolean::Not(_), a @ &Boolean::Is(_))
|
||||||
| (b @ &Boolean::Not(_), a @ &Boolean::Not(_)) => {
|
| (b @ &Boolean::Not(_), a @ &Boolean::Not(_)) => {
|
||||||
Ok(Boolean::and(cs, &a.not(), &b.not())?.not())
|
Ok(Boolean::and(cs, &a.not(), &b.not())?.not())
|
||||||
},
|
}
|
||||||
(&Boolean::Is(ref a), &Boolean::Is(ref b)) => {
|
(&Boolean::Is(ref a), &Boolean::Is(ref b)) => {
|
||||||
AllocatedBit::or(cs, a, b).map(Boolean::from)
|
AllocatedBit::or(cs, a, b).map(Boolean::from)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,22 +504,22 @@ impl Boolean {
|
|||||||
// false AND x is always false
|
// false AND x is always false
|
||||||
(&Boolean::Constant(false), _) | (_, &Boolean::Constant(false)) => {
|
(&Boolean::Constant(false), _) | (_, &Boolean::Constant(false)) => {
|
||||||
Ok(Boolean::Constant(false))
|
Ok(Boolean::Constant(false))
|
||||||
},
|
}
|
||||||
// true AND x is always x
|
// true AND x is always x
|
||||||
(&Boolean::Constant(true), x) | (x, &Boolean::Constant(true)) => Ok(*x),
|
(&Boolean::Constant(true), x) | (x, &Boolean::Constant(true)) => Ok(*x),
|
||||||
// a AND (NOT b)
|
// a AND (NOT b)
|
||||||
(&Boolean::Is(ref is), &Boolean::Not(ref not))
|
(&Boolean::Is(ref is), &Boolean::Not(ref not))
|
||||||
| (&Boolean::Not(ref not), &Boolean::Is(ref is)) => {
|
| (&Boolean::Not(ref not), &Boolean::Is(ref is)) => {
|
||||||
Ok(Boolean::Is(AllocatedBit::and_not(cs, is, not)?))
|
Ok(Boolean::Is(AllocatedBit::and_not(cs, is, not)?))
|
||||||
},
|
}
|
||||||
// (NOT a) AND (NOT b) = a NOR b
|
// (NOT a) AND (NOT b) = a NOR b
|
||||||
(&Boolean::Not(ref a), &Boolean::Not(ref b)) => {
|
(&Boolean::Not(ref a), &Boolean::Not(ref b)) => {
|
||||||
Ok(Boolean::Is(AllocatedBit::nor(cs, a, b)?))
|
Ok(Boolean::Is(AllocatedBit::nor(cs, a, b)?))
|
||||||
},
|
}
|
||||||
// a AND b
|
// a AND b
|
||||||
(&Boolean::Is(ref a), &Boolean::Is(ref b)) => {
|
(&Boolean::Is(ref a), &Boolean::Is(ref b)) => {
|
||||||
Ok(Boolean::Is(AllocatedBit::and(cs, a, b)?))
|
Ok(Boolean::Is(AllocatedBit::and(cs, a, b)?))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,7 +559,7 @@ impl Boolean {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
Boolean::Not(ref res) => {
|
Boolean::Not(ref res) => {
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "enforce nand",
|
|| "enforce nand",
|
||||||
@@ -569,7 +569,7 @@ impl Boolean {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,25 +760,25 @@ impl<ConstraintF: Field> ConditionalEqGadget<ConstraintF> for Boolean {
|
|||||||
// 1 - a
|
// 1 - a
|
||||||
(Constant(true), Is(a)) | (Is(a), Constant(true)) => {
|
(Constant(true), Is(a)) | (Is(a), Constant(true)) => {
|
||||||
LinearCombination::zero() + one - a.get_variable()
|
LinearCombination::zero() + one - a.get_variable()
|
||||||
},
|
}
|
||||||
// a - 0 = a
|
// a - 0 = a
|
||||||
(Constant(false), Is(a)) | (Is(a), Constant(false)) => {
|
(Constant(false), Is(a)) | (Is(a), Constant(false)) => {
|
||||||
LinearCombination::zero() + a.get_variable()
|
LinearCombination::zero() + a.get_variable()
|
||||||
},
|
}
|
||||||
// 1 - !a = 1 - (1 - a) = a
|
// 1 - !a = 1 - (1 - a) = a
|
||||||
(Constant(true), Not(a)) | (Not(a), Constant(true)) => {
|
(Constant(true), Not(a)) | (Not(a), Constant(true)) => {
|
||||||
LinearCombination::zero() + a.get_variable()
|
LinearCombination::zero() + a.get_variable()
|
||||||
},
|
}
|
||||||
// !a - 0 = !a = 1 - a
|
// !a - 0 = !a = 1 - a
|
||||||
(Constant(false), Not(a)) | (Not(a), Constant(false)) => {
|
(Constant(false), Not(a)) | (Not(a), Constant(false)) => {
|
||||||
LinearCombination::zero() + one - a.get_variable()
|
LinearCombination::zero() + one - a.get_variable()
|
||||||
},
|
}
|
||||||
// b - a,
|
// b - a,
|
||||||
(Is(a), Is(b)) => LinearCombination::zero() + b.get_variable() - a.get_variable(),
|
(Is(a), Is(b)) => LinearCombination::zero() + b.get_variable() - a.get_variable(),
|
||||||
// !b - a = (1 - b) - a
|
// !b - a = (1 - b) - a
|
||||||
(Is(a), Not(b)) | (Not(b), Is(a)) => {
|
(Is(a), Not(b)) | (Not(b), Is(a)) => {
|
||||||
LinearCombination::zero() + one - b.get_variable() - a.get_variable()
|
LinearCombination::zero() + one - b.get_variable() - a.get_variable()
|
||||||
},
|
}
|
||||||
// !b - !a = (1 - b) - (1 - a) = a - b,
|
// !b - !a = (1 - b) - (1 - a) = a - b,
|
||||||
(Not(a), Not(b)) => LinearCombination::zero() + a.get_variable() - b.get_variable(),
|
(Not(a), Not(b)) => LinearCombination::zero() + a.get_variable() - b.get_variable(),
|
||||||
};
|
};
|
||||||
@@ -831,7 +831,7 @@ impl<ConstraintF: PrimeField> CondSelectGadget<ConstraintF> for Boolean {
|
|||||||
Boolean::Constant(false) => Ok(false_value.clone()),
|
Boolean::Constant(false) => Ok(false_value.clone()),
|
||||||
cond @ Boolean::Not(_) => {
|
cond @ Boolean::Not(_) => {
|
||||||
Self::conditionally_select(cs, &cond.not(), false_value, true_value)
|
Self::conditionally_select(cs, &cond.not(), false_value, true_value)
|
||||||
},
|
}
|
||||||
cond @ Boolean::Is(_) => match (true_value, false_value) {
|
cond @ Boolean::Is(_) => match (true_value, false_value) {
|
||||||
(x, &Boolean::Constant(false)) => Boolean::and(cs.ns(|| "and"), cond, x).into(),
|
(x, &Boolean::Constant(false)) => Boolean::and(cs.ns(|| "and"), cond, x).into(),
|
||||||
(&Boolean::Constant(false), x) => Boolean::and(cs.ns(|| "and"), &cond.not(), x),
|
(&Boolean::Constant(false), x) => Boolean::and(cs.ns(|| "and"), &cond.not(), x),
|
||||||
@@ -847,7 +847,7 @@ impl<ConstraintF: PrimeField> CondSelectGadget<ConstraintF> for Boolean {
|
|||||||
cond_select_helper(cs, cond, (a.get_value(), a_lc), (b.get_value(), b_lc))?
|
cond_select_helper(cs, cond, (a.get_value(), a_lc), (b.get_value(), b_lc))?
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1138,42 +1138,42 @@ mod test {
|
|||||||
let mut b = Boolean::from(AllocatedBit::alloc(&mut cs, || Ok(true)).unwrap());
|
let mut b = Boolean::from(AllocatedBit::alloc(&mut cs, || Ok(true)).unwrap());
|
||||||
|
|
||||||
match b {
|
match b {
|
||||||
Boolean::Is(_) => {},
|
Boolean::Is(_) => {}
|
||||||
_ => panic!("unexpected value"),
|
_ => panic!("unexpected value"),
|
||||||
}
|
}
|
||||||
|
|
||||||
b = b.not();
|
b = b.not();
|
||||||
|
|
||||||
match b {
|
match b {
|
||||||
Boolean::Not(_) => {},
|
Boolean::Not(_) => {}
|
||||||
_ => panic!("unexpected value"),
|
_ => panic!("unexpected value"),
|
||||||
}
|
}
|
||||||
|
|
||||||
b = b.not();
|
b = b.not();
|
||||||
|
|
||||||
match b {
|
match b {
|
||||||
Boolean::Is(_) => {},
|
Boolean::Is(_) => {}
|
||||||
_ => panic!("unexpected value"),
|
_ => panic!("unexpected value"),
|
||||||
}
|
}
|
||||||
|
|
||||||
b = Boolean::constant(true);
|
b = Boolean::constant(true);
|
||||||
|
|
||||||
match b {
|
match b {
|
||||||
Boolean::Constant(true) => {},
|
Boolean::Constant(true) => {}
|
||||||
_ => panic!("unexpected value"),
|
_ => panic!("unexpected value"),
|
||||||
}
|
}
|
||||||
|
|
||||||
b = b.not();
|
b = b.not();
|
||||||
|
|
||||||
match b {
|
match b {
|
||||||
Boolean::Constant(false) => {},
|
Boolean::Constant(false) => {}
|
||||||
_ => panic!("unexpected value"),
|
_ => panic!("unexpected value"),
|
||||||
}
|
}
|
||||||
|
|
||||||
b = b.not();
|
b = b.not();
|
||||||
|
|
||||||
match b {
|
match b {
|
||||||
Boolean::Constant(true) => {},
|
Boolean::Constant(true) => {}
|
||||||
_ => panic!("unexpected value"),
|
_ => panic!("unexpected value"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1215,16 +1215,16 @@ mod test {
|
|||||||
OperandType::False => Boolean::constant(false),
|
OperandType::False => Boolean::constant(false),
|
||||||
OperandType::AllocatedTrue => {
|
OperandType::AllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::AllocatedFalse => {
|
OperandType::AllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedTrue => {
|
OperandType::NegatedAllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap()).not()
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap()).not()
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedFalse => {
|
OperandType::NegatedAllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap()).not()
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap()).not()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1237,22 +1237,22 @@ mod test {
|
|||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
|
|
||||||
match (first_operand, second_operand, c) {
|
match (first_operand, second_operand, c) {
|
||||||
(OperandType::True, OperandType::True, Boolean::Constant(false)) => {},
|
(OperandType::True, OperandType::True, Boolean::Constant(false)) => {}
|
||||||
(OperandType::True, OperandType::False, Boolean::Constant(true)) => {},
|
(OperandType::True, OperandType::False, Boolean::Constant(true)) => {}
|
||||||
(OperandType::True, OperandType::AllocatedTrue, Boolean::Not(_)) => {},
|
(OperandType::True, OperandType::AllocatedTrue, Boolean::Not(_)) => {}
|
||||||
(OperandType::True, OperandType::AllocatedFalse, Boolean::Not(_)) => {},
|
(OperandType::True, OperandType::AllocatedFalse, Boolean::Not(_)) => {}
|
||||||
(OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Is(_)) => {},
|
(OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Is(_)) => {}
|
||||||
(OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Is(_)) => {},
|
(OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Is(_)) => {}
|
||||||
|
|
||||||
(OperandType::False, OperandType::True, Boolean::Constant(true)) => {},
|
(OperandType::False, OperandType::True, Boolean::Constant(true)) => {}
|
||||||
(OperandType::False, OperandType::False, Boolean::Constant(false)) => {},
|
(OperandType::False, OperandType::False, Boolean::Constant(false)) => {}
|
||||||
(OperandType::False, OperandType::AllocatedTrue, Boolean::Is(_)) => {},
|
(OperandType::False, OperandType::AllocatedTrue, Boolean::Is(_)) => {}
|
||||||
(OperandType::False, OperandType::AllocatedFalse, Boolean::Is(_)) => {},
|
(OperandType::False, OperandType::AllocatedFalse, Boolean::Is(_)) => {}
|
||||||
(OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {},
|
(OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {}
|
||||||
(OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {},
|
(OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {}
|
||||||
|
|
||||||
(OperandType::AllocatedTrue, OperandType::True, Boolean::Not(_)) => {},
|
(OperandType::AllocatedTrue, OperandType::True, Boolean::Not(_)) => {}
|
||||||
(OperandType::AllocatedTrue, OperandType::False, Boolean::Is(_)) => {},
|
(OperandType::AllocatedTrue, OperandType::False, Boolean::Is(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1260,7 +1260,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1268,7 +1268,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1276,7 +1276,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1284,10 +1284,10 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
|
|
||||||
(OperandType::AllocatedFalse, OperandType::True, Boolean::Not(_)) => {},
|
(OperandType::AllocatedFalse, OperandType::True, Boolean::Not(_)) => {}
|
||||||
(OperandType::AllocatedFalse, OperandType::False, Boolean::Is(_)) => {},
|
(OperandType::AllocatedFalse, OperandType::False, Boolean::Is(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1295,7 +1295,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1303,7 +1303,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1311,7 +1311,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1319,10 +1319,10 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
(OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Is(_)) => {},
|
(OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Is(_)) => {}
|
||||||
(OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Not(_)) => {},
|
(OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Not(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1330,7 +1330,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1338,7 +1338,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1346,7 +1346,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1354,10 +1354,10 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
|
|
||||||
(OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Is(_)) => {},
|
(OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Is(_)) => {}
|
||||||
(OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Not(_)) => {},
|
(OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Not(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1365,7 +1365,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1373,7 +1373,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1381,7 +1381,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::one());
|
assert!(cs.get("xor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1389,7 +1389,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("xor result") == Fr::zero());
|
assert!(cs.get("xor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
_ => panic!("this should never be encountered"),
|
_ => panic!("this should never be encountered"),
|
||||||
}
|
}
|
||||||
@@ -1426,18 +1426,18 @@ mod test {
|
|||||||
OperandType::False => Boolean::constant(false),
|
OperandType::False => Boolean::constant(false),
|
||||||
OperandType::AllocatedTrue => {
|
OperandType::AllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::AllocatedFalse => {
|
OperandType::AllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedTrue => {
|
OperandType::NegatedAllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
||||||
.not()
|
.not()
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedFalse => {
|
OperandType::NegatedAllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
||||||
.not()
|
.not()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1498,16 +1498,16 @@ mod test {
|
|||||||
OperandType::False => Boolean::constant(false),
|
OperandType::False => Boolean::constant(false),
|
||||||
OperandType::AllocatedTrue => {
|
OperandType::AllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::AllocatedFalse => {
|
OperandType::AllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedTrue => {
|
OperandType::NegatedAllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap()).not()
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap()).not()
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedFalse => {
|
OperandType::NegatedAllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap()).not()
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap()).not()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1520,159 +1520,159 @@ mod test {
|
|||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
|
|
||||||
match (first_operand, second_operand, c) {
|
match (first_operand, second_operand, c) {
|
||||||
(OperandType::True, OperandType::True, Boolean::Constant(true)) => {},
|
(OperandType::True, OperandType::True, Boolean::Constant(true)) => {}
|
||||||
(OperandType::True, OperandType::False, Boolean::Constant(true)) => {},
|
(OperandType::True, OperandType::False, Boolean::Constant(true)) => {}
|
||||||
(OperandType::True, OperandType::AllocatedTrue, Boolean::Constant(true)) => {},
|
(OperandType::True, OperandType::AllocatedTrue, Boolean::Constant(true)) => {}
|
||||||
(OperandType::True, OperandType::AllocatedFalse, Boolean::Constant(true)) => {},
|
(OperandType::True, OperandType::AllocatedFalse, Boolean::Constant(true)) => {}
|
||||||
(
|
(
|
||||||
OperandType::True,
|
OperandType::True,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
Boolean::Constant(true),
|
Boolean::Constant(true),
|
||||||
) => {},
|
) => {}
|
||||||
(
|
(
|
||||||
OperandType::True,
|
OperandType::True,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
Boolean::Constant(true),
|
Boolean::Constant(true),
|
||||||
) => {},
|
) => {}
|
||||||
|
|
||||||
(OperandType::False, OperandType::True, Boolean::Constant(true)) => {},
|
(OperandType::False, OperandType::True, Boolean::Constant(true)) => {}
|
||||||
(OperandType::False, OperandType::False, Boolean::Constant(false)) => {},
|
(OperandType::False, OperandType::False, Boolean::Constant(false)) => {}
|
||||||
(OperandType::False, OperandType::AllocatedTrue, Boolean::Is(_)) => {},
|
(OperandType::False, OperandType::AllocatedTrue, Boolean::Is(_)) => {}
|
||||||
(OperandType::False, OperandType::AllocatedFalse, Boolean::Is(_)) => {},
|
(OperandType::False, OperandType::AllocatedFalse, Boolean::Is(_)) => {}
|
||||||
(OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {},
|
(OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {}
|
||||||
(OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {},
|
(OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {}
|
||||||
|
|
||||||
(OperandType::AllocatedTrue, OperandType::True, Boolean::Constant(true)) => {},
|
(OperandType::AllocatedTrue, OperandType::True, Boolean::Constant(true)) => {}
|
||||||
(OperandType::AllocatedTrue, OperandType::False, Boolean::Is(_)) => {},
|
(OperandType::AllocatedTrue, OperandType::False, Boolean::Is(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
Boolean::Is(ref v),
|
Boolean::Is(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
Boolean::Is(ref v),
|
Boolean::Is(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
(OperandType::AllocatedFalse, OperandType::True, Boolean::Constant(true)) => {},
|
(OperandType::AllocatedFalse, OperandType::True, Boolean::Constant(true)) => {}
|
||||||
(OperandType::AllocatedFalse, OperandType::False, Boolean::Is(_)) => {},
|
(OperandType::AllocatedFalse, OperandType::False, Boolean::Is(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
Boolean::Is(ref v),
|
Boolean::Is(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
Boolean::Is(ref v),
|
Boolean::Is(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::True,
|
OperandType::True,
|
||||||
Boolean::Constant(true),
|
Boolean::Constant(true),
|
||||||
) => {},
|
) => {}
|
||||||
(OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Not(_)) => {},
|
(OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Not(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::True,
|
OperandType::True,
|
||||||
Boolean::Constant(true),
|
Boolean::Constant(true),
|
||||||
) => {},
|
) => {}
|
||||||
(OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Not(_)) => {},
|
(OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Not(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
Boolean::Not(ref v),
|
Boolean::Not(ref v),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"this should never be encountered, in case: (a = {:?}, b = {:?}, c = {:?})",
|
"this should never be encountered, in case: (a = {:?}, b = {:?}, c = {:?})",
|
||||||
@@ -1710,16 +1710,16 @@ mod test {
|
|||||||
OperandType::False => Boolean::constant(false),
|
OperandType::False => Boolean::constant(false),
|
||||||
OperandType::AllocatedTrue => {
|
OperandType::AllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::AllocatedFalse => {
|
OperandType::AllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap())
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedTrue => {
|
OperandType::NegatedAllocatedTrue => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap()).not()
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(true)).unwrap()).not()
|
||||||
},
|
}
|
||||||
OperandType::NegatedAllocatedFalse => {
|
OperandType::NegatedAllocatedFalse => {
|
||||||
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap()).not()
|
Boolean::from(AllocatedBit::alloc(cs, || Ok(false)).unwrap()).not()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1732,33 +1732,31 @@ mod test {
|
|||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
|
|
||||||
match (first_operand, second_operand, c) {
|
match (first_operand, second_operand, c) {
|
||||||
(OperandType::True, OperandType::True, Boolean::Constant(true)) => {},
|
(OperandType::True, OperandType::True, Boolean::Constant(true)) => {}
|
||||||
(OperandType::True, OperandType::False, Boolean::Constant(false)) => {},
|
(OperandType::True, OperandType::False, Boolean::Constant(false)) => {}
|
||||||
(OperandType::True, OperandType::AllocatedTrue, Boolean::Is(_)) => {},
|
(OperandType::True, OperandType::AllocatedTrue, Boolean::Is(_)) => {}
|
||||||
(OperandType::True, OperandType::AllocatedFalse, Boolean::Is(_)) => {},
|
(OperandType::True, OperandType::AllocatedFalse, Boolean::Is(_)) => {}
|
||||||
(OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {},
|
(OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {}
|
||||||
(OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {},
|
(OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {}
|
||||||
|
|
||||||
(OperandType::False, OperandType::True, Boolean::Constant(false)) => {},
|
(OperandType::False, OperandType::True, Boolean::Constant(false)) => {}
|
||||||
(OperandType::False, OperandType::False, Boolean::Constant(false)) => {},
|
(OperandType::False, OperandType::False, Boolean::Constant(false)) => {}
|
||||||
(OperandType::False, OperandType::AllocatedTrue, Boolean::Constant(false)) => {
|
(OperandType::False, OperandType::AllocatedTrue, Boolean::Constant(false)) => {}
|
||||||
},
|
|
||||||
(OperandType::False, OperandType::AllocatedFalse, Boolean::Constant(false)) => {
|
(OperandType::False, OperandType::AllocatedFalse, Boolean::Constant(false)) => {
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::False,
|
OperandType::False,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
Boolean::Constant(false),
|
Boolean::Constant(false),
|
||||||
) => {},
|
) => {}
|
||||||
(
|
(
|
||||||
OperandType::False,
|
OperandType::False,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
Boolean::Constant(false),
|
Boolean::Constant(false),
|
||||||
) => {},
|
) => {}
|
||||||
|
|
||||||
(OperandType::AllocatedTrue, OperandType::True, Boolean::Is(_)) => {},
|
(OperandType::AllocatedTrue, OperandType::True, Boolean::Is(_)) => {}
|
||||||
(OperandType::AllocatedTrue, OperandType::False, Boolean::Constant(false)) => {
|
(OperandType::AllocatedTrue, OperandType::False, Boolean::Constant(false)) => {}
|
||||||
},
|
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1766,7 +1764,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and result") == Fr::one());
|
assert!(cs.get("and result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1774,7 +1772,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and result") == Fr::zero());
|
assert!(cs.get("and result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1782,7 +1780,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::zero());
|
assert!(cs.get("and not result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1790,11 +1788,11 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::one());
|
assert!(cs.get("and not result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
|
|
||||||
(OperandType::AllocatedFalse, OperandType::True, Boolean::Is(_)) => {},
|
(OperandType::AllocatedFalse, OperandType::True, Boolean::Is(_)) => {}
|
||||||
(OperandType::AllocatedFalse, OperandType::False, Boolean::Constant(false)) => {
|
(OperandType::AllocatedFalse, OperandType::False, Boolean::Constant(false)) => {
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1802,7 +1800,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and result") == Fr::zero());
|
assert!(cs.get("and result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1810,7 +1808,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and result") == Fr::zero());
|
assert!(cs.get("and result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1818,7 +1816,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::zero());
|
assert!(cs.get("and not result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1826,14 +1824,14 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::zero());
|
assert!(cs.get("and not result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
(OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Not(_)) => {},
|
(OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Not(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::False,
|
OperandType::False,
|
||||||
Boolean::Constant(false),
|
Boolean::Constant(false),
|
||||||
) => {},
|
) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1841,7 +1839,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::zero());
|
assert!(cs.get("and not result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1849,7 +1847,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::zero());
|
assert!(cs.get("and not result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1857,7 +1855,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("nor result") == Fr::zero());
|
assert!(cs.get("nor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1865,14 +1863,14 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("nor result") == Fr::zero());
|
assert!(cs.get("nor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
|
|
||||||
(OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Not(_)) => {},
|
(OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Not(_)) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::False,
|
OperandType::False,
|
||||||
Boolean::Constant(false),
|
Boolean::Constant(false),
|
||||||
) => {},
|
) => {}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::AllocatedTrue,
|
OperandType::AllocatedTrue,
|
||||||
@@ -1880,7 +1878,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::one());
|
assert!(cs.get("and not result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::AllocatedFalse,
|
OperandType::AllocatedFalse,
|
||||||
@@ -1888,7 +1886,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("and not result") == Fr::zero());
|
assert!(cs.get("and not result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::NegatedAllocatedTrue,
|
OperandType::NegatedAllocatedTrue,
|
||||||
@@ -1896,7 +1894,7 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("nor result") == Fr::zero());
|
assert!(cs.get("nor result") == Fr::zero());
|
||||||
assert_eq!(v.value, Some(false));
|
assert_eq!(v.value, Some(false));
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
OperandType::NegatedAllocatedFalse,
|
OperandType::NegatedAllocatedFalse,
|
||||||
@@ -1904,14 +1902,14 @@ mod test {
|
|||||||
) => {
|
) => {
|
||||||
assert!(cs.get("nor result") == Fr::one());
|
assert!(cs.get("nor result") == Fr::one());
|
||||||
assert_eq!(v.value, Some(true));
|
assert_eq!(v.value, Some(true));
|
||||||
},
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
panic!(
|
panic!(
|
||||||
"unexpected behavior at {:?} AND {:?}",
|
"unexpected behavior at {:?} AND {:?}",
|
||||||
first_operand, second_operand
|
first_operand, second_operand
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2072,7 +2070,7 @@ mod test {
|
|||||||
match r {
|
match r {
|
||||||
Boolean::Is(ref r) => {
|
Boolean::Is(ref r) => {
|
||||||
assert_eq!(r.value.unwrap(), expected);
|
assert_eq!(r.value.unwrap(), expected);
|
||||||
},
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use crate::{
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct UInt32 {
|
pub struct UInt32 {
|
||||||
// Least significant bit_gadget first
|
// Least significant bit_gadget first
|
||||||
bits: Vec<Boolean>,
|
bits: Vec<Boolean>,
|
||||||
value: Option<u32>,
|
value: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ impl UInt32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v
|
v
|
||||||
},
|
}
|
||||||
None => vec![None; 32],
|
None => vec![None; 32],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -94,19 +94,19 @@ impl UInt32 {
|
|||||||
if b {
|
if b {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
&Boolean::Is(ref b) => match b.get_value() {
|
&Boolean::Is(ref b) => match b.get_value() {
|
||||||
Some(true) => {
|
Some(true) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
},
|
}
|
||||||
Some(false) => {},
|
Some(false) => {}
|
||||||
None => value = None,
|
None => value = None,
|
||||||
},
|
},
|
||||||
&Boolean::Not(ref b) => match b.get_value() {
|
&Boolean::Not(ref b) => match b.get_value() {
|
||||||
Some(false) => {
|
Some(false) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
},
|
}
|
||||||
Some(true) => {},
|
Some(true) => {}
|
||||||
None => value = None,
|
None => value = None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ impl UInt32 {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
UInt32 {
|
UInt32 {
|
||||||
bits: new_bits,
|
bits: new_bits,
|
||||||
value: self.value.map(|v| v.rotate_right(by as u32)),
|
value: self.value.map(|v| v.rotate_right(by as u32)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,12 +193,12 @@ impl UInt32 {
|
|||||||
match op.value {
|
match op.value {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
result_value.as_mut().map(|v| *v += u64::from(val));
|
result_value.as_mut().map(|v| *v += u64::from(val));
|
||||||
},
|
}
|
||||||
None => {
|
None => {
|
||||||
// If any of our operands have unknown value, we won't
|
// If any of our operands have unknown value, we won't
|
||||||
// know the value of the result
|
// know the value of the result
|
||||||
result_value = None;
|
result_value = None;
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over each bit_gadget of the operand and add the operand to
|
// Iterate over each bit_gadget of the operand and add the operand to
|
||||||
@@ -211,18 +211,18 @@ impl UInt32 {
|
|||||||
|
|
||||||
// Add coeff * bit_gadget
|
// Add coeff * bit_gadget
|
||||||
lc += (coeff, bit.get_variable());
|
lc += (coeff, bit.get_variable());
|
||||||
},
|
}
|
||||||
Boolean::Not(ref bit) => {
|
Boolean::Not(ref bit) => {
|
||||||
all_constants = false;
|
all_constants = false;
|
||||||
|
|
||||||
// Add coeff * (1 - bit_gadget) = coeff * ONE - coeff * bit_gadget
|
// Add coeff * (1 - bit_gadget) = coeff * ONE - coeff * bit_gadget
|
||||||
lc = lc + (coeff, CS::one()) - (coeff, bit.get_variable());
|
lc = lc + (coeff, CS::one()) - (coeff, bit.get_variable());
|
||||||
},
|
}
|
||||||
Boolean::Constant(bit) => {
|
Boolean::Constant(bit) => {
|
||||||
if bit {
|
if bit {
|
||||||
lc += (coeff, CS::one());
|
lc += (coeff, CS::one());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
coeff.double_in_place();
|
coeff.double_in_place();
|
||||||
@@ -269,7 +269,7 @@ impl UInt32 {
|
|||||||
result_bits.truncate(32);
|
result_bits.truncate(32);
|
||||||
|
|
||||||
Ok(UInt32 {
|
Ok(UInt32 {
|
||||||
bits: result_bits,
|
bits: result_bits,
|
||||||
value: modular_value,
|
value: modular_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -298,7 +298,7 @@ impl<ConstraintF: Field> ToBytesGadget<ConstraintF> for UInt32 {
|
|||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
for (i, chunk8) in self.to_bits_le().chunks(8).enumerate() {
|
for (i, chunk8) in self.to_bits_le().chunks(8).enumerate() {
|
||||||
let byte = UInt8 {
|
let byte = UInt8 {
|
||||||
bits: chunk8.to_vec(),
|
bits: chunk8.to_vec(),
|
||||||
value: value_chunks[i],
|
value: value_chunks[i],
|
||||||
};
|
};
|
||||||
bytes.push(byte);
|
bytes.push(byte);
|
||||||
@@ -362,7 +362,7 @@ mod test {
|
|||||||
match bit_gadget {
|
match bit_gadget {
|
||||||
&Boolean::Constant(bit_gadget) => {
|
&Boolean::Constant(bit_gadget) => {
|
||||||
assert!(bit_gadget == ((b.value.unwrap() >> i) & 1 == 1));
|
assert!(bit_gadget == ((b.value.unwrap() >> i) & 1 == 1));
|
||||||
},
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,8 +371,8 @@ mod test {
|
|||||||
|
|
||||||
for x in v.iter().zip(expected_to_be_same.iter()) {
|
for x in v.iter().zip(expected_to_be_same.iter()) {
|
||||||
match x {
|
match x {
|
||||||
(&Boolean::Constant(true), &Boolean::Constant(true)) => {},
|
(&Boolean::Constant(true), &Boolean::Constant(true)) => {}
|
||||||
(&Boolean::Constant(false), &Boolean::Constant(false)) => {},
|
(&Boolean::Constant(false), &Boolean::Constant(false)) => {}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -407,13 +407,13 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
&Boolean::Is(ref b) => {
|
&Boolean::Is(ref b) => {
|
||||||
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
&Boolean::Not(ref b) => {
|
&Boolean::Not(ref b) => {
|
||||||
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
&Boolean::Constant(b) => {
|
&Boolean::Constant(b) => {
|
||||||
assert!(b == (expected & 1 == 1));
|
assert!(b == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expected >>= 1;
|
expected >>= 1;
|
||||||
@@ -448,7 +448,7 @@ mod test {
|
|||||||
&Boolean::Not(_) => panic!(),
|
&Boolean::Not(_) => panic!(),
|
||||||
&Boolean::Constant(b) => {
|
&Boolean::Constant(b) => {
|
||||||
assert!(b == (expected & 1 == 1));
|
assert!(b == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expected >>= 1;
|
expected >>= 1;
|
||||||
@@ -486,10 +486,10 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
&Boolean::Is(ref b) => {
|
&Boolean::Is(ref b) => {
|
||||||
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
&Boolean::Not(ref b) => {
|
&Boolean::Not(ref b) => {
|
||||||
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
&Boolean::Constant(_) => unreachable!(),
|
&Boolean::Constant(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +525,7 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
&Boolean::Constant(b) => {
|
&Boolean::Constant(b) => {
|
||||||
assert_eq!(b, tmp & 1 == 1);
|
assert_eq!(b, tmp & 1 == 1);
|
||||||
},
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use core::borrow::Borrow;
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct UInt64 {
|
pub struct UInt64 {
|
||||||
// Least significant bit_gadget first
|
// Least significant bit_gadget first
|
||||||
bits: Vec<Boolean>,
|
bits: Vec<Boolean>,
|
||||||
value: Option<u64>,
|
value: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ impl UInt64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v
|
v
|
||||||
}
|
},
|
||||||
None => vec![None; 64],
|
None => vec![None; 64],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,19 +95,19 @@ impl UInt64 {
|
|||||||
if b {
|
if b {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
&Boolean::Is(ref b) => match b.get_value() {
|
&Boolean::Is(ref b) => match b.get_value() {
|
||||||
Some(true) => {
|
Some(true) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
},
|
||||||
Some(false) => {}
|
Some(false) => {},
|
||||||
None => value = None,
|
None => value = None,
|
||||||
},
|
},
|
||||||
&Boolean::Not(ref b) => match b.get_value() {
|
&Boolean::Not(ref b) => match b.get_value() {
|
||||||
Some(false) => {
|
Some(false) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
},
|
||||||
Some(true) => {}
|
Some(true) => {},
|
||||||
None => value = None,
|
None => value = None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ impl UInt64 {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
UInt64 {
|
UInt64 {
|
||||||
bits: new_bits,
|
bits: new_bits,
|
||||||
value: self.value.map(|v| v.rotate_right(by as u32)),
|
value: self.value.map(|v| v.rotate_right(by as u32)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,12 +194,12 @@ impl UInt64 {
|
|||||||
match op.value {
|
match op.value {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
result_value.as_mut().map(|v| *v += u128::from(val));
|
result_value.as_mut().map(|v| *v += u128::from(val));
|
||||||
}
|
},
|
||||||
None => {
|
None => {
|
||||||
// If any of our operands have unknown value, we won't
|
// If any of our operands have unknown value, we won't
|
||||||
// know the value of the result
|
// know the value of the result
|
||||||
result_value = None;
|
result_value = None;
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over each bit_gadget of the operand and add the operand to
|
// Iterate over each bit_gadget of the operand and add the operand to
|
||||||
@@ -212,18 +212,18 @@ impl UInt64 {
|
|||||||
|
|
||||||
// Add coeff * bit_gadget
|
// Add coeff * bit_gadget
|
||||||
lc += (coeff, bit.get_variable());
|
lc += (coeff, bit.get_variable());
|
||||||
}
|
},
|
||||||
Boolean::Not(ref bit) => {
|
Boolean::Not(ref bit) => {
|
||||||
all_constants = false;
|
all_constants = false;
|
||||||
|
|
||||||
// Add coeff * (1 - bit_gadget) = coeff * ONE - coeff * bit_gadget
|
// Add coeff * (1 - bit_gadget) = coeff * ONE - coeff * bit_gadget
|
||||||
lc = lc + (coeff, CS::one()) - (coeff, bit.get_variable());
|
lc = lc + (coeff, CS::one()) - (coeff, bit.get_variable());
|
||||||
}
|
},
|
||||||
Boolean::Constant(bit) => {
|
Boolean::Constant(bit) => {
|
||||||
if bit {
|
if bit {
|
||||||
lc += (coeff, CS::one());
|
lc += (coeff, CS::one());
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
coeff.double_in_place();
|
coeff.double_in_place();
|
||||||
@@ -270,7 +270,7 @@ impl UInt64 {
|
|||||||
result_bits.truncate(64);
|
result_bits.truncate(64);
|
||||||
|
|
||||||
Ok(UInt64 {
|
Ok(UInt64 {
|
||||||
bits: result_bits,
|
bits: result_bits,
|
||||||
value: modular_value,
|
value: modular_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -330,7 +330,7 @@ impl<ConstraintF: Field> ToBytesGadget<ConstraintF> for UInt64 {
|
|||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
for (i, chunk8) in self.to_bits_le().chunks(8).enumerate() {
|
for (i, chunk8) in self.to_bits_le().chunks(8).enumerate() {
|
||||||
let byte = UInt8 {
|
let byte = UInt8 {
|
||||||
bits: chunk8.to_vec(),
|
bits: chunk8.to_vec(),
|
||||||
value: value_chunks[i],
|
value: value_chunks[i],
|
||||||
};
|
};
|
||||||
bytes.push(byte);
|
bytes.push(byte);
|
||||||
@@ -397,7 +397,7 @@ mod test {
|
|||||||
match bit_gadget {
|
match bit_gadget {
|
||||||
&Boolean::Constant(bit_gadget) => {
|
&Boolean::Constant(bit_gadget) => {
|
||||||
assert!(bit_gadget == ((b.value.unwrap() >> i) & 1 == 1));
|
assert!(bit_gadget == ((b.value.unwrap() >> i) & 1 == 1));
|
||||||
}
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,8 +406,8 @@ mod test {
|
|||||||
|
|
||||||
for x in v.iter().zip(expected_to_be_same.iter()) {
|
for x in v.iter().zip(expected_to_be_same.iter()) {
|
||||||
match x {
|
match x {
|
||||||
(&Boolean::Constant(true), &Boolean::Constant(true)) => {}
|
(&Boolean::Constant(true), &Boolean::Constant(true)) => {},
|
||||||
(&Boolean::Constant(false), &Boolean::Constant(false)) => {}
|
(&Boolean::Constant(false), &Boolean::Constant(false)) => {},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,13 +442,13 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
&Boolean::Is(ref b) => {
|
&Boolean::Is(ref b) => {
|
||||||
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
},
|
||||||
&Boolean::Not(ref b) => {
|
&Boolean::Not(ref b) => {
|
||||||
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
},
|
||||||
&Boolean::Constant(b) => {
|
&Boolean::Constant(b) => {
|
||||||
assert!(b == (expected & 1 == 1));
|
assert!(b == (expected & 1 == 1));
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
expected >>= 1;
|
expected >>= 1;
|
||||||
@@ -483,7 +483,7 @@ mod test {
|
|||||||
&Boolean::Not(_) => panic!(),
|
&Boolean::Not(_) => panic!(),
|
||||||
&Boolean::Constant(b) => {
|
&Boolean::Constant(b) => {
|
||||||
assert!(b == (expected & 1 == 1));
|
assert!(b == (expected & 1 == 1));
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
expected >>= 1;
|
expected >>= 1;
|
||||||
@@ -521,10 +521,10 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
&Boolean::Is(ref b) => {
|
&Boolean::Is(ref b) => {
|
||||||
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
},
|
||||||
&Boolean::Not(ref b) => {
|
&Boolean::Not(ref b) => {
|
||||||
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
},
|
||||||
&Boolean::Constant(_) => unreachable!(),
|
&Boolean::Constant(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,7 +560,7 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
&Boolean::Constant(b) => {
|
&Boolean::Constant(b) => {
|
||||||
assert_eq!(b, tmp & 1 == 1);
|
assert_eq!(b, tmp & 1 == 1);
|
||||||
}
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use core::borrow::Borrow;
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct UInt8 {
|
pub struct UInt8 {
|
||||||
// Least significant bit_gadget first
|
// Least significant bit_gadget first
|
||||||
pub(crate) bits: Vec<Boolean>,
|
pub(crate) bits: Vec<Boolean>,
|
||||||
pub(crate) value: Option<u8>,
|
pub(crate) value: Option<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,19 +134,19 @@ impl UInt8 {
|
|||||||
if b {
|
if b {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Boolean::Is(ref b) => match b.get_value() {
|
Boolean::Is(ref b) => match b.get_value() {
|
||||||
Some(true) => {
|
Some(true) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
},
|
}
|
||||||
Some(false) => {},
|
Some(false) => {}
|
||||||
None => value = None,
|
None => value = None,
|
||||||
},
|
},
|
||||||
Boolean::Not(ref b) => match b.get_value() {
|
Boolean::Not(ref b) => match b.get_value() {
|
||||||
Some(false) => {
|
Some(false) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
},
|
}
|
||||||
Some(true) => {},
|
Some(true) => {}
|
||||||
None => value = None,
|
None => value = None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -233,7 +233,7 @@ impl<ConstraintF: Field> AllocGadget<u8, ConstraintF> for UInt8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v
|
v
|
||||||
},
|
}
|
||||||
_ => vec![None; 8],
|
_ => vec![None; 8],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ impl<ConstraintF: Field> AllocGadget<u8, ConstraintF> for UInt8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v
|
v
|
||||||
},
|
}
|
||||||
_ => vec![None; 8],
|
_ => vec![None; 8],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -342,7 +342,7 @@ mod test {
|
|||||||
match bit_gadget {
|
match bit_gadget {
|
||||||
&Boolean::Constant(bit_gadget) => {
|
&Boolean::Constant(bit_gadget) => {
|
||||||
assert!(bit_gadget == ((b.value.unwrap() >> i) & 1 == 1));
|
assert!(bit_gadget == ((b.value.unwrap() >> i) & 1 == 1));
|
||||||
},
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,8 +351,8 @@ mod test {
|
|||||||
|
|
||||||
for x in v.iter().zip(expected_to_be_same.iter()) {
|
for x in v.iter().zip(expected_to_be_same.iter()) {
|
||||||
match x {
|
match x {
|
||||||
(&Boolean::Constant(true), &Boolean::Constant(true)) => {},
|
(&Boolean::Constant(true), &Boolean::Constant(true)) => {}
|
||||||
(&Boolean::Constant(false), &Boolean::Constant(false)) => {},
|
(&Boolean::Constant(false), &Boolean::Constant(false)) => {}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,13 +387,13 @@ mod test {
|
|||||||
match b {
|
match b {
|
||||||
&Boolean::Is(ref b) => {
|
&Boolean::Is(ref b) => {
|
||||||
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
&Boolean::Not(ref b) => {
|
&Boolean::Not(ref b) => {
|
||||||
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
&Boolean::Constant(b) => {
|
&Boolean::Constant(b) => {
|
||||||
assert!(b == (expected & 1 == 1));
|
assert!(b == (expected & 1 == 1));
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expected >>= 1;
|
expected >>= 1;
|
||||||
|
|||||||
@@ -111,14 +111,14 @@ impl<F: PrimeField> FpGadget<F> {
|
|||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
left = a;
|
left = a;
|
||||||
right = b;
|
right = b;
|
||||||
},
|
}
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
left = b;
|
left = b;
|
||||||
right = a;
|
right = a;
|
||||||
},
|
}
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
return Err(SynthesisError::Unsatisfiable);
|
return Err(SynthesisError::Unsatisfiable);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
let right_for_check = if should_also_check_equality {
|
let right_for_check = if should_also_check_equality {
|
||||||
right.add_constant(cs.ns(|| "plus one"), &F::one())?
|
right.add_constant(cs.ns(|| "plus one"), &F::one())?
|
||||||
@@ -252,7 +252,7 @@ mod test {
|
|||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
}
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
a_var
|
a_var
|
||||||
.enforce_cmp(
|
.enforce_cmp(
|
||||||
@@ -270,8 +270,8 @@ mod test {
|
|||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
@@ -300,7 +300,7 @@ mod test {
|
|||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
}
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
a_var
|
a_var
|
||||||
.enforce_cmp(
|
.enforce_cmp(
|
||||||
@@ -318,8 +318,8 @@ mod test {
|
|||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(!cs.is_satisfied());
|
assert!(!cs.is_satisfied());
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub mod cmp;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FpGadget<F: PrimeField> {
|
pub struct FpGadget<F: PrimeField> {
|
||||||
pub value: Option<F>,
|
pub value: Option<F>,
|
||||||
pub variable: ConstraintVar<F>,
|
pub variable: ConstraintVar<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ impl<F: PrimeField> ToBitsGadget<F> for FpGadget<F> {
|
|||||||
assert_eq!(tmp.len(), num_bits as usize);
|
assert_eq!(tmp.len(), num_bits as usize);
|
||||||
|
|
||||||
tmp
|
tmp
|
||||||
},
|
}
|
||||||
None => vec![None; num_bits as usize],
|
None => vec![None; num_bits as usize],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -422,7 +422,7 @@ impl<F: PrimeField> ToBytesGadget<F> for FpGadget<F> {
|
|||||||
let default = F::default();
|
let default = F::default();
|
||||||
let default_len = to_bytes![&default].unwrap().len();
|
let default_len = to_bytes![&default].unwrap().len();
|
||||||
vec![None; default_len]
|
vec![None; default_len]
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let bytes = UInt8::alloc_vec(cs.ns(|| "Alloc bytes"), &byte_values)?;
|
let bytes = UInt8::alloc_vec(cs.ns(|| "Alloc bytes"), &byte_values)?;
|
||||||
@@ -438,7 +438,7 @@ impl<F: PrimeField> ToBytesGadget<F> for FpGadget<F> {
|
|||||||
Boolean::Is(bit) => {
|
Boolean::Is(bit) => {
|
||||||
lc += (coeff, bit.get_variable());
|
lc += (coeff, bit.get_variable());
|
||||||
coeff.double_in_place();
|
coeff.double_in_place();
|
||||||
},
|
}
|
||||||
Boolean::Constant(_) | Boolean::Not(_) => unreachable!(),
|
Boolean::Constant(_) | Boolean::Not(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -577,7 +577,7 @@ impl<F: PrimeField> ThreeBitCondNegLookupGadget<F> for FpGadget<F> {
|
|||||||
impl<F: PrimeField> Clone for FpGadget<F> {
|
impl<F: PrimeField> Clone for FpGadget<F> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
value: self.value.clone(),
|
value: self.value.clone(),
|
||||||
variable: self.variable.clone(),
|
variable: self.variable.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ use algebra::{
|
|||||||
fp6_3over2::{Fp6, Fp6Parameters},
|
fp6_3over2::{Fp6, Fp6Parameters},
|
||||||
Fp2Parameters,
|
Fp2Parameters,
|
||||||
},
|
},
|
||||||
BitIterator, Field, One, PrimeField,
|
BitIterator, PrimeField,
|
||||||
};
|
};
|
||||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::{borrow::Borrow, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{prelude::*, Assignment, Vec};
|
use crate::{prelude::*, Vec};
|
||||||
|
|
||||||
type Fp2Gadget<P, ConstraintF> = super::fp2::Fp2Gadget<
|
type Fp2Gadget<P, ConstraintF> = super::fp2::Fp2Gadget<
|
||||||
<<P as Fp12Parameters>::Fp6Params as Fp6Parameters>::Fp2Params,
|
<<P as Fp12Parameters>::Fp6Params as Fp6Parameters>::Fp2Params,
|
||||||
@@ -31,8 +31,8 @@ where
|
|||||||
P: Fp12Parameters,
|
P: Fp12Parameters,
|
||||||
<P::Fp6Params as Fp6Parameters>::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
|
<P::Fp6Params as Fp6Parameters>::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
|
||||||
{
|
{
|
||||||
pub c0: Fp6Gadget<P, ConstraintF>,
|
pub c0: Fp6Gadget<P, ConstraintF>,
|
||||||
pub c1: Fp6Gadget<P, ConstraintF>,
|
pub c1: Fp6Gadget<P, ConstraintF>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@@ -546,47 +546,6 @@ where
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inverse<CS: ConstraintSystem<ConstraintF>>(
|
|
||||||
&self,
|
|
||||||
mut cs: CS,
|
|
||||||
) -> Result<Self, SynthesisError> {
|
|
||||||
let inverse = Self::alloc(&mut cs.ns(|| "alloc inverse"), || {
|
|
||||||
self.get_value().and_then(|val| val.inverse()).get()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Karatsuba multiplication for Fp2 with the inverse:
|
|
||||||
// v0 = A.c0 * B.c0
|
|
||||||
// v1 = A.c1 * B.c1
|
|
||||||
//
|
|
||||||
// 1 = v0 + non_residue * v1
|
|
||||||
// => v0 = 1 - non_residue * v1
|
|
||||||
//
|
|
||||||
// 0 = result.c1 = (A.c0 + A.c1) * (B.c0 + B.c1) - v0 - v1
|
|
||||||
// => v0 + v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Enforced with 2 constraints:
|
|
||||||
// A.c1 * B.c1 = v1
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Reference:
|
|
||||||
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
|
||||||
// Devegili, OhEigeartaigh, Scott, Dahab
|
|
||||||
|
|
||||||
// Constraint 1
|
|
||||||
let v1 = self.c1.mul(cs.ns(|| "inv_constraint_1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
// Constraint 2
|
|
||||||
let a0_plus_a1 = self.c0.add(cs.ns(|| "a0 + a1"), &self.c1)?;
|
|
||||||
let b0_plus_b1 = inverse.c0.add(cs.ns(|| "b0 + b1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
let one = Fp6::<P::Fp6Params>::one();
|
|
||||||
let rhs = Self::mul_fp6_by_nonresidue(cs.ns(|| "nr * v1"), &v1)?
|
|
||||||
.sub(cs.ns(|| "sub v1"), &v1)?
|
|
||||||
.negate(cs.ns(|| "negate it"))?
|
|
||||||
.add_constant(cs.ns(|| "add one"), &one)?;
|
|
||||||
a0_plus_a1.mul_equals(cs.ns(|| "inv_constraint_2"), &b0_plus_b1, &rhs)?;
|
|
||||||
Ok(inverse)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
@@ -639,16 +598,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul() -> usize {
|
fn cost_of_mul() -> usize {
|
||||||
unimplemented!()
|
3 * Fp6Gadget::<P, ConstraintF>::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul_equals() -> usize {
|
fn cost_of_mul_equals() -> usize {
|
||||||
Self::cost_of_mul()
|
Self::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_inv() -> usize {
|
|
||||||
Self::cost_of_mul() + <Self as EqGadget<ConstraintF>>::cost()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, ConstraintF: PrimeField> PartialEq for Fp12Gadget<P, ConstraintF>
|
impl<P, ConstraintF: PrimeField> PartialEq for Fp12Gadget<P, ConstraintF>
|
||||||
@@ -892,7 +847,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -917,7 +872,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use algebra::{
|
use algebra::{
|
||||||
fields::{Fp2, Fp2Parameters},
|
fields::{Fp2, Fp2Parameters},
|
||||||
Field, PrimeField,
|
PrimeField,
|
||||||
};
|
};
|
||||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::{borrow::Borrow, marker::PhantomData};
|
||||||
use r1cs_core::{ConstraintSystem, ConstraintVar, SynthesisError};
|
use r1cs_core::{ConstraintSystem, ConstraintVar, SynthesisError};
|
||||||
|
|
||||||
use crate::{fields::fp::FpGadget, prelude::*, Assignment, Vec};
|
use crate::{fields::fp::FpGadget, prelude::*, Vec};
|
||||||
|
|
||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Debug(bound = "P: Fp2Parameters, ConstraintF: PrimeField"))]
|
#[derivative(Debug(bound = "P: Fp2Parameters, ConstraintF: PrimeField"))]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct Fp2Gadget<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> {
|
pub struct Fp2Gadget<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> {
|
||||||
pub c0: FpGadget<ConstraintF>,
|
pub c0: FpGadget<ConstraintF>,
|
||||||
pub c1: FpGadget<ConstraintF>,
|
pub c1: FpGadget<ConstraintF>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@@ -289,47 +289,6 @@ impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> FieldGadget<Fp
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inverse<CS: ConstraintSystem<ConstraintF>>(
|
|
||||||
&self,
|
|
||||||
mut cs: CS,
|
|
||||||
) -> Result<Self, SynthesisError> {
|
|
||||||
let inverse = Self::alloc(&mut cs.ns(|| "alloc inverse"), || {
|
|
||||||
self.get_value().and_then(|val| val.inverse()).get()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Karatsuba multiplication for Fp2 with the inverse:
|
|
||||||
// v0 = A.c0 * B.c0
|
|
||||||
// v1 = A.c1 * B.c1
|
|
||||||
//
|
|
||||||
// 1 = v0 + non_residue * v1
|
|
||||||
// => v0 = 1 - non_residue * v1
|
|
||||||
//
|
|
||||||
// 0 = result.c1 = (A.c0 + A.c1) * (B.c0 + B.c1) - v0 - v1
|
|
||||||
// => v0 + v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Enforced with 2 constraints:
|
|
||||||
// A.c1 * B.c1 = v1
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Reference:
|
|
||||||
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
|
||||||
// Devegili, OhEigeartaigh, Scott, Dahab
|
|
||||||
|
|
||||||
// Constraint 1
|
|
||||||
let mut v1 = self.c1.mul(cs.ns(|| "inv_constraint_1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
// Constraint 2
|
|
||||||
let a0_plus_a1 = self.c0.add(cs.ns(|| "a0 + a1"), &self.c1)?;
|
|
||||||
let b0_plus_b1 = inverse.c0.add(cs.ns(|| "b0 + b1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
let one = P::Fp::one();
|
|
||||||
let rhs = v1
|
|
||||||
.mul_by_constant_in_place(cs.ns(|| "(1 - nonresidue) * v1"), &(one - &P::NONRESIDUE))?
|
|
||||||
.add_constant_in_place(cs.ns(|| "add one"), &one)?;
|
|
||||||
a0_plus_a1.mul_equals(cs.ns(|| "inv_constraint_2"), &b0_plus_b1, rhs)?;
|
|
||||||
Ok(inverse)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
@@ -450,16 +409,12 @@ impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> FieldGadget<Fp
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul() -> usize {
|
fn cost_of_mul() -> usize {
|
||||||
3
|
3 * FpGadget::<ConstraintF>::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul_equals() -> usize {
|
fn cost_of_mul_equals() -> usize {
|
||||||
Self::cost_of_mul()
|
Self::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_inv() -> usize {
|
|
||||||
2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> PartialEq
|
impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> PartialEq
|
||||||
@@ -571,8 +526,8 @@ impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> Clone
|
|||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
c0: self.c0.clone(),
|
c0: self.c0.clone(),
|
||||||
c1: self.c1.clone(),
|
c1: self.c1.clone(),
|
||||||
_params: PhantomData,
|
_params: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -669,7 +624,7 @@ impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> AllocGadget<Fp
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -694,7 +649,7 @@ impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> AllocGadget<Fp
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
use algebra::{
|
use algebra::{
|
||||||
fields::{
|
fields::fp3::{Fp3, Fp3Parameters},
|
||||||
fp3::{Fp3, Fp3Parameters},
|
|
||||||
Field,
|
|
||||||
},
|
|
||||||
PrimeField, SquareRootField,
|
PrimeField, SquareRootField,
|
||||||
};
|
};
|
||||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::{borrow::Borrow, marker::PhantomData};
|
||||||
use r1cs_core::{ConstraintSystem, ConstraintVar, SynthesisError};
|
use r1cs_core::{ConstraintSystem, ConstraintVar, SynthesisError};
|
||||||
|
|
||||||
use crate::{fields::fp::FpGadget, prelude::*, Assignment, Vec};
|
use crate::{fields::fp::FpGadget, prelude::*, Vec};
|
||||||
|
|
||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Debug(
|
#[derivative(Debug(
|
||||||
@@ -17,9 +14,9 @@ use crate::{fields::fp::FpGadget, prelude::*, Assignment, Vec};
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct Fp3Gadget<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootField>
|
pub struct Fp3Gadget<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootField>
|
||||||
{
|
{
|
||||||
pub c0: FpGadget<ConstraintF>,
|
pub c0: FpGadget<ConstraintF>,
|
||||||
pub c1: FpGadget<ConstraintF>,
|
pub c1: FpGadget<ConstraintF>,
|
||||||
pub c2: FpGadget<ConstraintF>,
|
pub c2: FpGadget<ConstraintF>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@@ -40,6 +37,7 @@ impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootFie
|
|||||||
_params: PhantomData,
|
_params: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiply a FpGadget by quadratic nonresidue P::NONRESIDUE.
|
/// Multiply a FpGadget by quadratic nonresidue P::NONRESIDUE.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_fp_gadget_by_nonresidue<CS: ConstraintSystem<ConstraintF>>(
|
pub fn mul_fp_gadget_by_nonresidue<CS: ConstraintSystem<ConstraintF>>(
|
||||||
@@ -332,122 +330,115 @@ impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootFie
|
|||||||
Ok(Self::new(c0, c1, c2))
|
Ok(Self::new(c0, c1, c2))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use the Toom-Cook-3x method to compute multiplication.
|
#[inline]
|
||||||
|
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
||||||
|
&self,
|
||||||
|
mut cs: CS,
|
||||||
|
other: &Self,
|
||||||
|
result: &Self,
|
||||||
|
) -> Result<(), SynthesisError> {
|
||||||
|
// Karatsuba multiplication for Fp3:
|
||||||
|
// v0 = A.c0 * B.c0
|
||||||
|
// v1 = A.c1 * B.c1
|
||||||
|
// v2 = A.c2 * B.c2
|
||||||
|
// result.c0 = v0 + β((a1 + a2)(b1 + b2) − v1 − v2)
|
||||||
|
// result.c1 = (a0 + a1)(b0 + b1) − v0 − v1 + βv2
|
||||||
|
// result.c2 = (a0 + a2)(b0 + b2) − v0 + v1 − v2,
|
||||||
|
// We enforce this with six constraints:
|
||||||
|
//
|
||||||
|
// v0 = A.c0 * B.c0
|
||||||
|
// v1 = A.c1 * B.c1
|
||||||
|
// v2 = A.c2 * B.c2
|
||||||
|
//
|
||||||
|
// result.c0 - v0 + \beta*(v1 + v2) = β(a1 + a2)(b1 + b2))
|
||||||
|
// result.c1 + v0 + v1 - βv2 = (a0 + a1)(b0 + b1)
|
||||||
|
// result.c2 + v0 - v1 + v2 = (a0 + a2)(b0 + b2)
|
||||||
|
// Reference:
|
||||||
|
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
||||||
|
// Devegili, OhEigeartaigh, Scott, Dahab
|
||||||
|
//
|
||||||
|
// This implementation adapted from
|
||||||
|
// https://github.com/ZencashOfficial/ginger-lib/blob/development/r1cs/gadgets/std/src/fields/fp3.rs
|
||||||
|
let v0 = self.c0.mul(cs.ns(|| "v0 = a0 * b0"), &other.c0)?;
|
||||||
|
let v1 = self.c1.mul(cs.ns(|| "v1 = a1 * b1"), &other.c1)?;
|
||||||
|
let v2 = self.c2.mul(cs.ns(|| "v2 = a2 * b2"), &other.c2)?;
|
||||||
|
|
||||||
|
// Check c0
|
||||||
|
let nr_a1_plus_a2 = self
|
||||||
|
.c1
|
||||||
|
.add(cs.ns(|| "a1 + a2"), &self.c2)?
|
||||||
|
.mul_by_constant(cs.ns(|| "nr*(a1 + a2)"), &P::NONRESIDUE)?;
|
||||||
|
let b1_plus_b2 = other.c1.add(cs.ns(|| "b1 + b2"), &other.c2)?;
|
||||||
|
let nr_v1 = v1.mul_by_constant(cs.ns(|| "nr * v1"), &P::NONRESIDUE)?;
|
||||||
|
let nr_v2 = v2.mul_by_constant(cs.ns(|| "nr * v2"), &P::NONRESIDUE)?;
|
||||||
|
let to_check = result
|
||||||
|
.c0
|
||||||
|
.sub(cs.ns(|| "c0 - v0"), &v0)?
|
||||||
|
.add(cs.ns(|| "c0 - v0 + nr * v1"), &nr_v1)?
|
||||||
|
.add(cs.ns(|| "c0 - v0 + nr * v1 + nr * v2"), &nr_v2)?;
|
||||||
|
nr_a1_plus_a2.mul_equals(cs.ns(|| "check c0"), &b1_plus_b2, &to_check)?;
|
||||||
|
|
||||||
|
// Check c1
|
||||||
|
let a0_plus_a1 = self.c0.add(cs.ns(|| "a0 + a1"), &self.c1)?;
|
||||||
|
let b0_plus_b1 = other.c0.add(cs.ns(|| "b0 + b1"), &other.c1)?;
|
||||||
|
let to_check = result
|
||||||
|
.c1
|
||||||
|
.sub(cs.ns(|| "c1 - nr * v2"), &nr_v2)?
|
||||||
|
.add(cs.ns(|| "c1 - nr * v2 + v0"), &v0)?
|
||||||
|
.add(cs.ns(|| "c1 - nr * v2 + v0 + v1"), &v1)?;
|
||||||
|
a0_plus_a1.mul_equals(cs.ns(|| "check c1"), &b0_plus_b1, &to_check)?;
|
||||||
|
|
||||||
|
// Check c2
|
||||||
|
let a0_plus_a2 = self.c0.add(cs.ns(|| "a0 + a2"), &self.c2)?;
|
||||||
|
let b0_plus_b2 = other.c0.add(cs.ns(|| "b0 + b2"), &other.c2)?;
|
||||||
|
let to_check = result
|
||||||
|
.c2
|
||||||
|
.add(cs.ns(|| "c2 + v0"), &v0)?
|
||||||
|
.sub(cs.ns(|| "c2 + v0 - v1"), &v1)?
|
||||||
|
.add(cs.ns(|| "c2 + v0 - v1 + v2"), &v2)?;
|
||||||
|
a0_plus_a2.mul_equals(cs.ns(|| "check c2"), &b0_plus_b2, &to_check)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use the Chung-Hasan asymmetric squaring formula.
|
||||||
|
///
|
||||||
|
/// (Devegili OhEig Scott Dahab --- Multiplication and Squaring on
|
||||||
|
/// Abstract Pairing-Friendly
|
||||||
|
/// Fields.pdf; Section 4 (CH-SQR2))
|
||||||
#[inline]
|
#[inline]
|
||||||
fn square<CS: ConstraintSystem<ConstraintF>>(
|
fn square<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
) -> Result<Self, SynthesisError> {
|
) -> Result<Self, SynthesisError> {
|
||||||
// Uses Toom-Cook-3x multiplication from
|
let a = self.c0.clone();
|
||||||
//
|
let b = self.c1.clone();
|
||||||
// Reference:
|
let c = self.c2.clone();
|
||||||
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
|
||||||
// Devegili, OhEigeartaigh, Scott, Dahab
|
|
||||||
|
|
||||||
// v0 = a(0)^2 = a0^2
|
let s0 = a.square(cs.ns(|| "s0"))?;
|
||||||
let v0 = self.c0.square(&mut cs.ns(|| "Calc v0"))?;
|
let ab = a.mul(cs.ns(|| "ab"), &b)?;
|
||||||
|
let s1 = ab.double(cs.ns(|| "s1"))?;
|
||||||
|
let s2 = a
|
||||||
|
.sub(cs.ns(|| "a-b"), &b)?
|
||||||
|
.add(cs.ns(|| "plus c"), &c)?
|
||||||
|
.square(cs.ns(|| "s2"))?;
|
||||||
|
let s3 = b.mul(cs.ns(|| "bc"), &c)?.double(cs.ns(|| "s3"))?;
|
||||||
|
let s4 = c.square(cs.ns(|| "s4"))?;
|
||||||
|
|
||||||
// v1 = a(1)^2 = (a0 + a1 + a2)^2
|
let c0 = Self::mul_fp_gadget_by_nonresidue(cs.ns(|| "c0 part 1"), &s3)?
|
||||||
let v1 = {
|
.add(cs.ns(|| "c0"), &s0)?;
|
||||||
let a0_plus_a1_plus_a2 = self
|
|
||||||
.c0
|
|
||||||
.add(cs.ns(|| "a0 + a1"), &self.c1)?
|
|
||||||
.add(cs.ns(|| "a0 + a1 + a2"), &self.c2)?;
|
|
||||||
a0_plus_a1_plus_a2.square(&mut cs.ns(|| "(a0 + a1 + a2)^2"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
// v2 = a(−1)^2 = (a0 − a1 + a2)^2
|
let c1 = Self::mul_fp_gadget_by_nonresidue(cs.ns(|| "c1 part 1"), &s4)?
|
||||||
let v2 = {
|
.add(cs.ns(|| "c1"), &s1)?;
|
||||||
let a0_minus_a1_plus_a2 = self
|
|
||||||
.c0
|
|
||||||
.sub(cs.ns(|| "a0 - a1"), &self.c1)?
|
|
||||||
.add(cs.ns(|| "a0 - a2 + a2"), &self.c2)?;
|
|
||||||
a0_minus_a1_plus_a2.square(&mut cs.ns(|| "(a0 - a1 + a2)^2"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
// v3 = a(2)^2 = (a0 + 2a1 + 4a2)^2
|
let c2 = s1
|
||||||
let v3 = {
|
.add(cs.ns(|| "c2 part1"), &s2)?
|
||||||
let a1_double = self.c1.double(cs.ns(|| "2a1"))?;
|
.add(cs.ns(|| "c2 part2"), &s3)?
|
||||||
let a2_quad = self.c2.double(cs.ns(|| "2a2"))?.double(cs.ns(|| "4a2"))?;
|
.sub(cs.ns(|| "c2 part3"), &s0)?
|
||||||
let a0_plus_2_a1_plus_4_a2 = self
|
.sub(cs.ns(|| "c2 part4"), &s4)?;
|
||||||
.c0
|
|
||||||
.add(cs.ns(|| "a0 + 2a1"), &a1_double)?
|
|
||||||
.add(cs.ns(|| "a0 + 2a1 + 4a2"), &a2_quad)?;
|
|
||||||
|
|
||||||
a0_plus_2_a1_plus_4_a2.square(&mut cs.ns(|| "(a0 + 2a1 + 4a2)^2"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
// v4 = a(∞)^2 = a2^2
|
|
||||||
let v4 = self.c2.square(&mut cs.ns(|| "a2^2"))?;
|
|
||||||
|
|
||||||
let two = P::Fp::one().double();
|
|
||||||
let six = two.double() + &two;
|
|
||||||
let mut two_and_six = [two, six];
|
|
||||||
algebra::fields::batch_inversion(&mut two_and_six);
|
|
||||||
let (two_inverse, six_inverse) = (two_and_six[0], two_and_six[1]);
|
|
||||||
|
|
||||||
let half_v0 = v0.mul_by_constant(cs.ns(|| "half_v0"), &two_inverse)?;
|
|
||||||
let half_v1 = v1.mul_by_constant(cs.ns(|| "half_v1"), &two_inverse)?;
|
|
||||||
let one_sixth_v2 = v2.mul_by_constant(cs.ns(|| "one_sixth_v2"), &six_inverse)?;
|
|
||||||
let one_sixth_v3 = v3.mul_by_constant(cs.ns(|| "one_sixth_v3"), &six_inverse)?;
|
|
||||||
let two_v4 = v4.double(cs.ns(|| "double_v4"))?;
|
|
||||||
|
|
||||||
// c0 = v0 + β((1/2)v0 − (1/2)v1 − (1/6)v2 + (1/6)v3 − 2v4)
|
|
||||||
let c0 = {
|
|
||||||
let mut c0_cs = cs.ns(|| "c0");
|
|
||||||
// No constraints, only get a linear combination back.
|
|
||||||
let inner = half_v0
|
|
||||||
.sub(c0_cs.ns(|| "sub1"), &half_v1)?
|
|
||||||
.sub(c0_cs.ns(|| "sub2"), &one_sixth_v2)?
|
|
||||||
.add(c0_cs.ns(|| "add3"), &one_sixth_v3)?
|
|
||||||
.sub(c0_cs.ns(|| "sub4"), &two_v4)?;
|
|
||||||
let non_residue_times_inner =
|
|
||||||
inner.mul_by_constant(c0_cs.ns(|| "mul_by_res"), &P::NONRESIDUE)?;
|
|
||||||
v0.add(c0_cs.ns(|| "add5"), &non_residue_times_inner)?
|
|
||||||
};
|
|
||||||
|
|
||||||
// −(1/2)v0 + v1 − (1/3)v2 − (1/6)v3 + 2v4 + βv4
|
|
||||||
let c1 = {
|
|
||||||
let mut c1_cs = cs.ns(|| "c1");
|
|
||||||
let one_third_v2 = one_sixth_v2.double(c1_cs.ns(|| "v2_by_3"))?;
|
|
||||||
let non_residue_v4 = v4.mul_by_constant(c1_cs.ns(|| "mul_by_res"), &P::NONRESIDUE)?;
|
|
||||||
|
|
||||||
half_v0
|
|
||||||
.negate(c1_cs.ns(|| "neg1"))?
|
|
||||||
.add(c1_cs.ns(|| "add1"), &v1)?
|
|
||||||
.sub(c1_cs.ns(|| "sub2"), &one_third_v2)?
|
|
||||||
.sub(c1_cs.ns(|| "sub3"), &one_sixth_v3)?
|
|
||||||
.add(c1_cs.ns(|| "add4"), &two_v4)?
|
|
||||||
.add(c1_cs.ns(|| "add5"), &non_residue_v4)?
|
|
||||||
};
|
|
||||||
|
|
||||||
// -v0 + (1/2)v1 + (1/2)v2 −v4
|
|
||||||
let c2 = {
|
|
||||||
let mut c2_cs = cs.ns(|| "c2");
|
|
||||||
let half_v2 = v2.mul_by_constant(c2_cs.ns(|| "half_v2"), &two_inverse)?;
|
|
||||||
half_v1
|
|
||||||
.add(c2_cs.ns(|| "add1"), &half_v2)?
|
|
||||||
.sub(c2_cs.ns(|| "sub1"), &v4)?
|
|
||||||
.sub(c2_cs.ns(|| "sub2"), &v0)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self::new(c0, c1, c2))
|
Ok(Self::new(c0, c1, c2))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 18 constraints, we can probably do better but not sure it's worth it.
|
|
||||||
#[inline]
|
|
||||||
fn inverse<CS: ConstraintSystem<ConstraintF>>(
|
|
||||||
&self,
|
|
||||||
mut cs: CS,
|
|
||||||
) -> Result<Self, SynthesisError> {
|
|
||||||
let inverse = Self::alloc(&mut cs.ns(|| "alloc inverse"), || {
|
|
||||||
self.get_value().and_then(|val| val.inverse()).get()
|
|
||||||
})?;
|
|
||||||
let one = Self::one(cs.ns(|| "one"))?;
|
|
||||||
inverse.mul_equals(cs.ns(|| "check inverse"), &self, &one)?;
|
|
||||||
Ok(inverse)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_constant<CS: ConstraintSystem<ConstraintF>>(
|
fn add_constant<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
@@ -634,8 +625,8 @@ impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootFie
|
|||||||
5 * FpGadget::<ConstraintF>::cost_of_mul()
|
5 * FpGadget::<ConstraintF>::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_inv() -> usize {
|
fn cost_of_mul_equals() -> usize {
|
||||||
Self::cost_of_mul() + <Self as EqGadget<ConstraintF>>::cost()
|
6 * FpGadget::<ConstraintF>::cost_of_mul()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,7 +880,7 @@ impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootFie
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -916,7 +907,7 @@ impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootFie
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use algebra::{
|
use algebra::{
|
||||||
fields::{Fp2, Fp2Parameters, Fp4, Fp4Parameters},
|
fields::{Fp2, Fp2Parameters, Fp4, Fp4Parameters},
|
||||||
BigInteger, Field, One, PrimeField,
|
BigInteger, PrimeField,
|
||||||
};
|
};
|
||||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::{borrow::Borrow, marker::PhantomData};
|
||||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
use r1cs_core::{ConstraintSystem, SynthesisError};
|
||||||
|
|
||||||
use crate::{prelude::*, Assignment, Vec};
|
use crate::{prelude::*, Vec};
|
||||||
|
|
||||||
type Fp2Gadget<P, ConstraintF> =
|
type Fp2Gadget<P, ConstraintF> =
|
||||||
super::fp2::Fp2Gadget<<P as Fp4Parameters>::Fp2Params, ConstraintF>;
|
super::fp2::Fp2Gadget<<P as Fp4Parameters>::Fp2Params, ConstraintF>;
|
||||||
@@ -22,8 +22,8 @@ where
|
|||||||
P: Fp4Parameters,
|
P: Fp4Parameters,
|
||||||
P::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
|
P::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
|
||||||
{
|
{
|
||||||
pub c0: Fp2Gadget<P, ConstraintF>,
|
pub c0: Fp2Gadget<P, ConstraintF>,
|
||||||
pub c1: Fp2Gadget<P, ConstraintF>,
|
pub c1: Fp2Gadget<P, ConstraintF>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@@ -308,48 +308,6 @@ where
|
|||||||
Ok(Self::new(c0, c1))
|
Ok(Self::new(c0, c1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inverse<CS: ConstraintSystem<ConstraintF>>(
|
|
||||||
&self,
|
|
||||||
mut cs: CS,
|
|
||||||
) -> Result<Self, SynthesisError> {
|
|
||||||
let inverse = Self::alloc(&mut cs.ns(|| "alloc inverse"), || {
|
|
||||||
self.get_value().and_then(|val| val.inverse()).get()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Karatsuba multiplication for Fp4 with the inverse:
|
|
||||||
// v0 = A.c0 * B.c0
|
|
||||||
// v1 = A.c1 * B.c1
|
|
||||||
//
|
|
||||||
// 1 = v0 + non_residue * v1
|
|
||||||
// => v0 = 1 - non_residue * v1
|
|
||||||
//
|
|
||||||
// 0 = result.c1 = (A.c0 + A.c1) * (B.c0 + B.c1) - v0 - v1
|
|
||||||
// => v0 + v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Enforced with 2 constraints:
|
|
||||||
// A.c1 * B.c1 = v1
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Reference:
|
|
||||||
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
|
||||||
// Devegili, OhEigeartaigh, Scott, Dahab
|
|
||||||
|
|
||||||
// Constraint 1
|
|
||||||
let v1 = self.c1.mul(cs.ns(|| "inv_constraint_1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
// Constraint 2
|
|
||||||
let a0_plus_a1 = self.c0.add(cs.ns(|| "a0 + a1"), &self.c1)?;
|
|
||||||
let b0_plus_b1 = inverse.c0.add(cs.ns(|| "b0 + b1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
let one = Fp2::<<P as Fp4Parameters>::Fp2Params>::one();
|
|
||||||
let rhs = Self::mul_fp2_gadget_by_nonresidue(cs.ns(|| "nr * v1"), &v1)?
|
|
||||||
.sub(cs.ns(|| "sub v1"), &v1)?
|
|
||||||
.negate(cs.ns(|| "negate it"))?
|
|
||||||
.add_constant(cs.ns(|| "add one"), &one)?;
|
|
||||||
a0_plus_a1.mul_equals(cs.ns(|| "inv_constraint_2"), &b0_plus_b1, &rhs)?;
|
|
||||||
Ok(inverse)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
@@ -475,17 +433,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul() -> usize {
|
fn cost_of_mul() -> usize {
|
||||||
3 * <Fp2Gadget<P, ConstraintF> as FieldGadget<Fp2<P::Fp2Params>, ConstraintF>>::cost_of_mul(
|
3 * Fp2Gadget::<P, ConstraintF>::cost_of_mul()
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul_equals() -> usize {
|
fn cost_of_mul_equals() -> usize {
|
||||||
Self::cost_of_mul()
|
Self::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_inv() -> usize {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, ConstraintF: PrimeField> PartialEq for Fp4Gadget<P, ConstraintF>
|
impl<P, ConstraintF: PrimeField> PartialEq for Fp4Gadget<P, ConstraintF>
|
||||||
@@ -616,8 +569,8 @@ where
|
|||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
c0: self.c0.clone(),
|
c0: self.c0.clone(),
|
||||||
c1: self.c1.clone(),
|
c1: self.c1.clone(),
|
||||||
_params: PhantomData,
|
_params: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -733,7 +686,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -758,7 +711,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ use algebra::{
|
|||||||
fp6_2over3::{Fp6, Fp6Parameters},
|
fp6_2over3::{Fp6, Fp6Parameters},
|
||||||
Fp3, Fp3Parameters,
|
Fp3, Fp3Parameters,
|
||||||
},
|
},
|
||||||
BigInteger, Field, One, PrimeField, SquareRootField,
|
BigInteger, PrimeField, SquareRootField,
|
||||||
};
|
};
|
||||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::{borrow::Borrow, marker::PhantomData};
|
||||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
use r1cs_core::{ConstraintSystem, SynthesisError};
|
||||||
|
|
||||||
use crate::{prelude::*, Assignment, Vec};
|
use crate::{prelude::*, Vec};
|
||||||
|
|
||||||
type Fp3Gadget<P, ConstraintF> =
|
type Fp3Gadget<P, ConstraintF> =
|
||||||
super::fp3::Fp3Gadget<<P as Fp6Parameters>::Fp3Params, ConstraintF>;
|
super::fp3::Fp3Gadget<<P as Fp6Parameters>::Fp3Params, ConstraintF>;
|
||||||
@@ -25,8 +25,8 @@ where
|
|||||||
P: Fp6Parameters,
|
P: Fp6Parameters,
|
||||||
P::Fp3Params: Fp3Parameters<Fp = ConstraintF>,
|
P::Fp3Params: Fp3Parameters<Fp = ConstraintF>,
|
||||||
{
|
{
|
||||||
pub c0: Fp3Gadget<P, ConstraintF>,
|
pub c0: Fp3Gadget<P, ConstraintF>,
|
||||||
pub c1: Fp3Gadget<P, ConstraintF>,
|
pub c1: Fp3Gadget<P, ConstraintF>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@@ -291,48 +291,6 @@ where
|
|||||||
Ok(Self::new(c0, c1))
|
Ok(Self::new(c0, c1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inverse<CS: ConstraintSystem<ConstraintF>>(
|
|
||||||
&self,
|
|
||||||
mut cs: CS,
|
|
||||||
) -> Result<Self, SynthesisError> {
|
|
||||||
let inverse = Self::alloc(&mut cs.ns(|| "alloc inverse"), || {
|
|
||||||
self.get_value().and_then(|val| val.inverse()).get()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Karatsuba multiplication for Fp6 with the inverse:
|
|
||||||
// v0 = A.c0 * B.c0
|
|
||||||
// v1 = A.c1 * B.c1
|
|
||||||
//
|
|
||||||
// 1 = v0 + non_residue * v1
|
|
||||||
// => v0 = 1 - non_residue * v1
|
|
||||||
//
|
|
||||||
// 0 = result.c1 = (A.c0 + A.c1) * (B.c0 + B.c1) - v0 - v1
|
|
||||||
// => v0 + v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Enforced with 2 constraints:
|
|
||||||
// A.c1 * B.c1 = v1
|
|
||||||
// => 1 + (1 - non_residue) * v1 = (A.c0 + A.c1) * (B.c0 + B.c1)
|
|
||||||
// Reference:
|
|
||||||
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
|
||||||
// Devegili, OhEigeartaigh, Scott, Dahab
|
|
||||||
|
|
||||||
// Constraint 1
|
|
||||||
let v1 = self.c1.mul(cs.ns(|| "inv_constraint_1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
// Constraint 2
|
|
||||||
let a0_plus_a1 = self.c0.add(cs.ns(|| "a0 + a1"), &self.c1)?;
|
|
||||||
let b0_plus_b1 = inverse.c0.add(cs.ns(|| "b0 + b1"), &inverse.c1)?;
|
|
||||||
|
|
||||||
let one = Fp3::<<P as Fp6Parameters>::Fp3Params>::one();
|
|
||||||
let rhs = Self::mul_fp3_gadget_by_nonresidue(cs.ns(|| "nr * v1"), &v1)?
|
|
||||||
.sub(cs.ns(|| "sub v1"), &v1)?
|
|
||||||
.negate(cs.ns(|| "negate it"))?
|
|
||||||
.add_constant(cs.ns(|| "add one"), &one)?;
|
|
||||||
a0_plus_a1.mul_equals(cs.ns(|| "inv_constraint_2"), &b0_plus_b1, &rhs)?;
|
|
||||||
Ok(inverse)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
@@ -458,17 +416,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul() -> usize {
|
fn cost_of_mul() -> usize {
|
||||||
3 * <Fp3Gadget<P, ConstraintF> as FieldGadget<Fp3<P::Fp3Params>, ConstraintF>>::cost_of_mul(
|
2 * Fp3Gadget::<P, ConstraintF>::cost_of_mul()
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_mul_equals() -> usize {
|
fn cost_of_mul_equals() -> usize {
|
||||||
Self::cost_of_mul()
|
Self::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_inv() -> usize {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, ConstraintF: PrimeField + SquareRootField> PartialEq for Fp6Gadget<P, ConstraintF>
|
impl<P, ConstraintF: PrimeField + SquareRootField> PartialEq for Fp6Gadget<P, ConstraintF>
|
||||||
@@ -604,8 +557,8 @@ where
|
|||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
c0: self.c0.clone(),
|
c0: self.c0.clone(),
|
||||||
c1: self.c1.clone(),
|
c1: self.c1.clone(),
|
||||||
_params: PhantomData,
|
_params: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -724,7 +677,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -749,7 +702,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1))
|
(Ok(fe.c0), Ok(fe.c1))
|
||||||
},
|
}
|
||||||
Err(_) => (
|
Err(_) => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use algebra::{
|
|||||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::{borrow::Borrow, marker::PhantomData};
|
||||||
use r1cs_core::{ConstraintSystem, ConstraintVar, SynthesisError};
|
use r1cs_core::{ConstraintSystem, ConstraintVar, SynthesisError};
|
||||||
|
|
||||||
use crate::{prelude::*, Assignment, Vec};
|
use crate::{prelude::*, Vec};
|
||||||
|
|
||||||
type Fp2Gadget<P, ConstraintF> =
|
type Fp2Gadget<P, ConstraintF> =
|
||||||
super::fp2::Fp2Gadget<<P as Fp6Parameters>::Fp2Params, ConstraintF>;
|
super::fp2::Fp2Gadget<<P as Fp6Parameters>::Fp2Params, ConstraintF>;
|
||||||
@@ -21,9 +21,9 @@ where
|
|||||||
P: Fp6Parameters,
|
P: Fp6Parameters,
|
||||||
P::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
|
P::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
|
||||||
{
|
{
|
||||||
pub c0: Fp2Gadget<P, ConstraintF>,
|
pub c0: Fp2Gadget<P, ConstraintF>,
|
||||||
pub c1: Fp2Gadget<P, ConstraintF>,
|
pub c1: Fp2Gadget<P, ConstraintF>,
|
||||||
pub c2: Fp2Gadget<P, ConstraintF>,
|
pub c2: Fp2Gadget<P, ConstraintF>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@@ -398,120 +398,113 @@ where
|
|||||||
Ok(Self::new(c0, c1, c2))
|
Ok(Self::new(c0, c1, c2))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use the Toom-Cook-3x method to compute multiplication.
|
/// Use the Chung-Hasan asymmetric squaring formula.
|
||||||
|
///
|
||||||
|
/// (Devegili OhEig Scott Dahab --- Multiplication and Squaring on
|
||||||
|
/// Abstract Pairing-Friendly
|
||||||
|
/// Fields.pdf; Section 4 (CH-SQR2))
|
||||||
#[inline]
|
#[inline]
|
||||||
fn square<CS: ConstraintSystem<ConstraintF>>(
|
fn square<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
) -> Result<Self, SynthesisError> {
|
) -> Result<Self, SynthesisError> {
|
||||||
// Uses Toom-Cook-3x multiplication from
|
let a = self.c0.clone();
|
||||||
//
|
let b = self.c1.clone();
|
||||||
// Reference:
|
let c = self.c2.clone();
|
||||||
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
|
||||||
// Devegili, OhEigeartaigh, Scott, Dahab
|
|
||||||
|
|
||||||
// v0 = a(0)^2 = a0^2
|
let s0 = a.square(cs.ns(|| "s0"))?;
|
||||||
let v0 = self.c0.square(&mut cs.ns(|| "Calc v0"))?;
|
let ab = a.mul(cs.ns(|| "ab"), &b)?;
|
||||||
|
let s1 = ab.double(cs.ns(|| "s1"))?;
|
||||||
|
let s2 = a
|
||||||
|
.sub(cs.ns(|| "a-b"), &b)?
|
||||||
|
.add(cs.ns(|| "plus c"), &c)?
|
||||||
|
.square(cs.ns(|| "s2"))?;
|
||||||
|
let s3 = b.mul(cs.ns(|| "bc"), &c)?.double(cs.ns(|| "s3"))?;
|
||||||
|
let s4 = c.square(cs.ns(|| "s4"))?;
|
||||||
|
|
||||||
// v1 = a(1)^2 = (a0 + a1 + a2)^2
|
let c0 = Self::mul_fp2_gadget_by_nonresidue(cs.ns(|| "c0 part 1"), &s3)?
|
||||||
let v1 = {
|
.add(cs.ns(|| "c0"), &s0)?;
|
||||||
let a0_plus_a1_plus_a2 = self
|
|
||||||
.c0
|
|
||||||
.add(cs.ns(|| "a0 + a1"), &self.c1)?
|
|
||||||
.add(cs.ns(|| "a0 + a1 + a2"), &self.c2)?;
|
|
||||||
a0_plus_a1_plus_a2.square(&mut cs.ns(|| "(a0 + a1 + a2)^2"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
// v2 = a(−1)^2 = (a0 − a1 + a2)^2
|
let c1 = Self::mul_fp2_gadget_by_nonresidue(cs.ns(|| "c1 part 1"), &s4)?
|
||||||
let v2 = {
|
.add(cs.ns(|| "c1"), &s1)?;
|
||||||
let a0_minus_a1_plus_a2 = self
|
|
||||||
.c0
|
|
||||||
.sub(cs.ns(|| "a0 - a1"), &self.c1)?
|
|
||||||
.add(cs.ns(|| "a0 - a2 + a2"), &self.c2)?;
|
|
||||||
a0_minus_a1_plus_a2.square(&mut cs.ns(|| "(a0 - a1 + a2)^2"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
// v3 = a(2)^2 = (a0 + 2a1 + 4a2)^2
|
let c2 = s1
|
||||||
let v3 = {
|
.add(cs.ns(|| "c2 part1"), &s2)?
|
||||||
let a1_double = self.c1.double(cs.ns(|| "2a1"))?;
|
.add(cs.ns(|| "c2 part2"), &s3)?
|
||||||
let a2_quad = self.c2.double(cs.ns(|| "2a2"))?.double(cs.ns(|| "4a2"))?;
|
.sub(cs.ns(|| "c2 part3"), &s0)?
|
||||||
let a0_plus_2_a1_plus_4_a2 = self
|
.sub(cs.ns(|| "c2 part4"), &s4)?;
|
||||||
.c0
|
|
||||||
.add(cs.ns(|| "a0 + 2a1"), &a1_double)?
|
|
||||||
.add(cs.ns(|| "a0 + 2a1 + 4a2"), &a2_quad)?;
|
|
||||||
|
|
||||||
a0_plus_2_a1_plus_4_a2.square(&mut cs.ns(|| "(a0 + 2a1 + 4a2)^2"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
// v4 = a(∞)^2 = a2^2
|
|
||||||
let v4 = self.c2.square(&mut cs.ns(|| "a2^2"))?;
|
|
||||||
|
|
||||||
let two = <P::Fp2Params as Fp2Parameters>::Fp::one().double();
|
|
||||||
let six = two.double() + &two;
|
|
||||||
let mut two_and_six = [two, six];
|
|
||||||
algebra::fields::batch_inversion(&mut two_and_six);
|
|
||||||
let (two_inverse, six_inverse) = (two_and_six[0], two_and_six[1]);
|
|
||||||
|
|
||||||
let half_v0 = v0.mul_by_fp_constant(cs.ns(|| "half_v0"), &two_inverse)?;
|
|
||||||
let half_v1 = v1.mul_by_fp_constant(cs.ns(|| "half_v1"), &two_inverse)?;
|
|
||||||
let one_sixth_v2 = v2.mul_by_fp_constant(cs.ns(|| "one_sixth_v2"), &six_inverse)?;
|
|
||||||
let one_sixth_v3 = v3.mul_by_fp_constant(cs.ns(|| "one_sixth_v3"), &six_inverse)?;
|
|
||||||
let two_v4 = v4.double(cs.ns(|| "double_v4"))?;
|
|
||||||
|
|
||||||
// c0 = v0 + β((1/2)v0 − (1/2)v1 − (1/6)v2 + (1/6)v3 − 2v4)
|
|
||||||
let c0 = {
|
|
||||||
let mut c0_cs = cs.ns(|| "c0");
|
|
||||||
// No constraints, only get a linear combination back.
|
|
||||||
let inner = half_v0
|
|
||||||
.sub(c0_cs.ns(|| "sub1"), &half_v1)?
|
|
||||||
.sub(c0_cs.ns(|| "sub2"), &one_sixth_v2)?
|
|
||||||
.add(c0_cs.ns(|| "add3"), &one_sixth_v3)?
|
|
||||||
.sub(c0_cs.ns(|| "sub4"), &two_v4)?;
|
|
||||||
let non_residue_times_inner =
|
|
||||||
inner.mul_by_constant(c0_cs.ns(|| "mul_by_res"), &P::NONRESIDUE)?;
|
|
||||||
v0.add(c0_cs.ns(|| "add5"), &non_residue_times_inner)?
|
|
||||||
};
|
|
||||||
|
|
||||||
// −(1/2)v0 + v1 − (1/3)v2 − (1/6)v3 + 2v4 + βv4
|
|
||||||
let c1 = {
|
|
||||||
let mut c1_cs = cs.ns(|| "c1");
|
|
||||||
let one_third_v2 = one_sixth_v2.double(c1_cs.ns(|| "v2_by_3"))?;
|
|
||||||
let non_residue_v4 = v4.mul_by_constant(c1_cs.ns(|| "mul_by_res"), &P::NONRESIDUE)?;
|
|
||||||
|
|
||||||
half_v0
|
|
||||||
.negate(c1_cs.ns(|| "neg1"))?
|
|
||||||
.add(c1_cs.ns(|| "add1"), &v1)?
|
|
||||||
.sub(c1_cs.ns(|| "sub2"), &one_third_v2)?
|
|
||||||
.sub(c1_cs.ns(|| "sub3"), &one_sixth_v3)?
|
|
||||||
.add(c1_cs.ns(|| "add4"), &two_v4)?
|
|
||||||
.add(c1_cs.ns(|| "add5"), &non_residue_v4)?
|
|
||||||
};
|
|
||||||
|
|
||||||
// -v0 + (1/2)v1 + (1/2)v2 −v4
|
|
||||||
let c2 = {
|
|
||||||
let mut c2_cs = cs.ns(|| "c2");
|
|
||||||
let half_v2 = v2.mul_by_fp_constant(c2_cs.ns(|| "half_v2"), &two_inverse)?;
|
|
||||||
half_v1
|
|
||||||
.add(c2_cs.ns(|| "add1"), &half_v2)?
|
|
||||||
.sub(c2_cs.ns(|| "sub1"), &v4)?
|
|
||||||
.sub(c2_cs.ns(|| "sub2"), &v0)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self::new(c0, c1, c2))
|
Ok(Self::new(c0, c1, c2))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 18 constraints, we can probably do better but not sure it's worth it.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse<CS: ConstraintSystem<ConstraintF>>(
|
fn mul_equals<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
) -> Result<Self, SynthesisError> {
|
other: &Self,
|
||||||
let inverse = Self::alloc(&mut cs.ns(|| "alloc inverse"), || {
|
result: &Self,
|
||||||
self.get_value().and_then(|val| val.inverse()).get()
|
) -> Result<(), SynthesisError> {
|
||||||
})?;
|
// Karatsuba multiplication for Fp3:
|
||||||
let one = Self::one(cs.ns(|| "one"))?;
|
// v0 = A.c0 * B.c0
|
||||||
inverse.mul_equals(cs.ns(|| "check inverse"), &self, &one)?;
|
// v1 = A.c1 * B.c1
|
||||||
Ok(inverse)
|
// v2 = A.c2 * B.c2
|
||||||
|
// result.c0 = v0 + β((a1 + a2)(b1 + b2) − v1 − v2)
|
||||||
|
// result.c1 = (a0 + a1)(b0 + b1) − v0 − v1 + βv2
|
||||||
|
// result.c2 = (a0 + a2)(b0 + b2) − v0 + v1 − v2,
|
||||||
|
// We enforce this with six constraints:
|
||||||
|
//
|
||||||
|
// v0 = A.c0 * B.c0
|
||||||
|
// v1 = A.c1 * B.c1
|
||||||
|
// v2 = A.c2 * B.c2
|
||||||
|
//
|
||||||
|
// result.c0 - v0 + \beta*(v1 + v2) = β(a1 + a2)(b1 + b2))
|
||||||
|
// result.c1 + v0 + v1 - βv2 = (a0 + a1)(b0 + b1)
|
||||||
|
// result.c2 + v0 - v1 + v2 = (a0 + a2)(b0 + b2)
|
||||||
|
// Reference:
|
||||||
|
// "Multiplication and Squaring on Pairing-Friendly Fields"
|
||||||
|
// Devegili, OhEigeartaigh, Scott, Dahab
|
||||||
|
//
|
||||||
|
// This implementation adapted from
|
||||||
|
// https://github.com/ZencashOfficial/ginger-lib/blob/development/r1cs/gadgets/std/src/fields/fp3.rs
|
||||||
|
let v0 = self.c0.mul(cs.ns(|| "v0 = a0 * b0"), &other.c0)?;
|
||||||
|
let v1 = self.c1.mul(cs.ns(|| "v1 = a1 * b1"), &other.c1)?;
|
||||||
|
let v2 = self.c2.mul(cs.ns(|| "v2 = a2 * b2"), &other.c2)?;
|
||||||
|
|
||||||
|
// Check c0
|
||||||
|
let nr_a1_plus_a2 = self
|
||||||
|
.c1
|
||||||
|
.add(cs.ns(|| "a1 + a2"), &self.c2)?
|
||||||
|
.mul_by_constant(cs.ns(|| "nr*(a1 + a2)"), &P::NONRESIDUE)?;
|
||||||
|
let b1_plus_b2 = other.c1.add(cs.ns(|| "b1 + b2"), &other.c2)?;
|
||||||
|
let nr_v1 = v1.mul_by_constant(cs.ns(|| "nr * v1"), &P::NONRESIDUE)?;
|
||||||
|
let nr_v2 = v2.mul_by_constant(cs.ns(|| "nr * v2"), &P::NONRESIDUE)?;
|
||||||
|
let to_check = result
|
||||||
|
.c0
|
||||||
|
.sub(cs.ns(|| "c0 - v0"), &v0)?
|
||||||
|
.add(cs.ns(|| "c0 - v0 + nr * v1"), &nr_v1)?
|
||||||
|
.add(cs.ns(|| "c0 - v0 + nr * v1 + nr * v2"), &nr_v2)?;
|
||||||
|
nr_a1_plus_a2.mul_equals(cs.ns(|| "check c0"), &b1_plus_b2, &to_check)?;
|
||||||
|
|
||||||
|
// Check c1
|
||||||
|
let a0_plus_a1 = self.c0.add(cs.ns(|| "a0 + a1"), &self.c1)?;
|
||||||
|
let b0_plus_b1 = other.c0.add(cs.ns(|| "b0 + b1"), &other.c1)?;
|
||||||
|
let to_check = result
|
||||||
|
.c1
|
||||||
|
.sub(cs.ns(|| "c1 - nr * v2"), &nr_v2)?
|
||||||
|
.add(cs.ns(|| "c1 - nr * v2 + v0"), &v0)?
|
||||||
|
.add(cs.ns(|| "c1 - nr * v2 + v0 + v1"), &v1)?;
|
||||||
|
a0_plus_a1.mul_equals(cs.ns(|| "check c1"), &b0_plus_b1, &to_check)?;
|
||||||
|
|
||||||
|
// Check c2
|
||||||
|
let a0_plus_a2 = self.c0.add(cs.ns(|| "a0 + a2"), &self.c2)?;
|
||||||
|
let b0_plus_b2 = other.c0.add(cs.ns(|| "b0 + b2"), &other.c2)?;
|
||||||
|
let to_check = result
|
||||||
|
.c2
|
||||||
|
.add(cs.ns(|| "c2 + v0"), &v0)?
|
||||||
|
.sub(cs.ns(|| "c2 + v0 - v1"), &v1)?
|
||||||
|
.add(cs.ns(|| "c2 + v0 - v1 + v2"), &v2)?;
|
||||||
|
a0_plus_a2.mul_equals(cs.ns(|| "check c2"), &b0_plus_b2, &to_check)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -704,8 +697,8 @@ where
|
|||||||
5 * Fp2Gadget::<P, ConstraintF>::cost_of_mul()
|
5 * Fp2Gadget::<P, ConstraintF>::cost_of_mul()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_inv() -> usize {
|
fn cost_of_mul_equals() -> usize {
|
||||||
Self::cost_of_mul() + <Self as EqGadget<ConstraintF>>::cost()
|
6 * Fp2Gadget::<P, ConstraintF>::cost_of_mul()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -984,7 +977,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -1011,7 +1004,7 @@ where
|
|||||||
Ok(fe) => {
|
Ok(fe) => {
|
||||||
let fe = *fe.borrow();
|
let fe = *fe.borrow();
|
||||||
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
(Ok(fe.c0), Ok(fe.c1), Ok(fe.c2))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use algebra::{fields::BitIterator, Field};
|
|||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
use r1cs_core::{ConstraintSystem, SynthesisError};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::{prelude::*, Assignment};
|
||||||
|
|
||||||
pub mod fp;
|
pub mod fp;
|
||||||
pub mod fp12;
|
pub mod fp12;
|
||||||
@@ -188,7 +188,17 @@ pub trait FieldGadget<F: Field, ConstraintF: Field>:
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inverse<CS: ConstraintSystem<ConstraintF>>(&self, _: CS) -> Result<Self, SynthesisError>;
|
fn inverse<CS: ConstraintSystem<ConstraintF>>(
|
||||||
|
&self,
|
||||||
|
mut cs: CS,
|
||||||
|
) -> Result<Self, SynthesisError> {
|
||||||
|
let one = Self::one(&mut cs.ns(|| "one"))?;
|
||||||
|
let inverse = Self::alloc(&mut cs.ns(|| "alloc inverse"), || {
|
||||||
|
self.get_value().and_then(|val| val.inverse()).get()
|
||||||
|
})?;
|
||||||
|
self.mul_equals(cs.ns(|| "check inv"), &inverse, &one)?;
|
||||||
|
Ok(inverse)
|
||||||
|
}
|
||||||
|
|
||||||
fn frobenius_map<CS: ConstraintSystem<ConstraintF>>(
|
fn frobenius_map<CS: ConstraintSystem<ConstraintF>>(
|
||||||
&self,
|
&self,
|
||||||
@@ -255,7 +265,9 @@ pub trait FieldGadget<F: Field, ConstraintF: Field>:
|
|||||||
Self::cost_of_mul() + <Self as EqGadget<ConstraintF>>::cost()
|
Self::cost_of_mul() + <Self as EqGadget<ConstraintF>>::cost()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_of_inv() -> usize;
|
fn cost_of_inv() -> usize {
|
||||||
|
Self::cost_of_mul_equals()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ pub type G2Gadget<P> =
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
|
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
|
||||||
pub struct G1PreparedGadget<P: MNT4Parameters> {
|
pub struct G1PreparedGadget<P: MNT4Parameters> {
|
||||||
pub x: FpGadget<P::Fp>,
|
pub x: FpGadget<P::Fp>,
|
||||||
pub y: FpGadget<P::Fp>,
|
pub y: FpGadget<P::Fp>,
|
||||||
pub x_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub x_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub y_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub y_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
}
|
}
|
||||||
@@ -113,11 +113,11 @@ type Fp2G<P> = Fp2Gadget<<P as MNT4Parameters>::Fp2Params, <P as MNT4Parameters>
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
|
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
|
||||||
pub struct G2PreparedGadget<P: MNT4Parameters> {
|
pub struct G2PreparedGadget<P: MNT4Parameters> {
|
||||||
pub x: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub x: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub y: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub y: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub x_over_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub x_over_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub y_over_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub y_over_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub double_coefficients: Vec<AteDoubleCoefficientsGadget<P>>,
|
pub double_coefficients: Vec<AteDoubleCoefficientsGadget<P>>,
|
||||||
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>,
|
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,11 +222,11 @@ impl<P: MNT4Parameters> G2PreparedGadget<P> {
|
|||||||
let twist_inv = P::TWIST.inverse().unwrap();
|
let twist_inv = P::TWIST.inverse().unwrap();
|
||||||
|
|
||||||
let mut g2p = G2PreparedGadget {
|
let mut g2p = G2PreparedGadget {
|
||||||
x: q.x.clone(),
|
x: q.x.clone(),
|
||||||
y: q.y.clone(),
|
y: q.y.clone(),
|
||||||
x_over_twist: q.x.mul_by_constant(cs.ns(|| "x over twist"), &twist_inv)?,
|
x_over_twist: q.x.mul_by_constant(cs.ns(|| "x over twist"), &twist_inv)?,
|
||||||
y_over_twist: q.y.mul_by_constant(cs.ns(|| "y over twist"), &twist_inv)?,
|
y_over_twist: q.y.mul_by_constant(cs.ns(|| "y over twist"), &twist_inv)?,
|
||||||
double_coefficients: vec![],
|
double_coefficients: vec![],
|
||||||
addition_coefficients: vec![],
|
addition_coefficients: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -302,10 +302,10 @@ impl<P: MNT4Parameters> G2PreparedGadget<P> {
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
|
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
|
||||||
pub struct AteDoubleCoefficientsGadget<P: MNT4Parameters> {
|
pub struct AteDoubleCoefficientsGadget<P: MNT4Parameters> {
|
||||||
pub c_h: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub c_h: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub c_4c: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub c_4c: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub c_j: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub c_j: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
pub c_l: Fp2Gadget<P::Fp2Params, P::Fp>,
|
pub c_l: Fp2Gadget<P::Fp2Params, P::Fp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
|
impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ pub type G2Gadget<P> =
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
|
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
|
||||||
pub struct G1PreparedGadget<P: MNT6Parameters> {
|
pub struct G1PreparedGadget<P: MNT6Parameters> {
|
||||||
pub x: FpGadget<P::Fp>,
|
pub x: FpGadget<P::Fp>,
|
||||||
pub y: FpGadget<P::Fp>,
|
pub y: FpGadget<P::Fp>,
|
||||||
pub x_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub x_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub y_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub y_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
}
|
}
|
||||||
@@ -115,11 +115,11 @@ type Fp3G<P> = Fp3Gadget<<P as MNT6Parameters>::Fp3Params, <P as MNT6Parameters>
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
|
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
|
||||||
pub struct G2PreparedGadget<P: MNT6Parameters> {
|
pub struct G2PreparedGadget<P: MNT6Parameters> {
|
||||||
pub x: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub x: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub y: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub y: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub x_over_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub x_over_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub y_over_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub y_over_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub double_coefficients: Vec<AteDoubleCoefficientsGadget<P>>,
|
pub double_coefficients: Vec<AteDoubleCoefficientsGadget<P>>,
|
||||||
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>,
|
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,11 +224,11 @@ impl<P: MNT6Parameters> G2PreparedGadget<P> {
|
|||||||
let twist_inv = P::TWIST.inverse().unwrap();
|
let twist_inv = P::TWIST.inverse().unwrap();
|
||||||
|
|
||||||
let mut g2p = G2PreparedGadget {
|
let mut g2p = G2PreparedGadget {
|
||||||
x: q.x.clone(),
|
x: q.x.clone(),
|
||||||
y: q.y.clone(),
|
y: q.y.clone(),
|
||||||
x_over_twist: q.x.mul_by_constant(cs.ns(|| "x over twist"), &twist_inv)?,
|
x_over_twist: q.x.mul_by_constant(cs.ns(|| "x over twist"), &twist_inv)?,
|
||||||
y_over_twist: q.y.mul_by_constant(cs.ns(|| "y over twist"), &twist_inv)?,
|
y_over_twist: q.y.mul_by_constant(cs.ns(|| "y over twist"), &twist_inv)?,
|
||||||
double_coefficients: vec![],
|
double_coefficients: vec![],
|
||||||
addition_coefficients: vec![],
|
addition_coefficients: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -304,10 +304,10 @@ impl<P: MNT6Parameters> G2PreparedGadget<P> {
|
|||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
|
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
|
||||||
pub struct AteDoubleCoefficientsGadget<P: MNT6Parameters> {
|
pub struct AteDoubleCoefficientsGadget<P: MNT6Parameters> {
|
||||||
pub c_h: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub c_h: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub c_4c: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub c_4c: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub c_j: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub c_j: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
pub c_l: Fp3Gadget<P::Fp3Params, P::Fp>,
|
pub c_l: Fp3Gadget<P::Fp3Params, P::Fp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
|
impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ pub struct AffineGadget<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
F: FieldGadget<P::BaseField, ConstraintF>,
|
F: FieldGadget<P::BaseField, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
pub x: F,
|
pub x: F,
|
||||||
pub y: F,
|
pub y: F,
|
||||||
pub infinity: Boolean,
|
pub infinity: Boolean,
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
_engine: PhantomData<ConstraintF>,
|
_engine: PhantomData<ConstraintF>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: SWModelParameters, ConstraintF: Field, F: FieldGadget<P::BaseField, ConstraintF>>
|
impl<P: SWModelParameters, ConstraintF: Field, F: FieldGadget<P::BaseField, ConstraintF>>
|
||||||
@@ -53,7 +53,7 @@ impl<P: SWModelParameters, ConstraintF: Field, F: FieldGadget<P::BaseField, Cons
|
|||||||
Ok(ge) => {
|
Ok(ge) => {
|
||||||
let ge = ge.into_affine();
|
let ge = ge.into_affine();
|
||||||
(Ok(ge.x), Ok(ge.y), Ok(ge.infinity))
|
(Ok(ge.x), Ok(ge.y), Ok(ge.infinity))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -107,7 +107,7 @@ where
|
|||||||
) {
|
) {
|
||||||
(Some(x), Some(y), Some(infinity)) => {
|
(Some(x), Some(y), Some(infinity)) => {
|
||||||
Some(SWAffine::new(x, y, infinity).into_projective())
|
Some(SWAffine::new(x, y, infinity).into_projective())
|
||||||
},
|
}
|
||||||
(None, None, None) => None,
|
(None, None, None) => None,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@@ -450,7 +450,7 @@ where
|
|||||||
Ok(ge) => {
|
Ok(ge) => {
|
||||||
let ge = ge.borrow().into_affine();
|
let ge = ge.borrow().into_affine();
|
||||||
(Ok(ge.x), Ok(ge.y), Ok(ge.infinity))
|
(Ok(ge.x), Ok(ge.y), Ok(ge.infinity))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -574,7 +574,7 @@ where
|
|||||||
Ok(ge) => {
|
Ok(ge) => {
|
||||||
let ge = ge.borrow().into_affine();
|
let ge = ge.borrow().into_affine();
|
||||||
(Ok(ge.x), Ok(ge.y), Ok(ge.infinity))
|
(Ok(ge.x), Ok(ge.y), Ok(ge.infinity))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ pub struct MontgomeryAffineGadget<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
F: FieldGadget<P::BaseField, ConstraintF>,
|
F: FieldGadget<P::BaseField, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
pub x: F,
|
pub x: F,
|
||||||
pub y: F,
|
pub y: F,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
@@ -90,7 +90,7 @@ mod montgomery_affine_impl {
|
|||||||
t0.mul_assign(&invy);
|
t0.mul_assign(&invy);
|
||||||
|
|
||||||
Ok(t0)
|
Ok(t0)
|
||||||
},
|
}
|
||||||
None => Err(SynthesisError::DivisionByZero),
|
None => Err(SynthesisError::DivisionByZero),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
@@ -108,7 +108,7 @@ mod montgomery_affine_impl {
|
|||||||
t0.mul_assign(&t1);
|
t0.mul_assign(&t1);
|
||||||
|
|
||||||
Ok(t0)
|
Ok(t0)
|
||||||
},
|
}
|
||||||
None => Err(SynthesisError::DivisionByZero),
|
None => Err(SynthesisError::DivisionByZero),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
@@ -140,7 +140,7 @@ mod montgomery_affine_impl {
|
|||||||
Some(d) => {
|
Some(d) => {
|
||||||
n.mul_assign(&d);
|
n.mul_assign(&d);
|
||||||
Ok(n)
|
Ok(n)
|
||||||
},
|
}
|
||||||
None => Err(SynthesisError::DivisionByZero),
|
None => Err(SynthesisError::DivisionByZero),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
@@ -193,8 +193,8 @@ pub struct AffineGadget<
|
|||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
F: FieldGadget<P::BaseField, ConstraintF>,
|
F: FieldGadget<P::BaseField, ConstraintF>,
|
||||||
> {
|
> {
|
||||||
pub x: F,
|
pub x: F,
|
||||||
pub y: F,
|
pub y: F,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
_params: PhantomData<P>,
|
_params: PhantomData<P>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
@@ -504,7 +504,7 @@ mod affine_impl {
|
|||||||
Ok(ge) => {
|
Ok(ge) => {
|
||||||
let ge = *ge.borrow();
|
let ge = *ge.borrow();
|
||||||
(Ok(ge.x), Ok(ge.y))
|
(Ok(ge.x), Ok(ge.y))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -621,7 +621,7 @@ mod affine_impl {
|
|||||||
Ok(ge) => {
|
Ok(ge) => {
|
||||||
let ge = *ge.borrow();
|
let ge = *ge.borrow();
|
||||||
(Ok(ge.x), Ok(ge.y))
|
(Ok(ge.x), Ok(ge.y))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -960,14 +960,14 @@ mod projective_impl {
|
|||||||
match edwards_result {
|
match edwards_result {
|
||||||
None => {
|
None => {
|
||||||
edwards_result = Some(segment_result);
|
edwards_result = Some(segment_result);
|
||||||
},
|
}
|
||||||
Some(ref mut edwards_result) => {
|
Some(ref mut edwards_result) => {
|
||||||
*edwards_result = GroupGadget::<TEAffine<P>, ConstraintF>::add(
|
*edwards_result = GroupGadget::<TEAffine<P>, ConstraintF>::add(
|
||||||
&segment_result,
|
&segment_result,
|
||||||
cs.ns(|| "edwards addition"),
|
cs.ns(|| "edwards addition"),
|
||||||
edwards_result,
|
edwards_result,
|
||||||
)?;
|
)?;
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1050,13 +1050,13 @@ mod projective_impl {
|
|||||||
match result {
|
match result {
|
||||||
None => {
|
None => {
|
||||||
result = Some(tmp);
|
result = Some(tmp);
|
||||||
},
|
}
|
||||||
Some(ref mut result) => {
|
Some(ref mut result) => {
|
||||||
*result = tmp.add(
|
*result = tmp.add(
|
||||||
cs.ns(|| format!("addition of window {}, {}", segment_i, i)),
|
cs.ns(|| format!("addition of window {}, {}", segment_i, i)),
|
||||||
result,
|
result,
|
||||||
)?;
|
)?;
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,7 +1101,7 @@ mod projective_impl {
|
|||||||
Ok(ge) => {
|
Ok(ge) => {
|
||||||
let ge = ge.borrow().into_affine();
|
let ge = ge.borrow().into_affine();
|
||||||
(Ok(ge.x), Ok(ge.y))
|
(Ok(ge.x), Ok(ge.y))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
@@ -1223,7 +1223,7 @@ mod projective_impl {
|
|||||||
Ok(ge) => {
|
Ok(ge) => {
|
||||||
let ge = ge.borrow().into_affine();
|
let ge = ge.borrow().into_affine();
|
||||||
(Ok(ge.x), Ok(ge.y))
|
(Ok(ge.x), Ok(ge.y))
|
||||||
},
|
}
|
||||||
_ => (
|
_ => (
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
Err(SynthesisError::AssignmentMissing),
|
Err(SynthesisError::AssignmentMissing),
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ use ralloc::{collections::BTreeMap, string::String, vec::Vec};
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::{collections::BTreeMap, string::String, vec::Vec};
|
use std::{collections::BTreeMap, string::String, vec::Vec};
|
||||||
|
|
||||||
pub mod test_constraint_system;
|
|
||||||
pub mod test_constraint_counter;
|
pub mod test_constraint_counter;
|
||||||
|
pub mod test_constraint_system;
|
||||||
|
|
||||||
pub mod bits;
|
pub mod bits;
|
||||||
pub use self::bits::*;
|
pub use self::bits::*;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl<P: Bls12Parameters> PairingGadget<P> {
|
|||||||
c1.c1 = c1.c1.mul(cs.ns(|| "mul c1.c1"), &p.x)?;
|
c1.c1 = c1.c1.mul(cs.ns(|| "mul c1.c1"), &p.x)?;
|
||||||
*f = f.mul_by_014(cs.ns(|| "sparse mul f"), &c0, &c1, &c2)?;
|
*f = f.mul_by_014(cs.ns(|| "sparse mul f"), &c0, &c1, &c2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
TwistType::D => {
|
TwistType::D => {
|
||||||
let c0 = Fp2G::<P>::new(p.y.clone(), zero);
|
let c0 = Fp2G::<P>::new(p.y.clone(), zero);
|
||||||
let mut c1 = coeffs.0.clone();
|
let mut c1 = coeffs.0.clone();
|
||||||
@@ -46,7 +46,7 @@ impl<P: Bls12Parameters> PairingGadget<P> {
|
|||||||
c1.c1 = c1.c1.mul(cs.ns(|| "mul c1.c1"), &p.x)?;
|
c1.c1 = c1.c1.mul(cs.ns(|| "mul c1.c1"), &p.x)?;
|
||||||
*f = f.mul_by_034(cs.ns(|| "sparse mul f"), &c0, &c1, &c2)?;
|
*f = f.mul_by_034(cs.ns(|| "sparse mul f"), &c0, &c1, &c2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ use r1cs_core::{ConstraintSystem, Index, LinearCombination, SynthesisError, Vari
|
|||||||
|
|
||||||
/// Constraint counter for testing purposes.
|
/// Constraint counter for testing purposes.
|
||||||
pub struct ConstraintCounter {
|
pub struct ConstraintCounter {
|
||||||
pub num_inputs: usize,
|
pub num_inputs: usize,
|
||||||
pub num_aux: usize,
|
pub num_aux: usize,
|
||||||
pub num_constraints: usize,
|
pub num_constraints: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstraintCounter {
|
impl ConstraintCounter {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
num_aux: 0,
|
num_aux: 0,
|
||||||
num_inputs: 0,
|
num_inputs: 0,
|
||||||
num_constraints: 0,
|
num_constraints: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ enum NamedObject {
|
|||||||
|
|
||||||
/// Constraint system for testing purposes.
|
/// Constraint system for testing purposes.
|
||||||
pub struct TestConstraintSystem<ConstraintF: Field> {
|
pub struct TestConstraintSystem<ConstraintF: Field> {
|
||||||
named_objects: BTreeMap<String, NamedObject>,
|
named_objects: BTreeMap<String, NamedObject>,
|
||||||
current_namespace: Vec<String>,
|
current_namespace: Vec<String>,
|
||||||
pub constraints: Vec<(
|
pub constraints: Vec<(
|
||||||
LinearCombination<ConstraintF>,
|
LinearCombination<ConstraintF>,
|
||||||
@@ -19,8 +19,8 @@ pub struct TestConstraintSystem<ConstraintF: Field> {
|
|||||||
LinearCombination<ConstraintF>,
|
LinearCombination<ConstraintF>,
|
||||||
String,
|
String,
|
||||||
)>,
|
)>,
|
||||||
inputs: Vec<(ConstraintF, String)>,
|
inputs: Vec<(ConstraintF, String)>,
|
||||||
aux: Vec<(ConstraintF, String)>,
|
aux: Vec<(ConstraintF, String)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ConstraintF: Field> TestConstraintSystem<ConstraintF> {
|
impl<ConstraintF: Field> TestConstraintSystem<ConstraintF> {
|
||||||
@@ -54,11 +54,11 @@ impl<ConstraintF: Field> TestConstraintSystem<ConstraintF> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
TestConstraintSystem {
|
TestConstraintSystem {
|
||||||
named_objects: map,
|
named_objects: map,
|
||||||
current_namespace: vec![],
|
current_namespace: vec![],
|
||||||
constraints: vec![],
|
constraints: vec![],
|
||||||
inputs: vec![(ConstraintF::one(), "ONE".into())],
|
inputs: vec![(ConstraintF::one(), "ONE".into())],
|
||||||
aux: vec![],
|
aux: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
reorder_imports = true
|
reorder_imports = true
|
||||||
wrap_comments = true
|
wrap_comments = true
|
||||||
normalize_comments = true
|
normalize_comments = true
|
||||||
format_strings = true
|
|
||||||
struct_field_align_threshold = 40
|
|
||||||
use_try_shorthand = true
|
use_try_shorthand = true
|
||||||
match_block_trailing_comma = true
|
match_block_trailing_comma = true
|
||||||
use_field_init_shorthand = true
|
use_field_init_shorthand = true
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
condense_wildcard_suffixes = true
|
condense_wildcard_suffixes = true
|
||||||
merge_imports = true
|
merge_imports = true
|
||||||
imports_layout = "Mixed"
|
|
||||||
unstable_features = true
|
|
||||||
|
|||||||
Reference in New Issue
Block a user