mirror of
https://github.com/plume-sig/zk-nullifier-sig.git
synced 2026-01-09 21:08:00 -05:00
moved arkworks impl to this repo
This commit is contained in:
30
rust-arkworks/Cargo.toml
Normal file
30
rust-arkworks/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
[package]
|
||||
name = "sig"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ark-ec = "0.3.0"
|
||||
ark-ff = "0.3.0"
|
||||
ark-std = "0.3.0"
|
||||
ark-serialize = "0.3.0"
|
||||
ark-serialize-derive = "0.3.0"
|
||||
thiserror = "1.0.30"
|
||||
secp256k1 = { git = "https://github.com/geometryresearch/ark-secp256k1.git" }
|
||||
rand_core = {version = "0.6", default-features=false, features = ["getrandom"] }
|
||||
rand = "0.8.4"
|
||||
tiny-keccak = { version = "2.0.2", features = [ "shake" ] }
|
||||
sha2 = "0.10.2"
|
||||
elliptic-curve = { version = "0.12.2", features = ["arithmetic"]}
|
||||
k256 = {version = "0.11.3", features = ["arithmetic", "hash2curve", "expose-field", "sha2"] }
|
||||
generic-array = { version = "0.14", default-features = false }
|
||||
hex = "0.4.3"
|
||||
|
||||
[patch.crates-io]
|
||||
ark-ec = { git = "https://github.com/FindoraNetwork/ark-algebra" }
|
||||
ark-ff = { git = "https://github.com/FindoraNetwork/ark-algebra" }
|
||||
ark-serialize = { git = "https://github.com/FindoraNetwork/ark-algebra" }
|
||||
ark-algebra-test-templates = { git = "https://github.com/FindoraNetwork/ark-algebra" }
|
||||
ark-std = { git = "https://github.com/FindoraNetwork/ark-std" }
|
||||
11
rust-arkworks/src/error.rs
Normal file
11
rust-arkworks/src/error.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use thiserror::Error;
|
||||
|
||||
/// This is an error that could occur when running a cryptograhic primitive
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum CryptoError {
|
||||
#[error("Cannot hash to curve")]
|
||||
CannotHashToCurve,
|
||||
|
||||
#[error("Cannot encode a point not on the curve")]
|
||||
PointNotOnCurve,
|
||||
}
|
||||
89
rust-arkworks/src/hash_to_curve.rs
Normal file
89
rust-arkworks/src/hash_to_curve.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use crate::error::CryptoError;
|
||||
use ark_ec::{AffineCurve, ProjectiveCurve};
|
||||
use tiny_keccak::{Hasher, Shake, Xof};
|
||||
use elliptic_curve::hash2curve::{ExpandMsgXmd, GroupDigest};
|
||||
use k256::{AffinePoint};
|
||||
use k256::sha2::Sha256;
|
||||
use elliptic_curve::sec1::ToEncodedPoint;
|
||||
use ark_ec::short_weierstrass_jacobian::GroupAffine;
|
||||
use k256::{ProjectivePoint, Secp256k1};
|
||||
use ark_ff::FromBytes;
|
||||
use secp256k1::Sec1EncodePoint;
|
||||
|
||||
pub fn hash_to_curve<
|
||||
Fp: ark_ff::PrimeField,
|
||||
P: ark_ec::SWModelParameters,
|
||||
>(
|
||||
msg: &[u8],
|
||||
pk: &GroupAffine<P>,
|
||||
) -> GroupAffine<P> {
|
||||
|
||||
let pk_encoded = pk.to_encoded_point(true);
|
||||
let b = hex::decode(pk_encoded).unwrap();
|
||||
let x = [msg, b.as_slice()];
|
||||
let x = x.concat().clone();
|
||||
let x = x.as_slice();
|
||||
|
||||
let pt: ProjectivePoint = Secp256k1::hash_from_bytes::<ExpandMsgXmd<Sha256>>(
|
||||
&[x],
|
||||
b"CURVE_XMD:SHA-256_SSWU_RO_"
|
||||
).unwrap();
|
||||
|
||||
let pt_affine = pt.to_affine();
|
||||
|
||||
k256_affine_to_arkworks_secp256k1_affine::<Fp, P>(pt_affine)
|
||||
}
|
||||
|
||||
pub fn k256_affine_to_arkworks_secp256k1_affine<
|
||||
Fp: ark_ff::PrimeField,
|
||||
P: ark_ec::SWModelParameters
|
||||
>(
|
||||
k_pt: AffinePoint,
|
||||
) -> GroupAffine<P> {
|
||||
let encoded_pt = k_pt.to_encoded_point(false);
|
||||
|
||||
let num_field_bytes = 320;
|
||||
|
||||
// extract k_pt.x
|
||||
let k_pt_x_bytes = encoded_pt.x().unwrap();
|
||||
|
||||
// pad x bytes
|
||||
let mut k_pt_x_bytes_vec = vec![0u8; num_field_bytes];
|
||||
for (i, _) in k_pt_x_bytes.clone().iter().enumerate() {
|
||||
let _ = std::mem::replace(&mut k_pt_x_bytes_vec[i], k_pt_x_bytes[k_pt_x_bytes.len() - 1 - i]);
|
||||
}
|
||||
let reader = std::io::BufReader::new(k_pt_x_bytes_vec.as_slice());
|
||||
let g_x = P::BaseField::read(reader).unwrap();
|
||||
|
||||
// extract k_pt.y
|
||||
let k_pt_y_bytes = encoded_pt.y().unwrap();
|
||||
|
||||
// pad y bytes
|
||||
let mut k_pt_y_bytes_vec = vec![0u8; num_field_bytes];
|
||||
for (i, _) in k_pt_y_bytes.clone().iter().enumerate() {
|
||||
let _ = std::mem::replace(&mut k_pt_y_bytes_vec[i], k_pt_y_bytes[k_pt_y_bytes.len() - 1 - i]);
|
||||
}
|
||||
|
||||
let reader = std::io::BufReader::new(k_pt_y_bytes_vec.as_slice());
|
||||
let g_y = P::BaseField::read(reader).unwrap();
|
||||
|
||||
GroupAffine::<P>::new(g_x, g_y, false)
|
||||
}
|
||||
|
||||
/// Kobi's hash_to_curve function, here for reference only
|
||||
pub fn _try_and_increment<C: ProjectiveCurve>(msg: &[u8]) -> Result<C::Affine, CryptoError> {
|
||||
for nonce in 0u8..=255 {
|
||||
let mut h = Shake::v128();
|
||||
h.update(&[nonce]);
|
||||
h.update(msg.as_ref());
|
||||
let output_size = C::zero().serialized_size();
|
||||
let mut output = vec![0u8; output_size];
|
||||
h.squeeze(&mut output);
|
||||
|
||||
if let Some(p) = C::Affine::from_random_bytes(&output) {
|
||||
return Ok(p);
|
||||
}
|
||||
}
|
||||
|
||||
Err(CryptoError::CannotHashToCurve)
|
||||
}
|
||||
256
rust-arkworks/src/lib.rs
Normal file
256
rust-arkworks/src/lib.rs
Normal file
@@ -0,0 +1,256 @@
|
||||
mod error;
|
||||
mod hash_to_curve;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub mod sig {
|
||||
use crate::error::CryptoError;
|
||||
use crate::hash_to_curve;
|
||||
use ark_ec::{AffineCurve, ProjectiveCurve, models::SWModelParameters};
|
||||
use ark_ec::short_weierstrass_jacobian::GroupAffine;
|
||||
use ark_ff::{PrimeField, ToBytes};
|
||||
use ark_std::{
|
||||
marker::PhantomData,
|
||||
UniformRand,
|
||||
rand::Rng,
|
||||
};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError, Read, Write};
|
||||
use sha2::{Sha512, Digest};
|
||||
use secp256k1::sec1::Sec1EncodePoint;
|
||||
|
||||
pub struct DeterministicNullifierSignatureScheme<'a, C: ProjectiveCurve, Fq: ark_ff::PrimeField, P: ark_ec::SWModelParameters> {
|
||||
_group: PhantomData<C>,
|
||||
_field: PhantomData<Fq>,
|
||||
_parameters: PhantomData<P>,
|
||||
_message_lifetime: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
pub fn affine_to_bytes<P: SWModelParameters>(
|
||||
point: &GroupAffine<P>
|
||||
) -> Vec::<u8> {
|
||||
let encoded = point.to_encoded_point(true);
|
||||
let b = hex::decode(encoded).unwrap();
|
||||
b.to_vec()
|
||||
}
|
||||
|
||||
fn compute_h<'a, C: ProjectiveCurve, Fq: PrimeField, P: SWModelParameters>(
|
||||
pk: &GroupAffine<P>,
|
||||
message: &'a [u8],
|
||||
) -> Result<GroupAffine<P>, CryptoError> {
|
||||
//let pk_affine_bytes_vec = affine_to_bytes::<P>(pk);
|
||||
//let m_pk = [message, pk_affine_bytes_vec.as_slice()].concat();
|
||||
//hash_to_curve::try_and_increment::<C>(m_pk.as_slice())
|
||||
Ok(hash_to_curve::hash_to_curve::<Fq, P>(message, pk))
|
||||
}
|
||||
|
||||
fn compute_c<P: SWModelParameters>(
|
||||
g: &GroupAffine<P>,
|
||||
pk: &GroupAffine<P>,
|
||||
h: &GroupAffine<P>,
|
||||
nul: &GroupAffine<P>,
|
||||
g_r: &GroupAffine<P>,
|
||||
z: &GroupAffine<P>,
|
||||
) -> P::ScalarField {
|
||||
// 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);
|
||||
let h_bytes = affine_to_bytes::<P>(h);
|
||||
let nul_bytes = affine_to_bytes::<P>(nul);
|
||||
let g_r_bytes = affine_to_bytes::<P>(g_r);
|
||||
let z_bytes = affine_to_bytes::<P>(z);
|
||||
|
||||
let c_preimage_vec = [
|
||||
g_bytes,
|
||||
pk_bytes,
|
||||
h_bytes,
|
||||
nul_bytes,
|
||||
g_r_bytes,
|
||||
z_bytes,
|
||||
].concat();
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
pub trait VerifiableUnpredictableFunction {
|
||||
type Message: ToBytes;
|
||||
type Parameters: CanonicalSerialize + CanonicalDeserialize;
|
||||
type PublicKey: CanonicalSerialize + CanonicalDeserialize;
|
||||
type SecretKey: CanonicalSerialize + CanonicalDeserialize;
|
||||
type Signature: CanonicalSerialize + CanonicalDeserialize;
|
||||
|
||||
/// Generate a public key and a private key.
|
||||
fn keygen<R: Rng>(
|
||||
pp: &Self::Parameters,
|
||||
rng: &mut R,
|
||||
) -> Result<(Self::PublicKey, Self::SecretKey), CryptoError>;
|
||||
|
||||
/// Sign a message.
|
||||
fn sign<R: Rng>(
|
||||
pp: &Self::Parameters,
|
||||
rng: &mut R,
|
||||
keypair: (&Self::PublicKey, &Self::SecretKey),
|
||||
message: Self::Message,
|
||||
) -> Result<Self::Signature, CryptoError>;
|
||||
|
||||
/// Sign a message using an specified r value
|
||||
fn sign_with_r(
|
||||
pp: &Self::Parameters,
|
||||
keypair: (&Self::PublicKey, &Self::SecretKey),
|
||||
message: Self::Message,
|
||||
r: Self::SecretKey,
|
||||
) -> Result<Self::Signature, CryptoError>;
|
||||
|
||||
fn verify_non_zk(
|
||||
pp: &Self::Parameters,
|
||||
pk: &Self::PublicKey,
|
||||
sig: &Self::Signature,
|
||||
message: Self::Message,
|
||||
) -> Result<bool, CryptoError>;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, ark_serialize_derive::CanonicalSerialize, ark_serialize_derive::CanonicalDeserialize)]
|
||||
pub struct Parameters<P: SWModelParameters> {
|
||||
pub g: GroupAffine<P>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, ark_serialize_derive::CanonicalSerialize, ark_serialize_derive::CanonicalDeserialize)]
|
||||
pub struct Signature<P: SWModelParameters> {
|
||||
pub z: GroupAffine<P>,
|
||||
pub g_r: GroupAffine<P>,
|
||||
pub s: P::ScalarField,
|
||||
pub c: P::ScalarField,
|
||||
pub nul: GroupAffine<P>,
|
||||
}
|
||||
|
||||
impl<'a, C: ProjectiveCurve, Fq: PrimeField, P: SWModelParameters> VerifiableUnpredictableFunction for DeterministicNullifierSignatureScheme<'a, C, Fq, P> {
|
||||
type Message = &'a [u8];
|
||||
type Parameters = Parameters<P>;
|
||||
type PublicKey = GroupAffine<P>;
|
||||
type SecretKey = P::ScalarField;
|
||||
type Signature = Signature<P>;
|
||||
|
||||
fn keygen<R: Rng>(
|
||||
pp: &Self::Parameters,
|
||||
rng: &mut R,
|
||||
) -> Result<(Self::PublicKey, Self::SecretKey), CryptoError> {
|
||||
let secret_key = Self::SecretKey::rand(rng).into();
|
||||
let public_key = pp.g.mul(secret_key).into();
|
||||
Ok((public_key, secret_key))
|
||||
}
|
||||
|
||||
fn sign_with_r(
|
||||
pp: &Self::Parameters,
|
||||
keypair: (&Self::PublicKey, &Self::SecretKey),
|
||||
message: Self::Message,
|
||||
r: P::ScalarField,
|
||||
) -> Result<Self::Signature, CryptoError> {
|
||||
let g = pp.g;
|
||||
let g_r = g.mul(r).into_affine();
|
||||
|
||||
// Compute h = htc([m, pk])
|
||||
let h = compute_h::<C, Fq, P>(&keypair.0, &message).unwrap();
|
||||
|
||||
// Compute z = h^r
|
||||
let z = h.mul(r).into_affine();
|
||||
|
||||
// Compute nul = h^sk
|
||||
let nul = h.mul(*keypair.1).into_affine();
|
||||
|
||||
// Compute c = sha512([g, pk, h, nul, g^r, z])
|
||||
let c_scalar: P::ScalarField = compute_c::<P>(
|
||||
&g,
|
||||
keypair.0,
|
||||
&h,
|
||||
&nul,
|
||||
&g_r,
|
||||
&z,
|
||||
);
|
||||
|
||||
// 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;
|
||||
|
||||
let s_scalar = P::ScalarField::from(s);
|
||||
|
||||
let signature = Signature {
|
||||
z,
|
||||
s: s_scalar,
|
||||
g_r,
|
||||
c: c_scalar,
|
||||
nul
|
||||
};
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
fn sign<R: Rng>(
|
||||
pp: &Self::Parameters,
|
||||
rng: &mut R,
|
||||
keypair: (&Self::PublicKey, &Self::SecretKey),
|
||||
message: Self::Message,
|
||||
) -> Result<Self::Signature, CryptoError> {
|
||||
// Pick a random r from Fp
|
||||
let r: P::ScalarField = Self::SecretKey::rand(rng).into();
|
||||
|
||||
Self::sign_with_r(pp, keypair, message, r)
|
||||
}
|
||||
|
||||
fn verify_non_zk(
|
||||
pp: &Self::Parameters,
|
||||
pk: &Self::PublicKey,
|
||||
sig: &Self::Signature,
|
||||
message: Self::Message,
|
||||
) -> Result<bool, CryptoError> {
|
||||
// Compute h = htc([m, pk])
|
||||
let h = compute_h::<C, Fq, P>(pk, message).unwrap();
|
||||
|
||||
// Compute c' = sha512([g, pk, h, nul, g^r, z])
|
||||
let c_scalar: P::ScalarField = compute_c::<P>(
|
||||
&pp.g,
|
||||
pk,
|
||||
&h,
|
||||
&sig.nul,
|
||||
&sig.g_r,
|
||||
&sig.z,
|
||||
);
|
||||
|
||||
// Reject if g^s ⋅ pk^{-c} != g^r
|
||||
let g_s = pp.g.mul(sig.s);
|
||||
let pk_c = pk.mul(sig.c);
|
||||
let g_s_pk_c = g_s - pk_c;
|
||||
|
||||
if sig.g_r != g_s_pk_c {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
// Reject if h^s ⋅ nul^{-c} = z
|
||||
let h_s = h.mul(sig.s);
|
||||
let nul_c = sig.nul.mul(sig.c);
|
||||
let h_s_nul_c = h_s - nul_c;
|
||||
|
||||
if sig.z != h_s_nul_c {
|
||||
return Ok(false)
|
||||
}
|
||||
|
||||
// Reject if c != c'
|
||||
if c_scalar != sig.c {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
215
rust-arkworks/src/tests.rs
Normal file
215
rust-arkworks/src/tests.rs
Normal file
@@ -0,0 +1,215 @@
|
||||
use secp256k1::curves::Affine;
|
||||
use secp256k1::curves::Secp256k1Parameters;
|
||||
use secp256k1::fields::Fq;
|
||||
use crate::sig::VerifiableUnpredictableFunction;
|
||||
use crate::hash_to_curve::{
|
||||
hash_to_curve,
|
||||
k256_affine_to_arkworks_secp256k1_affine,
|
||||
};
|
||||
use ark_std::rand;
|
||||
use crate::sig::DeterministicNullifierSignatureScheme;
|
||||
use ark_ec::{AffineCurve, ProjectiveCurve};
|
||||
use ark_ec::models::short_weierstrass_jacobian::GroupAffine;
|
||||
use ark_ff::bytes::{ToBytes, FromBytes};
|
||||
use ark_ff::biginteger;
|
||||
use rand::{prelude::ThreadRng, thread_rng};
|
||||
use k256::{ProjectivePoint, Scalar};
|
||||
|
||||
type Parameters = crate::sig::Parameters<Secp256k1Parameters>;
|
||||
|
||||
fn test_template() -> (ThreadRng, Affine) {
|
||||
let rng = thread_rng();
|
||||
let g = Affine::prime_subgroup_generator();
|
||||
|
||||
(rng, g)
|
||||
}
|
||||
|
||||
type Scheme<'a> = DeterministicNullifierSignatureScheme::<'a, secp256k1::Projective, Fq, Secp256k1Parameters>;
|
||||
|
||||
#[test]
|
||||
pub fn test_k256_affine_to_arkworks_secp256k1_affine() {
|
||||
for i in 1..50 {
|
||||
let i_u64 = i as u64;
|
||||
let k256_scalar = Scalar::from(i_u64);
|
||||
let ark_scalar = Fq::from(i_u64);
|
||||
|
||||
// Compute g^i_u64
|
||||
let k256_pt = ProjectivePoint::GENERATOR.to_affine() * k256_scalar;
|
||||
let ark_pt = Affine::prime_subgroup_generator().mul(ark_scalar);
|
||||
|
||||
// Convert k256_pt to an arkworks point
|
||||
let converted_pt = k256_affine_to_arkworks_secp256k1_affine::<
|
||||
secp256k1::fields::Fq,
|
||||
Secp256k1Parameters
|
||||
>(k256_pt.to_affine());
|
||||
|
||||
// The points should match
|
||||
assert_eq!(ark_pt.into_affine(), converted_pt);
|
||||
}
|
||||
}
|
||||
|
||||
fn hex_to_fr(
|
||||
hex: &str,
|
||||
) -> secp256k1::fields::Fr {
|
||||
let num_field_bytes = 320;
|
||||
let mut sk_bytes_vec = vec![0u8; num_field_bytes];
|
||||
let mut sk_bytes = hex::decode(hex).unwrap();
|
||||
|
||||
sk_bytes.reverse();
|
||||
|
||||
for (i, _) in sk_bytes.clone().iter().enumerate() {
|
||||
let _ = std::mem::replace(&mut sk_bytes_vec[i], sk_bytes[i]);
|
||||
}
|
||||
|
||||
secp256k1::fields::Fr::read(sk_bytes_vec.as_slice()).unwrap()
|
||||
}
|
||||
|
||||
fn coord_to_hex(
|
||||
coord: biginteger::BigInteger320
|
||||
) -> String {
|
||||
let mut coord_bytes = vec![];
|
||||
let _ = coord.write(&mut coord_bytes);
|
||||
coord_bytes.reverse();
|
||||
|
||||
String::from(hex::encode(coord_bytes))
|
||||
}
|
||||
|
||||
fn hardcoded_sk() -> String {
|
||||
"519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464".to_string()
|
||||
}
|
||||
|
||||
fn hardcoded_r() -> String {
|
||||
"93b9323b629f251b8f3fc2dd11f4672c5544e8230d493eceea98a90bda789808".to_string()
|
||||
}
|
||||
|
||||
pub fn hardcoded_msg() -> String {
|
||||
"An example app message string".to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_keygen() {
|
||||
let (mut rng, g) = test_template();
|
||||
let pp = Parameters{ g };
|
||||
|
||||
let (pk, sk) = Scheme::keygen(&pp, &mut rng).unwrap();
|
||||
|
||||
let expected_pk = g.mul(sk);
|
||||
assert_eq!(pk, expected_pk);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_sign_and_verify() {
|
||||
let (mut rng, g) = test_template();
|
||||
let pp = Parameters{ g };
|
||||
|
||||
let message = b"Message";
|
||||
let keypair = Scheme::keygen(&pp, &mut rng).unwrap();
|
||||
|
||||
let sig = Scheme::sign(
|
||||
&pp,
|
||||
&mut rng,
|
||||
(&keypair.0, &keypair.1),
|
||||
message
|
||||
).unwrap();
|
||||
|
||||
let is_valid = Scheme::verify_non_zk(
|
||||
&pp,
|
||||
&keypair.0,
|
||||
&sig,
|
||||
message,
|
||||
);
|
||||
assert!(is_valid.unwrap());
|
||||
}
|
||||
|
||||
pub fn compute_h() -> GroupAffine::<Secp256k1Parameters> {
|
||||
let msg = hardcoded_msg();
|
||||
let message = msg.as_bytes();
|
||||
|
||||
let sk = hex_to_fr(&hardcoded_sk());
|
||||
let (_, g) = test_template();
|
||||
let pk_projective = g.mul(sk);
|
||||
let pk = GroupAffine::<Secp256k1Parameters>::from(pk_projective);
|
||||
|
||||
let h = hash_to_curve::<secp256k1::fields::Fq, Secp256k1Parameters>(message, &pk);
|
||||
h
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_against_zk_nullifier_sig_pk() {
|
||||
// Check the pubkey generated from the hardcoded secret key
|
||||
let sk = hex_to_fr(&hardcoded_sk());
|
||||
|
||||
let (_, g) = test_template();
|
||||
let pk_projective = g.mul(sk);
|
||||
let pk = GroupAffine::<Secp256k1Parameters>::from(pk_projective);
|
||||
|
||||
assert_eq!(coord_to_hex(pk.x.into()), "00000000000000000cec028ee08d09e02672a68310814354f9eabfff0de6dacc1cd3a774496076ae");
|
||||
assert_eq!(coord_to_hex(pk.y.into()), "0000000000000000eff471fba0409897b6a48e8801ad12f95d0009b753cf8f51c128bf6b0bd27fbd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_against_zk_nullifier_sig_g_r() {
|
||||
// Test g^r using the hardcoded r
|
||||
let r = secp256k1::fields::Fr::from(hex_to_fr(&hardcoded_r()));
|
||||
let (_, g) = test_template();
|
||||
let g_r_projective = g.mul(r);
|
||||
let g_r = GroupAffine::<Secp256k1Parameters>::from(g_r_projective);
|
||||
assert_eq!(coord_to_hex(g_r.x.into()), "00000000000000009d8ca4350e7e2ad27abc6d2a281365818076662962a28429590e2dc736fe9804");
|
||||
assert_eq!(coord_to_hex(g_r.y.into()), "0000000000000000ff08c30b8afd4e854623c835d9c3aac6bcebe45112472d9b9054816a7670c5a1");
|
||||
}
|
||||
|
||||
//TODO: add test vectors for hash_to_curve
|
||||
#[test]
|
||||
pub fn test_against_zk_nullifier_sig_h() {
|
||||
let h = compute_h();
|
||||
|
||||
assert_eq!(coord_to_hex(h.x.into()), "000000000000000027cdee7f388ba2981f4ef3a499abdd7506281bdc4f535109ec66e0e80824a37b");
|
||||
assert_eq!(coord_to_hex(h.y.into()), "00000000000000008beb2fe7adeecadb3e99be05c3979bcf734c2caa768aaed09a26cb48d1236f42");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_against_zk_nullifier_sig_h_r() {
|
||||
let h = compute_h();
|
||||
|
||||
// Test h^r using the hardcoded r
|
||||
let r = secp256k1::fields::Fr::from(hex_to_fr(&hardcoded_r()));
|
||||
let h_r_projective = h.mul(r);
|
||||
let h_r = GroupAffine::<Secp256k1Parameters>::from(h_r_projective);
|
||||
assert_eq!(coord_to_hex(h_r.x.into()), "0000000000000000adf22a767a1f43b8dc4e77ce00c4eea54a63b10126e03e5f418d460e1fe1b2c2");
|
||||
assert_eq!(coord_to_hex(h_r.y.into()), "0000000000000000d9bc5ce25d1fd63dd56fe6b7b2260747758c0bdda4b0e09a4028eed29a8049d8");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_against_zk_nullifier_sig_h_sk() {
|
||||
let h = compute_h();
|
||||
let sk = hex_to_fr(&hardcoded_sk());
|
||||
|
||||
// Test h^r using the hardcoded sk
|
||||
let h_sk_projective = h.mul(sk);
|
||||
let h_sk = GroupAffine::<Secp256k1Parameters>::from(h_sk_projective);
|
||||
assert_eq!(coord_to_hex(h_sk.x.into()), "000000000000000015db23237364493d346e7ecf367c65c3861ba088e53a757deb5e8eaaa3e24e3f");
|
||||
assert_eq!(coord_to_hex(h_sk.y.into()), "0000000000000000c3623b03cd7d92136dba28f6077e28c8fb731cc585e61fcb26d5c8f0f3b83fd0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_against_zk_nullifier_sig_c_and_s() {
|
||||
let r = secp256k1::fields::Fr::from(hex_to_fr(&hardcoded_r()));
|
||||
let message = hardcoded_msg();
|
||||
let message = message.as_bytes();
|
||||
let sk = hex_to_fr(&hardcoded_sk());
|
||||
let (_, g) = test_template();
|
||||
let pp = Parameters{ g };
|
||||
let pk_projective = g.mul(sk);
|
||||
let pk = GroupAffine::<Secp256k1Parameters>::from(pk_projective);
|
||||
|
||||
let keypair = (pk, sk);
|
||||
let sig = Scheme::sign_with_r(
|
||||
&pp,
|
||||
(&keypair.0, &keypair.1),
|
||||
message,
|
||||
r
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(coord_to_hex(sig.c.into()), "00000000000000009de4daa951b8728db267eea9aa54ae48f8496bfde11387e91a39b261782a2b43");
|
||||
assert_eq!(coord_to_hex(sig.s.into()), "0000000000000000b4e19b36312e7489b708e9e277280ae51ca0bbf350add3b93c897902040fdd76");
|
||||
}
|
||||
Reference in New Issue
Block a user