use bbs::prelude::*;
use pairing_plus::{
bls12_381::{Bls12, Fr, G1, G2},
hash_to_field::BaseFromRO,
serdes::SerDes,
CurveProjective,
};
use rand_old::prelude::*;
use serde::{
de::{SeqAccess, Visitor},
ser::SerializeTuple,
Deserialize, Deserializer, Serialize, Serializer,
};
use std::fmt::Formatter;
use thiserror::Error;
use zeroize::Zeroize;
pub const BLINDING_G1: &[u8] = &[
185, 201, 5, 142, 138, 68, 184, 112, 20, 249, 139, 228, 225, 129, 141, 183, 24, 248, 178, 213,
16, 31, 200, 158, 105, 131, 98, 95, 50, 31, 20, 184, 77, 124, 246, 225, 85, 0, 73, 135, 162,
21, 238, 66, 109, 241, 115, 201,
];
pub const BLINDING_G2: &[u8] = &[
169, 99, 222, 42, 223, 177, 22, 60, 244, 190, 210, 77, 112, 140, 228, 116, 50, 116, 45, 32,
128, 178, 87, 62, 190, 46, 25, 168, 105, 143, 96, 197, 65, 206, 192, 0, 252, 177, 151, 131,
233, 190, 115, 52, 19, 86, 223, 95, 17, 145, 205, 222, 199, 196, 118, 215, 116, 43, 204, 66,
26, 252, 93, 80, 94, 99, 55, 60, 98, 126, 160, 31, 218, 4, 240, 228, 1, 89, 210, 91, 221, 18,
244, 90, 1, 13, 133, 128, 167, 143, 106, 125, 38, 34, 114, 243,
];
#[derive(Clone, Debug)]
pub struct BlsSecretKey(pub Fr);
impl From<SecretKey> for BlsSecretKey {
fn from(x: SecretKey) -> Self {
unsafe { std::mem::transmute(x) }
}
}
impl Zeroize for BlsSecretKey {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
impl Drop for BlsSecretKey {
fn drop(&mut self) {
self.0.zeroize();
}
}
impl Serialize for BlsSecretKey {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut ss = s.serialize_tuple(32)?;
let mut bytes = [0u8; 32];
self.0.serialize(&mut bytes.as_mut(), true).unwrap();
for b in &bytes {
ss.serialize_element(b)?;
}
ss.end()
}
}
impl<'de> Deserialize<'de> for BlsSecretKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct SecretKeyVisitor;
impl<'de> Visitor<'de> for SecretKeyVisitor {
type Value = BlsSecretKey;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
write!(formatter, "a byte sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut arr = [0u8; 32];
for (i, item) in arr.iter_mut().enumerate() {
*item = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
}
let mut cursor = std::io::Cursor::new(arr);
let value = Fr::deserialize(&mut cursor, true).map_err(|_| {
serde::de::Error::invalid_value(serde::de::Unexpected::Bytes(&arr), &self)
})?;
Ok(BlsSecretKey(value))
}
}
deserializer.deserialize_tuple(32, SecretKeyVisitor)
}
}
pub fn bls_generate_blinded_g2_key() -> Result<BlsKeyPair<G2>, BlsGenerateKeyPairError> {
bls_generate_keypair(None, Some(BLINDING_G2))
}
pub fn bls_generate_blinded_g1_key() -> Result<BlsKeyPair<G1>, BlsGenerateKeyPairError> {
bls_generate_keypair(None, Some(BLINDING_G1))
}
pub fn bls_generate_g2_key() -> Result<BlsKeyPair<G2>, BlsGenerateKeyPairError> {
bls_generate_keypair(None, None)
}
pub fn bls_generate_g1_key() -> Result<BlsKeyPair<G1>, BlsGenerateKeyPairError> {
bls_generate_keypair(None, None)
}
#[derive(Copy, Clone, Debug)]
pub struct BlsPublicKey<G: CurveProjective<Engine = Bls12, Scalar = Fr>>(pub G);
impl<G: CurveProjective<Engine = Bls12, Scalar = Fr>> Zeroize for BlsPublicKey<G> {
fn zeroize(&mut self) {
let tv = self.0;
self.0.sub_assign(&tv);
}
}
#[derive(Error, Debug)]
pub enum BlsToBbsPublicKeyError {
#[error("Unable to convert BLS key to BBS+ key")]
Convert(BBSError),
}
impl BlsPublicKey<G2> {
pub fn to_bbs_public_key(
&self,
message_count: usize,
) -> Result<PublicKey, BlsToBbsPublicKeyError> {
let dpk = DeterministicPublicKey::from(self.0);
dpk.to_public_key(message_count)
.map_err(BlsToBbsPublicKeyError::Convert)
}
}
pub struct BlsKeyPair<G: CurveProjective<Engine = Bls12, Scalar = Fr> + SerDes> {
pub secret_key: BlsSecretKey,
pub public_key: BlsPublicKey<G>,
pub blinder: Option<Fr>,
}
impl<G: CurveProjective<Engine = Bls12, Scalar = Fr> + SerDes> BlsKeyPair<G> {
pub fn new(
seed: Option<&[u8]>,
blinder: Option<&[u8]>,
) -> Result<Self, BlsGenerateKeyPairError> {
bls_generate_keypair(seed, blinder)
}
}
impl From<BlsSecretKey> for SecretKey {
fn from(k: BlsSecretKey) -> Self {
SecretKey::from(k.0)
}
}
impl BlsSecretKey {
pub fn to_bbs_public_key(
&self,
message_count: usize,
) -> Result<PublicKey, BlsToBbsPublicKeyError> {
let mut g2 = G2::one();
g2.mul_assign(self.0);
let dpk = DeterministicPublicKey::from(g2);
dpk.to_public_key(message_count)
.map_err(BlsToBbsPublicKeyError::Convert)
}
}
#[derive(Error, Debug)]
pub enum BlsGenerateKeyPairError {
#[error("Unable to deserialize blinder")]
DeserializeBlinder(#[source] std::io::Error),
}
fn bls_generate_keypair<G: CurveProjective<Engine = Bls12, Scalar = Fr> + SerDes>(
seed: Option<&[u8]>,
blinder: Option<&[u8]>,
) -> Result<BlsKeyPair<G>, BlsGenerateKeyPairError> {
let passed_seed;
let seed = match seed {
Some(arg) => {
passed_seed = true;
arg.to_vec()
}
None => {
passed_seed = false;
let mut rng = thread_rng();
let mut seed_data = vec![0u8, 32];
rng.fill_bytes(seed_data.as_mut_slice());
seed_data
}
};
let sk = gen_sk(seed.as_slice());
let mut pk = G::one();
pk.mul_assign(sk);
let r = match blinder {
Some(g) => {
let mut data = g.to_vec();
let mut gg = g;
if passed_seed {
data.extend_from_slice(seed.as_slice());
} else {
let mut rng = thread_rng();
let mut blinding_factor = vec![0u8, 32];
rng.fill_bytes(blinding_factor.as_mut_slice());
data.extend_from_slice(blinding_factor.as_slice());
}
let mut blinding_g = G::deserialize(&mut gg, true)
.map_err(BlsGenerateKeyPairError::DeserializeBlinder)?;
let r = gen_sk(data.as_slice());
blinding_g.mul_assign(r);
pk.add_assign(&blinding_g);
Some(r)
}
None => None,
};
Ok(BlsKeyPair {
secret_key: BlsSecretKey(sk),
public_key: BlsPublicKey(pk),
blinder: r,
})
}
fn gen_sk(msg: &[u8]) -> Fr {
use sha2_old::digest::generic_array::{typenum::U48, GenericArray};
const SALT: &[u8] = b"BLS-SIG-KEYGEN-SALT-";
let mut msg_prime = Vec::<u8>::with_capacity(msg.as_ref().len() + 1);
msg_prime.extend_from_slice(msg.as_ref());
msg_prime.extend_from_slice(&[0]);
let mut result = GenericArray::<u8, U48>::default();
assert!(
hkdf::Hkdf::<sha2_old::Sha256>::new(Some(SALT), &msg_prime[..])
.expand(&[0, 48], &mut result)
.is_ok()
);
Fr::from_okm(&result)
}