Skip to content

Commit

Permalink
Fix use of (multiplicative) group opration, instead of assuming field
Browse files Browse the repository at this point in the history
  • Loading branch information
cmester0 committed Mar 12, 2024
1 parent bf67e20 commit fbe1cd9
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 44 deletions.
3 changes: 3 additions & 0 deletions ovn/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
#![feature(trait_alias)]

pub mod ovn_traits;

pub mod ovn_z_89;
pub mod ovn_secp256k1;
pub mod ovn_group;

pub mod ovn_zk_z_89;
pub mod ovn_zkgroup;
111 changes: 111 additions & 0 deletions ovn/src/ovn_zk_z_89.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#![no_std]
#![feature(register_tool)]
#![register_tool(hax)]

#[hax_lib_macros::exclude]
extern crate hax_lib_macros;

#[hax_lib_macros::exclude]
use hax_lib_macros::*;

#[exclude]
use hacspec_concordium::*;
#[exclude]
use hacspec_concordium_derive::*;

use group::*;

////////////////////
// Impl for Z/89Z //
////////////////////

pub struct z_89 (u32);

// impl Group for z_89 {

// }

// #[derive(Clone, Copy)]
// pub struct z_89 {}
// impl Z_Field for z_89 {
// type field_type = u32;
// fn q() -> Self::field_type {
// 89u32
// } // Prime order
// fn random_field_elem(random: u32) -> Self::field_type {
// random % (Self::q() - 1)
// }

// fn field_zero() -> Self::field_type {
// 0u32
// }

// fn field_one() -> Self::field_type {
// 1u32
// }

// fn add(x: Self::field_type, y: Self::field_type) -> Self::field_type {
// (x + y) % (Self::q() - 1)
// }

// fn sub(x: Self::field_type, y: Self::field_type) -> Self::field_type {
// (x + (Self::q() - 1) - y) % (Self::q() - 1)
// }

// fn mul(x: Self::field_type, y: Self::field_type) -> Self::field_type {
// (x * y) % (Self::q() - 1)
// }
// }

// #[derive(Clone, Copy)]
// pub struct g_z_89 {}
// impl Group<z_89> for g_z_89 {
// type group_type = u32;

// fn g() -> Self::group_type {
// 3u32
// } // Generator (elemnent of group)

// fn hash(x: Vec<Self::group_type>) -> <z_89 as Z_Field>::field_type {
// let mut res = z_89::field_one();
// for y in x {
// res = z_89::mul(y, res);
// }
// res // TODO
// }

// fn g_pow(x: <z_89 as Z_Field>::field_type) -> Self::group_type {
// Self::pow(Self::g(), x)
// }

// // TODO: use repeated squaring instead!
// fn pow(g: Self::group_type, x: <z_89 as Z_Field>::field_type) -> Self::group_type {
// let mut result = Self::group_one();
// for i in 0..(x % (z_89::q() - 1)) {
// result = Self::prod(result, g);
// }
// result
// }

// fn group_one() -> Self::group_type {
// 1
// }

// fn prod(x: Self::group_type, y: Self::group_type) -> Self::group_type {
// ((x % z_89::q()) * (y % z_89::q())) % z_89::q()
// }

// fn inv(x: Self::group_type) -> Self::group_type {
// for j in 0..89 {
// if Self::prod(x, j) == Self::group_one() {
// return j;
// }
// }
// assert!(false);
// return x;
// }

// fn div(x: Self::group_type, y: Self::group_type) -> Self::group_type {
// Self::prod(x, Self::inv(y))
// }
// }
62 changes: 31 additions & 31 deletions ovn/src/ovn_zkgroup.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(trait_alias)]

#[hax_lib_macros::exclude]
use hax_lib_macros::*;
Expand All @@ -12,21 +11,22 @@ use ff::Field;
use group::*;
use rand_core::RngCore;

pub trait MGroup = Group + Field;
pub trait MGroup = Group;

fn pow<G: MGroup>(x: G, n: G::Scalar) -> G {
if n == Field::ZERO {
G::identity()
} else {
x * pow(x, n - <G::Scalar as Field>::ONE)
x + pow(x, n - <G::Scalar as Field>::ONE)
}
}

// Multiplicative group?
fn g_pow<G: MGroup>(n: G::Scalar) -> G {
if n == Field::ZERO {
G::identity()
} else {
G::generator() * g_pow::<G>(n - <G::Scalar as Field>::ONE)
G::generator() + g_pow::<G>(n - <G::Scalar as Field>::ONE)
}
}

Expand All @@ -35,7 +35,7 @@ fn hash<G: MGroup>(inp: Vec<G>) -> G::Scalar {
}

fn div<G: MGroup>(x: G, y: G) -> G {
x * y.invert().unwrap()
x - y
}

////////////////////
Expand Down Expand Up @@ -71,7 +71,7 @@ pub fn schnorr_zkp<G: MGroup>(
// https://crypto.stanford.edu/cs355/19sp/lec5.pdf
pub fn schnorr_zkp_validate<G: MGroup>(h: G, pi: SchnorrZKPCommit<G>) -> bool {
pi.schnorr_zkp_c == hash::<G>(vec![G::generator(), h, pi.schnorr_zkp_u])
&& g_pow::<G>(pi.schnorr_zkp_z) == pi.schnorr_zkp_u * pow::<G>(h, pi.schnorr_zkp_c)
&& g_pow::<G>(pi.schnorr_zkp_z) == pi.schnorr_zkp_u + pow::<G>(h, pi.schnorr_zkp_c)
}

#[derive(SchemaType, Clone, Copy)]
Expand Down Expand Up @@ -106,10 +106,10 @@ pub fn zkp_one_out_of_two<G: MGroup>(
let d1 = rand_d;

let x = g_pow::<G>(xi);
let y = pow::<G>(h, xi) * G::generator();
let y = pow::<G>(h, xi) + G::generator();

let a1 = g_pow::<G>(r1) * pow::<G>(x, d1);
let b1 = pow::<G>(h, r1) * pow::<G>(y, d1);
let a1 = g_pow::<G>(r1) + pow::<G>(x, d1);
let b1 = pow::<G>(h, r1) + pow::<G>(y, d1);

let a2 = g_pow::<G>(w);
let b2 = pow::<G>(h, w);
Expand Down Expand Up @@ -142,8 +142,8 @@ pub fn zkp_one_out_of_two<G: MGroup>(
let a1 = g_pow::<G>(w);
let b1 = pow::<G>(h, w);

let a2 = g_pow::<G>(r2) * pow::<G>(x, d2);
let b2 = pow::<G>(h, r2) * pow::<G>(div::<G>(y, G::generator()), d2);
let a2 = g_pow::<G>(r2) + pow::<G>(x, d2);
let b2 = pow::<G>(h, r2) + pow::<G>(div::<G>(y, G::generator()), d2);

let c = hash::<G>(vec![x, y, a1, b1, a2, b2]);

Expand Down Expand Up @@ -178,12 +178,12 @@ pub fn zkp_one_out_of_two_validate<G: MGroup>(h: G, zkp: OrZKPCommit<G>) -> bool
]); // TODO: add i

(c == zkp.or_zkp_d1 + zkp.or_zkp_d2
&& zkp.or_zkp_a1 == g_pow::<G>(zkp.or_zkp_r1) * pow::<G>(zkp.or_zkp_x, zkp.or_zkp_d1)
&& zkp.or_zkp_b1 == pow::<G>(h, zkp.or_zkp_r1) * pow::<G>(zkp.or_zkp_y, zkp.or_zkp_d1)
&& zkp.or_zkp_a2 == g_pow::<G>(zkp.or_zkp_r2) * pow::<G>(zkp.or_zkp_x, zkp.or_zkp_d2)
&& zkp.or_zkp_a1 == g_pow::<G>(zkp.or_zkp_r1) + pow::<G>(zkp.or_zkp_x, zkp.or_zkp_d1)
&& zkp.or_zkp_b1 == pow::<G>(h, zkp.or_zkp_r1) + pow::<G>(zkp.or_zkp_y, zkp.or_zkp_d1)
&& zkp.or_zkp_a2 == g_pow::<G>(zkp.or_zkp_r2) + pow::<G>(zkp.or_zkp_x, zkp.or_zkp_d2)
&& zkp.or_zkp_b2
== pow::<G>(h, zkp.or_zkp_r2)
* pow::<G>(div::<G>(zkp.or_zkp_y, G::generator()), zkp.or_zkp_d2))
+ pow::<G>(div::<G>(zkp.or_zkp_y, G::generator()), zkp.or_zkp_d2))
}

pub fn commit_to<G: MGroup>(g_pow_xi_yi_vi: G) -> G::Scalar {
Expand Down Expand Up @@ -214,23 +214,23 @@ pub struct OvnContractState<G: MGroup, const n: usize> {
pub fn init_ovn_contract<G: MGroup, const n: usize>(// _: &impl HasInitContext,
) -> InitResult<OvnContractState<G, n>> {
Ok(OvnContractState::<G, n> {
g_pow_xis: [<G as Field>::ONE; n],
g_pow_xis: [G::identity(); n],
zkp_xis: [SchnorrZKPCommit::<G> {
schnorr_zkp_u: <G as Field>::ONE,
schnorr_zkp_u: G::identity(),
schnorr_zkp_z: G::Scalar::ZERO,
schnorr_zkp_c: G::Scalar::ZERO,
}; n],

commit_vis: [G::Scalar::ZERO; n],

g_pow_xi_yi_vis: [<G as Field>::ONE; n],
g_pow_xi_yi_vis: [G::identity(); n],
zkp_vis: [OrZKPCommit::<G> {
or_zkp_x: <G as Field>::ONE,
or_zkp_y: <G as Field>::ONE,
or_zkp_a1: <G as Field>::ONE,
or_zkp_b1: <G as Field>::ONE,
or_zkp_a2: <G as Field>::ONE,
or_zkp_b2: <G as Field>::ONE,
or_zkp_x: G::identity(),
or_zkp_y: G::identity(),
or_zkp_a1: G::identity(),
or_zkp_b1: G::identity(),
or_zkp_a2: G::identity(),
or_zkp_b2: G::identity(),

or_zkp_c: G::Scalar::ZERO,

Expand Down Expand Up @@ -289,14 +289,14 @@ pub struct CastVoteParam<Z: Field + Serialize> {
}

pub fn compute_g_pow_yi<G: MGroup, const n: usize>(i: usize, xis: [G; n]) -> G {
let mut prod1 = <G as Field>::ONE;
let mut prod1 = G::identity();
for j in 0..i {
prod1 = prod1 * xis[j];
prod1 = prod1 + xis[j];
}

let mut prod2 = <G as Field>::ONE;
let mut prod2 = G::identity();
for j in (i + 1)..n {
prod2 = prod2 * xis[j];
prod2 = prod2 + xis[j];
}

// implicitly: Y_i = g^y_i
Expand All @@ -306,7 +306,7 @@ pub fn compute_g_pow_yi<G: MGroup, const n: usize>(i: usize, xis: [G; n]) -> G {

pub fn compute_group_element_for_vote<G: MGroup>(xi: G::Scalar, vote: bool, g_pow_yi: G) -> G {
pow::<G>(g_pow_yi, xi)
* g_pow::<G>(if vote {
+ g_pow::<G>(if vote {
G::Scalar::ONE
} else {
G::Scalar::ZERO
Expand Down Expand Up @@ -386,9 +386,9 @@ pub fn tally_votes<G: MGroup, const n: usize, A: HasActions>(
}
}

let mut vote_result = <G as Field>::ONE;
let mut vote_result = G::identity();
for g_pow_vote in state.g_pow_xi_yi_vis {
vote_result = vote_result * g_pow_vote;
vote_result = vote_result + g_pow_vote;
}

let mut tally = 0;
Expand Down
18 changes: 5 additions & 13 deletions ovn/tests/ovn_zk_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,16 @@ extern crate quickcheck_macros;
#[cfg(test)]
use quickcheck::*;

pub use bls12_381::*;
pub use hacspec_ovn::ovn_zkgroup::*;
pub use group::ff::Field;
// pub use bls12_381::*;
// pub use hacspec_ovn::ovn_zkgroup::*;
// pub use group::ff::Field;

struct bls_g_ty (Gt);

impl Field for bls_g_ty {

}

impl Group for bls_g_ty {

}
use hacspec_bip_340::*;

#[test]
pub fn schorr_zkp_correctness() {
fn test(random_x: u32, random_r: u32) -> bool {
type G = bls_g_ty;
type G = Point;

let x: u32 = G::random(random_x);
// let pow_x = G::g_pow(x);
Expand Down

0 comments on commit fbe1cd9

Please sign in to comment.