-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1. Freivalds Algorithm 2. Reed Solomon Fingerprint 3. univariate lagrange polynomial 1. encoding a using it as coeffients 2. using lagrange polynomail with (domain, evaluation) Left a error. Fix it later.
- Loading branch information
1 parent
199adc1
commit 9da0757
Showing
28 changed files
with
835 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,4 +14,7 @@ Cargo.lock | |
*.pdb | ||
|
||
.idea | ||
.vscode | ||
.vscode | ||
|
||
# ignore tmp dump data | ||
**/*.bin |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "Freivalds_Algorithm" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
ff = "0.13.0" | ||
bls12_381 = "0.8.0" | ||
rand = "0.8.5" | ||
rand_core = { version = "0.6.4", default-features = false, features = ["std"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use crate::matrix::Matrix; | ||
use crate::prover::Prover; | ||
use crate::utils::gen_x; | ||
use rand_core::OsRng; | ||
|
||
mod matrix; | ||
/// For matrix A and B, C = A · B. | ||
/// | ||
/// How can one verify that two matrices were multiplied correctly. | ||
/// First,choose a random `r∈Fp`,and let x=(1,r,r2,...,rn−1). | ||
/// Then compute `y=Cx` and `z=A·Bx`,outputting YES if y = z and NO otherwise. | ||
mod prover; | ||
mod utils; | ||
mod verifier; | ||
|
||
#[test] | ||
fn completeness() { | ||
let n: usize = std::env::var("n") | ||
.unwrap_or_else(|_| "4".to_string()) | ||
.parse() | ||
.expect("Cannot parse DEGREE env var as u32"); | ||
|
||
// prover | ||
let alice = Prover::random(n); | ||
// C = A · B | ||
let c = alice.matrix_multiplication(); | ||
|
||
let x = gen_x(OsRng, n); | ||
// z=A·Bx | ||
let z = alice.hash(&x); | ||
|
||
// verify | ||
// y=Cx | ||
let y = c.matrix_mul_vec(&x); | ||
|
||
assert_eq!(z, y); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
use bls12_381::Scalar; | ||
use ff::Field; | ||
use rand_core::{OsRng, RngCore}; | ||
use std::ops::AddAssign; | ||
|
||
/// This define `matrix` (rows * cols) (m × n) | ||
#[derive(Debug, Clone)] | ||
pub struct Matrix { | ||
rows: usize, | ||
cols: usize, | ||
// columns | ||
values: Vec<Vec<Scalar>>, | ||
} | ||
|
||
impl Matrix { | ||
pub fn random(rows: usize, cols: usize) -> Self { | ||
let values = (0..rows) | ||
.map(|_| (0..cols).map(|_| Scalar::random(OsRng)).collect::<Vec<_>>()) | ||
.collect::<Vec<_>>(); | ||
|
||
Self { cols, rows, values } | ||
} | ||
|
||
fn get_columns(&self, column_index: usize) -> Vec<Scalar> { | ||
assert!(0 <= column_index || self.cols > column_index); | ||
|
||
self.values | ||
.iter() | ||
.map(|v| v.get(column_index).unwrap().clone()) | ||
.collect::<Vec<_>>() | ||
} | ||
|
||
fn vec_mul(a: &Vec<Scalar>, b: &Vec<Scalar>) -> Scalar { | ||
assert_eq!(a.len(), b.len()); | ||
|
||
let mut res = Scalar::zero(); | ||
for (ai, bi) in a.into_iter().zip(b) { | ||
let producti = ai.mul(bi); | ||
res.add_assign(producti); | ||
} | ||
res | ||
} | ||
|
||
/// https://en.wikipedia.org/wiki/Dot_product | ||
/// Suppose A(m * n), x(n) => A * x = y(n) | ||
pub fn matrix_mul_vec(&self, vector: &Vec<Scalar>) -> Vec<Scalar> { | ||
assert_eq!(self.cols, vector.len()); | ||
let n = self.cols; | ||
|
||
let mut result: Vec<Scalar> = Vec::with_capacity(n); | ||
for i in 0..self.rows { | ||
let row_i = self.values.get(i).unwrap().clone(); | ||
|
||
let elem = Self::vec_mul(&row_i, vector); | ||
|
||
result.push(elem); | ||
} | ||
|
||
result | ||
} | ||
|
||
/// https://en.wikipedia.org/wiki/Dot_product | ||
/// Suppose A(m * n), B(n, p) => A * B = C(m * p) | ||
pub fn mul(m_a: &Matrix, m_b: &Matrix) -> Self { | ||
assert!(m_a.cols > 0 || m_b.rows > 0, "matrix a is empty"); | ||
assert!(m_b.cols > 0 || m_b.rows > 0, "matrix a is empty"); | ||
// ma.cols == mb.rows | ||
assert_eq!(m_a.cols, m_b.rows); | ||
let m = m_a.rows; | ||
let n = m_a.cols; | ||
// let n = m_b.rows; | ||
let p = m_b.cols; | ||
|
||
let mut matrix: Vec<Vec<Scalar>> = Vec::with_capacity(m); | ||
for i in 0..m { | ||
let mut new_row = Vec::with_capacity(p); | ||
|
||
let row_i = m_a.values.get(i).unwrap().clone(); | ||
for j in 0..p { | ||
// todo: this can be optimized by converting m_b columns as rows | ||
let col_j = m_b.get_columns(j); | ||
let elem_ij = Self::vec_mul(&row_i, &col_j); | ||
new_row.push(elem_ij); | ||
} | ||
|
||
matrix.push(new_row); | ||
} | ||
|
||
Self { | ||
rows: m, | ||
cols: p, | ||
values: matrix, | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use crate::matrix::Matrix; | ||
use bls12_381::Scalar; | ||
|
||
#[test] | ||
fn test_random_matrix() { | ||
let matrix = Matrix::random(3, 4); | ||
println!("{:#?}", matrix); | ||
} | ||
|
||
#[test] | ||
fn test_matrix_mul() { | ||
let m: usize = 2; | ||
let mut values: Vec<Vec<Scalar>> = Vec::with_capacity(m); | ||
let mut row_1: Vec<Scalar> = Vec::with_capacity(m); | ||
row_1.push(Scalar::one()); | ||
row_1.push(Scalar::zero()); | ||
let mut row_2: Vec<Scalar> = Vec::with_capacity(m); | ||
row_2.push(Scalar::zero()); | ||
row_2.push(Scalar::one()); | ||
values.push(row_1); | ||
values.push(row_2); | ||
|
||
let a = Matrix { | ||
rows: m, | ||
cols: m, | ||
values, | ||
}; | ||
let b = a.clone(); | ||
|
||
let res = Matrix::mul(&a, &b); | ||
assert_eq!(a.values, res.values); | ||
println!("{:#?}", res); | ||
} | ||
|
||
#[test] | ||
fn test_matrix_mul_vec() { | ||
let m: usize = 2; | ||
let mut values: Vec<Vec<Scalar>> = Vec::with_capacity(m); | ||
let mut row_1: Vec<Scalar> = Vec::with_capacity(m); | ||
row_1.push(Scalar::one()); | ||
row_1.push(Scalar::zero()); | ||
let mut row_2: Vec<Scalar> = Vec::with_capacity(m); | ||
row_2.push(Scalar::zero()); | ||
row_2.push(Scalar::one()); | ||
values.push(row_1.clone()); | ||
values.push(row_2); | ||
|
||
let a = Matrix { | ||
rows: m, | ||
cols: m, | ||
values, | ||
}; | ||
let b = a.clone(); | ||
|
||
let res = a.matrix_mul_vec(&row_1); | ||
assert_eq!(row_1, res); | ||
println!("{:#?}", res); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use crate::matrix::Matrix; | ||
use bls12_381::Scalar; | ||
use ff::Field; | ||
|
||
pub struct Prover { | ||
a: Matrix, | ||
b: Matrix, | ||
} | ||
|
||
impl Prover { | ||
pub fn random(n: usize) -> Self { | ||
Self { | ||
a: Matrix::random(n, n), | ||
b: Matrix::random(n, n), | ||
} | ||
} | ||
|
||
pub fn matrix_multiplication(&self) -> Matrix { | ||
Matrix::mul(&self.a, &self.b) | ||
} | ||
|
||
pub fn hash(&self, x: &Vec<Scalar>) -> Vec<Scalar> { | ||
// tmp = Ax | ||
let tmp = self.a.matrix_mul_vec(x); | ||
// z = B temp | ||
self.b.matrix_mul_vec(&tmp) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use crate::matrix::Matrix; | ||
use bls12_381::Scalar; | ||
use ff::Field; | ||
use rand_core::RngCore; | ||
use std::ops::MulAssign; | ||
|
||
/// x=(1,r,r2,...,rn−1) | ||
pub fn gen_x(rng: impl RngCore, n: usize) -> Vec<Scalar> { | ||
let r: Scalar = Scalar::random(rng); | ||
|
||
let mut cur_r = Scalar::one(); | ||
(0..n) | ||
.map(|_| { | ||
let res = cur_r; | ||
cur_r.mul_assign(r); | ||
res | ||
}) | ||
.collect::<Vec<_>>() | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use bls12_381::Scalar; | ||
use ff::Field; | ||
use rand_core::OsRng; | ||
use std::ops::MulAssign; | ||
|
||
#[test] | ||
fn test_gen_x() { | ||
let n = 4; | ||
|
||
let r: Scalar = Scalar::random(OsRng); | ||
|
||
let target = vec![Scalar::one(), r, r.mul(&r), r.mul(&r).mul(&r)]; | ||
|
||
// Param::gen_x | ||
let mut cur_r = Scalar::one(); | ||
let x = (0..n) | ||
.map(|_| { | ||
let res = cur_r; | ||
cur_r.mul_assign(r); | ||
res | ||
}) | ||
.collect::<Vec<_>>(); | ||
|
||
assert_eq!(target, x); | ||
println!("{:?}", x); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "Reed_Solomon_Fingerprinting" | ||
version = "0.1.0" | ||
edition = "2021" | ||
description = "The Reed-Solomon Fingerprinting case(2.1) in chapter 2" | ||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
ff = "0.13.0" | ||
bls12_381 = "0.8.0" | ||
rand = "0.8.5" | ||
rand_core = { version = "0.6.4", default-features = false, features = ["std"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use crate::prover::Prover; | ||
/// The Reed-Solomon Fingerprinting case(2.1) in chapter 2 | ||
/// In this case, we'll check whether Alice and Bob has the same file by checking RS-fingerprint. | ||
use crate::utils::{dump_field_data, read_from_file}; | ||
use crate::verify::Verifier; | ||
use bls12_381::Scalar; | ||
use ff::Field; | ||
use rand_core::{OsRng, RngCore}; | ||
|
||
mod prover; | ||
mod utils; | ||
mod verify; | ||
|
||
#[derive(Default, Eq, PartialEq)] | ||
pub(crate) struct Person { | ||
data: Vec<Scalar>, | ||
} | ||
|
||
impl Person { | ||
pub(crate) fn new(file_name: &str) -> Self { | ||
let data = read_from_file(file_name); | ||
Self { data } | ||
} | ||
} | ||
|
||
const file_A: &str = "file_A.bin"; | ||
const file_B: &str = "file_B.bin"; | ||
|
||
fn prepare_data() { | ||
let length = 10 + OsRng.next_u64() % 90; | ||
dump_field_data(file_A, 10 + length); | ||
dump_field_data(file_B, 10 + 2 * length); | ||
} | ||
|
||
#[test] | ||
fn completeness() { | ||
prepare_data(); | ||
|
||
let Alice = Person::new(file_A); | ||
let Bob = Person::new(file_A); | ||
|
||
// Alice RS fingerprint | ||
let r = Person::challenge(); | ||
let fingerprint = Alice.fs_hash(r.clone()); | ||
|
||
// Bob check it | ||
let result = Bob.verify(r, fingerprint); | ||
|
||
assert!(result, "They are not same."); | ||
} | ||
|
||
#[test] | ||
fn soundness() { | ||
prepare_data(); | ||
|
||
let Alice = Person::new(file_A); | ||
let Bob = Person::new(file_B); | ||
|
||
// use the prover trait by alice | ||
|
||
// Alice RS fingerprint | ||
let r = Person::challenge(); | ||
let fingerprint = Alice.fs_hash(r.clone()); | ||
|
||
// Bob check it | ||
let result = Bob.verify(r, fingerprint); | ||
|
||
assert!(!result, "They are same."); | ||
} |
Oops, something went wrong.