mod bytes;
mod parse;
mod serialize;
mod verify;
#[cfg(feature = "private_key")]
mod sign;
#[cfg(feature = "compute_key")]
use crate::ComputeKey;
#[cfg(feature = "private_key")]
use crate::PrivateKey;
use crate::address::Address;
use snarkvm_console_network::prelude::*;
use snarkvm_console_types::{Field, Scalar};
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Signature<N: Network> {
challenge: Scalar<N>,
response: Scalar<N>,
compute_key: ComputeKey<N>,
}
impl<N: Network> From<(Scalar<N>, Scalar<N>, ComputeKey<N>)> for Signature<N> {
fn from((challenge, response, compute_key): (Scalar<N>, Scalar<N>, ComputeKey<N>)) -> Self {
Self { challenge, response, compute_key }
}
}
impl<N: Network> From<&(Scalar<N>, Scalar<N>, ComputeKey<N>)> for Signature<N> {
fn from((challenge, response, compute_key): &(Scalar<N>, Scalar<N>, ComputeKey<N>)) -> Self {
Self { challenge: *challenge, response: *response, compute_key: *compute_key }
}
}
impl<N: Network> Signature<N> {
pub const fn challenge(&self) -> Scalar<N> {
self.challenge
}
pub const fn response(&self) -> Scalar<N> {
self.response
}
pub const fn compute_key(&self) -> ComputeKey<N> {
self.compute_key
}
pub fn to_address(&self) -> Address<N> {
self.compute_key.to_address()
}
}
#[cfg(test)]
mod test_helpers {
use super::*;
use snarkvm_console_network::Testnet3;
type CurrentNetwork = Testnet3;
pub(super) fn sample_signature(num_fields: u64, rng: &mut TestRng) -> Signature<CurrentNetwork> {
let private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let address = Address::try_from(&private_key).unwrap();
let message: Vec<_> = (0..num_fields).map(|_| Uniform::rand(rng)).collect();
let signature = Signature::sign(&private_key, &message, rng).unwrap();
assert!(signature.verify(&address, &message));
signature
}
}
#[cfg(test)]
mod tests {
use super::*;
const ITERATIONS: u64 = 100;
#[test]
fn test_from() -> Result<()> {
let mut rng = TestRng::default();
for i in 0..ITERATIONS {
let signature = test_helpers::sample_signature(i, &mut rng);
let candidate = Signature::from((signature.challenge(), signature.response(), signature.compute_key()));
assert_eq!(signature, candidate);
}
Ok(())
}
}