Pārlūkot izejas kodu

Start on the documentation of the main sigma_compiler macro

Ian Goldberg 4 mēneši atpakaļ
vecāks
revīzija
027760ffde

+ 2 - 2
sigma_compiler_core/src/syntax.rs

@@ -183,10 +183,10 @@ pub struct SigmaCompSpec {
     pub proto_name: Ident,
 
     /// An identifier for the mathematical
-    /// [`PrimeGroup`](https://docs.rs/group/latest/group/prime/trait.PrimeGroup.html)
+    /// [`PrimeGroup`](https://docs.rs/group/0.13.0/group/prime/trait.PrimeGroup.html)
     /// being used (if none is specified, it is assumed there is a
     /// default type called `G` in scope that implements the
-    /// [`PrimeGroup`](https://docs.rs/group/latest/group/prime/trait.PrimeGroup.html)
+    /// [`PrimeGroup`](https://docs.rs/group/0.13.0/group/prime/trait.PrimeGroup.html)
     /// trait)
     pub group_name: Ident,
 

+ 128 - 0
sigma_compiler_derive/src/lib.rs

@@ -2,18 +2,146 @@ use proc_macro::TokenStream;
 use sigma_compiler_core::{sigma_compiler_core, SigmaCompSpec};
 use syn::parse_macro_input;
 
+#[cfg(not(doctest))]
+/// The main macro provided by this crate.
+///
+/// The general form of this macro is:
+/// ```
+/// sigma_compiler! { proto_name<Grp>,
+///    (scalar_list),
+///    (point_list),
+///    statement_1,
+///    statement_2,
+///    ...
+/// }
+/// ```
+///
+/// The pieces are as follows:
+///
+///   - `proto_name`: The name of the protocol.  A Rust submodule will
+///      be created with this name, containing all of the data
+///      structures and code associated with this sigma protocol.
+///   - `<Grp>`: an optional indication of the mathematical group to use
+///     (a set of `Point`s and associated `Scalar`s) for this sigma
+///     protocol.  The group must implement the
+///     [`PrimeGroup`](https://docs.rs/group/0.13.0/group/prime/trait.PrimeGroup.html)
+///     trait.  If `<Grp>` is omitted, it defaults to assuming there is
+///     a group called `G` in the current scope.
+///   - `scalar_list` is a list of variables representing `Scalar`s.
+///     Each variable can be optionally tagged with one or more of the
+///     tags `pub`, `rand`, or `vec`.  The tags `pub` and `rand` cannot
+///     both be used on the same variable.
+///     - `pub` means that the `Scalar` is public; this can be used for
+///       public parameters to the protocol, such as the limits of
+///       ranges, or other constants that can appear in the statements.
+///       Any `Scalar` not marked as `pub` is assumed to be private to
+///       the prover, and the verifier will learn nothing about that
+///       value other than what is implied by the truth of the
+///       statements.
+///     - `rand` means that the `Scalar` is a uniform random `Scalar`.
+///       A `rand` `Scalar` must be used only once in the statements.
+///       These are typically used as randomizers in Pedersen
+///       commitments.
+///     - `vec` means that the variable represents a vector of
+///       `Scalar`s, as opposed to a single `Scalar`.  The number of
+///       entries in the vector can be set at runtime, when the sigma
+///       protocol is executed.
+///   - `point_list` is a list of variables representing `Point`s.  All
+///     `Point` variables are considered public.  Each variable can be
+///     optionally tagged with one or more of the tags `cind`, `const`,
+///     or `vec`.  All combinations of tags are valid.
+///     - All `Point`s tagged with `cind` are _computationally
+///       independent_.  This means that the _prover_ does not know a
+///       discrete logarithm relationship between any of them.
+///       Formally, `P1`, `P2`, ..., `Pn` being computationally
+///       independent `Point`s means that if the prover knows `Scalar`s
+///       `s1`, `s2`, ..., `sn` such that `s1*P1 + s2*P2 + ... + sn*Pn =
+///       0` (where `0` is the identity element of the group), then it
+///       must be the case that each of `s1`, `s2`, ..., `sn` is the
+///       zero `Scalar` (modulo the order of the group).  Typically,
+///       these elements would be generators of the group, generated
+///       with a hash-to-group function, as opposed to multiplying the
+///       standard generator by a random number (at least not one known
+///       by the prover).  `Point`s marked `cind` are typically the
+///       bases used in Pedersen commitments.
+///     - `const` means that the value of the `Point` will always be the
+///       same for each invocation of the sigma protocol.  This is
+///       typical for fixed generators, but possibly other `Point`s as
+///       well.
+///     - `vec` means that the variable represents a vector of `Point`s,
+///       as opposed to a single `Point`.  The number of entries in the
+///       vector can be set at runtime, when the sigma protocol is
+///       executed.
+///    - Each `statement` is a statement that the prover is proving the
+///      truth of to the verifier.  Each statement can have one of the
+///      following forms:
+///      - `C = arith_expr`, where `C` is a variable representing a
+///        `Point`, and `arith_expr` is an _arithmetic expression_
+///        evaluating to a `Point`.  This is a _linear combination
+///        statement_.  An arithmetic expression can consist of:
+///        - `Scalar` or `Point` variables
+///        - integer constants
+///        - the operations `*`, `+`, `-` (binary or unary)
+///        - the operation `<<` where both operands are expressions with no
+///          variables
+///        - parens
+///
+///        You cannot multiply together two private subexpressions, and
+///        you cannot multiply together two subexpressions that both
+///        evaluate to `Point`s.  You cannot add a `Point` to a
+///        `Scalar`.  Integer constants are considered `Scalar`s, but
+///        all arithmetic subexpressions involving only constants must
+///        have values that fit in an [`i128`].
+///
+///        If any variable in `arith_expr` is marked `vec`, then this is
+///        a vector expression, and `C` must also be marked `vec`.  The
+///        statement is considered to hold in 'SIMD' style; that is, the
+///        lengths of all of the vector variables involved in the
+///        statement must be the same, and the statement is proven to
+///        hold component-wise.  Any non-vector variable in the
+///        statement is considered equivalent to a vector variable, all
+///        of whose entries have the same value.
+///      - `a = arith_expr`, where `a` is a variable representing a
+///        private `Scalar`.  This is a _substitution statement_.  Its
+///        meaning is to say that the private `Scalar` `a` has the value
+///        given by the arithmetic expression, which must evaluate to a
+///        `Scalar`.  The effect is to substitute `a` anywhere it
+///        appears in the list of statements (including the right side
+///        of other substitutions) with the given expression.  The
+///        expression must not contain the variable `a` itself, either
+///        directly, or after other substitutions.  For example, the
+///        statement `a = a + b` is not allowed, nor is the combination
+///        of substitutions `a = b + 1, b = c + 2, c = 2*a`.
+///      - `(a..b).contains(x)`, where `a` and `b` are _public_
+///        `Scalar`s (or arithmetic expressions evaluating to public
+///        `Scalar`s), and `x` is a private `Scalar`, possibly
+///        multiplied by a constant and adding or subtracting an
+///        expression evaluating to a public `Scalar`.  For example,
+///        `((a+2)..(3*b-7)).contains(2*x+2*c*c+12)` is allowed, if `a`,
+///        `b`, and `c` are public `Scalar`s and `x` is a private
+///        `Scalar`.  `(a..b).contains(x)` is a _range statement_, and
+///        it means that `x` lies in the range `a..b`.  As usual in
+///        Rust, the range `a..b` _includes_ `a`, but _excludes_ `b`.
+///        If you want to include both endpoints, you can also use the
+///        usual Rust notation `a..=b`.  The size of the range must fit
+///        in an [`i128`].
+
 #[proc_macro]
 pub fn sigma_compiler(input: TokenStream) -> TokenStream {
     let mut spec = parse_macro_input!(input as SigmaCompSpec);
     sigma_compiler_core(&mut spec, true, true).into()
 }
 
+/// A version of the [`sigma_compiler!`] macro that only outputs the code
+/// needed by the prover.
 #[proc_macro]
 pub fn sigma_compiler_prover(input: TokenStream) -> TokenStream {
     let mut spec = parse_macro_input!(input as SigmaCompSpec);
     sigma_compiler_core(&mut spec, true, false).into()
 }
 
+/// A version of the [`sigma_compiler!`] macro that only outputs the code
+/// needed by the verifier.
 #[proc_macro]
 pub fn sigma_compiler_verifier(input: TokenStream) -> TokenStream {
     let mut spec = parse_macro_input!(input as SigmaCompSpec);

+ 1 - 1
src/rangeutils.rs

@@ -1,5 +1,5 @@
 //! A module containing some utility functions useful for the runtime
-//! processing of range proofs.
+//! processing of range statements.
 
 use group::ff::PrimeField;
 use sigma_rs::errors::Error;