Skip to content

Commit

Permalink
c switched to be hash in the crates
Browse files Browse the repository at this point in the history
`c` conversion to number / field element moved to consuming functions
more like it's in <./javascript> now
  • Loading branch information
skaunov authored Sep 24, 2023
1 parent e7490a8 commit f787cb3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 46 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ If you would like to get a grant to create PLUME applications or help to fix bug

## Contributions

If you'd like to contribute, we offer $50 bounties in Eth/DAI for resolving any of the bugs in our issues! Each of them is quite small. That includes [#28](https://github.com/plume-sig/zk-nullifier-sig/issues/28), [#24](https://github.com/plume-sig/zk-nullifier-sig/issues/24), [#23](https://github.com/plume-sig/zk-nullifier-sig/issues/23), [#22](https://github.com/plume-sig/zk-nullifier-sig/issues/22), [#20](https://github.com/plume-sig/zk-nullifier-sig/issues/20), [#19](https://github.com/plume-sig/zk-nullifier-sig/issues/19), [#18](https://github.com/plume-sig/zk-nullifier-sig/issues/18), [#17](https://github.com/plume-sig/zk-nullifier-sig/issues/17), [#16](https://github.com/plume-sig/zk-nullifier-sig/issues/16), [#15](https://github.com/plume-sig/zk-nullifier-sig/issues/15), [#14](https://github.com/plume-sig/zk-nullifier-sig/issues/14),and [#13](https://github.com/plume-sig/zk-nullifier-sig/issues/13).
If you'd like to contribute, we offer $50 bounties in Eth/DAI for resolving any of the bugs in our issues! Each of them is quite small. That includes [#28](https://github.com/plume-sig/zk-nullifier-sig/issues/28), [#24](https://github.com/plume-sig/zk-nullifier-sig/issues/24), [#22](https://github.com/plume-sig/zk-nullifier-sig/issues/22), [#20](https://github.com/plume-sig/zk-nullifier-sig/issues/20), [#19](https://github.com/plume-sig/zk-nullifier-sig/issues/19), [#18](https://github.com/plume-sig/zk-nullifier-sig/issues/18), [#17](https://github.com/plume-sig/zk-nullifier-sig/issues/17), [#16](https://github.com/plume-sig/zk-nullifier-sig/issues/16), [#15](https://github.com/plume-sig/zk-nullifier-sig/issues/15), [#14](https://github.com/plume-sig/zk-nullifier-sig/issues/14),and [#13](https://github.com/plume-sig/zk-nullifier-sig/issues/13).

## Implementations

Expand Down
43 changes: 13 additions & 30 deletions rust-arkworks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@ pub mod sig {
Ok(hash_to_curve::hash_to_curve::<Fq, P>(message, pk))
}

// TODO [replace SHA-512](https://github.com/plume-sig/zk-nullifier-sig/issues/39#issuecomment-1732497672)
fn compute_c_v1<P: SWModelParameters>(
g: &GroupAffine<P>,
pk: &GroupAffine<P>,
h: &GroupAffine<P>,
nul: &GroupAffine<P>,
g_r: &GroupAffine<P>,
z: &GroupAffine<P>,
) -> P::ScalarField {
// should be `Output<Sha256>` when tests are fixed <https://github.com/plume-sig/zk-nullifier-sig/issues/39#issuecomment-1732538695>
) -> Vec<u8> {
// Compute c = sha512([g, pk, h, nul, g^r, z])
let g_bytes = affine_to_bytes::<P>(g);
let pk_bytes = affine_to_bytes::<P>(pk);
Expand All @@ -68,26 +70,16 @@ pub mod sig {

let mut sha512_hasher = Sha512::new();
sha512_hasher.update(c_preimage_vec.as_slice());
let sha512_hasher_result = sha512_hasher.finalize();

// Take the first 32 bytes
let mut first_32 = Vec::<u8>::with_capacity(32);
for i in 0..32 {
first_32.push(sha512_hasher_result[i]);
}

// Convert digest bytes to a scalar
let c = first_32.as_slice();
let c_be = P::ScalarField::from_be_bytes_mod_order(c);

P::ScalarField::from(c_be)
sha512_hasher.finalize()[0..32].to_owned()
}

// TODO [replace SHA-512](https://github.com/plume-sig/zk-nullifier-sig/issues/39#issuecomment-1732497672)
fn compute_c_v2<P: SWModelParameters>(
nul: &GroupAffine<P>,
g_r: &GroupAffine<P>,
z: &GroupAffine<P>,
) -> P::ScalarField {
// should be `Output<Sha256>` when tests are fixed <https://github.com/plume-sig/zk-nullifier-sig/issues/39#issuecomment-1732538695>
) -> Vec<u8> {
// Compute c = sha512([nul, g^r, z])
let nul_bytes = affine_to_bytes::<P>(nul);
let g_r_bytes = affine_to_bytes::<P>(g_r);
Expand All @@ -97,19 +89,7 @@ pub mod sig {

let mut sha512_hasher = Sha512::new();
sha512_hasher.update(c_preimage_vec.as_slice());
let sha512_hasher_result = sha512_hasher.finalize();

// Take the first 32 bytes
let mut first_32 = Vec::<u8>::with_capacity(32);
for i in 0..32 {
first_32.push(sha512_hasher_result[i]);
}

// Convert digest bytes to a scalar
let c = first_32.as_slice();
let c_be = P::ScalarField::from_be_bytes_mod_order(c);

P::ScalarField::from(c_be)
sha512_hasher.finalize()[0..32].to_owned()
}

pub trait VerifiableUnpredictableFunction {
Expand Down Expand Up @@ -214,10 +194,11 @@ pub mod sig {
let nul = h.mul(*keypair.1).into_affine();

// Compute c = sha512([g, pk, h, nul, g^r, z])
let c_scalar: P::ScalarField = match version {
let c = match version {
PlumeVersion::V1 => compute_c_v1::<P>(&g, keypair.0, &h, &nul, &g_r, &z),
PlumeVersion::V2 => compute_c_v2(&nul, &g_r, &z),
};
let c_scalar = P::ScalarField::from_be_bytes_mod_order(c.as_ref());
// Compute s = r + sk ⋅ c
let sk_c = keypair.1.into_repr().into() * c_scalar.into_repr().into();
let s = r.into_repr().into() + sk_c;
Expand Down Expand Up @@ -257,12 +238,14 @@ pub mod sig {
// Compute h = htc([m, pk])
let h = compute_h::<C, Fq, P>(pk, message).unwrap();

// TODO [replace SHA-512](https://github.com/plume-sig/zk-nullifier-sig/issues/39#issuecomment-1732497672)
// Compute c' = sha512([g, pk, h, nul, g^r, z]) for v1
// c' = sha512([nul, g^r, z]) for v2
let c_scalar: P::ScalarField = match version {
let c = match version {
PlumeVersion::V1 => compute_c_v1::<P>(&pp.g, pk, &h, &sig.nul, &sig.g_r, &sig.z),
PlumeVersion::V2 => compute_c_v2(&sig.nul, &sig.g_r, &sig.z),
};
let c_scalar = P::ScalarField::from_be_bytes_mod_order(c.as_ref());

// Reject if g^s ⋅ pk^{-c} != g^r
let g_s = pp.g.mul(sig.s);
Expand Down
34 changes: 19 additions & 15 deletions rust-k256/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
// #![feature(generic_const_expr)]
// #![allow(incomplete_features)]

use digest::Output;
use elliptic_curve::bigint::ArrayEncoding;
use elliptic_curve::hash2curve::{ExpandMsgXmd, GroupDigest};
use elliptic_curve::ops::Reduce;
use elliptic_curve::sec1::ToEncodedPoint;
use hex_literal::hex;
use k256::U256;
use k256::{
// ecdsa::{signature::Signer, Signature, SigningKey},
elliptic_curve::group::ff::PrimeField,
Expand Down Expand Up @@ -47,18 +51,15 @@ fn gen_test_scalar_r() -> Scalar {
.unwrap()
}

fn sha256hash_vec_signal(values: &[ProjectivePoint]) -> Scalar {
fn sha256hash_vec_signal(values: &[ProjectivePoint]) -> Output<Sha256> {
let preimage_vec = values
.iter()
.map(|value| encode_pt(*value).unwrap())
.collect::<Vec<_>>()
.concat();
let mut sha256_hasher = Sha256::new();
sha256_hasher.update(preimage_vec.as_slice());
let sha512_hasher_result = sha256_hasher.finalize(); //256 bit hash

let bytes = FieldBytes::from_iter(sha512_hasher_result.iter().copied());
Scalar::from_repr(bytes).unwrap()
sha256_hasher.finalize() //256 bit hash
}

fn sha256hash6signals(
Expand Down Expand Up @@ -123,7 +124,7 @@ fn verify_signals(
m: &[u8],
pk: &ProjectivePoint,
nullifier: &ProjectivePoint,
c: &Scalar,
c: &Output<Sha256>,
r_sk_c: &Scalar,
g_r_option: &Option<ProjectivePoint>,
hash_m_pk_pow_r_option: &Option<ProjectivePoint>,
Expand All @@ -139,27 +140,29 @@ fn verify_signals(

// Check whether g^r equals g^s * pk^{-c}
let g_r: ProjectivePoint;
// TODO should we use non-zero `Scalar`?
let c_scalar = &Scalar::from_uint_reduced(U256::from_be_byte_array(*c));
match *g_r_option {
Some(_g_r_value) => {
if (g * r_sk_c - pk * c) != _g_r_value {
if (g * r_sk_c - pk * c_scalar) != _g_r_value {
verified = false;
}
}
None => println!("g^r not provided, check skipped"),
}
g_r = g * r_sk_c - pk * c;
g_r = g * r_sk_c - pk * c_scalar;

// Check whether h^r equals h^{r + sk * c} * nullifier^{-c}
let hash_m_pk_pow_r: ProjectivePoint;
match *hash_m_pk_pow_r_option {
Some(_hash_m_pk_pow_r_value) => {
if (hash_m_pk * r_sk_c - nullifier * c) != _hash_m_pk_pow_r_value {
if (hash_m_pk * r_sk_c - nullifier * c_scalar) != _hash_m_pk_pow_r_value {
verified = false;
}
}
None => println!("hash_m_pk_pow_r not provided, check skipped"),
}
hash_m_pk_pow_r = hash_m_pk * r_sk_c - nullifier * c;
hash_m_pk_pow_r = hash_m_pk * r_sk_c - nullifier * c_scalar;

// Check if the given hash matches
match version {
Expand Down Expand Up @@ -221,7 +224,7 @@ mod tests {
) -> (
ProjectivePoint,
ProjectivePoint,
Scalar,
Output<Sha256>,
Scalar,
Option<ProjectivePoint>,
Option<ProjectivePoint>,
Expand Down Expand Up @@ -286,8 +289,10 @@ mod tests {
}
PlumeVersion::V2 => sha256hash_vec_signal(&[nullifier, g_r, hash_m_pk_pow_r]),
};

let c_scalar = &Scalar::from_uint_reduced(U256::from_be_byte_array(c.clone()));
// This value is part of the discrete log equivalence (DLEQ) proof.
let r_sk_c = r + sk * c;
let r_sk_c = r + sk * c_scalar;

// Return the signature.
(pk, nullifier, c, r_sk_c, Some(g_r), Some(hash_m_pk_pow_r))
Expand Down Expand Up @@ -337,7 +342,7 @@ mod tests {
);

// Print c
println!("c: {:?}", hex::encode(&c.to_bytes()));
println!("c: {:?}", hex::encode(&c));

// Print r_sk_c
println!("r_sk_c: {:?}", hex::encode(r_sk_c.to_bytes()));
Expand Down Expand Up @@ -396,8 +401,7 @@ mod tests {
);

// Test byte_array_to_scalar()
let bytes_to_convert = c.to_bytes();
let scalar = byte_array_to_scalar(&bytes_to_convert);
let scalar = byte_array_to_scalar(&c); // TODO this `fn` looks suspicious as in reproducing const time ops
assert_eq!(
hex::encode(scalar.to_bytes()),
"c6a7fc2c926ddbaf20731a479fb6566f2daa5514baae5223fe3b32edbce83254"
Expand Down

0 comments on commit f787cb3

Please sign in to comment.