Skip to content

Commit

Permalink
fragmented-proof
Browse files Browse the repository at this point in the history
  • Loading branch information
chudkowsky committed Sep 12, 2024
1 parent 05fb716 commit f02e730
Showing 1 changed file with 73 additions and 0 deletions.
73 changes: 73 additions & 0 deletions fact_registry/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ trait IFactRegistry<TContractState> {
ref self: TContractState, contract_address: ContractAddress
);
fn is_valid(self: @TContractState, fact: felt252) -> bool;
fn publish_fragment(ref self: TContractState, stark_proof: Array<felt252>) -> felt252;
fn verify_and_register_fact_from_fragments(
ref self: TContractState, fragments: Array<felt252>, cairo_version: CairoVersion
);
}

#[starknet::interface]
Expand All @@ -21,6 +25,8 @@ trait ISmartProof<TContractState> {

#[starknet::contract]
mod FactRegistry {
use core::array::ArrayTrait;
use core::hash::HashStateTrait;
use cairo_verifier::{StarkProofWithSerde, CairoVersion};
use starknet::ContractAddress;
use core::{
Expand All @@ -37,6 +43,7 @@ mod FactRegistry {
#[substorage(v0)]
cairo_verifier: CairoVerifier::Storage,
facts: LegacyMap<felt252, bool>,
fragments: LegacyMap<felt252, felt252>,
}

#[event]
Expand Down Expand Up @@ -77,6 +84,72 @@ mod FactRegistry {
fn is_valid(self: @ContractState, fact: felt252) -> bool {
self.facts.read(fact)
}

fn publish_fragment(ref self: ContractState, mut stark_proof: Array<felt252>) -> felt252 {
if stark_proof.len() > 3000 {
panic(array!['Writing more then 3000', ' fragments will', ' exaust resources.']);
}

let mut hasher = PoseidonImpl::new();
let mut to_hash = stark_proof.span();

let original_key = loop {
match to_hash.pop_front() {
Option::Some(value) => { hasher = hasher.update(*value); },
Option::None => { break hasher.finalize(); },
}
};

// The key itself is the last element.
self.fragments.write(original_key, original_key + stark_proof.len().into());

// The fragment will be kept at continuous keys starting from the hash of the data.
let mut key = original_key;
loop {
match stark_proof.pop_front() {
Option::Some(value) => {
key += 1;
self.fragments.write(key, value);
},
Option::None => { break; },
}
};

original_key
}

fn verify_and_register_fact_from_fragments(
ref self: ContractState, mut fragments: Array<felt252>, cairo_version: CairoVersion
) {
let mut complete_proof = ArrayTrait::new();

loop {
match fragments.pop_front() {
Option::Some(mut key) => {
let last_element = self.fragments.read(key);

if last_element == 0 {
panic(array!['No such fragment']);
}

loop {
key += 1;
let fragment = self.fragments.read(key);
complete_proof.append(fragment);

if key == last_element {
break;
}
}
},
Option::None => { break; },
}
};
let mut complete_proof = complete_proof.span();

let proof = Serde::<StarkProofWithSerde>::deserialize(ref complete_proof).unwrap();
self.verify_and_register_fact(proof, cairo_version);
}
}

#[generate_trait]
Expand Down

0 comments on commit f02e730

Please sign in to comment.