lib.rs 3.1 KB

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