diff --git a/Cargo.toml b/Cargo.toml index 06e6406..7e726fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "halo2-trials", "[Sha97]shamir-secret-sharing", "[Fel87]feldman-verifiable-secret-sharing", + "[Sch91]schnorr-discrete-log-proof-of-knowledge", ] resolver = "2" @@ -18,6 +19,7 @@ ark-bls12-381 = "0.4.0" ark-ec = "0.4.2" ark-ff = "0.4.2" ark-std = "0.4.0" +ark-crypto-primitives = "0.4.0" num-traits = "0.2.18" nalgebra = "0.32.5" halo2 = "0.0.0" diff --git a/README.md b/README.md index 109b828..f4be4e8 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,4 @@ cd Cryptography-Research && cargo test ## References - **\[Sha97\]**: Shamir's secret sharing https://apps.dtic.mil/sti/pdfs/ADA069397.pdf. - **\[Fel87\]**: Feldman's verifiable secret sharing https://www.zkdocs.com/docs/zkdocs/protocol-primitives/verifiable-secret-sharing/ +- **\[Sch91\]**: Schnorr's DLog PoK https://www.zkdocs.com/docs/zkdocs/zero-knowledge-protocols/schnorr/ diff --git a/ToDo.md b/ToDo.md new file mode 100644 index 0000000..98b5372 --- /dev/null +++ b/ToDo.md @@ -0,0 +1,10 @@ +## Further implementations +- Reckle trees: http://lagrange.dev/reckle-trees +- Verkle trees: +- Caulk lookup argument +- Caulk+ lookup argument +- Halo2 lookup argument +- Plonk lookup argument +- Lagrange interpolation +- Multivariate polynomial domain extension +- Weak fiat shamir: https://eprint.iacr.org/2023/691.pdf diff --git a/[Sch91]schnorr-discrete-log-proof-of-knowledge/Cargo.toml b/[Sch91]schnorr-discrete-log-proof-of-knowledge/Cargo.toml new file mode 100644 index 0000000..3f73410 --- /dev/null +++ b/[Sch91]schnorr-discrete-log-proof-of-knowledge/Cargo.toml @@ -0,0 +1,11 @@ +[package] +edition = "2021" +name = "schnorr-discrete-log-proof-of-knowledge" +version = "0.1.0" + +[dependencies] +ark-bls12-381 = { workspace = true } +ark-crypto-primitives = { workspace = true } +ark-ec = { workspace = true } +ark-ff = { workspace = true } +ark-std = { workspace = true } diff --git a/[Sch91]schnorr-discrete-log-proof-of-knowledge/README.md b/[Sch91]schnorr-discrete-log-proof-of-knowledge/README.md new file mode 100644 index 0000000..9731952 --- /dev/null +++ b/[Sch91]schnorr-discrete-log-proof-of-knowledge/README.md @@ -0,0 +1,14 @@ +# Schnorr's Identification Protocol +Schnorr's Identification Protocol represented in this repo via \[Sch91\] is a simple zero-knowledge protocol wherein a prover $P$ can convince a verifier $V$ that they know of some private value $x$ under $G$ (where discrete-log problem is hard), against a securely held value $h=g^x$ (where $g$ is a generator of $G$) at $V$ without revealing $x$ itself. + +In the interactive format, the protocol runs as follows: +![Interactive Schnorr Protocol](assets/interactive_schnorr.png) + +Here, generation of $u$ is necessary to maintain secrecy of x (the additive blinding factor). As without the value $r$, $z = x c$, and $x$ can be retrieved by operation $x = z c^{-1}$ where $c^{-1}$ is the inverse of element $c$ in the group. + +## References +## References + +[Stanford CS355 Lecture 5](https://crypto.stanford.edu/cs355/19sp/lec5.pdf) + +- https://crypto.stackexchange.com/questions/58954/multiplication-of-two-points-belong-to-elliptic-curve diff --git a/[Sch91]schnorr-discrete-log-proof-of-knowledge/assets/interactive_schnorr.png b/[Sch91]schnorr-discrete-log-proof-of-knowledge/assets/interactive_schnorr.png new file mode 100644 index 0000000..bb312fb Binary files /dev/null and b/[Sch91]schnorr-discrete-log-proof-of-knowledge/assets/interactive_schnorr.png differ diff --git a/[Sch91]schnorr-discrete-log-proof-of-knowledge/src/lib.rs b/[Sch91]schnorr-discrete-log-proof-of-knowledge/src/lib.rs new file mode 100644 index 0000000..f709441 --- /dev/null +++ b/[Sch91]schnorr-discrete-log-proof-of-knowledge/src/lib.rs @@ -0,0 +1,83 @@ +// Much reference borrowed from +// https://github.com/arkworks-rs/r1cs-tutorial/blob/main/simple-payments/src/signature/schnorr/mod.rs#L53 + +use std::marker::PhantomData; + +use ark_crypto_primitives::Error; +use ark_ec::{AffineRepr, CurveGroup, Group}; +use ark_ff::PrimeField; + +pub struct Schnorr { + _group: PhantomData, +} + +pub type PublicKey = ::Affine; + +#[derive(Clone, Default, Debug)] +pub struct SecretKey { + pub secret_key: C::ScalarField, + pub public_key: PublicKey, +} + +pub struct Parameters { + pub generator: C::Affine, + pub salt: Option<[u8; 32]>, +} + +impl Schnorr +where + C::ScalarField: PrimeField, +{ + fn setup() -> Result, Error> { + Ok(Parameters:: { + generator: C::generator().into(), + salt: Default::default(), + }) + } + + fn from_secret(parameters: &Parameters, secret: u64) -> Result, Error> { + let secret_key = C::ScalarField::from_bigint(secret.into()).unwrap(); + let public_key = parameters.generator.mul_bigint(&[secret]).into(); + Ok(SecretKey:: { + secret_key, + public_key, + }) + } +} + +#[cfg(test)] +mod tests { + use ark_bls12_381::G1Projective; + use ark_ec::{AffineRepr, Group}; + use ark_ff::PrimeField; + + use super::Schnorr; + use crate::Parameters; + + #[test] + fn schnorr_dlog_pok() { + let secret_x = 541; + let setup_params: Parameters = Schnorr::setup().unwrap(); + let secret = Schnorr::from_secret(&setup_params, secret_x).unwrap(); + + // initiate protocol + let prover_random_r = ::ScalarField::from(412); + let verifier_random_c = ::ScalarField::from(31981); + let prover_computed_z = prover_random_r + + ::ScalarField::from(secret_x) * verifier_random_c; + + let prover_generated_u = setup_params + .generator + .mul_bigint(prover_random_r.into_bigint()); + + let verifier_lhs = setup_params + .generator + .mul_bigint(prover_computed_z.into_bigint()); + let verifier_rhs = prover_generated_u + + secret + .public_key + .mul_bigint(verifier_random_c.into_bigint()); + + assert_eq!(verifier_lhs, verifier_rhs); + } +}