Browse Source

dleq proof working

pull/8/head
Nanak Nihal Singh Khalsa 11 months ago
parent
commit
c0b4f7888f
1 changed files with 42 additions and 86 deletions
  1. +42
    -86
      src/lib.rs

+ 42
- 86
src/lib.rs

@ -3,7 +3,7 @@
use ff::*;
use rand::ThreadRng;
use std::{iter::Sum, ops::{Neg, AddAssign}};
use std::{iter::Sum, ops::{Neg, AddAssign}, fmt::Error};
use num::Num;
use std::fmt;
// use serde::{Serialize, ser::SerializeSeq, Deserialize};
@ -213,6 +213,7 @@ pub trait FrBigIntConversion {
impl FrBigIntConversion<Fr> for Fr {
// Note: this could probably be more efficient by converting bigint to raw repr to Fr
fn from_bigint(bi: &BigInt) -> Fr {
println!("bi: {}", bi.to_string());
Fr::from_str(&bi.to_string()).unwrap()
}
fn to_bigint(&self) -> BigInt {
@ -736,108 +737,65 @@ pub struct DLEQProof {
pub B: Point,
pub xA: Point,
pub xB: Point,
pub challenge: BigInt,
pub response: BigInt,
pub challenge: Fl,
pub response: Fl,
}
impl DLEQProof {
// Prove that ∃ x s.t. x*A = variable xA and x*B = variable xB
pub fn new(x: BigInt, point_A: Point, point_B: Point) -> DLEQProof {
let xA = point_A.mul_scalar(&x);
let xB = point_B.mul_scalar(&x);
let mut rng = rand_new::thread_rng();
let k = rng.gen_biguint(512).to_bigint().unwrap() % Q.clone();
let kA = point_A.mul_scalar(&k);
let kB = point_B.mul_scalar(&k);
// Prove x*A = variable xA and x*B = variable xB
pub fn new(x: Fl, point_A: Point, point_B: Point) -> Result<DLEQProof, Error> {
let x_bigint = x.to_bigint();
let challenge = DLEQProof::get_challenge(&point_A, &point_B, &xA, &xB, &kA, &kB);
// let modulus_overflowed = ORDER.clone(); // TODO: shouldn't this be the subgroup order? This is not order of Babyjubjub curve nor the subgroup; it's the order Babyjubjub is defined over
let modulus = SUBORDER.clone();
// TODO: better error handling (not assert), make it more efficient too:
assert!(x_bigint < modulus);
let k_field = Fr::from_str(&k.to_string()).unwrap();
let x_field = Fr::from_str(&k.to_string()).unwrap();
let challenge_field = Fr::from_str(&challenge.to_string()).unwrap();
let mut response_field = challenge_field.clone();
response_field.negate();
response_field.mul_assign(&x_field);
response_field.add_assign(&k_field);
// let response = Fr::from k - &challenge * &x) % Q.clone();
// let response = BigInt::from_str("-10").unwrap();//(ORDER_BI.clone() + BigInt::from_str("100").unwrap()).neg();
let response = response_field.to_bigint();
println!("response: {:?}", response);
// -7:
// let neg7 = "-7".parse::<BigInt>().unwrap();
// let neg7_ = Q.clone() + &neg7;
// let product = B8.mul_scalar(&neg7);
// let product_ = B8.mul_scalar(&neg7_);
// println!("\nproduct: {:?} ====================== {:?} \n", product.x, product_.x);
// println!("modulus overflow? isn't it bigger than Fr's order: {:?}", modulus_overflowed);
let k_bigint = rand_new::thread_rng().gen_biguint(512).to_bigint().unwrap() % &modulus;
let k = Fl::from_bigint(&k_bigint);
// let cxA = xA.mul_scalar(&challenge);
// let cxA_ = point_A.mul_scalar(&challenge).mul_scalar(&x);
// println!("cxA: {:?} ====================== {:?} ", cxA, cxA_);
let xA = point_A.mul_scalar(&x_bigint);
let xB = point_B.mul_scalar(&x_bigint);
let xchallenge = &x * &challenge;
let response_plus_xchallenge = &response + &xchallenge;
let kA = point_A.mul_scalar(&k_bigint);
let kB = point_B.mul_scalar(&k_bigint);
let xchallengeA = point_A.mul_scalar(&xchallenge);
let responseA = point_A.mul_scalar(&response);
let sum_method1 = responseA.add(&xchallengeA);
let sum_method2 = point_A.mul_scalar(&(response_plus_xchallenge));
// DELETE THIS:
// let kA1 = point_A.mul_scalar(&(&response + &challenge * &x));
// let kA2 = point_A.mul_scalar(&response).add(
// &point_A.mul_scalar(&(&challenge * &x))
// );
// let _a = Q.clone() - BigInt::from_str("10").unwrap();
// let _b = BigInt::from_str("2000").unwrap();
// let _A = B8.mul_scalar(&_a);
// let _B = B8.mul_scalar(&_b);
// let _prod = _A.add(&_B);
// let __prod = B8.mul_scalar(&(_a+_b));
// println!("\n\n\n\n\n\nprods: {:?} =================== {:?}\n\n\n\n", _prod.x, __prod.x);
// println!("one {:?}", point_A.mul_scalar(&BigInt::from_bytes_be(Sign::Plus,&[1])).x);
// println!("two {:?}", point_A.mul_scalar(&BigInt::from_bytes_be(Sign::Plus,&[2])).x);
// println!("one {:?}", point_A.mul_scalar(&BigInt::from_bytes_be(Sign::Plus,&[1])).x);
// let kB_ =
// point_B.mul_scalar(&response).add(
// &xA.mul_scalar(&challenge)
// );
// println!("kA==kA_? {:?}. kB==kB_? {:?}", kA_.equals(kA), kB_.equals(kB));
// println!("1x: {:?}\n2x: {:?}", sum_method1.x, sum_method2.x);
println!("kA: {:?}. kB {:?}", kA, kB);
DLEQProof {
let challenge = DLEQProof::get_challenge(&point_A, &point_B, &xA, &xB, &kA, &kB);
let mut challenge_x = challenge.clone(); challenge_x.mul_assign(&x);
// response = k - challenge * x;
let mut response = k.clone(); response.sub_assign(&challenge_x);
Ok(DLEQProof {
A: point_A,
B: point_B,
xA,
xB,
challenge,
response
}
xA: xA,
xB: xB,
challenge: challenge,
response: response,
})
}
pub fn verify(&self) -> bool {
// This should equal kA
let kA_ =
self.A.mul_scalar(&self.response).add(
&self.xA.mul_scalar(&self.challenge)
self.A.mul_scalar(&self.response.to_bigint()).add(
&self.xA.mul_scalar(&self.challenge.to_bigint())
);
// This should equal kB
let kB_ =
self.B.mul_scalar(&self.response).add(
&self.xB.mul_scalar(&self.challenge)
self.B.mul_scalar(&self.response.to_bigint()).add(
&self.xB.mul_scalar(&self.challenge.to_bigint())
);
println!("kA_: {:?}. kB_ {:?}", kA_, kB_);
// Check that kA_ == kA and kB_ == kB by recomputing the challenge and checking that it matches
let challenge = DLEQProof::get_challenge(&self.A, &self.B, &self.xA, &self.xB, &kA_, &kB_);
// println!("got challenge: {:?} which should equal {:?}", challenge, self.challenge);
println!("got challenge: {:?} which should equal {:?}", challenge, self.challenge);
return challenge == self.challenge;
}
// Generates randomness for DLEQ Fiat-Shamir transform
fn get_challenge(point_A: &Point, point_B: &Point, xA: &Point, xB: &Point, kA: &Point, kB: &Point) -> BigInt {
fn get_challenge(point_A: &Point, point_B: &Point, xA: &Point, xB: &Point, kA: &Point, kB: &Point) -> Fl {
// This could probably be faster if we neglect either the x or y coordinate, but rn doing both to be safe until i study this more
let inputs: Vec<Fr> = vec![
point_A.x,point_A.y,
@ -855,9 +813,7 @@ impl DLEQProof {
.collect();
let challenge_hash = blh(&input);
// println!("{:?} is hash of input {:?}", challenge_hash, input);
BigInt::from_bytes_be(Sign::Plus, &challenge_hash.as_slice())
% ORDER_BI.clone()
Fl::from_bigint(&BigInt::from_bytes_be(Sign::Plus, &challenge_hash.as_slice()))
}
}
@ -876,8 +832,8 @@ mod tests {
let point_B = B8.mul_scalar(&b);
let mut rng = rand_new::thread_rng();
let x = rng.gen_biguint(512).to_bigint().unwrap() % ORDER_BI.clone();
let proof = DLEQProof::new(x, point_A, point_B);
let x = Fl::from_bigint(&rng.gen_biguint(512).to_bigint().unwrap());
let proof = DLEQProof::new(x, point_A, point_B).unwrap();
println!("proof: {:?}", proof.verify());
assert!(proof.verify());
}

Loading…
Cancel
Save