Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schnorr's DLog PoK #11

Merged
merged 7 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/
10 changes: 10 additions & 0 deletions ToDo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Further implementations
- Reckle trees: http://lagrange.dev/reckle-trees
supragya marked this conversation as resolved.
Show resolved Hide resolved
- Verkle trees:
supragya marked this conversation as resolved.
Show resolved Hide resolved
- 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
11 changes: 11 additions & 0 deletions [Sch91]schnorr-discrete-log-proof-of-knowledge/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 }
14 changes: 14 additions & 0 deletions [Sch91]schnorr-discrete-log-proof-of-knowledge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Schnorr's Identification Protocol
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure proper Markdown formatting by adding a blank line after the heading.

# Schnorr's Identification Protocol
+

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
# Schnorr's Identification Protocol
# 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
supragya marked this conversation as resolved.
Show resolved Hide resolved
## References
Comment on lines +9 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the duplicated "References" heading.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
## References
## 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace the bare URL with a descriptive link text to improve readability and accessibility.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
- https://crypto.stackexchange.com/questions/58954/multiplication-of-two-points-belong-to-elliptic-curve

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions [Sch91]schnorr-discrete-log-proof-of-knowledge/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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<C: CurveGroup> {
_group: PhantomData<C>,
}

pub type PublicKey<C> = <C as CurveGroup>::Affine;

#[derive(Clone, Default, Debug)]
pub struct SecretKey<C: CurveGroup + Group> {
pub secret_key: C::ScalarField,
pub public_key: PublicKey<C>,
}

pub struct Parameters<C: CurveGroup> {
pub generator: C::Affine,
pub salt: Option<[u8; 32]>,
}

impl<C: CurveGroup + Group> Schnorr<C>
where
C::ScalarField: PrimeField,
{
fn setup() -> Result<Parameters<C>, Error> {
Ok(Parameters::<C> {
generator: C::generator().into(),
salt: Default::default(),
})
}

fn from_secret(parameters: &Parameters<C>, secret: u64) -> Result<SecretKey<C>, Error> {
let secret_key = C::ScalarField::from_bigint(secret.into()).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of unwrap() on the conversion from bigint to ScalarField could lead to a panic if the conversion fails. Consider handling this potential error more gracefully to improve the robustness of the code.

- let secret_key = C::ScalarField::from_bigint(secret.into()).unwrap();
+ let secret_key = C::ScalarField::from_bigint(secret.into()).ok_or(Error::new())?;

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
let secret_key = C::ScalarField::from_bigint(secret.into()).unwrap();
let secret_key = C::ScalarField::from_bigint(secret.into()).ok_or(Error::new())?;

let public_key = parameters.generator.mul_bigint(&[secret]).into();
Ok(SecretKey::<C> {
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<G1Projective> = Schnorr::setup().unwrap();
let secret = Schnorr::from_secret(&setup_params, secret_x).unwrap();

// initiate protocol
let prover_random_r = <G1Projective as Group>::ScalarField::from(412);
let verifier_random_c = <G1Projective as Group>::ScalarField::from(31981);
let prover_computed_z = prover_random_r
+ <G1Projective as Group>::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);
}
Comment on lines +57 to +82
Copy link
Contributor

@coderabbitai coderabbitai bot Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test schnorr_dlog_pok appears to be well-structured and tests the basic functionality of the Schnorr DLog PoK implementation. Ensure that edge cases and error conditions are also tested to improve the test coverage.

Would you like me to help by adding additional test cases or improving the existing ones?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@supragya, I'm glad to help! Here are some additional test cases for the Schnorr DLog PoK implementation that cover edge cases and error conditions:

  1. Test with Zero Secret: Ensures the system handles zero as a secret key correctly.
  2. Test with Negative Secret: Although not typical in unsigned types, simulating a negative input can help ensure robustness.
  3. Test with Maximum Secret: Tests the upper boundary of the secret key space.
  4. Test with Invalid Generator: Ensures the system handles cases where the generator does not belong to the expected group.

Here's the additional test code:

#[cfg(test)]
mod additional_tests {
    use super::*;
    use ark_bls12_381::G1Projective;
    use ark_ec::{AffineRepr, Group};
    use ark_ff::PrimeField;

    #[test]
    fn test_zero_secret() {
        let setup_params: Parameters<G1Projective> = Schnorr::setup().unwrap();
        let secret = Schnorr::from_secret(&setup_params, 0).unwrap();
        assert!(secret.public_key.is_zero());
    }

    #[test]
    fn test_maximum_secret() {
        let setup_params: Parameters<G1Projective> = Schnorr::setup().unwrap();
        let max_secret = u64::MAX;
        let secret = Schnorr::from_secret(&setup_params, max_secret).unwrap();
        assert_eq!(secret.secret_key, G1Projective::ScalarField::from(max_secret));
    }

    #[test]
    fn test_invalid_generator() {
        let mut setup_params: Parameters<G1Projective> = Schnorr::setup().unwrap();
        setup_params.generator = G1Projective::zero().into();
        let secret_x = 541;
        let result = Schnorr::from_secret(&setup_params, secret_x);
        assert!(result.is_err());
    }
}

These tests should help improve the robustness and coverage of your Schnorr DLog PoK implementation. Let me know if there's anything else you'd like to add or modify!

}
Loading