Skip to content

Commit

Permalink
variety of feedback from PR review
Browse files Browse the repository at this point in the history
  • Loading branch information
ralexstokes committed Mar 2, 2021
1 parent d556a54 commit 52574c3
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 67 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2018"

[dependencies]
rand = "0.8.3"
blst = "0.3.2"
oblast = { path = "oblast" }
num-bigint = "0.3.1"

Expand Down
1 change: 1 addition & 0 deletions oblast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ description = "High-level wrapper for blst"
hex = "0.4.2"
paste = "1.0.4"
blst = "0.3.2"
num-bigint = "0.3.1"
11 changes: 11 additions & 0 deletions oblast/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
use num_bigint::BigUint;

pub const MODULUS_BIT_SIZE: usize = 255;

/// Return the order of the group(s) defined over elliptic curves in BLS12-381. The `r` in `Fr`.
pub fn curve_order() -> BigUint {
BigUint::parse_bytes(
b"52435875175126190479447740508185965837690552500527637822603658699938581184513",
10,
)
.unwrap()
}
4 changes: 3 additions & 1 deletion oblast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ mod constants;
#[cfg(test)]
mod tests;

pub use constants::curve_order;

use blst::{blst_fp12, blst_fr, blst_scalar};
use paste::paste;

Expand Down Expand Up @@ -178,7 +180,7 @@ macro_rules! define_curve_struct {
#[doc = "Point on the curve sub-group " $group_name "."]
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
pub struct $struct_name {
pub point: blst::[<blst_ $blst_name>],
point: blst::[<blst_ $blst_name>],
}
}

Expand Down
56 changes: 19 additions & 37 deletions src/commitment.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use crate::polynomial;
use crate::setup;
use oblast;
use oblast::{verify_pairings, Fr, P1, P2};

#[derive(Debug)]
pub struct Opening {
pub value: oblast::Fr,
pub proof: oblast::P1,
pub value: Fr,
pub proof: P1,
}

#[derive(Debug)]
pub struct Commitment<'a> {
element: oblast::P1,
element: P1,
polynomial: &'a polynomial::Polynomial,
setup: &'a setup::Setup,
}
Expand Down Expand Up @@ -47,11 +47,11 @@ fn compute_quotient(
}

impl<'a> Commitment<'a> {
pub fn open_at(self: &Self, point: oblast::Fr) -> Opening {
pub fn open_at(self: &Self, point: Fr) -> Opening {
let result = self.polynomial.evaluate_at(point);

// divisor `s - x` for `f(x) = y`
let divisor_coefficients = vec![-point, oblast::Fr::from_u64(1)];
let divisor_coefficients = vec![-point, Fr::from_u64(1)];
let divisor = polynomial::from_coefficients(divisor_coefficients.into_iter());

let quotient_polynomial = compute_quotient(self.polynomial, &divisor);
Expand All @@ -72,7 +72,7 @@ pub fn create<'a>(
let basis = &setup.in_g1;
let coefficients = &polynomial.coefficients;

let mut result = oblast::P1::default();
let mut result = P1::default();
for (coefficient, element) in coefficients.iter().zip(basis.iter()) {
let term = *coefficient * *element;
result = result + term;
Expand All @@ -86,21 +86,16 @@ pub fn create<'a>(
}

impl Opening {
pub fn verify(&self, input: &oblast::Fr, commitment: &Commitment) -> bool {
pub fn verify(&self, input: &Fr, commitment: &Commitment) -> bool {
// Compute [f(s) - y]_1 for LHS
let y_p1 = self.value * oblast::P1::generator();
let y_p1 = self.value * P1::generator();
let commitment_minus_y = commitment.element + -y_p1;

// Compute [s - z]_2 for RHS
let z_p2 = *input * oblast::P2::generator();
let z_p2 = *input * P2::generator();
let s_minus_z = commitment.setup.in_g2 + -z_p2;

oblast::verify_pairings(
commitment_minus_y,
oblast::P2::generator(),
self.proof,
s_minus_z,
)
verify_pairings(commitment_minus_y, P2::generator(), self.proof, s_minus_z)
}
}

Expand Down Expand Up @@ -243,16 +238,13 @@ mod tests {
),
];

let point = oblast::Fr::from_u64(15);
let point = Fr::from_u64(15);

for (secret_hex, polynomial, value, expected_commitment_hex, expected_proof_hex) in
test_cases
{
let secret = hex::decode(secret_hex).unwrap();
let coefficients = polynomial
.into_iter()
.map(oblast::Fr::from_u64)
.collect::<Vec<_>>();
let coefficients = polynomial.into_iter().map(Fr::from_u64).collect::<Vec<_>>();

let degree = coefficients.len();

Expand All @@ -269,21 +261,12 @@ mod tests {
assert_eq!(opening.value.as_u64(), value);

// does commitment match?
let mut commitment_serialization = vec![0u8; 48];
unsafe {
blst::blst_p1_compress(
commitment_serialization.as_mut_ptr(),
&commitment.element.point,
);
}
let commitment_serialization = commitment.element.compress();
let expected_commitment_serialization = hex::decode(expected_commitment_hex).unwrap();
assert_eq!(commitment_serialization, expected_commitment_serialization);

// does proof match?
let mut proof_serialization = vec![0u8; 48];
unsafe {
blst::blst_p1_compress(proof_serialization.as_mut_ptr(), &opening.proof.point);
}
let proof_serialization = opening.proof.compress();
let expected_proof_serialization = hex::decode(expected_proof_hex).unwrap();
assert_eq!(proof_serialization, expected_proof_serialization);

Expand All @@ -301,11 +284,10 @@ mod tests {
// Using f(x) = x, so [f(s)] = [s]
let commitment_element = &setup.in_g1[1];
// Use the same point for input & output
let point = oblast::Fr::from_u64(2);
let point = Fr::from_u64(2);

let polynomial = &polynomial::from_coefficients(
vec![oblast::Fr::from_u64(0), oblast::Fr::from_u64(1)].into_iter(),
);
let polynomial =
&polynomial::from_coefficients(vec![Fr::from_u64(0), Fr::from_u64(1)].into_iter());

let commitment = Commitment {
element: *commitment_element,
Expand All @@ -314,7 +296,7 @@ mod tests {
};

// Therefore the quotient polynomial is q(x) = 1
let proof = oblast::P1::generator();
let proof = P1::generator();

let opening = Opening {
value: point,
Expand Down
9 changes: 0 additions & 9 deletions src/constants.rs

This file was deleted.

5 changes: 2 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
mod commitment;
mod constants;
mod polynomial;
mod setup;

#[cfg(test)]
mod tests {
use super::*;
use oblast;
use oblast::Fr;

#[test]
fn end_to_end() {
Expand All @@ -24,7 +23,7 @@ mod tests {
let commitment = commitment::create(&polynomial, &setup);

// verifier sends over a point
let point = oblast::Fr::from_u64(1234);
let point = Fr::from_u64(1234);

// prover "opens" at that point
let opening = commitment.open_at(point);
Expand Down
12 changes: 6 additions & 6 deletions src/polynomial.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use oblast;
use oblast::Fr;

#[derive(Debug)]
pub struct Polynomial {
// NOTE: low-order coefficients are first in the vector
pub coefficients: Vec<oblast::Fr>,
pub coefficients: Vec<Fr>,
}

impl Polynomial {
pub fn evaluate_at(self: &Self, point: oblast::Fr) -> oblast::Fr {
pub fn evaluate_at(self: &Self, point: Fr) -> Fr {
let mut sum = self.coefficients[0].clone();
let mut powers = point.clone();

Expand All @@ -21,7 +21,7 @@ impl Polynomial {
}
}

pub fn from_coefficients(coefficients: impl Iterator<Item = oblast::Fr>) -> Polynomial {
pub fn from_coefficients(coefficients: impl Iterator<Item = Fr>) -> Polynomial {
Polynomial {
coefficients: coefficients.collect(),
}
Expand All @@ -35,10 +35,10 @@ mod tests {
fn can_eval_polynomial() {
let coefficients = vec![42, 1, 1, 0, 1]
.into_iter()
.map(oblast::Fr::from_u64)
.map(Fr::from_u64)
.collect::<Vec<_>>();
let polynomial = from_coefficients(coefficients.into_iter());
let point = oblast::Fr::from_u64(2);
let point = Fr::from_u64(2);
let result_in_fr = polynomial.evaluate_at(point);
let result = result_in_fr.as_u64();
assert_eq!(result, 64);
Expand Down
19 changes: 9 additions & 10 deletions src/setup.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::constants;
use num_bigint::BigUint;
use oblast;
use oblast::{curve_order, Scalar, P1, P2};
use rand::prelude::*;

#[derive(Debug, PartialEq, Eq)]
pub struct Setup {
pub in_g1: Vec<oblast::P1>,
pub in_g2: oblast::P2,
pub in_g1: Vec<P1>,
pub in_g2: P2,
}

/// Generate a `Setup` with randomness supplied by the `rand` crate.
Expand All @@ -19,7 +18,7 @@ pub fn generate_with_random_secret(degree: usize) -> Setup {

let mut s = BigUint::from_bytes_be(&secret);

let modulus = constants::get_modulus();
let modulus = curve_order();
while s >= modulus {
rng.fill_bytes(&mut secret);
s = BigUint::from_bytes_be(&secret);
Expand All @@ -29,30 +28,30 @@ pub fn generate_with_random_secret(degree: usize) -> Setup {
}

pub fn generate(secret: &[u8; 32], degree: usize) -> Setup {
let modulus = constants::get_modulus();
let modulus = curve_order();
let s = BigUint::from_bytes_be(secret);

assert!(s < modulus, "secret must be less than size of group r");

let mut points_in_g1 = vec![];

let g1 = oblast::P1::generator();
let g1 = P1::generator();
for i in 0..=degree {
let i_as_bigint = BigUint::from_slice(&[i as u32]);
let s_i_as_bigint = s.modpow(&i_as_bigint, &modulus);

let mut s_i_bytes = vec![0u8; 32];
let raw_bytes = s_i_as_bigint.to_bytes_be();
s_i_bytes[32 - raw_bytes.len()..].copy_from_slice(&raw_bytes);
let s_i_scalar = oblast::Scalar::from_fr_bytes(&s_i_bytes);
let s_i_scalar = Scalar::from_fr_bytes(&s_i_bytes);

let result = s_i_scalar * g1;
points_in_g1.push(result);
}

// NOTE: `secret` in Fr via prior `assert`.
let scalar = oblast::Scalar::from_fr_bytes(secret);
let result_in_g2 = scalar * oblast::P2::generator();
let scalar = Scalar::from_fr_bytes(secret);
let result_in_g2 = scalar * P2::generator();

Setup {
in_g1: points_in_g1,
Expand Down

0 comments on commit 52574c3

Please sign in to comment.