Skip to content

Commit

Permalink
crude implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Jan 5, 2024
1 parent 403ab41 commit e6d1f14
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
2 changes: 2 additions & 0 deletions calc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
print(2 ** 64)
print(256 ** 8)
30 changes: 30 additions & 0 deletions src/common/array_append.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,33 @@ impl ArrayU32AppendU128 of ArrayAppendTrait<u32, u128> {
}
}
}

impl ArrayU32AppendU64 of ArrayAppendTrait<u32, u64> {
fn append_little_endian(ref self: Array<u32>, mut element: u64) {
let mut i = 2;
loop {
if i != 0 {
i -= 1;
let (q, r) = DivRem::div_rem(element, U64maxU32.try_into().unwrap());
self.append(r.try_into().unwrap());
element = q;
} else {
break;
}
}
}

fn append_big_endian(ref self: Array<u32>, mut element: u64) {
let mut array = ArrayTrait::<u32>::new();
array.append_little_endian(element);
let mut i = array.len();
loop {
if i != 0 {
i -= 1;
self.append((*array.at(i)).flip_endianness());
} else {
break;
}
}
}
}
1 change: 1 addition & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod fri;
mod table_commitment;
mod vector_commitment;
mod queries;
mod proof_of_work;

use cairo_verifier::input_structs::stark_proof::StarkProof;

Expand Down
5 changes: 5 additions & 0 deletions src/proof_of_work.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod proof_of_work;
mod config;

#[cfg(test)]
mod tests;
15 changes: 15 additions & 0 deletions src/proof_of_work/config.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const MIN_PROOF_OF_WORK_BITS: u256 = 30;
const MAX_PROOF_OF_WORK_BITS: u256 = 50;
const BYTE_UPPER_BOUND: u32 = 256; // 2 ** 8
const WORD_UPPER_BOUND: u128 = 18446744073709551616; // 2 ** 64

#[derive(Drop, Copy)]
struct ProofOfWorkConfig {
// Proof of work difficulty (number of bits required to be 0).
n_bits: u8,
}

fn proof_of_work_config_validate(config: ProofOfWorkConfig) {
assert(config.n_bits.into() >= MIN_PROOF_OF_WORK_BITS, 'value proof of work bits to low');
assert(config.n_bits.into() <= MIN_PROOF_OF_WORK_BITS, 'value proof of work bits to big');
}
53 changes: 53 additions & 0 deletions src/proof_of_work/proof_of_work.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use cairo_verifier::{
common::{blake2s::blake2s, array_append::ArrayAppendTrait, math::pow},
channel::channel::{Channel, ChannelTrait},
proof_of_work::config::{ProofOfWorkConfig, BYTE_UPPER_BOUND, WORD_UPPER_BOUND}
};

#[derive(Drop, Copy)]
struct ProofOfWorkUnsentCommitment {
nonce: u64,
}

fn proof_of_work_commit(
ref channel: Channel, unsent_commitment: ProofOfWorkUnsentCommitment, config: ProofOfWorkConfig
) {
channel.read_uint64_from_prover(unsent_commitment.nonce);
verify_proof_of_work(channel.digest, config.n_bits, unsent_commitment.nonce);
}

fn verify_proof_of_work(digest: u256, n_bits: u8, nonce: u64) {
// Compute the initial hash.
// Hash(0123456789abcded || digest || n_bits)
// 8 bytes || 0x20 bytes || 1 byte
// Total of 0x29 bytes.
// Arrange the hash input according to the keccak requirement of 0x10 byte chunks.
let init_hash_value: u256 = 0x0123456789abcded000000000000000000000000000000000000000000000000
// digest >> 12 -> digest << 4
+ digest / 79228162514264337593543950336 * 4294967296
// nbits << 3
+ n_bits.into() * 16777216;

let mut init_hash_data = ArrayTrait::<u32>::new();
init_hash_data.append_big_endian(init_hash_value);
let init_hash = blake2s(init_hash_data);

// Compute Hash(init_hash || nonce )
// 0x20 bytes || 8 bytes
// Total of 0x28 bytes.

// init_hash >> 12 -> init_hash << 8 + 4
let hash_value: u256 = init_hash / 79228162514264337593543950336 * 79228162514264337593543950336
// nonce << 4
+ nonce.into() * 4294967296;

let mut hash_data = ArrayTrait::<u32>::new();
hash_data.append_big_endian(hash_value);
let hash = blake2s(hash_data);
let work_limit = pow(2, 128 - n_bits.into());

assert(
Into::<u128, u256>::into(hash.high) < Into::<felt252, u256>::into(work_limit),
'proof of work failed'
)
}
Empty file added src/proof_of_work/tests.cairo
Empty file.

0 comments on commit e6d1f14

Please sign in to comment.