mirror of
https://github.com/plume-sig/zk-nullifier-sig.git
synced 2026-01-09 12:57:55 -05:00
* current progress * link to relevant issue * crate name edit * Flat the docs entities * meta information * Update the crate name in `tests` * current progress
This commit is contained in:
@@ -1,18 +1,22 @@
|
||||
[package]
|
||||
name = "sig"
|
||||
version = "0.1.0"
|
||||
name = "plume_arkworks"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Implementation of PLUME: nullifier friendly signature scheme on ECDSA; using the `arkworks-rs` libraries"
|
||||
repository = "https://github.com/plume-sig/zk-nullifier-sig/"
|
||||
categories = ["cryptography", "cryptography::cryptocurrencies"]
|
||||
keywords = ["nullifier", "zero-knowledge", "ECDSA", "PLUME"]
|
||||
|
||||
# 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" }
|
||||
ark-ff = "~0.3.0"
|
||||
ark-std = "~0.3.0"
|
||||
ark-serialize = "~0.3.0"
|
||||
ark-serialize-derive = "~0.3.0"
|
||||
secp256k1 = { git = "https://github.com/geometryresearch/ark-secp256k1.git", version = "0.1.0" }
|
||||
rand_core = { version = "0.6", default-features = false, features = [
|
||||
"getrandom",
|
||||
] }
|
||||
|
||||
3
rust-arkworks/README.MD
Normal file
3
rust-arkworks/README.MD
Normal file
@@ -0,0 +1,3 @@
|
||||
https://github.com/plume-sig/zk-nullifier-sig/blob/main/README.md
|
||||
# HAZMAT
|
||||
Please note that until `v0.1.0` this is very much a preview crate which lets you have some preliminary feel of the structure and the reference implementation approach.
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// use thiserror::Error;
|
||||
|
||||
/// This is an error that could occur when running a cryptograhic primitive
|
||||
// /// This is an error that could occur when running a cryptograhic primitive
|
||||
// #[derive(Error, Debug, PartialEq)]
|
||||
// pub enum CryptoError {
|
||||
// #[error("Cannot hash to curve")]
|
||||
@@ -14,13 +14,18 @@
|
||||
// }
|
||||
|
||||
// Let's outline what errors will be in `~0.4.0`
|
||||
/// It's an interim `enum` between legacy definition of the errors and prospective which will be relying on [`ark_ec::hashing::HashToCurveError`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum HashToCurveError {
|
||||
/// Mimics the `ark_ec::hashing::HashToCurveError` enum
|
||||
UnsupportedCurveError(String),
|
||||
/// Mimics the `ark_ec::hashing::HashToCurveError` enum
|
||||
MapToCurveError(String),
|
||||
/* let's add two more items to absorb everything
|
||||
in `crate::hash_to_curve` which is
|
||||
subject to deprecation */
|
||||
/// Absorbs any legacy error in [`mod@crate::hash_to_curve`]. They will be deprecated with upgrade to `~0.4.0`.
|
||||
Legacy,
|
||||
/// A special case for a reference function. It will be moved to <./examples> with the upgrade to `~0.4.0`.
|
||||
ReferenceTryAndIncrement,
|
||||
}
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
use crate::error::HashToCurveError;
|
||||
/// This crate provides the PLUME signature scheme.
|
||||
///
|
||||
/// See <https://blog.aayushg.com/nullifier> for more information.
|
||||
///
|
||||
/// Find RustCrypto crate as `plume_rustcrypto`.
|
||||
|
||||
pub use crate::error::HashToCurveError;
|
||||
use crate::hash_to_curve::hash_to_curve;
|
||||
use ark_ec::short_weierstrass_jacobian::GroupAffine;
|
||||
use ark_ec::{models::SWModelParameters, AffineCurve, ProjectiveCurve};
|
||||
|
||||
/// Re-exports the `GroupAffine` and `SWModelParameters` types from the `ark_ec` crate.
|
||||
///
|
||||
/// `GroupAffine` represents an affine point on a short Weierstrass elliptic curve.
|
||||
/// `SWModelParameters` contains the parameters defining a short Weierstrass curve.
|
||||
pub use ark_ec::{models::SWModelParameters, short_weierstrass_jacobian::GroupAffine};
|
||||
/// Re-exports the `Rng` trait from the `rand` crate in `ark_std`.
|
||||
///
|
||||
/// `Rng` provides methods for generating random values.
|
||||
pub use ark_std::rand::Rng;
|
||||
|
||||
use ark_ec::{AffineCurve, ProjectiveCurve};
|
||||
use ark_ff::PrimeField;
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write};
|
||||
use ark_std::{rand::Rng, UniformRand};
|
||||
use ark_std::UniformRand;
|
||||
use secp256k1::sec1::Sec1EncodePoint;
|
||||
use sha2::digest::Output;
|
||||
use sha2::{Digest, Sha256};
|
||||
@@ -14,11 +30,15 @@ mod hash_to_curve;
|
||||
|
||||
const EXPECT_MSG_DECODE: &str = "the value decoded have been generated by a function which is improbable to output a malformed hexstring (still a place for refactoring)";
|
||||
|
||||
/// An `enum` representing the variant of the PLUME protocol.
|
||||
pub enum PlumeVersion {
|
||||
V1,
|
||||
V2,
|
||||
}
|
||||
|
||||
/// Converts an affine point on the curve to the byte representation.
|
||||
///
|
||||
/// Serializes the affine point to its SEC1 encoding and returns the raw bytes.
|
||||
pub fn affine_to_bytes<P: SWModelParameters>(point: &GroupAffine<P>) -> Vec<u8> {
|
||||
hex::decode(point.to_encoded_point(true))
|
||||
.expect(EXPECT_MSG_DECODE)
|
||||
@@ -72,6 +92,8 @@ fn compute_c_v2<P: SWModelParameters>(
|
||||
Sha256::digest(c_preimage_vec.as_slice())
|
||||
}
|
||||
|
||||
/// A struct containing parameters for the SW model, including the generator point `g_point`.
|
||||
/// This struct implements traits for (de)serialization.
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
@@ -79,9 +101,11 @@ fn compute_c_v2<P: SWModelParameters>(
|
||||
ark_serialize_derive::CanonicalDeserialize,
|
||||
)]
|
||||
pub struct Parameters<P: SWModelParameters> {
|
||||
/// The generator point for the SW model parameters.
|
||||
pub g_point: GroupAffine<P>,
|
||||
}
|
||||
|
||||
/// A struct containing the PLUME signature data
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
@@ -89,28 +113,37 @@ pub struct Parameters<P: SWModelParameters> {
|
||||
ark_serialize_derive::CanonicalDeserialize,
|
||||
)]
|
||||
pub struct PlumeSignature<P: SWModelParameters> {
|
||||
/// The hash-to-curve output multiplied by the random `r`.
|
||||
pub hashed_to_curve_r: GroupAffine<P>,
|
||||
/// The randomness `r` represented as the curve point.
|
||||
pub r_point: GroupAffine<P>,
|
||||
pub s: P::ScalarField,
|
||||
pub c: P::ScalarField,
|
||||
/// The nullifier.
|
||||
pub nullifier: GroupAffine<P>,
|
||||
}
|
||||
|
||||
// These aliases should be gone in #88 . If they won't TODO pay attention to the warning about `trait` boundaries being not checked for aliases
|
||||
// also not enforcing trait bounds can impact PublicKey -- it's better to find appropriate upstream type
|
||||
type Message<'a> = &'a [u8];
|
||||
type PublicKey<P: SWModelParameters> = GroupAffine<P>;
|
||||
type SecretKeyMaterial<P: SWModelParameters> = P::ScalarField;
|
||||
|
||||
/// A type alias for a byte slice reference, used for representing the message.
|
||||
pub type Message<'a> = &'a [u8];
|
||||
/// The public key.
|
||||
pub type PublicKey<P: SWModelParameters> = GroupAffine<P>;
|
||||
/// The scalar field element representing the secret key.
|
||||
pub type SecretKeyMaterial<P: SWModelParameters> = P::ScalarField;
|
||||
|
||||
impl<P: SWModelParameters> PlumeSignature<P> {
|
||||
/// Generate the public key and a private key.
|
||||
fn keygen(pp: &Parameters<P>, rng: &mut impl Rng) -> (PublicKey<P>, SecretKeyMaterial<P>) {
|
||||
/// # HAZMAT
|
||||
/// No measures yet taken for the [`SecretKeyMaterial`] protection
|
||||
pub fn keygen(pp: &Parameters<P>, rng: &mut impl Rng) -> (PublicKey<P>, SecretKeyMaterial<P>) {
|
||||
let secret_key = SecretKeyMaterial::<P>::rand(rng);
|
||||
let public_key = pp.g_point.mul(secret_key).into();
|
||||
(public_key, secret_key)
|
||||
}
|
||||
|
||||
/// Sign a message using a specified r value
|
||||
/// Sign a message using the specified `r` value
|
||||
fn sign_with_r(
|
||||
pp: &Parameters<P>,
|
||||
keypair: (&PublicKey<P>, &SecretKeyMaterial<P>),
|
||||
@@ -174,6 +207,16 @@ impl<P: SWModelParameters> PlumeSignature<P> {
|
||||
Self::sign_with_r(pp, keypair, message, r_scalar, version)
|
||||
}
|
||||
|
||||
/// Verifies a PLUME signature.
|
||||
/// Returns `true` if the signature is valid, `false` otherwise.
|
||||
///
|
||||
/// Computes the curve points and scalars needed for verification from the
|
||||
/// signature parameters. Then performs the verification steps:
|
||||
/// - Confirm g^s * pk^-c = g^r
|
||||
/// - Confirm h^s * nul^-c = z
|
||||
/// - Confirm c = c'
|
||||
///
|
||||
/// Rejects if any check fails.
|
||||
fn verify_non_zk(
|
||||
self,
|
||||
pp: &Parameters<P>,
|
||||
|
||||
41
rust-k256/.vscode/launch.json
vendored
41
rust-k256/.vscode/launch.json
vendored
@@ -1,41 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug executable 'zk-nullifier'",
|
||||
"cargo": {
|
||||
"args": ["build", "--bin=zk-nullifier", "--package=zk-nullifier"],
|
||||
"filter": {
|
||||
"name": "zk-nullifier",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in executable 'zk-nullifier'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--bin=zk-nullifier",
|
||||
"--package=zk-nullifier"
|
||||
],
|
||||
"filter": {
|
||||
"name": "zk-nullifier",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
[package]
|
||||
name = "zk-nullifier"
|
||||
name = "plume_rustcrypto"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Implementation of PLUME: nullifier friendly signature scheme on ECDSA; using the k256 library"
|
||||
repository = "https://github.com/plume-sig/zk-nullifier-sig/"
|
||||
categories = ["cryptography", "cryptography::cryptocurrencies"]
|
||||
keywords = ["nullifier", "zero-knowledge", "ECDSA", "PLUME"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
||||
1
rust-k256/README.MD
Normal file
1
rust-k256/README.MD
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/plume-sig/zk-nullifier-sig/blob/main/README.md
|
||||
@@ -1,101 +1,81 @@
|
||||
// #![feature(generic_const_expr)]
|
||||
// #![allow(incomplete_features)]
|
||||
|
||||
use k256::{
|
||||
elliptic_curve::hash2curve::{ExpandMsgXmd, GroupDigest},
|
||||
elliptic_curve::ops::ReduceNonZero,
|
||||
elliptic_curve::sec1::ToEncodedPoint,
|
||||
elliptic_curve::{bigint::ArrayEncoding, group::ff::PrimeField},
|
||||
sha2::{digest::Output, Digest, Sha256},
|
||||
FieldBytes, Scalar, Secp256k1, U256,
|
||||
}; // requires 'getrandom' feature
|
||||
use std::panic;
|
||||
// TODO #86
|
||||
pub use k256::ProjectivePoint;
|
||||
//! A library for generating (coming [soon](https://github.com/plume-sig/zk-nullifier-sig/issues/84)) and verifying PLUME signatures.
|
||||
//!
|
||||
//! See <https://blog.aayushg.com/nullifier> for more information.
|
||||
//!
|
||||
// Find `arkworks-rs` crate as `plume_arkworks`.
|
||||
//
|
||||
// # Examples
|
||||
// For V2 just set `v1` to `None`
|
||||
// ```rust
|
||||
// # fn main() {
|
||||
// let sig_good = PlumeSignature<'a>{
|
||||
// message: &b"An example app message string",
|
||||
// pk: ProjectivePoint::GENERATOR * Scalar::from_repr(hex!("519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464").into()).unwrap(),
|
||||
// ...
|
||||
// };
|
||||
// # }
|
||||
// ```
|
||||
|
||||
const L: usize = 48;
|
||||
const COUNT: usize = 2;
|
||||
const OUT: usize = L * COUNT;
|
||||
use k256::{
|
||||
elliptic_curve::ops::ReduceNonZero,
|
||||
elliptic_curve::{bigint::ArrayEncoding, group::ff::PrimeField},
|
||||
FieldBytes, U256,
|
||||
}; // requires 'getrandom' feature
|
||||
// TODO
|
||||
pub use k256::ProjectivePoint;
|
||||
/// Re-exports the [`Scalar`] type, [`Sha256`] hash function, and [`Output`] type
|
||||
/// from the [`k256`] crate's [`sha2`] module. This allows them to be used
|
||||
/// from the current module.
|
||||
pub use k256::{
|
||||
sha2::{digest::Output, Digest, Sha256},
|
||||
Scalar,
|
||||
};
|
||||
use std::panic;
|
||||
|
||||
mod utils;
|
||||
// not published due to use of `Projective...`; these utils can be found in other crates
|
||||
use utils::*;
|
||||
|
||||
/// The domain separation tag used for hashing to the `secp256k1` curve
|
||||
pub const DST: &[u8] = b"QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_RO_"; // Hash to curve algorithm
|
||||
|
||||
fn print_type_of<T>(_: &T) {
|
||||
println!("{}", std::any::type_name::<T>());
|
||||
}
|
||||
|
||||
fn c_sha256_vec_signal(values: Vec<&ProjectivePoint>) -> Output<Sha256> {
|
||||
let preimage_vec = values
|
||||
.into_iter()
|
||||
.map(encode_pt)
|
||||
.collect::<Vec<_>>()
|
||||
.concat();
|
||||
let mut sha256_hasher = Sha256::new();
|
||||
sha256_hasher.update(preimage_vec.as_slice());
|
||||
sha256_hasher.finalize()
|
||||
}
|
||||
|
||||
fn sha256hash6signals(
|
||||
g: &ProjectivePoint,
|
||||
pk: &ProjectivePoint,
|
||||
hash_m_pk: &ProjectivePoint,
|
||||
nullifier: &ProjectivePoint,
|
||||
g_r: &ProjectivePoint,
|
||||
hash_m_pk_pow_r: &ProjectivePoint,
|
||||
) -> Scalar {
|
||||
let g_bytes = encode_pt(g);
|
||||
let pk_bytes = encode_pt(pk);
|
||||
let h_bytes = encode_pt(hash_m_pk);
|
||||
let nul_bytes = encode_pt(nullifier);
|
||||
let g_r_bytes = encode_pt(g_r);
|
||||
let z_bytes = encode_pt(hash_m_pk_pow_r);
|
||||
|
||||
let c_preimage_vec = [g_bytes, pk_bytes, h_bytes, nul_bytes, g_r_bytes, z_bytes].concat();
|
||||
|
||||
//println!("c_preimage_vec: {:?}", c_preimage_vec);
|
||||
|
||||
let mut sha256_hasher = Sha256::new();
|
||||
sha256_hasher.update(c_preimage_vec.as_slice());
|
||||
let sha512_hasher_result = sha256_hasher.finalize(); //512 bit hash
|
||||
|
||||
let c_bytes = FieldBytes::from_iter(sha512_hasher_result.iter().copied());
|
||||
Scalar::from_repr(c_bytes).unwrap()
|
||||
}
|
||||
|
||||
// Hashes two values to the curve
|
||||
fn hash_to_curve(
|
||||
m: &[u8],
|
||||
pk: &ProjectivePoint,
|
||||
) -> Result<ProjectivePoint, k256::elliptic_curve::Error> {
|
||||
Secp256k1::hash_from_bytes::<ExpandMsgXmd<Sha256>>(
|
||||
&[[m, &encode_pt(pk)].concat().as_slice()],
|
||||
//b"CURVE_XMD:SHA-256_SSWU_RO_",
|
||||
&[DST],
|
||||
)
|
||||
}
|
||||
|
||||
/* currently seems to right place for this `struct` declaration;
|
||||
should be moved (to the beginning of the file?) during refactoring for proper order of the items */
|
||||
/* while no consistent #API is present here it's completely `pub`;
|
||||
when API will be designed it should include this `struct` (and it also probably will hold values instead of references) */
|
||||
#[derive(Debug)]
|
||||
/// Struct holding signature data for a PLUME signature.
|
||||
///
|
||||
/// `v1` field differintiate whether V1 or V2 protocol will be used.
|
||||
pub struct PlumeSignature<'a> {
|
||||
/// The message that was signed.
|
||||
pub message: &'a [u8],
|
||||
/// The public key used to verify the signature.
|
||||
pub pk: &'a ProjectivePoint,
|
||||
/// The nullifier.
|
||||
pub nullifier: &'a ProjectivePoint,
|
||||
/// Part of the signature data.
|
||||
pub c: &'a [u8],
|
||||
/// Part of the signature data, a scalar value.
|
||||
pub s: &'a Scalar,
|
||||
/// Optional signature data for variant 1 signatures.
|
||||
pub v1: Option<PlumeSignatureV1Fields<'a>>,
|
||||
}
|
||||
/// Nested struct holding additional signature data used in variant 1 of the protocol.
|
||||
#[derive(Debug)]
|
||||
pub struct PlumeSignatureV1Fields<'a> {
|
||||
/// Part of the signature data, a curve point.
|
||||
pub r_point: &'a ProjectivePoint,
|
||||
/// Part of the signature data, a curve point.
|
||||
pub hashed_to_curve_r: &'a ProjectivePoint,
|
||||
}
|
||||
impl PlumeSignature<'_> {
|
||||
// Verifier check in SNARK:
|
||||
// g^[r + sk * c] / (g^sk)^c = g^r
|
||||
// hash[m, gsk]^[r + sk * c] / (hash[m, pk]^sk)^c = hash[m, pk]^r
|
||||
// c = hash2(g, g^sk, hash[m, g^sk], hash[m, pk]^sk, gr, hash[m, pk]^r)
|
||||
pub fn verify_signals(&self) -> bool {
|
||||
/// Verifies a PLUME signature.
|
||||
/// Returns `true` if the signature is valid.
|
||||
pub fn verify(&self) -> bool {
|
||||
// Verifier check in SNARK:
|
||||
// g^[r + sk * c] / (g^sk)^c = g^r
|
||||
// hash[m, gsk]^[r + sk * c] / (hash[m, pk]^sk)^c = hash[m, pk]^r
|
||||
// c = hash2(g, g^sk, hash[m, g^sk], hash[m, pk]^sk, gr, hash[m, pk]^r)
|
||||
|
||||
// don't forget to check `c` is `Output<Sha256>` in the #API
|
||||
let c = panic::catch_unwind(|| Output::<Sha256>::from_slice(self.c));
|
||||
if c.is_err() {
|
||||
@@ -148,22 +128,43 @@ impl PlumeSignature<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Encodes the point by compressing it to 33 bytes
|
||||
fn encode_pt(point: &ProjectivePoint) -> Vec<u8> {
|
||||
point.to_encoded_point(true).to_bytes().to_vec()
|
||||
fn c_sha256_vec_signal(values: Vec<&ProjectivePoint>) -> Output<Sha256> {
|
||||
let preimage_vec = values
|
||||
.into_iter()
|
||||
.map(encode_pt)
|
||||
.collect::<Vec<_>>()
|
||||
.concat();
|
||||
let mut sha256_hasher = Sha256::new();
|
||||
sha256_hasher.update(preimage_vec.as_slice());
|
||||
sha256_hasher.finalize()
|
||||
}
|
||||
|
||||
/// Convert a 32-byte array to a scalar
|
||||
fn byte_array_to_scalar(bytes: &[u8]) -> Scalar {
|
||||
// From https://docs.rs/ark-ff/0.3.0/src/ark_ff/fields/mod.rs.html#371-393
|
||||
assert!(bytes.len() == 32);
|
||||
let mut res = Scalar::from(0u64);
|
||||
let window_size = Scalar::from(256u64);
|
||||
for byte in bytes.iter() {
|
||||
res *= window_size;
|
||||
res += Scalar::from(*byte as u64);
|
||||
}
|
||||
res
|
||||
// Withhold removing this before implementing `sign`
|
||||
fn sha256hash6signals(
|
||||
g: &ProjectivePoint,
|
||||
pk: &ProjectivePoint,
|
||||
hash_m_pk: &ProjectivePoint,
|
||||
nullifier: &ProjectivePoint,
|
||||
g_r: &ProjectivePoint,
|
||||
hash_m_pk_pow_r: &ProjectivePoint,
|
||||
) -> Scalar {
|
||||
let g_bytes = encode_pt(g);
|
||||
let pk_bytes = encode_pt(pk);
|
||||
let h_bytes = encode_pt(hash_m_pk);
|
||||
let nul_bytes = encode_pt(nullifier);
|
||||
let g_r_bytes = encode_pt(g_r);
|
||||
let z_bytes = encode_pt(hash_m_pk_pow_r);
|
||||
|
||||
let c_preimage_vec = [g_bytes, pk_bytes, h_bytes, nul_bytes, g_r_bytes, z_bytes].concat();
|
||||
|
||||
//println!("c_preimage_vec: {:?}", c_preimage_vec);
|
||||
|
||||
let mut sha256_hasher = Sha256::new();
|
||||
sha256_hasher.update(c_preimage_vec.as_slice());
|
||||
let sha512_hasher_result = sha256_hasher.finalize(); //512 bit hash
|
||||
|
||||
let c_bytes = FieldBytes::from_iter(sha512_hasher_result.iter().copied());
|
||||
Scalar::from_repr(c_bytes).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -181,6 +182,19 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// Convert a 32-byte array to a scalar
|
||||
fn byte_array_to_scalar(bytes: &[u8]) -> Scalar {
|
||||
// From https://docs.rs/ark-ff/0.3.0/src/ark_ff/fields/mod.rs.html#371-393
|
||||
assert!(bytes.len() == 32);
|
||||
let mut res = Scalar::from(0u64);
|
||||
let window_size = Scalar::from(256u64);
|
||||
for byte in bytes.iter() {
|
||||
res *= window_size;
|
||||
res += Scalar::from(*byte as u64);
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
// Test byte_array_to_scalar()
|
||||
#[test]
|
||||
fn test_byte_array_to_scalar() {
|
||||
|
||||
25
rust-k256/src/utils.rs
Normal file
25
rust-k256/src/utils.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use super::*;
|
||||
use k256::{
|
||||
elliptic_curve::{
|
||||
hash2curve::{ExpandMsgXmd, GroupDigest},
|
||||
sec1::ToEncodedPoint,
|
||||
},
|
||||
ProjectivePoint, Secp256k1,
|
||||
}; // requires 'getrandom' feature
|
||||
|
||||
// Hashes two values to the curve
|
||||
pub(crate) fn hash_to_curve(
|
||||
m: &[u8],
|
||||
pk: &ProjectivePoint,
|
||||
) -> Result<ProjectivePoint, k256::elliptic_curve::Error> {
|
||||
Secp256k1::hash_from_bytes::<ExpandMsgXmd<Sha256>>(
|
||||
&[[m, &encode_pt(pk)].concat().as_slice()],
|
||||
//b"CURVE_XMD:SHA-256_SSWU_RO_",
|
||||
&[DST],
|
||||
)
|
||||
}
|
||||
|
||||
/// Encodes the point by compressing it to 33 bytes
|
||||
pub(crate) fn encode_pt(point: &ProjectivePoint) -> Vec<u8> {
|
||||
point.to_encoded_point(true).to_bytes().to_vec()
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use helpers::{gen_test_scalar_sk, test_gen_signals, PlumeVersion};
|
||||
use k256::elliptic_curve::sec1::ToEncodedPoint;
|
||||
use zk_nullifier::{PlumeSignature, PlumeSignatureV1Fields, ProjectivePoint};
|
||||
use plume_rustcrypto::{PlumeSignature, PlumeSignatureV1Fields, ProjectivePoint};
|
||||
|
||||
const G: ProjectivePoint = ProjectivePoint::GENERATOR;
|
||||
const M: &[u8; 29] = b"An example app message string";
|
||||
@@ -39,7 +39,7 @@ fn plume_v1_test() {
|
||||
hashed_to_curve_r,
|
||||
}),
|
||||
};
|
||||
let verified = sig.verify_signals();
|
||||
let verified = sig.verify();
|
||||
println!("Verified: {}", verified);
|
||||
|
||||
// Print nullifier
|
||||
@@ -112,7 +112,7 @@ fn plume_v2_test() {
|
||||
s: &test_data.3,
|
||||
v1: None
|
||||
}
|
||||
.verify_signals());
|
||||
.verify());
|
||||
}
|
||||
|
||||
mod helpers {
|
||||
@@ -158,7 +158,7 @@ mod helpers {
|
||||
let pt: ProjectivePoint = Secp256k1::hash_from_bytes::<ExpandMsgXmd<Sha256>>(
|
||||
&[s],
|
||||
//b"CURVE_XMD:SHA-256_SSWU_RO_"
|
||||
&[zk_nullifier::DST],
|
||||
&[plume_rustcrypto::DST],
|
||||
)
|
||||
.unwrap();
|
||||
pt
|
||||
@@ -199,16 +199,16 @@ mod helpers {
|
||||
let g_r = &g * &r;
|
||||
|
||||
// hash[m, pk]
|
||||
let hash_m_pk =
|
||||
let hash_m_pk =
|
||||
// zk_nullifier::hash_to_curve(m, &pk)
|
||||
Secp256k1::hash_from_bytes::<ExpandMsgXmd<Sha256>>(
|
||||
&[[
|
||||
m,
|
||||
m,
|
||||
// &encode_pt(pk)
|
||||
&pk.to_encoded_point(true).to_bytes().to_vec()
|
||||
].concat().as_slice()],
|
||||
//b"CURVE_XMD:SHA-256_SSWU_RO_",
|
||||
&[zk_nullifier::DST],
|
||||
&[plume_rustcrypto::DST],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user