sigma-protocols 0.5.1

SIGMA zero-knowledge proof protocols
Documentation
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::pedersen::{PedersenProof, PedersenStatement, PedersenWitness};
use sigma_protocols::sigma::{Challenge, Commitment, ScalarChallenge, SigmaProtocol};

#[test]
fn test_pedersen_interactive() {
    let g = RISTRETTO_BASEPOINT_POINT;
    let mut h_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut h_bytes)
        .expect("Failed to generate random bytes");
    let h = Scalar::from_bytes_mod_order(h_bytes) * g;

    let mut v_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut v_bytes)
        .expect("Failed to generate random bytes");
    let value = Scalar::from_bytes_mod_order(v_bytes);
    let mut r_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut r_bytes)
        .expect("Failed to generate random bytes");
    let randomness = Scalar::from_bytes_mod_order(r_bytes);

    let commitment = value * g + randomness * h;

    let statement = PedersenStatement { g, h, commitment };
    let witness = PedersenWitness { value, randomness };

    let (prover_commitment, state) = PedersenProof::prover_commit(&statement, &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 = PedersenProof::prover_response(&statement, &witness, &state, &challenge)
        .expect("Failed to generate response");

    let result = PedersenProof::verifier(&statement, &prover_commitment, &challenge, &response);
    assert!(result.is_ok(), "Pedersen proof verification failed");
}

#[test]
fn test_pedersen_non_interactive() {
    let g = RISTRETTO_BASEPOINT_POINT;
    let mut h_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut h_bytes)
        .expect("Failed to generate random bytes");
    let h = Scalar::from_bytes_mod_order(h_bytes) * g;

    let mut v_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut v_bytes)
        .expect("Failed to generate random bytes");
    let value = Scalar::from_bytes_mod_order(v_bytes);
    let mut r_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut r_bytes)
        .expect("Failed to generate random bytes");
    let randomness = Scalar::from_bytes_mod_order(r_bytes);

    let commitment = value * g + randomness * h;

    let statement = PedersenStatement { g, h, commitment };
    let witness = PedersenWitness { value, randomness };

    let (prover_commitment, state) = PedersenProof::prover_commit(&statement, &witness);

    let mut fs = FiatShamirTransform::new(b"pedersen-proof", b"test-protocol", b"test-session");

    fs.absorb_commitment(&prover_commitment.to_bytes());

    let challenge_bytes = fs.generate_challenge(32);
    let challenge =
        ScalarChallenge::from_bytes(&challenge_bytes).expect("Failed to create challenge");

    let response = PedersenProof::prover_response(&statement, &witness, &state, &challenge)
        .expect("Failed to generate response");

    let result = PedersenProof::verifier(&statement, &prover_commitment, &challenge, &response);
    assert!(
        result.is_ok(),
        "Non-interactive Pedersen proof verification failed"
    );
}

#[test]
fn test_pedersen_invalid_proof() {
    let g = RISTRETTO_BASEPOINT_POINT;
    let mut h_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut h_bytes)
        .expect("Failed to generate random bytes");
    let h = Scalar::from_bytes_mod_order(h_bytes) * g;

    let mut v_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut v_bytes)
        .expect("Failed to generate random bytes");
    let value = Scalar::from_bytes_mod_order(v_bytes);
    let mut r_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut r_bytes)
        .expect("Failed to generate random bytes");
    let randomness = Scalar::from_bytes_mod_order(r_bytes);

    let commitment = value * g + randomness * h;

    let mut wv_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut wv_bytes)
        .expect("Failed to generate random bytes");
    let wrong_value = Scalar::from_bytes_mod_order(wv_bytes);
    let mut wr_bytes = [0u8; 32];
    OsRng
        .try_fill_bytes(&mut wr_bytes)
        .expect("Failed to generate random bytes");
    let wrong_randomness = Scalar::from_bytes_mod_order(wr_bytes);

    let statement = PedersenStatement { g, h, commitment };
    let wrong_witness = PedersenWitness {
        value: wrong_value,
        randomness: wrong_randomness,
    };

    let (prover_commitment, state) = PedersenProof::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 = PedersenProof::prover_response(&statement, &wrong_witness, &state, &challenge)
        .expect("Failed to generate response");

    let result = PedersenProof::verifier(&statement, &prover_commitment, &challenge, &response);
    assert!(result.is_err(), "Invalid Pedersen proof should not verify");
}