Skip to content

Commit bd092fc

Browse files
committed
docs: minor improvements on relations
1 parent d2c6671 commit bd092fc

File tree

2 files changed

+41
-15
lines changed

2 files changed

+41
-15
lines changed

src/linear_relation/canonical.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@ use super::{GroupMap, GroupVar, LinearCombination, LinearRelation, ScalarTerm, S
1010
use crate::errors::{Error, InvalidInstance};
1111
use crate::linear_relation::msm::VariableMultiScalarMul;
1212

13+
// XXX. this definition is uncomfortably similar to LinearRelation, exception made for the weights.
14+
// It'd be nice to better compress potentially duplicated code.
1315
/// A normalized form of the [`LinearRelation`], which is used for serialization into the transcript.
1416
///
1517
/// This struct represents a normalized form of a linear relation where each
1618
/// constraint is of the form: image_i = Σ (scalar_j * group_element_k)
1719
/// without weights or extra scalars.
18-
///
19-
/// XXX. this definition is uncomfortably similar to LinearRelation, exception made for the weights.
20-
/// It'd be nice to squash the two together.
2120
#[derive(Clone, Debug, Default)]
2221
pub struct CanonicalLinearRelation<G: PrimeGroup> {
2322
/// The image group elements (left-hand side of equations)
@@ -39,7 +38,10 @@ pub struct CanonicalLinearRelation<G: PrimeGroup> {
3938
type WeightedGroupCache<G> = HashMap<GroupVar<G>, Vec<(<G as group::Group>::Scalar, GroupVar<G>)>>;
4039

4140
impl<G: PrimeGroup> CanonicalLinearRelation<G> {
42-
/// Create a new empty canonical linear relation
41+
/// Create a new empty canonical linear relation.
42+
///
43+
/// This function is not meant to be publicly exposed. It is internally used to build a type-safe linear relation,
44+
/// so that all instances guaranteed to be "good" relations over which the prover will want to make a proof.
4345
fn new() -> Self {
4446
Self {
4547
image: Vec::new(),
@@ -57,7 +59,8 @@ impl<G: PrimeGroup> CanonicalLinearRelation<G> {
5759
/// # Panic
5860
///
5961
/// Panics if the number of scalars given is less than the number of scalar variables in this
60-
/// linear relation
62+
/// linear relation.
63+
/// If the vector of scalars if longer than the number of terms in each linear combinations, the extra terms are ignored.
6164
pub fn evaluate(&self, scalars: &[G::Scalar]) -> Vec<G> {
6265
self.linear_combinations
6366
.iter()
@@ -104,7 +107,7 @@ impl<G: PrimeGroup> CanonicalLinearRelation<G> {
104107
Ok(new_var)
105108
}
106109

107-
/// Process a single constraint equation and add it to the canonical relation
110+
/// Process a single constraint equation and add it to the canonical relation.
108111
fn process_constraint(
109112
&mut self,
110113
&image_var: &GroupVar<G>,
@@ -157,12 +160,13 @@ impl<G: PrimeGroup> CanonicalLinearRelation<G> {
157160
/// Serialize the linear relation to bytes.
158161
///
159162
/// The output format is:
160-
/// - [Ne: u32] number of equations
161-
/// - Ne × equations:
162-
/// - [lhs_index: u32] output group element index
163-
/// - [Nt: u32] number of terms
164-
/// - Nt × [scalar_index: u32, group_index: u32] term entries
165-
/// - Followed by all group elements in serialized form
163+
///
164+
/// - `[Ne: u32]` number of equations
165+
/// - `Ne × equations`:
166+
/// - `[lhs_index: u32]` output group element index
167+
/// - `[Nt: u32]` number of terms
168+
/// - `Nt × [scalar_index: u32, group_index: u32]` term entries
169+
/// - All group elements in serialized form.
166170
pub fn label(&self) -> Vec<u8> {
167171
let mut out = Vec::new();
168172

@@ -237,7 +241,21 @@ impl<G: PrimeGroup> CanonicalLinearRelation<G> {
237241
out
238242
}
239243

240-
/// Parse a canonical linear relation from its label representation
244+
/// Parse a canonical linear relation from its label representation.
245+
///
246+
/// Returns an [`InvalidInstance`] error if the label is malformed.
247+
///
248+
/// # Examples
249+
///
250+
/// ```
251+
/// use hex_literal::hex;
252+
/// use sigma_rs::linear_relation::CanonicalLinearRelation;
253+
/// type G = bls12_381::G1Projective;
254+
///
255+
/// let dlog_instance_label = hex!("01000000000000000100000000000000010000009823a3def60a6e07fb25feb35f211ee2cbc9c130c1959514f5df6b5021a2b21a4c973630ec2090c733c1fe791834ce1197f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb");
256+
/// let instance = CanonicalLinearRelation::<G>::from_label(&dlog_instance_label).unwrap();
257+
/// assert_eq!(&dlog_instance_label[..], &instance.label()[..]);
258+
/// ```
241259
pub fn from_label(data: &[u8]) -> Result<Self, Error> {
242260
use crate::errors::InvalidInstance;
243261
use crate::serialization::group_elt_serialized_len;
@@ -399,7 +417,7 @@ impl<G: PrimeGroup> TryFrom<&LinearRelation<G>> for CanonicalLinearRelation<G> {
399417
fn try_from(relation: &LinearRelation<G>) -> Result<Self, Self::Error> {
400418
if relation.image.len() != relation.linear_map.linear_combinations.len() {
401419
return Err(InvalidInstance::new(
402-
"Equations and image elements must match",
420+
"Number of equations must be equal to number of image elements.",
403421
));
404422
}
405423

@@ -447,6 +465,14 @@ impl<G: PrimeGroup> TryFrom<&LinearRelation<G>> for CanonicalLinearRelation<G> {
447465
}
448466

449467
impl<G: PrimeGroup + ConstantTimeEq> CanonicalLinearRelation<G> {
468+
/// Tests is the witness is valid.
469+
///
470+
/// Returns a [`Choice`] indicating if the witness is valid for the instance constructed.
471+
///
472+
/// # Panic
473+
///
474+
/// Panics if the number of scalars given is less than the number of scalar variables.
475+
/// If the number of scalars is more than the number of scalar variables, the extra elements are ignored.
450476
pub fn is_witness_valid(&self, witness: &[G::Scalar]) -> Choice {
451477
let got = self.evaluate(witness);
452478
self.image

src/tests/test_relations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn discrete_logarithm<G: PrimeGroup, R: rand::RngCore>(
2929

3030
assert_eq!(X, G::generator() * x);
3131
let witness = vec![x];
32-
let instance = (&relation).try_into().unwrap();
32+
let instance: CanonicalLinearRelation<G> = (&relation).try_into().unwrap();
3333
(instance, witness)
3434
}
3535

0 commit comments

Comments
 (0)