diff --git a/.gitignore b/.gitignore index 86499d41f..4ebfbaa62 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ vendor/ .env* sim/__pycache__/ *.pyc +brand/Unbounded.ttf diff --git a/brand/igneum-icon-1024.png b/brand/igneum-icon-1024.png new file mode 100644 index 000000000..6ab4be74f Binary files /dev/null and b/brand/igneum-icon-1024.png differ diff --git a/brand/igneum-icon-512.png b/brand/igneum-icon-512.png new file mode 100644 index 000000000..4b0ca17ca Binary files /dev/null and b/brand/igneum-icon-512.png differ diff --git a/brand/igneum-mark-transparent-1024.png b/brand/igneum-mark-transparent-1024.png new file mode 100644 index 000000000..29f691f5e Binary files /dev/null and b/brand/igneum-mark-transparent-1024.png differ diff --git a/brand/igneum-wordmark-dark-1600x500.png b/brand/igneum-wordmark-dark-1600x500.png new file mode 100644 index 000000000..39df978e4 Binary files /dev/null and b/brand/igneum-wordmark-dark-1600x500.png differ diff --git a/brand/igneum-wordmark-light-1600x500.png b/brand/igneum-wordmark-light-1600x500.png new file mode 100644 index 000000000..c0e39cf93 Binary files /dev/null and b/brand/igneum-wordmark-light-1600x500.png differ diff --git a/brand/igneum-wordmark-transparent-1600x500.png b/brand/igneum-wordmark-transparent-1600x500.png new file mode 100644 index 000000000..ef93f70f1 Binary files /dev/null and b/brand/igneum-wordmark-transparent-1600x500.png differ diff --git a/brand/igneum-workspace-header-320x132.png b/brand/igneum-workspace-header-320x132.png new file mode 100644 index 000000000..cc766c393 Binary files /dev/null and b/brand/igneum-workspace-header-320x132.png differ diff --git a/proto-vdf/src/main.rs b/proto-vdf/src/main.rs index 7a883c6b2..13375def4 100644 --- a/proto-vdf/src/main.rs +++ b/proto-vdf/src/main.rs @@ -197,9 +197,13 @@ struct ProofTiming { } fn time_proof(g: &G, x: &G::Elem, t: u64, threads: usize, kappa_opt: Option) -> ProofTiming { - let spacing0 = wesolowski::choose_spacing(t, 1 << 16); - let kappa = kappa_opt.unwrap_or_else(|| seed::pick_kappa(spacing0)); - let spacing = (spacing0 - spacing0 % kappa as u64).max(kappa as u64); + let (spacing, kappa) = match kappa_opt { + None => seed::plan(t), + Some(k) => { + let gamma = ((t + (k as u64) * seed::MAX_CHECKPOINTS - 1) / ((k as u64) * seed::MAX_CHECKPOINTS)).max(1); + (k as u64 * gamma, k) + } + }; let ev = wesolowski::eval(g, x, t, spacing); let s = Instant::now(); let pf1 = wesolowski::prove(g, x, &ev, kappa, 1); diff --git a/proto-vdf/src/rsa.rs b/proto-vdf/src/rsa.rs index 4ab9e9556..fd41ebb30 100644 --- a/proto-vdf/src/rsa.rs +++ b/proto-vdf/src/rsa.rs @@ -30,7 +30,7 @@ impl RsaGroup { let s = sha256(&[b"igneum-vdf-rsa-standin", seed.as_bytes()]); rs.seed(&Integer::from_digits(&s, Order::MsfBe)); let half = MODULUS_BITS / 2; - let mut gen_prime = |rs: &mut RandState| -> Integer { + let gen_prime = |rs: &mut RandState| -> Integer { let mut p = Integer::from(Integer::random_bits(half, rs)); p.set_bit(half - 1, true); p.set_bit(half - 2, true); diff --git a/proto-vdf/src/seed.rs b/proto-vdf/src/seed.rs index c5d6f96a9..fd7328203 100644 --- a/proto-vdf/src/seed.rs +++ b/proto-vdf/src/seed.rs @@ -44,10 +44,7 @@ fn derive_seed(checkpoint_hash: &[u8; 32], t: u64, y_bytes: &[u8]) -> [u8; 32] { pub fn epoch_seed(checkpoint_hash: &[u8; 32], t: u64, threads: usize) -> ([u8; 32], EpochProof) { let g = class_group_for(checkpoint_hash); let x: Form = g.generator(); - let spacing = wesolowski::choose_spacing(t, 1 << 16); - let kappa = pick_kappa(spacing); - let spacing = spacing - spacing % kappa as u64; - let spacing = spacing.max(kappa as u64); + let (spacing, kappa) = plan(t); let ev = wesolowski::eval(&g, &x, t, spacing); let proof = wesolowski::prove(&g, &x, &ev, kappa, threads); let y_bytes = g.serialize(&proof.y); @@ -76,9 +73,7 @@ pub fn verify_epoch_seed(checkpoint_hash: &[u8; 32], program_seed: &[u8; 32], pr /// Same pipeline over the RSA stand-in, for timing comparison only. pub fn epoch_seed_rsa(g: &RsaGroup, checkpoint_hash: &[u8; 32], t: u64, threads: usize) -> ([u8; 32], EpochProof) { let x = g.hash_to_elem(checkpoint_hash); - let spacing = wesolowski::choose_spacing(t, 1 << 16); - let kappa = pick_kappa(spacing); - let spacing = (spacing - spacing % kappa as u64).max(kappa as u64); + let (spacing, kappa) = plan(t); let ev = wesolowski::eval(g, &x, t, spacing); let proof = wesolowski::prove(g, &x, &ev, kappa, threads); let y_bytes = g.serialize(&proof.y); @@ -102,12 +97,14 @@ pub fn verify_epoch_seed_rsa(g: &RsaGroup, checkpoint_hash: &[u8; 32], program_s derive_seed(checkpoint_hash, proof.t, &proof.y) == *program_seed } -/// Digit width: 12 bits when the spacing allows it, smaller for tiny T. -pub fn pick_kappa(spacing: u64) -> u32 { - for k in [12u32, 10, 8, 6, 4, 2, 1] { - if spacing >= (k as u64) * 4 || k == 1 { - return k; - } - } - 1 +/// Proof plan: digit width kappa and checkpoint spacing kappa * gamma. +/// Cost of the proof is about T/kappa + gamma 2^(kappa+1) group multiplications, memory is +/// T/spacing checkpoints. We cap checkpoints near 2^16 (17 MB for 1024-bit forms) and use +/// 12-bit digits once T is large enough for the bucket combine to be negligible. +pub fn plan(t: u64) -> (u64, u32) { + let kappa: u32 = if t >= 1 << 16 { 12 } else if t >= 1 << 10 { 8 } else { 4 }; + let gamma = ((t + (kappa as u64) * MAX_CHECKPOINTS - 1) / ((kappa as u64) * MAX_CHECKPOINTS)).max(1); + (kappa as u64 * gamma, kappa) } + +pub const MAX_CHECKPOINTS: u64 = 1 << 16;