use std::sync::{Once};
use std::{mem::MaybeUninit};
use std::collections::HashMap;
use serde_json;
use hex;
use crate::bls48581::big;
use crate::bls48581::ecp;
use crate::bls48581::ecp8;
use crate::bls48581::bls256;
pub struct SingletonKZGSetup {
pub RootOfUnityBLS48581: HashMap<u64, big::BIG>,
pub RootsOfUnityBLS48581: HashMap<u64, Vec<big::BIG>>,
pub ReverseRootsOfUnityBLS48581: HashMap<u64, Vec<big::BIG>>,
pub CeremonyBLS48581G1: Vec<ecp::ECP>,
pub CeremonyBLS48581G2: Vec<ecp8::ECP8>,
pub FFTBLS48581: HashMap<u64, Vec<ecp::ECP>>,
}
pub fn singleton() -> &'static SingletonKZGSetup {
static mut SINGLETON: MaybeUninit<SingletonKZGSetup> = MaybeUninit::uninit();
static ONCE: Once = Once::new();
unsafe {
ONCE.call_once(|| {
bls256::init();
let bytes = include_bytes!("optimized_ceremony.json");
let v: serde_json::Value = serde_json::from_slice(bytes).unwrap();
let mut blsg1 = Vec::<ecp::ECP>::new();
let mut blsg2 = Vec::<ecp8::ECP8>::new();
let mut rootOfUnity = HashMap::<u64, big::BIG>::new();
let mut rootsOfUnity = HashMap::<u64, Vec<big::BIG>>::new();
let mut reverseRootsOfUnity = HashMap::<u64, Vec<big::BIG>>::new();
let mut ffts = HashMap::<u64, Vec<ecp::ECP>>::new();
for power in v["powersOfTau"]["G1Powers"].as_array().unwrap() {
let p = hex::decode(power.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
blsg1.push(ecp::ECP::frombytes(&p));
}
for power in v["powersOfTau"]["G2Powers"].as_array().unwrap() {
let p = hex::decode(power.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
blsg2.push(ecp8::ECP8::frombytes(&p));
}
{
let root = v["sized"]["rootOfUnity"]["rootOfUnity16"].clone();
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootOfUnity.insert(16, big::BIG::frombytes(&r));
}
{
let root = v["sized"]["rootOfUnity"]["rootOfUnity32"].clone();
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootOfUnity.insert(32, big::BIG::frombytes(&r));
}
{
let root = v["sized"]["rootOfUnity"]["rootOfUnity64"].clone();
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootOfUnity.insert(64, big::BIG::frombytes(&r));
}
{
let root = v["sized"]["rootOfUnity"]["rootOfUnity128"].clone();
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootOfUnity.insert(128, big::BIG::frombytes(&r));
}
{
let root = v["sized"]["rootOfUnity"]["rootOfUnity256"].clone();
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootOfUnity.insert(256, big::BIG::frombytes(&r));
}
let mut rootsOfUnity16 = Vec::<big::BIG>::new();
for root in v["sized"]["rootsOfUnity"]["rootsOfUnity16"].as_array().unwrap() {
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootsOfUnity16.push(big::BIG::frombytes(&r));
}
rootsOfUnity.insert(16, rootsOfUnity16.clone());
reverseRootsOfUnity.insert(16, rootsOfUnity16.into_iter().rev().collect());
let mut rootsOfUnity32 = Vec::<big::BIG>::new();
for root in v["sized"]["rootsOfUnity"]["rootsOfUnity32"].as_array().unwrap() {
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootsOfUnity32.push(big::BIG::frombytes(&r));
}
rootsOfUnity.insert(32, rootsOfUnity32.clone());
reverseRootsOfUnity.insert(32, rootsOfUnity32.into_iter().rev().collect());
let mut rootsOfUnity64 = Vec::<big::BIG>::new();
for root in v["sized"]["rootsOfUnity"]["rootsOfUnity64"].as_array().unwrap() {
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootsOfUnity64.push(big::BIG::frombytes(&r));
}
rootsOfUnity.insert(64, rootsOfUnity64.clone());
reverseRootsOfUnity.insert(64, rootsOfUnity64.into_iter().rev().collect());
let mut rootsOfUnity128 = Vec::<big::BIG>::new();
for root in v["sized"]["rootsOfUnity"]["rootsOfUnity128"].as_array().unwrap() {
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootsOfUnity128.push(big::BIG::frombytes(&r));
}
rootsOfUnity.insert(128, rootsOfUnity128.clone());
reverseRootsOfUnity.insert(128, rootsOfUnity128.into_iter().rev().collect());
let mut rootsOfUnity256 = Vec::<big::BIG>::new();
for root in v["sized"]["rootsOfUnity"]["rootsOfUnity256"].as_array().unwrap() {
let r = hex::decode(root.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
rootsOfUnity256.push(big::BIG::frombytes(&r));
}
rootsOfUnity.insert(256, rootsOfUnity256.clone());
reverseRootsOfUnity.insert(256, rootsOfUnity256.into_iter().rev().collect());
let mut f16 = Vec::<ecp::ECP>::new();
for power in v["sized"]["G1FFT"]["G1FFT16"].as_array().unwrap() {
let p = hex::decode(power.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
f16.push(ecp::ECP::frombytes(&p));
}
ffts.insert(16, f16);
let mut f32 = Vec::<ecp::ECP>::new();
for power in v["sized"]["G1FFT"]["G1FFT32"].as_array().unwrap() {
let p = hex::decode(power.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
f32.push(ecp::ECP::frombytes(&p));
}
ffts.insert(32, f32);
let mut f64 = Vec::<ecp::ECP>::new();
for power in v["sized"]["G1FFT"]["G1FFT64"].as_array().unwrap() {
let p = hex::decode(power.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
f64.push(ecp::ECP::frombytes(&p));
}
ffts.insert(64, f64);
let mut f128 = Vec::<ecp::ECP>::new();
for power in v["sized"]["G1FFT"]["G1FFT128"].as_array().unwrap() {
let p = hex::decode(power.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
f128.push(ecp::ECP::frombytes(&p));
}
ffts.insert(128, f128);
let mut f256 = Vec::<ecp::ECP>::new();
for power in v["sized"]["G1FFT"]["G1FFT256"].as_array().unwrap() {
let p = hex::decode(power.as_str().unwrap().strip_prefix("0x").unwrap()).unwrap();
f256.push(ecp::ECP::frombytes(&p));
}
ffts.insert(256, f256);
let singleton = SingletonKZGSetup {
RootOfUnityBLS48581: rootOfUnity,
RootsOfUnityBLS48581: rootsOfUnity,
ReverseRootsOfUnityBLS48581: reverseRootsOfUnity,
CeremonyBLS48581G1: blsg1,
CeremonyBLS48581G2: blsg2,
FFTBLS48581: ffts,
};
SINGLETON.write(singleton);
});
SINGLETON.assume_init_ref()
}
}