sigma_compiler_core/
lib.rs

1use proc_macro2::TokenStream;
2
3/// The submodules that would be useful to have in the lower-level
4/// `sigma-proofs` crate are for now included as submodules of a local
5/// `sigma` module.
6pub mod sigma {
7    pub mod codegen;
8    pub mod combiners;
9    pub mod types;
10}
11mod codegen;
12mod notequals;
13mod pedersen;
14mod pubscalareq;
15mod rangeproof;
16mod substitution;
17mod syntax;
18mod transform;
19
20pub use codegen::CodeGen;
21pub use syntax::{SigmaCompSpec, TaggedIdent, TaggedPoint, TaggedScalar, TaggedVarDict};
22
23use syn::Result;
24
25/// Transform the [`StatementTree`] so that it satisfies the
26/// [disjunction invariant].
27///
28/// [`StatementTree`]: sigma::combiners::StatementTree
29/// [disjunction invariant]: sigma::combiners::StatementTree::check_disjunction_invariant
30pub fn enforce_disjunction_invariant(
31    codegen: &mut CodeGen,
32    spec: &mut SigmaCompSpec,
33) -> Result<()> {
34    transform::enforce_disjunction_invariant(codegen, &mut spec.statements, &mut spec.vars)
35}
36
37/// Apply all of the compiler transformations.
38///
39/// The [disjunction invariant] must be true before calling this
40/// function, and will remain true after each transformation (and at the
41/// end of this function).  Call [enforce_disjunction_invariant] before
42/// calling this function if you're not sure the disjunction invariant
43/// already holds.
44///
45/// [disjunction invariant]: sigma::combiners::StatementTree::check_disjunction_invariant
46pub fn apply_transformations(codegen: &mut CodeGen, spec: &mut SigmaCompSpec) -> Result<()> {
47    // Apply any substitution transformations
48    substitution::transform(codegen, &mut spec.statements, &mut spec.vars)?;
49
50    // Apply any range statement transformations
51    rangeproof::transform(codegen, &mut spec.statements, &mut spec.vars)?;
52
53    // Apply any not-equals statement transformations
54    notequals::transform(codegen, &mut spec.statements, &mut spec.vars)?;
55
56    // Apply any public scalar equality transformations
57    pubscalareq::transform(codegen, &mut spec.statements, &mut spec.vars)?;
58
59    Ok(())
60}
61
62/// The main function of this macro.
63///
64/// Parse the macro input with [`parse`](SigmaCompSpec#method.parse) to
65/// produce a [`SigmaCompSpec`], and then pass that to this function to
66/// output the data structures and code for the ZKP protocol
67/// implementation.
68///
69/// If `emit_prover` is `true`, output the data structures and code for
70/// the prover side.  If `emit_verifier` is `true`, output the data
71/// structures and code for the verifier side.  (Typically both will be
72/// `true`, but you can set one to `false` if you don't need that side
73/// of the protocol.)
74pub fn sigma_compiler_core(
75    spec: &mut SigmaCompSpec,
76    emit_prover: bool,
77    emit_verifier: bool,
78) -> TokenStream {
79    let mut codegen = codegen::CodeGen::new(spec);
80
81    // Enforce the disjunction invariant (do this before any other
82    // transformations, since they assume the invariant holds, and will
83    // maintain it)
84    enforce_disjunction_invariant(&mut codegen, spec).unwrap();
85
86    // Apply the transformations
87    apply_transformations(&mut codegen, spec).unwrap();
88
89    // Generate the code to be output
90    codegen.generate(spec, emit_prover, emit_verifier)
91}