Skip to content

Commit

Permalink
conflict resolve
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Dec 22, 2023
2 parents de341fb + 7e5cd34 commit 362f745
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 73 deletions.
79 changes: 56 additions & 23 deletions src/channel/channel.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ use core::array::ArrayTrait;
use cairo_verifier::common::{
flip_endiannes::FlipEndiannessTrait, to_array::ToArrayTrait, blake2s::blake2s
};
use poseidon::poseidon_hash_span;
use core::integer::BoundedU128;

const C_PRIME_AS_UINT256_LOW: u128 = 31;
const C_PRIME_AS_UINT256_HIGH: u128 =
329648542954659146201578277794459156480; // 31 * 0x8000000000000110000000000000000;
const STARK_PRIME: u256 =
3618502788666131213697322783095070105623107215331596699973092056135872020481;
const INVERSE_2_TO_256_MOD_STARK_PRIME: felt252 =
const MONTGOMERY_R: felt252 =
3618502788666127798953978732740734578953660990361066340291730267701097005025; // 2**256 % STARK_PRIME
const MONTGOMERY_R_INVERSE: felt252 =
113078212145816603762751633895895194930089271709401121343797004406777446400;

#[derive(Drop)]
Expand All @@ -17,20 +21,6 @@ struct Channel {
counter: u256,
}

// A wrapper around felt with a guarantee that the felt must be read from the channel before
// use.
#[derive(Drop, Copy)]
struct ChannelUnsentFelt {
value: felt252,
}

// A wrapper around felt with a guarantee that the felt was read from the channel as data from the
// prover.
#[derive(Drop, Copy)]
struct ChannelSentFelt {
value: felt252,
}

#[generate_trait]
impl ChannelImpl of ChannelTrait {
fn new(digest: u256) -> Channel {
Expand All @@ -56,7 +46,7 @@ impl ChannelImpl of ChannelTrait {
let rand = self.random_uint256_to_prover();
if (rand < u256 { low: C_PRIME_AS_UINT256_LOW, high: C_PRIME_AS_UINT256_HIGH }) {
let to_append = (rand % STARK_PRIME).try_into().unwrap();
res = to_append * INVERSE_2_TO_256_MOD_STARK_PRIME;
res = to_append * MONTGOMERY_R_INVERSE;
break;
}
};
Expand All @@ -76,12 +66,55 @@ impl ChannelImpl of ChannelTrait {
res
}

// Reads a field element vector from the prover. Unlike read_felts_from_prover, this hashes all the
// field elements at once. See Channel.
fn read_felt_vector_from_prover(
ref self: Channel, values: Span<ChannelUnsentFelt>
) -> Array<ChannelSentFelt> {
let sent_felts = ArrayTrait::<ChannelSentFelt>::new();
sent_felts
fn read_felt_from_prover(ref self: Channel, value: felt252) {
let value_u256: u256 = value.into();
let mut hash_data = ArrayTrait::<u32>::new();

assert(self.digest.low != BoundedU128::max(), 'digest low is 2^128-1');
(self.digest + 1).to_array_be(ref hash_data);
value_u256.to_array_be(ref hash_data);

self.digest = blake2s(hash_data).flip_endiannes();
self.counter = 0;
}

fn read_felts_from_prover(ref self: Channel, values: Span<felt252>) {
let hashed = poseidon_hash_span(values);
self.read_felt_from_prover(hashed);
}

fn read_felt_vector_from_prover(ref self: Channel, values: Span<felt252>) {
let mut hash_data = ArrayTrait::<u32>::new();

assert(self.digest.low != BoundedU128::max(), 'digest low is 2^128-1');
(self.digest + 1).to_array_be(ref hash_data);

let mut i = 0;
loop {
if i == values.len() {
break;
};
let value_u256: u256 = (*values[i] * MONTGOMERY_R).into();
value_u256.to_array_be(ref hash_data);
i += 1;
};

self.digest = blake2s(hash_data).flip_endiannes();
self.counter = 0;
}

fn read_uint64_from_prover(ref self: Channel, value: u64) {
let mut hash_data = ArrayTrait::<u32>::new();

assert(self.digest.low != BoundedU128::max(), 'digest low is 2^128-1');
(self.digest + 1).to_array_be(ref hash_data);

let low: u32 = (value % 0x100000000).try_into().unwrap();
let high: u32 = (value / 0x100000000).try_into().unwrap();
hash_data.append(high.flip_endiannes());
hash_data.append(low.flip_endiannes());

self.digest = blake2s(hash_data).flip_endiannes();
self.counter = 0;
}
}
135 changes: 135 additions & 0 deletions src/channel/tests/test_channel.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,138 @@ fn test_random_uint256_to_prover() {
'invalid random uint256'
);
}

#[test]
#[available_gas(9999999999)]
fn test_read_from_prover() {
let mut channel = ChannelTrait::new(0);

channel.read_felt_from_prover(0xffffffffffffffffffffffffffffffffffffffff);

assert(channel.counter == 0, 'invalid read felt');
assert(
channel.digest == 0xb056692f5fc4f27dedd1fb6269b02c542a415f1d84555708a354ffb25cf97ad5,
'invalid read felt'
);

let mut arr = ArrayTrait::<felt252>::new();
arr.append(2);
arr.append(3);
arr.append(-1);
channel.read_felts_from_prover(arr.span());

assert(channel.counter == 0, 'invalid read felts');
assert(
channel.digest == 0x135bc3291210bb6248a09cea1a97b0023c5602b18a9e0786aeed16352972504,
'invalid read felts'
);

channel.read_felt_vector_from_prover(arr.span());

assert(channel.counter == 0, 'invalid read felts');
assert(
channel.digest == 0x413b1e08fe14f181acc48007a89e4d044a9edb54523e8eae5829fde606d4074d,
'invalid read felts'
);

channel.read_uint64_from_prover(6969);

assert(channel.counter == 0, 'invalid read uint64');
assert(
channel.digest == 0xeeee1f1910516152d49bea3829151bdd149fcd878fe4e7b52881300c113395ce,
'invalid read uint64'
);
}

#[test]
#[available_gas(9999999999)]
fn test_read_felt_from_prover() {
let mut channel = ChannelTrait::new(
32204560462099576052071116479981543464788400881991862378480356767528153881242
);

channel
.read_felt_from_prover(
2189543135532000975073223102299103804374316765743393096814633396722915142781
);

assert(channel.counter == 0, 'invalid read felt');
assert(
channel
.digest == 45225624675187382281293799788723729210709046294536191403393069808321359573734,
'invalid read felt'
);
}

#[test]
#[available_gas(9999999999)]
fn test_read_felts_from_prover() {
let mut channel = ChannelTrait::new(
32204560462099576052071116479981543464788400881991862378480356767528153881242
);

let input: Array<felt252> = array![
801118498771077385876680702501056689617384700744497628665736844456538025970,
136480279717397680743751578088474164975408857089091902035326656170846663451,
2651216551934055237793488162754368170820458364194359599585259842725151359862,
1329979499816441827238714390674457535408265475870499110057295862043364226076,
1296657666566505608212940111737606773084572384346777899263419033521078751013,
2670331407575655388711197125855776741254884375650252030276227999952482413107,
495372650276597730770783063328923909247361253131174237717335302286062865236,
];

channel.read_felts_from_prover(input.span());

assert(channel.counter == 0, 'invalid read felts');
assert(
channel
.digest == 9361551412742470520142265470561908553217097453533185961440210388135835515653,
'invalid read felts'
);
}

#[test]
#[available_gas(9999999999)]
fn test_read_felt_vector_from_prover() {
let mut channel = ChannelTrait::new(
32204560462099576052071116479981543464788400881991862378480356767528153881242
);

let input: Array<felt252> = array![
801118498771077385876680702501056689617384700744497628665736844456538025970,
136480279717397680743751578088474164975408857089091902035326656170846663451,
2651216551934055237793488162754368170820458364194359599585259842725151359862,
1329979499816441827238714390674457535408265475870499110057295862043364226076,
1296657666566505608212940111737606773084572384346777899263419033521078751013,
2670331407575655388711197125855776741254884375650252030276227999952482413107,
495372650276597730770783063328923909247361253131174237717335302286062865236,
530987496743476398107560876052655845720523049587973335384780354401593620645,
3345549494797593157992468861554060638252345356820185819238082993079257164020
];

channel.read_felt_vector_from_prover(input.span());

assert(channel.counter == 0, 'invalid read felts');
assert(
channel
.digest == 4348116345188292541807408380512632346270917025990245174258204584556253737000,
'invalid read felts'
);
}

#[test]
#[available_gas(9999999999)]
fn test_read_uint64_from_prover() {
let mut channel = ChannelTrait::new(
32204560462099576052071116479981543464788400881991862378480356767528153881242
);

channel.read_uint64_from_prover(4815830333676699184);

assert(channel.counter == 0, 'invalid read uint64');
assert(
channel
.digest == 82019160662385672738794368995803566011653417904767166511054323305428036240181,
'invalid read uint64'
);
}
1 change: 1 addition & 0 deletions src/common.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod from_span;
mod horner_eval;
mod to_array;
mod math;
mod array_print;

#[cfg(test)]
mod tests;
15 changes: 15 additions & 0 deletions src/common/array_print.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use core::debug::PrintTrait;

impl ArrayPrintTrait<T, +PrintTrait<T>, +Drop<T>, +Copy<T>> of PrintTrait<Array<T>> {
fn print(self: Array<T>) {
let span = self.span();
let mut i = 0;
loop {
if i == span.len() {
break;
};
(*span[i]).print();
i += 1;
};
}
}
9 changes: 9 additions & 0 deletions src/common/flip_endiannes.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ trait FlipEndiannessTrait<F> {
fn flip_endiannes(self: F) -> F;
}

impl FlipEndiannessU32 of FlipEndiannessTrait<u32> {
fn flip_endiannes(self: u32) -> u32 {
(self % 256) * 16777216
+ (self / 256 % 256) * 65536
+ (self / 65536 % 256) * 256
+ (self / 16777216 % 256)
}
}

impl FlipEndiannessU256 of FlipEndiannessTrait<u256> {
fn flip_endiannes(self: u256) -> u256 {
let mut data = ArrayTrait::<u32>::new();
Expand Down
6 changes: 2 additions & 4 deletions src/common/horner_eval.cairo
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
use cairo_verifier::channel::channel::ChannelSentFelt;

// `horner_eval` is a function that evaluates a polynomial at a given point using Horner's method.
// `coefs` is an array of coefficients representing the polynomial in the format a0, a1, a2, ... an.
// `point` is the value at which the polynomial will be evaluated.
// The function returns the polynomial evaluation as `felt252`.

fn horner_eval(coefs: Span<ChannelSentFelt>, point: felt252) -> felt252 {
fn horner_eval(coefs: Span<felt252>, point: felt252) -> felt252 {
let mut res = 0;
let mut i = coefs.len();
loop {
if i != 0 {
i -= 1;
res = (*(coefs.at(i))).value + point * res;
res = *coefs.at(i) + point * res;
} else {
break;
}
Expand Down
49 changes: 24 additions & 25 deletions src/common/tests/test_horner_eval.cairo
Original file line number Diff line number Diff line change
@@ -1,55 +1,54 @@
use core::array::ArrayTrait;
use cairo_verifier::channel::channel::ChannelSentFelt;
use cairo_verifier::common::horner_eval::horner_eval;

#[test]
#[available_gas(9999999999)]
fn test_horner_eval_0() {
let mut coefs = ArrayTrait::<ChannelSentFelt>::new();
let mut coefs = ArrayTrait::<felt252>::new();
let eval = horner_eval(coefs.span(), 1);
assert(eval == 0, 'invalid evaluation result');
}

#[test]
#[available_gas(9999999999)]
fn test_horner_eval_1() {
let mut coefs = ArrayTrait::<ChannelSentFelt>::new();
coefs.append(ChannelSentFelt { value: 1 });
let mut coefs = ArrayTrait::<felt252>::new();
coefs.append(1);
let eval = horner_eval(coefs.span(), 7);
assert(eval == 1, 'invalid evaluation result');
}

#[test]
#[available_gas(9999999999)]
fn test_horner_eval_2() {
let mut coefs = ArrayTrait::<ChannelSentFelt>::new();
coefs.append(ChannelSentFelt { value: 4 });
coefs.append(ChannelSentFelt { value: 10 });
coefs.append(ChannelSentFelt { value: 19 });
coefs.append(ChannelSentFelt { value: 1 });
coefs.append(ChannelSentFelt { value: 9 });
let mut coefs = ArrayTrait::<felt252>::new();
coefs.append(4);
coefs.append(10);
coefs.append(19);
coefs.append(1);
coefs.append(9);
let eval = horner_eval(coefs.span(), 13);
assert(eval == 262591, 'invalid evaluation result');
}

#[test]
#[available_gas(9999999999)]
fn test_horner_eval_3() {
let mut coefs = ArrayTrait::<ChannelSentFelt>::new();
coefs.append(ChannelSentFelt { value: 4 });
coefs.append(ChannelSentFelt { value: 10 });
coefs.append(ChannelSentFelt { value: 19 });
coefs.append(ChannelSentFelt { value: 1 });
coefs.append(ChannelSentFelt { value: 9 });
coefs.append(ChannelSentFelt { value: 99 });
coefs.append(ChannelSentFelt { value: 1 });
coefs.append(ChannelSentFelt { value: 7 });
coefs.append(ChannelSentFelt { value: 13 });
coefs.append(ChannelSentFelt { value: 2 });
coefs.append(ChannelSentFelt { value: 5 });
coefs.append(ChannelSentFelt { value: 7 });
coefs.append(ChannelSentFelt { value: 111 });
coefs.append(ChannelSentFelt { value: 1 });
let mut coefs = ArrayTrait::<felt252>::new();
coefs.append(4);
coefs.append(10);
coefs.append(19);
coefs.append(1);
coefs.append(9);
coefs.append(99);
coefs.append(1);
coefs.append(7);
coefs.append(13);
coefs.append(2);
coefs.append(5);
coefs.append(7);
coefs.append(111);
coefs.append(1);
let eval = horner_eval(coefs.span(), 19);
assert(eval == 288577899334361215, 'invalid evaluation result');
}
Loading

0 comments on commit 362f745

Please sign in to comment.