ps_sig 0.2.0

Pointcheval Sanders signatures
Documentation
use amcl_wrapper::field_elem::FieldElement;
use amcl_wrapper::group_elem::GroupElement;

use crate::errors::PSError;
use crate::{VerkeyGroup, SignatureGroup};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Sigkey {
    pub x: FieldElement,
    pub y: Vec<FieldElement>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Verkey {
    pub X_tilde: VerkeyGroup,
    pub Y_tilde: Vec<VerkeyGroup>,
}

// Parameters generated by random oracle.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Params {
    pub g: SignatureGroup,
    pub g_tilde: VerkeyGroup,
}

impl Params {
    /// Generate g1, g2. These are shared by signer and all users.
    pub fn new(label: &[u8]) -> Self {
        let g = SignatureGroup::from_msg_hash(&[label, " : g".as_bytes()].concat());
        let g_tilde = VerkeyGroup::from_msg_hash(&[label, " : g_tilde".as_bytes()].concat());
        Self { g, g_tilde }
    }
}

/// Generate signing and verification keys for scheme from 2016 paper
pub fn keygen(count_messages: usize, params: &Params) -> (Sigkey, Verkey) {
    // TODO: Take PRNG as argument
    let x = FieldElement::random();
    let X_tilde = &params.g_tilde * &x;
    let mut y = vec![];
    let mut Y_tilde = vec![];
    for _ in 0..count_messages {
        let y_i = FieldElement::random();
        Y_tilde.push(&params.g_tilde * &y_i);
        y.push(y_i);
    }
    (Sigkey { x, y }, Verkey { X_tilde, Y_tilde })
}

/// Generate signing and verification keys for scheme from 2018 paper. The signing and verification
/// keys will have 1 extra element for m'
pub fn keygen_2018(count_messages: usize, params: &Params) -> (Sigkey, Verkey) {
    keygen(count_messages + 1, params)
}

#[cfg(test)]
mod tests {
    use super::*;
    // For benchmarking
    use std::time::{Duration, Instant};

    #[test]
    fn test_keygen() {
        let count_msgs = 5;
        let params = Params::new("test".as_bytes());
        let (sk, vk) = keygen(count_msgs, &params);
        assert_eq!(sk.y.len(), count_msgs);
        assert_eq!(vk.Y_tilde.len(), count_msgs);
    }

    #[test]
    fn test_keygen_2018() {
        let count_msgs = 5;
        let params = Params::new("test".as_bytes());
        let (sk, vk) = keygen_2018(count_msgs, &params);
        assert_eq!(sk.y.len(), count_msgs+1);
        assert_eq!(vk.Y_tilde.len(), count_msgs+1);
    }
}