From f40697817a16b5fbace944249c617e75ff378227 Mon Sep 17 00:00:00 2001 From: asherli <444649358@qq.com> Date: Tue, 29 Oct 2024 15:49:12 +0800 Subject: [PATCH] add secp256k1 vrf rust part --- Cargo.lock | 254 +++++++++++++++++++++- Cargo.toml | 2 +- Changelog.md | 7 + crypto/vrf/secp256k1/Cargo.toml | 17 ++ crypto/vrf/secp256k1/src/lib.rs | 362 ++++++++++++++++++++++++++++++++ release_note.txt | 2 +- 6 files changed, 636 insertions(+), 8 deletions(-) create mode 100644 crypto/vrf/secp256k1/Cargo.toml create mode 100644 crypto/vrf/secp256k1/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 07006cb..438c47a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,6 +129,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.12.3" @@ -141,6 +147,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "1.3.2" @@ -195,6 +207,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "block-modes" version = "0.7.0" @@ -360,6 +381,12 @@ dependencies = [ "unreachable", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -436,6 +463,28 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "typenum", +] + [[package]] name = "crypto-mac" version = "0.8.0" @@ -493,9 +542,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", @@ -504,6 +553,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "digest" version = "0.6.1" @@ -531,13 +590,40 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "serdect", + "signature 2.2.0", + "spki", +] + [[package]] name = "ed25519" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "signature", + "signature 1.6.4", ] [[package]] @@ -546,7 +632,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "curve25519-dalek 3.2.1", + "curve25519-dalek 3.2.0", "ed25519", "rand 0.7.3", "serde", @@ -566,6 +652,26 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562cc8504a01eb20c10fb154abd7c4baeb9beba2329cf85838ee2bd48a468b18" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array 0.14.7", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "errno" version = "0.3.8" @@ -700,6 +806,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ffi_c_crypto_binary" version = "1.0.0" @@ -783,6 +899,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -815,6 +932,17 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "half" version = "1.8.2" @@ -866,6 +994,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "hmac-drbg" version = "0.3.0" @@ -930,6 +1067,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "serdect", + "sha2 0.10.8", + "signature 2.2.0", +] + [[package]] name = "keccak" version = "0.1.4" @@ -1167,6 +1319,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.28" @@ -1529,6 +1691,16 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + [[package]] name = "ripemd160" version = "0.6.0" @@ -1592,6 +1764,21 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "secp256k1" version = "0.26.0" @@ -1666,6 +1853,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" version = "0.6.0" @@ -1692,6 +1889,17 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + [[package]] name = "sha3" version = "0.6.0" @@ -1723,6 +1931,16 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "sm4" version = "0.3.0" @@ -1734,6 +1952,16 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "sputnikvm" version = "0.10.1" @@ -2464,6 +2692,20 @@ dependencies = [ "wedpr_l_utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wedpr_l_crypto_vrf_secp256k1" +version = "1.4.0" +dependencies = [ + "k256", + "rand 0.6.5", + "serde", + "sha2 0.10.8", + "wedpr_l_crypto_hash_keccak256 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wedpr_l_crypto_zkp_utils 1.2.0", + "wedpr_l_macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wedpr_l_utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wedpr_l_crypto_zkp_discrete_logarithm_proof" version = "1.3.0" @@ -2726,9 +2968,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] diff --git a/Cargo.toml b/Cargo.toml index 767d4d4..942011b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ members = [ "crypto/signature/ed25519", "crypto/signature/secp256k1", "crypto/signature/sm2", - "crypto/vrf/curve25519", + "crypto/vrf/curve25519", "crypto/vrf/secp256k1", "crypto/zkp/discrete_logarithm_proof", "crypto/zkp/range_proof", "crypto/zkp/utils", diff --git a/Changelog.md b/Changelog.md index 0e1bc8b..1bb5ba0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,10 @@ +## v1.4.0 +(2024-10-28) + +**新增** + +- 新增基于secp256k1曲线的ecvrf + ## v1.3.0 (2022-08-22) diff --git a/crypto/vrf/secp256k1/Cargo.toml b/crypto/vrf/secp256k1/Cargo.toml new file mode 100644 index 0000000..de01fa1 --- /dev/null +++ b/crypto/vrf/secp256k1/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "wedpr_l_crypto_vrf_secp256k1" +version = "1.4.0" +authors = ["WeDPR "] +edition = "2018" +license = "Apache-2.0" +description = "Library of WeDPR shared VRF Function implement by secp256k1." + +[dependencies] +k256 = { version = "0.13.4", features = ["serde", "arithmetic"] } +rand = "0.6" +sha2 = "0.10.8" +wedpr_l_crypto_hash_keccak256 = "1.1.0" +wedpr_l_crypto_zkp_utils = "1.2.0" +wedpr_l_macros = "1.0.0" +wedpr_l_utils = "1.1.0" +serde = { version = "1.0", features = ["derive"] } diff --git a/crypto/vrf/secp256k1/src/lib.rs b/crypto/vrf/secp256k1/src/lib.rs new file mode 100644 index 0000000..d5cedfe --- /dev/null +++ b/crypto/vrf/secp256k1/src/lib.rs @@ -0,0 +1,362 @@ +// Copyright 2024 WeDPR Lab Project Authors. Licensed under Apache-2.0. + +//! secp256k1 VRF functions. + +extern crate k256; + +use k256::{ + elliptic_curve::{ + generic_array::GenericArray, rand_core::OsRng, sec1::FromEncodedPoint, + PrimeField, + }, + AffinePoint, EncodedPoint, Scalar, +}; +use wedpr_l_utils::traits::Vrf; + +use crate::k256::elliptic_curve::{ + group::{prime::PrimeCurveAffine, GroupEncoding}, + Field, +}; +use sha2::{Digest, Sha256}; +use wedpr_l_utils::error::WedprError; + +const SECP256K1_POINT_LENGTH: usize = 33; +const SECP256K1_SCALAR_LENGTH: usize = 32; + +/// Implements secp256k1 as a VRF instance. +#[derive(PartialEq, Debug, Clone, Default)] +pub struct WedprSecp256k1Vrf { + // 33 bytes + pub gamma_param: Vec, + // 32 bytes + pub c_param: Vec, + // 32 bytes + pub s_param: Vec, +} + +fn hash_to_scalar(hash_vec: &Vec) -> Result { + let mut hasher = Sha256::new(); + hasher.update(hash_vec); + let hash_vec = hasher.finalize().to_vec(); + + let array: GenericArray = + GenericArray::clone_from_slice(hash_vec.as_slice()); + + let scalar_option = k256::Scalar::from_repr(array); + + if scalar_option.is_some().into() { + return Ok(scalar_option.unwrap()); + } else { + return Err(WedprError::FormatError); + }; +} + +fn bytes_to_affine(bytes: &[u8]) -> Result { + let encoded_point = EncodedPoint::from_bytes(bytes); + match encoded_point { + Ok(encoded_point) => { + let affine_point = AffinePoint::from_encoded_point(&encoded_point); + if affine_point.is_some().into() { + return Ok(affine_point.unwrap()); + } else { + return Err(WedprError::FormatError); + } + }, + Err(_) => Err(WedprError::FormatError), + } +} + +fn bytes_to_scalar(bytes: &[u8]) -> Result { + let scalar_option = + k256::Scalar::from_repr(GenericArray::clone_from_slice(bytes)); + if scalar_option.is_some().into() { + return Ok(scalar_option.unwrap()); + } else { + return Err(WedprError::FormatError); + } +} + +impl Vrf for WedprSecp256k1Vrf { + fn encode_proof(&self) -> Vec { + let mut proof = Vec::new(); + proof.append(&mut self.gamma_param.to_vec()); + proof.append(&mut self.c_param.to_vec()); + proof.append(&mut self.s_param.to_vec()); + proof + } + + fn decode_proof>( + proof: &T, + ) -> Result { + if proof.as_ref().len() + != (SECP256K1_POINT_LENGTH + + SECP256K1_SCALAR_LENGTH + + SECP256K1_SCALAR_LENGTH) + { + return Err(WedprError::FormatError); + } + let mut gamma = [0u8; SECP256K1_POINT_LENGTH]; + gamma.copy_from_slice(&proof.as_ref()[0..SECP256K1_POINT_LENGTH]); + + let mut c = [0u8; SECP256K1_SCALAR_LENGTH]; + c.copy_from_slice( + &proof.as_ref()[SECP256K1_POINT_LENGTH + ..SECP256K1_POINT_LENGTH + SECP256K1_SCALAR_LENGTH], + ); + + let mut s = [0u8; SECP256K1_SCALAR_LENGTH]; + s.copy_from_slice( + &proof.as_ref()[SECP256K1_POINT_LENGTH + SECP256K1_SCALAR_LENGTH + ..SECP256K1_POINT_LENGTH + + SECP256K1_SCALAR_LENGTH + + SECP256K1_SCALAR_LENGTH], + ); + Ok(WedprSecp256k1Vrf { + gamma_param: gamma.to_vec(), + c_param: c.to_vec(), + s_param: s.to_vec(), + }) + } + + fn prove>( + private_key: &T, + message: &T, + ) -> Result + where + Self: Sized, + { + let private_key_result = + k256::SecretKey::from_slice(private_key.as_ref()); + + let private_key = match private_key_result { + Ok(private_key) => private_key, + Err(_) => return Err(WedprError::FormatError), + }; + + let private_key_scalar: Scalar = + private_key.as_scalar_primitive().into(); + + let public_key = private_key.public_key(); + + let public_key_bytes = public_key.as_affine().to_bytes().to_vec(); + + let message = message.as_ref(); + + let mut hash_vec = Vec::new(); + hash_vec.append(&mut public_key_bytes.clone()); + hash_vec.append(&mut message.to_vec()); + + let h_scalar_result = hash_to_scalar(&hash_vec); + let h_scalar = match h_scalar_result { + Ok(h_scalar_result) => h_scalar_result, + Err(_) => return Err(WedprError::FormatError), + }; + + let base_point = k256::AffinePoint::generator(); + let h_point = base_point * h_scalar; + + let gamma = h_point * private_key_scalar; + + let blinding_k = k256::Scalar::random(&mut OsRng); + + let scalar_k = private_key_scalar * blinding_k; + + let point_k = base_point * scalar_k; + + let point_kh = h_point * scalar_k; + + let mut c_vec = Vec::new(); + c_vec.append(&mut h_point.to_bytes().to_vec()); + c_vec.append(&mut gamma.to_bytes().to_vec()); + c_vec.append(&mut point_k.to_bytes().to_vec()); + c_vec.append(&mut point_kh.to_bytes().to_vec()); + + let c_scalar_result = hash_to_scalar(&c_vec); + let c_scalar = match c_scalar_result { + Ok(c_scalar_result) => c_scalar_result, + Err(_) => return Err(WedprError::FormatError), + }; + + let s = scalar_k + (c_scalar * private_key_scalar); + + // println!("gamma : {:?}", gamma.to_bytes().to_vec()); + // println!("c : {:?}", c_scalar.to_bytes().to_vec()); + // println!("s : {:?}", s.to_bytes().to_vec()); + + return Ok(WedprSecp256k1Vrf { + gamma_param: gamma.to_bytes().to_vec(), + c_param: c_scalar.to_bytes().to_vec(), + s_param: s.to_bytes().to_vec(), + }); + } + + fn prove_fast>( + private_key: &T, + public_key: &T, + message: &T, + ) -> Result + where + Self: Sized, + { + // TODO: We found use input public key directly is slower than derive + // public key from private key + Self::prove(private_key, message) + } + + fn verify>( + &self, + public_key: &T, + message: &T, + ) -> bool { + let public_key_bytes = public_key.as_ref().to_vec(); + + let public_key_point = match bytes_to_affine(&public_key_bytes) { + Ok(public_key_point) => public_key_point, + Err(_) => return false, + }; + + let message = message.as_ref(); + + let mut hash_vec = Vec::new(); + hash_vec.append(&mut public_key_bytes.clone()); + hash_vec.append(&mut message.to_vec()); + + let base_point = k256::AffinePoint::generator(); + + let h_scalar = hash_to_scalar(&hash_vec).unwrap(); + let h_point = base_point * h_scalar; + + let gamma = match bytes_to_affine(&self.gamma_param) { + Ok(gamma) => gamma, + Err(_) => return false, + }; + + let c = match bytes_to_scalar(&self.c_param) { + Ok(c) => c, + Err(_) => return false, + }; + + let s = match bytes_to_scalar(&self.s_param) { + Ok(s) => s, + Err(_) => return false, + }; + + let u = (base_point * s) - (public_key_point * c); + let v = (h_point * s) - (gamma * c); + + let mut c_vec = Vec::new(); + c_vec.append(&mut h_point.to_bytes().to_vec()); + c_vec.append(&mut self.gamma_param.clone()); + c_vec.append(&mut u.to_bytes().to_vec()); + c_vec.append(&mut v.to_bytes().to_vec()); + + let c_scalar_result = hash_to_scalar(&c_vec); + let c_scalar = match c_scalar_result { + Ok(c_scalar_result) => c_scalar_result, + Err(_) => return false, + }; + + return c_scalar.to_bytes().to_vec().eq(self.c_param.as_slice()); + } + + fn derive_public_key>(private_key: &T) -> Vec { + let private_key_result = + k256::SecretKey::from_slice(private_key.as_ref()); + + let private_key = match private_key_result { + Ok(private_key) => private_key, + Err(_) => return Vec::new(), + }; + + let public_key = private_key.public_key(); + + public_key.as_affine().to_bytes().to_vec() + } + + fn is_valid_public_key>(public_key: &T) -> bool { + let public_key_bytes = public_key.as_ref().to_vec(); + match bytes_to_affine(&public_key_bytes) { + Ok(_) => return true, + Err(_) => return false, + }; + } + + fn proof_to_hash(&self) -> Result, WedprError> { + let gamma = match bytes_to_affine(&self.gamma_param) { + Ok(gamma) => gamma, + Err(_) => return Err(WedprError::FormatError), + }; + + let base_order = Scalar::from_u128(8); + let base = gamma * base_order; + + let mut hasher = Sha256::new(); + hasher.update(base.to_bytes().as_slice()); + let hash_vec = hasher.finalize().to_vec(); + + Ok(hash_vec) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_secp256k1_vrf() { + let private_key = k256::SecretKey::random(&mut OsRng); + let public_key = private_key.public_key(); + let message = "hello world".as_bytes().to_vec(); + + let proof = WedprSecp256k1Vrf::prove( + &private_key.to_bytes().to_vec(), + &message, + ) + .unwrap(); + + assert_eq!( + proof.verify(&public_key.as_affine().to_bytes().to_vec(), &message), + true + ); + // println!("proof hash : {:?}", proof.proof_to_hash().unwrap()); + } + + #[test] + fn test_encode_proof() { + let private_key = k256::SecretKey::random(&mut OsRng); + // let public_key = private_key.public_key(); + let message = "hello world".as_bytes().to_vec(); + + let proof = WedprSecp256k1Vrf::prove( + &private_key.to_bytes().to_vec(), + &message, + ) + .unwrap(); + let encoded_proof = proof.encode_proof(); + // println!("encoded_proof : {:?}, length: {}", encoded_proof, + // encoded_proof.len()); + let decoded_proof = + WedprSecp256k1Vrf::decode_proof(&encoded_proof).unwrap(); + assert_eq!(decoded_proof, proof); + + assert_eq!( + proof.verify( + &private_key.public_key().as_affine().to_bytes().to_vec(), + &message + ), + true + ); + } + + #[test] + fn test_utils() { + let private_key = k256::SecretKey::random(&mut OsRng); + let public_key = private_key.public_key(); + let expected_pk = WedprSecp256k1Vrf::derive_public_key( + &private_key.to_bytes().to_vec(), + ); + assert_eq!(public_key.as_affine().to_bytes().to_vec(), expected_pk); + + assert_eq!(WedprSecp256k1Vrf::is_valid_public_key(&expected_pk), true); + } +} diff --git a/release_note.txt b/release_note.txt index 8b3a022..ec7b967 100644 --- a/release_note.txt +++ b/release_note.txt @@ -1 +1 @@ -v1.3.0 \ No newline at end of file +v1.4.0 \ No newline at end of file