use super::ecp::ECP;
use super::ecp2::ECP2;
use std::str;
use super::big;
use super::big::BIG;
use super::pair;
use super::rom;
use rand::RAND;
use sha3::SHA3;
use sha3::SHAKE256;
pub const BFS: usize = big::MODBYTES as usize;
pub const BGS: usize = big::MODBYTES as usize;
pub const BLS_OK: isize = 0;
pub const BLS_FAIL: isize = -1;
#[allow(non_snake_case)]
fn bls_hashit(m: &str) -> ECP {
let mut sh = SHA3::new(SHAKE256);
let mut hm: [u8; BFS] = [0; BFS];
let t = m.as_bytes();
for i in 0..m.len() {
sh.process(t[i]);
}
sh.shake(&mut hm, BFS);
let P = ECP::mapit(&hm);
return P;
}
pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
let q = BIG::new_ints(&rom::CURVE_ORDER);
let g = ECP2::generator();
let mut sc = BIG::randomnum(&q, &mut rng);
sc.tobytes(s);
pair::g2mul(&g, &mut sc).tobytes(w);
return BLS_OK;
}
pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
let d = bls_hashit(m);
let mut sc = BIG::frombytes(&s);
pair::g1mul(&d, &mut sc).tobytes(sig, true);
return BLS_OK;
}
pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
let hm = bls_hashit(m);
let mut d = ECP::frombytes(&sig);
let g = ECP2::generator();
let pk = ECP2::frombytes(&w);
d.neg();
let mut r = pair::initmp();
pair::another(&mut r, &g, &d);
pair::another(&mut r, &pk, &hm);
let mut v = pair::miller(&r);
v = pair::fexp(&v);
if v.isunity() {
return BLS_OK;
}
return BLS_FAIL;
}