Merge pull request #3 from kobigurk/feat/reduce_powers

Adds a power reducing utility
This commit is contained in:
Kobi Gurkan 2020-01-29 12:11:21 +02:00 committed by GitHub
commit 40e2e31e76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 126 additions and 0 deletions

@ -0,0 +1,118 @@
extern crate powersoftau;
extern crate rand;
extern crate blake2;
extern crate byteorder;
extern crate bellman_ce;
use bellman_ce::pairing::{CurveAffine, CurveProjective};
use bellman_ce::pairing::bn256::Bn256;
use bellman_ce::pairing::bn256::{G1, G2};
use powersoftau::small_bn256::{Bn256CeremonyParameters};
use powersoftau::batched_accumulator::*;
use powersoftau::parameters::{UseCompression};
use powersoftau::utils::{reduced_hash};
use powersoftau::*;
use crate::parameters::*;
use bellman_ce::multicore::Worker;
use bellman_ce::domain::{EvaluationDomain, Point};
use std::fs::OpenOptions;
use std::io::{BufWriter, Write};
use memmap::*;
#[derive(Clone)]
pub struct Bn256ReducedCeremonyParameters {
}
impl PowersOfTauParameters for Bn256ReducedCeremonyParameters {
const REQUIRED_POWER: usize = 10;
// This ceremony is based on the BN256 elliptic curve construction.
const G1_UNCOMPRESSED_BYTE_SIZE: usize = 64;
const G2_UNCOMPRESSED_BYTE_SIZE: usize = 128;
const G1_COMPRESSED_BYTE_SIZE: usize = 32;
const G2_COMPRESSED_BYTE_SIZE: usize = 64;
}
const fn num_bits<T>() -> usize { std::mem::size_of::<T>() * 8 }
fn log_2(x: u64) -> u32 {
assert!(x > 0);
num_bits::<u64>() as u32 - x.leading_zeros() - 1
}
fn main() {
// Try to load `./challenge` from disk.
let reader = OpenOptions::new()
.read(true)
.open("challenge")
.expect("unable open `./challenge` in this directory");
let challenge_readable_map = unsafe { MmapOptions::new().map(&reader).expect("unable to create a memory map for input") };
let current_accumulator = BachedAccumulator::<Bn256, Bn256CeremonyParameters>::deserialize(
&challenge_readable_map,
CheckForCorrectness::Yes,
UseCompression::No,
).expect("unable to read compressed accumulator");
let mut reduced_accumulator = BachedAccumulator::<Bn256, Bn256ReducedCeremonyParameters>::empty();
reduced_accumulator.tau_powers_g1 = current_accumulator.tau_powers_g1[..Bn256ReducedCeremonyParameters::TAU_POWERS_G1_LENGTH].to_vec();
reduced_accumulator.tau_powers_g2 = current_accumulator.tau_powers_g2[..Bn256ReducedCeremonyParameters::TAU_POWERS_LENGTH].to_vec();
reduced_accumulator.alpha_tau_powers_g1 = current_accumulator.alpha_tau_powers_g1[..Bn256ReducedCeremonyParameters::TAU_POWERS_LENGTH].to_vec();
reduced_accumulator.beta_tau_powers_g1 = current_accumulator.beta_tau_powers_g1[..Bn256ReducedCeremonyParameters::TAU_POWERS_LENGTH].to_vec();
reduced_accumulator.beta_g2 = current_accumulator.beta_g2;
let writer = OpenOptions::new()
.read(true)
.write(true)
.create_new(true)
.open("reduced_challenge").expect("unable to create `./reduced_challenge` in this directory");
// Recomputation stips the public key and uses hashing to link with the previous contibution after decompression
writer.set_len(Bn256ReducedCeremonyParameters::ACCUMULATOR_BYTE_SIZE as u64).expect("must make output file large enough");
let mut writable_map = unsafe { MmapOptions::new().map_mut(&writer).expect("unable to create a memory map for output") };
let hash = reduced_hash(Bn256CeremonyParameters::REQUIRED_POWER as u8, Bn256ReducedCeremonyParameters::REQUIRED_POWER as u8);
(&mut writable_map[0..]).write(hash.as_slice()).expect("unable to write a default hash to mmap");
writable_map.flush().expect("unable to write reduced hash to `./reduced_challenge`");
println!("Reduced hash for a reduced challenge:");
for line in hash.as_slice().chunks(16) {
print!("\t");
for section in line.chunks(4) {
for b in section {
print!("{:02x}", b);
}
print!(" ");
}
println!("");
}
reduced_accumulator.serialize(&mut writable_map, UseCompression::No);
// Get the hash of the contribution, so the user can compare later
let output_readonly = writable_map.make_read_only().expect("must make a map readonly");
let contribution_hash = BachedAccumulator::<Bn256, Bn256ReducedCeremonyParameters>::calculate_hash(&output_readonly);
println!("Reduced contribution is formed with a hash:");
for line in contribution_hash.as_slice().chunks(16) {
print!("\t");
for section in line.chunks(4) {
for b in section {
print!("{:02x}", b);
}
print!(" ");
}
println!("");
}
println!("Wrote a reduced accumulator to `./challenge`");
}

@ -140,6 +140,14 @@ pub fn blank_hash() -> GenericArray<u8, U64> {
Blake2b::new().result()
}
pub fn reduced_hash(old_power: u8, new_power: u8) -> GenericArray<u8, U64> {
let mut hasher = Blake2b::new();
hasher.input(&[old_power, new_power]);
hasher.result()
}
/// Checks if pairs have the same ratio.
/// Under the hood uses pairing to check
/// x1/x2 = y1/y2 => x1*y2 = x2*y1