#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(feature = "std", doc = include_str!("../README.md"))]
#[cfg(doctest)]
pub struct ReadmeDoctests;
extern crate ark_serialize;
extern crate ark_serialize_derive;
extern crate ark_ec;
extern crate ark_ff;
extern crate digest;
extern crate rand;
extern crate rand_chacha;
extern crate rand_core;
extern crate sha3;
extern crate alloc;
#[cfg(feature = "serde")]
extern crate serde;
use core::borrow::Borrow;
use digest::DynDigest;
pub mod chaum_pedersen_signature;
pub mod double;
pub mod double_pop;
pub mod engine;
pub mod schnorr_pop;
pub mod serialize;
pub mod single;
pub mod verifiers;
#[cfg(feature = "std")]
pub mod multi_pop_aggregator;
#[cfg(feature = "std")]
pub mod single_pop_aggregator;
#[cfg(feature = "experimental")]
pub mod bit;
#[cfg(feature = "experimental")]
pub mod delinear;
#[cfg(feature = "experimental")]
pub mod distinct;
pub use engine::*;
pub use double::{
DoublePublicKey, DoublePublicKeyScheme, DoubleSignature, PublicKeyInSignatureGroup,
};
pub use double_pop::{NuggetBLSPoP, NuggetBLSnCPPoP};
pub use schnorr_pop::SchnorrProof;
pub use serialize::SerializableToBytes;
pub use single::{Keypair, KeypairVT, PublicKey, SecretKey, SecretKeyVT, Signature, SignedMessage};
use alloc::vec::Vec;
const MESSAGE_SIZE: usize = 32;
const PROOF_OF_POSSESSION_ID: &'static [u8] = b"BLS_POP_";
const NORMAL_MESSAGE_SIGNATURE_ID: &'static [u8] = b"BLS_SIG_";
const NORMAL_MESSAGE_SIGNATURE_ASSUMING_POP: &'static [u8] = b"POP_";
const NORMAL_MESSAGE_SIGNATURE_BASIC: &'static [u8] = b"NUL_";
const POP_MESSAGE: &'static [u8] = b"POP_";
type MessageDigest = [u8; MESSAGE_SIZE];
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Message(pub MessageDigest, pub alloc::vec::Vec<u8>, MessageType);
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
enum MessageType {
ProofOfPossession,
NormalAssumingPoP,
NormalBasic,
}
impl Message {
pub fn new(context: &[u8], message: &[u8]) -> Message {
let msg_hash = Self::compute_internal_hash(context, message);
Message(
msg_hash,
[context, message].concat(),
MessageType::NormalBasic,
)
}
pub fn new_assuming_pop(context: &[u8], message: &[u8]) -> Message {
let msg_hash = Self::compute_internal_hash(context, message);
Message(
msg_hash,
[context, message].concat(),
MessageType::NormalAssumingPoP,
)
}
pub fn new_pop_message(context: &[u8], message: &[u8]) -> Message {
let msg_hash = Self::compute_internal_hash(context, message);
Message(
msg_hash,
[context, message].concat(),
MessageType::ProofOfPossession,
)
}
fn compute_internal_hash(context: &[u8], message: &[u8]) -> [u8; MESSAGE_SIZE] {
use sha3::{
digest::{ExtendableOutput, Update, XofReader},
Shake128,
};
let mut h = Shake128::default();
h.update(context);
let l = message.len() as u64;
h.update(&l.to_le_bytes());
h.update(message);
let mut msg_hash = [0u8; MESSAGE_SIZE];
h.finalize_xof().read(&mut msg_hash[..]);
msg_hash
}
fn cipher_suite<E: EngineBLS>(&self) -> Vec<u8> {
let id = match self.2 {
MessageType::ProofOfPossession => PROOF_OF_POSSESSION_ID,
_ => NORMAL_MESSAGE_SIGNATURE_ID,
};
let h2c_suite_id = [
E::CURVE_NAME,
E::SIG_GROUP_NAME,
E::CIPHER_SUIT_DOMAIN_SEPARATION,
]
.concat();
let sc_tag = match self.2 {
MessageType::ProofOfPossession => POP_MESSAGE,
MessageType::NormalAssumingPoP => NORMAL_MESSAGE_SIGNATURE_ASSUMING_POP,
_ => NORMAL_MESSAGE_SIGNATURE_BASIC,
};
[id, &h2c_suite_id[..], sc_tag].concat()
}
pub fn hash_to_signature_curve<E: EngineBLS>(&self) -> E::SignatureGroup {
E::hash_to_signature_curve(&[&self.cipher_suite::<E>()[..], &self.1[..]].concat()[..])
}
}
impl<'a> From<&'a [u8]> for Message {
fn from(x: &[u8]) -> Message {
Message::new(b"", x)
}
}
pub trait Signed: Sized {
type E: EngineBLS;
fn signature(&self) -> Signature<Self::E>;
type M: Borrow<Message>; type PKG: Borrow<PublicKey<Self::E>>;
type PKnM: Iterator<Item = (Self::M, Self::PKG)> + ExactSizeIterator;
fn messages_and_publickeys(self) -> Self::PKnM;
fn verify(self) -> bool {
verifiers::verify_simple(self)
}
}
pub trait ProofOfPossession<E, H, PV>
where
E: EngineBLS,
H: DynDigest + Default + Clone,
{
fn verify(&self, public_key_of_prover: &PV) -> bool;
}
pub trait ProofOfPossessionGenerator<
E: EngineBLS,
H: DynDigest + Default + Clone,
PV,
P: ProofOfPossession<E, H, PV>,
>
{
fn generate_pok(&mut self) -> P;
}