use std::fmt;
use std::fs::{File, OpenOptions};
use std::io::{Read, Write};
use std::path::Path;
use std::time::SystemTime;
#[cfg(feature = "commercial")]
use pent_house::{ResonanceEngine, ResonanceLedger};
use power_house::{Field, SumClaim};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Shard {
pub label: String,
pub seed: u64,
pub checksum: u128,
pub energy: u64,
}
impl Shard {
pub fn mint(label: &str, seed: u64) -> Result<Self, String> {
validate_label(label)?;
let field = Field::new(101);
let n = ((seed % 16) as usize).max(8);
let claim = SumClaim::prove_demo(&field, n);
if !claim.verify_demo() {
return Err("internal: demo verification failed".into());
}
let mut acc: u128 = 0;
for (i, b) in format!("{:X?}", claim).bytes().enumerate() {
let v = ((b as u128) * ((i as u128) + 1)) % 10_000_019;
acc = acc.wrapping_add(v);
}
Ok(Shard {
label: label.to_string(),
seed,
checksum: acc,
energy: (n as u64) * 11,
})
}
}
fn validate_label(s: &str) -> Result<(), String> {
if s.is_empty() || s.len() > 128 {
return Err("label length invalid".into());
}
if !s
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
{
return Err("label contains invalid characters".into());
}
Ok(())
}
#[derive(Default)]
pub struct Ledger {
shards: Vec<Shard>,
state: u128, }
impl Ledger {
pub fn new() -> Self {
Self {
shards: vec![],
state: 1,
}
}
pub fn ingest(&mut self, shard: Shard) -> Result<Report, String> {
let expect = Shard::mint(&shard.label, shard.seed)?;
if !constant_time_eq_u128(shard.checksum, expect.checksum) {
return Err("verification failed: checksum mismatch".into());
}
self.state = self.state.wrapping_mul(shard.checksum.wrapping_add(17));
self.shards.push(shard.clone());
Ok(Report {
energy: shard.energy,
confidence: 1.0,
})
}
pub fn digest(&self) -> u128 {
self.state
}
pub fn len(&self) -> usize {
self.shards.len()
}
pub fn is_empty(&self) -> bool {
self.shards.is_empty()
}
pub fn persist_to<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
let mut f = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(path)
.map_err(|e| e.to_string())?;
for sh in &self.shards {
writeln!(f, "{} {} {} {}", sh.label, sh.seed, sh.checksum, sh.energy)
.map_err(|e| e.to_string())?;
}
f.sync_all().map_err(|e| e.to_string())?;
Ok(())
}
pub fn load_from<P: AsRef<Path>>(path: P) -> Result<Self, String> {
let mut s = String::new();
File::open(path.as_ref())
.map_err(|e| e.to_string())?
.read_to_string(&mut s)
.map_err(|e| e.to_string())?;
let mut me = Ledger::new();
for line in s.lines() {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() != 4 {
continue;
}
let label = parts[0].to_string();
let seed: u64 = parts[1].parse().map_err(|_| "bad seed")?;
let checksum: u128 = parts[2].parse().map_err(|_| "bad checksum")?;
let energy: u64 = parts[3].parse().map_err(|_| "bad energy")?;
let sh = Shard {
label,
seed,
checksum,
energy,
};
me.state = me.state.wrapping_mul(sh.checksum.wrapping_add(17));
me.shards.push(sh);
}
Ok(me)
}
}
#[inline]
fn constant_time_eq_u128(a: u128, b: u128) -> bool {
let mut x = a ^ b;
x |= x >> 64;
x |= x >> 32;
x |= x >> 16;
x |= x >> 8;
x |= x >> 4;
x |= x >> 2;
x |= x >> 1;
(x & 1) == 0
}
pub struct Report {
pub energy: u64,
pub confidence: f64,
}
impl fmt::Display for Report {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{{\"energy\":{},\"confidence\":{}}}",
self.energy, self.confidence
)
}
}
pub fn log_json(event: &str, msg: &str) {
let ts = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis();
println!(
"{{\"ts\":{},\"event\":\"{}\",\"msg\":\"{}\"}}",
ts,
esc(event),
esc(msg)
);
}
fn esc(s: &str) -> String {
s.replace('\"', "\\\"")
}
#[cfg(feature = "commercial")]
pub fn commercial_banner() -> Result<(), String> {
if std::env::var("FLAME_ALLOW_COMMERCIAL").ok().as_deref() != Some("1") {
return Err("Commercial mode requires FLAME_ALLOW_COMMERCIAL=1 and a valid license".into());
}
Ok(())
}