use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::scalar::Scalar;
use rand::rngs::OsRng;
use rand::TryRngCore;
use sigma_protocols::fiat_shamir::FiatShamirTransform;
use sigma_protocols::protocols::schnorr::{SchnorrProof, SchnorrStatement, SchnorrWitness};
use sigma_protocols::sigma::{Challenge, Commitment, Response, ScalarChallenge, SigmaProtocol};
#[test]
fn test_schnorr_interactive() {
let mut sk_bytes = [0u8; 32];
OsRng
.try_fill_bytes(&mut sk_bytes)
.expect("Failed to generate random bytes");
let secret_key = Scalar::from_bytes_mod_order(sk_bytes);
let public_key = secret_key * RISTRETTO_BASEPOINT_POINT;
let statement = SchnorrStatement { public_key };
let witness = SchnorrWitness { secret_key };
let (commitment, state) = SchnorrProof::prover_commit(&statement, &witness);
let mut challenge_bytes = [0u8; 32];
OsRng
.try_fill_bytes(&mut challenge_bytes)
.expect("Failed to generate random bytes");
let challenge_scalar = Scalar::from_bytes_mod_order(challenge_bytes);
let challenge = ScalarChallenge(challenge_scalar);
let response = SchnorrProof::prover_response(&statement, &witness, &state, &challenge)
.expect("Failed to generate response");
let result = SchnorrProof::verifier(&statement, &commitment, &challenge, &response);
assert!(result.is_ok(), "Proof verification failed");
}
#[test]
fn test_schnorr_non_interactive() {
let mut sk_bytes = [0u8; 32];
OsRng
.try_fill_bytes(&mut sk_bytes)
.expect("Failed to generate random bytes");
let secret_key = Scalar::from_bytes_mod_order(sk_bytes);
let public_key = secret_key * RISTRETTO_BASEPOINT_POINT;
let statement = SchnorrStatement { public_key };
let witness = SchnorrWitness { secret_key };
let (commitment, state) = SchnorrProof::prover_commit(&statement, &witness);
let mut fs = FiatShamirTransform::new(b"schnorr-proof", b"test-protocol", b"test-session");
fs.absorb_commitment(&commitment.to_bytes());
let challenge_bytes = fs.generate_challenge(32);
let challenge =
ScalarChallenge::from_bytes(&challenge_bytes).expect("Failed to create challenge");
let response = SchnorrProof::prover_response(&statement, &witness, &state, &challenge)
.expect("Failed to generate response");
let result = SchnorrProof::verifier(&statement, &commitment, &challenge, &response);
assert!(result.is_ok(), "Non-interactive proof verification failed");
let mut verifier_fs =
FiatShamirTransform::new(b"schnorr-proof", b"test-protocol", b"test-session");
let verify_result = verifier_fs.verify_transcript(
&commitment.to_bytes(),
&challenge_bytes,
&response.to_bytes(),
);
assert!(verify_result.is_ok(), "Transcript verification failed");
}
#[test]
fn test_schnorr_invalid_proof() {
let mut sk_bytes = [0u8; 32];
OsRng
.try_fill_bytes(&mut sk_bytes)
.expect("Failed to generate random bytes");
let secret_key = Scalar::from_bytes_mod_order(sk_bytes);
let public_key = secret_key * RISTRETTO_BASEPOINT_POINT;
let mut ws_bytes = [0u8; 32];
OsRng
.try_fill_bytes(&mut ws_bytes)
.expect("Failed to generate random bytes");
let wrong_secret = Scalar::from_bytes_mod_order(ws_bytes);
let statement = SchnorrStatement { public_key };
let wrong_witness = SchnorrWitness {
secret_key: wrong_secret,
};
let (commitment, state) = SchnorrProof::prover_commit(&statement, &wrong_witness);
let mut ch_bytes = [0u8; 32];
OsRng
.try_fill_bytes(&mut ch_bytes)
.expect("Failed to generate random bytes");
let challenge = ScalarChallenge(Scalar::from_bytes_mod_order(ch_bytes));
let response = SchnorrProof::prover_response(&statement, &wrong_witness, &state, &challenge)
.expect("Failed to generate response");
let result = SchnorrProof::verifier(&statement, &commitment, &challenge, &response);
assert!(result.is_err(), "Invalid proof should not verify");
}