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}