use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use crate::error::Result;
use crate::sigma::{PointCommitment, ScalarChallenge, ScalarResponse, SigmaProtocol};
use crate::utils::{random_scalar, scalar_from_state};
#[derive(Clone, Debug)]
pub struct SchnorrStatement {
pub public_key: RistrettoPoint,
}
#[derive(Clone, Debug)]
pub struct SchnorrWitness {
pub secret_key: Scalar,
}
pub struct SchnorrProof;
impl SigmaProtocol for SchnorrProof {
type Statement = SchnorrStatement;
type Witness = SchnorrWitness;
type Commitment = PointCommitment;
type Challenge = ScalarChallenge;
type Response = ScalarResponse;
fn prover_commit(
_statement: &Self::Statement,
_witness: &Self::Witness,
) -> (Self::Commitment, Vec<u8>) {
let r = random_scalar();
let commitment = r * RISTRETTO_BASEPOINT_POINT;
(PointCommitment(commitment), r.to_bytes().to_vec())
}
fn prover_response(
_statement: &Self::Statement,
witness: &Self::Witness,
state: &[u8],
challenge: &Self::Challenge,
) -> Result<Self::Response> {
let r = scalar_from_state(state)?;
let response = r + challenge.0 * witness.secret_key;
Ok(ScalarResponse(response))
}
fn verifier(
statement: &Self::Statement,
commitment: &Self::Commitment,
challenge: &Self::Challenge,
response: &Self::Response,
) -> Result<()> {
let lhs = response.0 * RISTRETTO_BASEPOINT_POINT;
let rhs = commitment.0 + challenge.0 * statement.public_key;
if lhs == rhs {
Ok(())
} else {
Err(crate::error::Error::InvalidProof)
}
}
}