use rand::{CryptoRng, RngCore};
use amcl_wrapper::errors::SerzDeserzError;
use amcl_wrapper::field_elem::FieldElement;
use amcl_wrapper::group_elem::GroupElement;
use amcl_wrapper::group_elem_g2::G2;
use VerkeyGroup;
pub(crate) const MESSAGE_DOMAIN_PREFIX: [u8; 2] = [0, 0];
pub(crate) const VERKEY_DOMAIN_PREFIX: [u8; 2] = [1, 1];
pub struct Params {
pub g: VerkeyGroup,
}
impl Params {
pub fn new(label: &[u8]) -> Self {
let g = VerkeyGroup::from_msg_hash(label);
Params { g }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SigKey {
pub x: FieldElement,
}
impl SigKey {
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
Self {
x: FieldElement::random_using_rng(rng),
}
}
pub fn from_bytes(sk_bytes: &[u8]) -> Result<SigKey, SerzDeserzError> {
FieldElement::from_bytes(sk_bytes).map(|x| SigKey { x })
}
pub fn to_bytes(&self) -> Vec<u8> {
self.x.to_bytes()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerKey {
pub point: VerkeyGroup,
}
impl VerKey {
pub fn from_sigkey(sk: &SigKey, params: &Params) -> Self {
VerKey {
point: ¶ms.g * &sk.x,
}
}
pub fn from_bytes(vk_bytes: &[u8]) -> Result<VerKey, SerzDeserzError> {
VerkeyGroup::from_bytes(vk_bytes).map(|point| VerKey { point })
}
pub fn to_bytes(&self) -> Vec<u8> {
self.point.to_bytes()
}
}
pub struct Keypair {
pub sig_key: SigKey,
pub ver_key: VerKey,
}
impl Keypair {
pub fn new<R: RngCore + CryptoRng>(rng: &mut R, params: &Params) -> Self {
let sk = SigKey::new(rng);
let vk = VerKey::from_sigkey(&sk, params);
Keypair {
sig_key: sk,
ver_key: vk,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use rand::thread_rng;
#[test]
fn gen_verkey() {
let mut rng = thread_rng();
let sk1 = SigKey::new(&mut rng);
let sk2 = SigKey::new(&mut rng);
let params = Params::new("test".as_bytes());
for mut sk in vec![sk1, sk2] {
let mut vk1 = VerKey::from_sigkey(&sk, ¶ms);
debug!("{}", sk.x.to_hex());
debug!("{}", &vk1.point.to_hex());
let mut vk2 = VerKey::from_sigkey(&sk, ¶ms);
debug!("{}", &vk2.point.to_hex());
let bs = vk1.to_bytes();
let mut vk11 = VerKey::from_bytes(&bs).unwrap();
assert_eq!(vk1.point.to_bytes(), vk11.point.to_bytes());
let bs = sk.to_bytes();
let mut sk1 = SigKey::from_bytes(&bs).unwrap();
assert_eq!(sk1.x.to_hex(), sk.x.to_hex());
}
}
}