Skip to content

Commit

Permalink
feat: vm2
Browse files Browse the repository at this point in the history
  • Loading branch information
IlyasRidhuan committed Jan 23, 2025
1 parent b229a04 commit c6ffba9
Show file tree
Hide file tree
Showing 61 changed files with 3,127 additions and 6,431 deletions.
9 changes: 9 additions & 0 deletions barretenberg/cpp/.clangd
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,12 @@ Diagnostics:
Remove:
- cppcoreguidelines-avoid-non-const-global-variables
- cppcoreguidelines-special-member-functions

--- # this divider is necessary
# Suppressing some noisy AVM warnings
If:
PathMatch: [src/barretenberg/vm.*\.cpp]
Diagnostics:
Suppress:
- -Wmissing-designated-field-initializers

375 changes: 7 additions & 368 deletions barretenberg/cpp/pil/avm/gadgets/sha256.pil
Original file line number Diff line number Diff line change
@@ -1,373 +1,12 @@
include "sha256_params.pil";
namespace sha256(256);

// Memory ops
pol commit state_offset;
pol commit input_offset;
pol commit output_offset;

// Initial state values loaded from state_offset;
pol commit init_a;
pol commit init_b;
pol commit init_c;
pol commit init_d;
pol commit init_e;
pol commit init_f;
pol commit init_g;
pol commit init_h;

// Output state values to be written to memory, the need to be "limbed" since it's addition modulo 2^32
// We could re-use the init columns but we need to reverse the round orders.
// Only the output_X_rhs is written to memory
pol commit output_a_lhs;
pol commit output_a_rhs;
pol commit output_b_lhs;
pol commit output_b_rhs;
pol commit output_c_lhs;
pol commit output_c_rhs;
pol commit output_d_lhs;
pol commit output_d_rhs;
pol commit output_e_lhs;
pol commit output_e_rhs;
pol commit output_f_lhs;
pol commit output_f_rhs;
pol commit output_g_lhs;
pol commit output_g_rhs;
pol commit output_h_lhs;
pol commit output_h_rhs;


// Control flow
pol commit clk;

// Selector for Sha256Compression Operation
pol commit sel;
sel * (1 - sel) = 0;
// These are needed while we can't use constant values in lookups.
// For the XOR lookups
pol commit xor_sel;
perform_round * (xor_sel - 2) = 0;
// For the AND lookups
pol commit and_sel;
and_sel = 0;

// Start Row
pol commit start;
start * (1 - start) = 0;
// If the current row is latched and the next row is "on", the next row is the start of the new computation
start' - (latch * sel') = 0;

// Selector to stop after 64 rounds
pol commit latch;
latch * (1 - latch) = 0;

// We perform a compression operation if we are not at a latched row
pol commit perform_round;
perform_round - (sel * (1 - latch)) = 0;
// Temp while we don't have the lookups enabled
pol commit dummy_zero;
dummy_zero = 0;
pol LAST = sel * latch;

// Counter
pol NUM_ROUNDS = 64;
pol commit rounds_remaining;
start * (rounds_remaining - NUM_ROUNDS) + perform_round * (rounds_remaining - rounds_remaining' - 1) = 0;
pol commit round_count;
sel * (round_count - (NUM_ROUNDS - rounds_remaining)) = 0;
pol commit rounds_remaining_inv;
// latch == 1 when the rounds_remaining == 0
sel * (rounds_remaining * (latch * (1 - rounds_remaining_inv) + rounds_remaining_inv) - 1 + latch) = 0;

// Hash Values
pol commit a;
pol commit b;
pol commit c;
pol commit d;
pol commit e;
pol commit f;
pol commit g;
pol commit h;

// ========== COMPUTE W =============
// w is only computed on the 16th round (as 0-15 are populated from the input)
// s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3)
// s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10)
// w[i] := w[i-16] + s0 + w[i-7] + s1

// Computing the w values for each round requires the 16th, 15th, 7th and 2nd previous w values (i - 16, i - 15, i - 7 and i - 2)
// To store this in the vm, we track 16 columns that are added to by each row and we denote the following
// helper_w0 = i - 16, helper_w1 = i - 15, helper_w9 = i - 7, helper_w14 = i - 2, helper_w15 = i - 1

pol commit helper_w0, helper_w1, helper_w2, helper_w3;
pol commit helper_w4, helper_w5, helper_w6, helper_w7;
pol commit helper_w8, helper_w9, helper_w10, helper_w11;
pol commit helper_w12, helper_w13, helper_w14, helper_w15;

perform_round * (helper_w0' - helper_w1) = 0;
perform_round * (helper_w1' - helper_w2) = 0;
perform_round * (helper_w2' - helper_w3) = 0;
perform_round * (helper_w3' - helper_w4) = 0;
perform_round * (helper_w4' - helper_w5) = 0;
perform_round * (helper_w5' - helper_w6) = 0;
perform_round * (helper_w6' - helper_w7) = 0;
perform_round * (helper_w7' - helper_w8) = 0;
perform_round * (helper_w8' - helper_w9) = 0;
perform_round * (helper_w9' - helper_w10) = 0;
perform_round * (helper_w10' - helper_w11) = 0;
perform_round * (helper_w11' - helper_w12) = 0;
perform_round * (helper_w12' - helper_w13) = 0;
perform_round * (helper_w13' - helper_w14) = 0;
perform_round * (helper_w14' - helper_w15) = 0;
// The last value is given the currently computed w value
perform_round * (helper_w15' - w) = 0;

// Message Schedule Array, in the first row
pol commit w;
// These are for rounds > 15
pol COMPUTED_W = helper_w0 + w_s_0 + helper_w9 + w_s_1;
pol commit computed_w_lhs;
pol commit computed_w_rhs;
perform_round * ((computed_w_lhs * 2**32 + computed_w_rhs) - COMPUTED_W) = 0;
pol commit is_input_round;// TODO: Constrain this
perform_round * (w - (is_input_round * helper_w0 + (1 - is_input_round) * computed_w_rhs)) = 0;


// ========== Compute w_s0 ===================
// w[i-15] `rotr` 7
pol commit w_15_rotr_7;
pol commit lhs_w_7;
pol commit rhs_w_7;
perform_round * (helper_w1 - (lhs_w_7 * 2**7 + rhs_w_7)) = 0;
perform_round * (w_15_rotr_7 - (rhs_w_7 * 2**25 + lhs_w_7)) = 0;
// w[i-15] `rotr` 18
pol commit w_15_rotr_18;
pol commit lhs_w_18;
pol commit rhs_w_18;
perform_round * (helper_w1 - (lhs_w_18 * 2**18 + rhs_w_18)) = 0;
perform_round * (w_15_rotr_18 - (rhs_w_18 * 2**14 + lhs_w_18)) = 0;
// w[i-15] `rightshift` 3
pol commit w_15_rshift_3;
pol commit lhs_w_3;
pol commit rhs_w_3;
perform_round * (helper_w1 - (lhs_w_3 * 2**3 + rhs_w_3)) = 0;
perform_round * (w_15_rshift_3 - lhs_w_3) = 0;
// s0 := (w[i-15] `rotr` 7) `xor` (w[i-15] `rotr` 18) `xor` (w[i-15] `rightshift` 3)
pol commit w_15_rotr_7_xor_w_15_rotr_18;
#[LOOKUP_W_S_0_XOR_0]
dummy_zero {w_15_rotr_7, w_15_rotr_18, w_15_rotr_7_xor_w_15_rotr_18, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit w_s_0;
#[LOOKUP_W_S_0_XOR_1]
dummy_zero {w_15_rotr_7_xor_w_15_rotr_18, w_15_rshift_3, w_s_0, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

// ========== Compute w_s1 ===================
// w[i-2] `rotr` 17
pol commit w_2_rotr_17;
pol commit lhs_w_17;
pol commit rhs_w_17;
perform_round * (helper_w14 - (lhs_w_17 * 2**17 + rhs_w_17)) = 0;
perform_round * (w_2_rotr_17 - (rhs_w_17 * 2**15 + lhs_w_17)) = 0;
// w[i-2] `rotr` 19
pol commit w_2_rotr_19;
pol commit lhs_w_19;
pol commit rhs_w_19;
perform_round * (helper_w14 - (lhs_w_19 * 2**19 + rhs_w_19)) = 0;
perform_round * (w_2_rotr_19 - (rhs_w_19 * 2**13 + lhs_w_19)) = 0;
// w[i-2] `rightshift` 10
pol commit w_2_rshift_10;
pol commit lhs_w_10;
pol commit rhs_w_10;
perform_round * (helper_w14 - (lhs_w_10 * 2**10 + rhs_w_10)) = 0;
perform_round * (w_2_rshift_10 - lhs_w_10) = 0;
// s1 := (w[i-2] `rotr` 17) `xor` (w[i-2] `rotr` 19) `xor` (w[i-2] `rightshift` 10)
pol commit w_2_rotr_17_xor_w_2_rotr_19;
#[LOOKUP_W_S_1_XOR_0]
dummy_zero {w_2_rotr_17, w_2_rotr_19, w_2_rotr_17_xor_w_2_rotr_19, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit w_s_1;
#[LOOKUP_W_S_1_XOR_1]
dummy_zero {w_2_rotr_17_xor_w_2_rotr_19, w_2_rshift_10, w_s_1, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

// ========== START OF COMPRESSION BLOCK ==================

// ====== Computing S1 ====================
// e `rotr` 6
pol commit e_rotr_6;
pol commit lhs_e_6;
pol commit rhs_e_6;
perform_round * (e - (lhs_e_6 * 2**6 + rhs_e_6)) = 0;
perform_round * (e_rotr_6 - (rhs_e_6 * 2**26 + lhs_e_6)) = 0;
// e `rotr` 11
pol commit e_rotr_11;
pol commit lhs_e_11;
pol commit rhs_e_11;
perform_round * (e - (lhs_e_11 * 2**11 + rhs_e_11)) = 0;
perform_round * (e_rotr_11 - (rhs_e_11 * 2**21 + lhs_e_11)) = 0;
// e `rotr` 25
pol commit e_rotr_25;
pol commit lhs_e_25;
pol commit rhs_e_25;
perform_round * (e - (lhs_e_25 * 2**25 + rhs_e_25)) = 0;
perform_round * (e_rotr_25 - (rhs_e_25 * 2**7 + lhs_e_25)) = 0;

// pol S_1 = (E_0 `rotr` 6) `xor` (E_0 `rotr` 11) `xor` (E_0 `rotr` 25);

pol commit e_rotr_6_xor_e_rotr_11;
#[LOOKUP_S_1_XOR_0]
dummy_zero {e_rotr_6, e_rotr_11, e_rotr_6_xor_e_rotr_11, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit s_1;
#[LOOKUP_S_1_XOR_1]
dummy_zero {e_rotr_6_xor_e_rotr_11, e_rotr_25, s_1, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

// ==== COMPUTING CH ===========
// pol CH_0 = (E_0 `and` F_0) `xor` ((`not` E_0) `and` G_0);
pol commit e_and_f;

#[LOOKUP_CH_AND_0]
dummy_zero {e, f, e_and_f, and_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit not_e;
perform_round * (e + not_e - (2**32 - 1)) = 0;

pol commit not_e_and_g;
#[LOOKUP_CH_AND_1]
dummy_zero {not_e, g, not_e_and_g, and_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit ch;
#[LOOKUP_CH_XOR]
dummy_zero {e_and_f, not_e_and_g, ch, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

// ===== COMPUTING TMP 1 ===========
// Lookup round constants
pol commit round_constant;
#[LOOKUP_ROUND_CONSTANT]
dummy_zero {round_count, round_constant}
in
binary.start {sha256_params_lookup.table_round_index, sha256_params_lookup.table_round_constant};

pol TMP_1 = h + s_1 + ch + round_constant + w;

// ===== S0 ==================
// pol S_0_0 = (A_0 `rotr` 2) `xor` (A_0 `rotr` 13) `xor` (A_0 `rotr` 22);
// a `rotr` 2
pol commit a_rotr_2;
pol commit lhs_a_2;
pol commit rhs_a_2;
perform_round * (a - (lhs_a_2 * 2**2 + rhs_a_2)) = 0;
perform_round * (a_rotr_2 - (rhs_a_2 * 2**30 + lhs_a_2)) = 0;
// a `rotr` 13
pol commit a_rotr_13;
pol commit lhs_a_13;
pol commit rhs_a_13;
perform_round * (a - (lhs_a_13 * 2**13 + rhs_a_13)) = 0;
perform_round * (a_rotr_13 - (rhs_a_13 * 2**19 + lhs_a_13)) = 0;
// a `rotr` 22
pol commit a_rotr_22;
pol commit lhs_a_22;
pol commit rhs_a_22;
perform_round * (a - (lhs_a_22 * 2**22 + rhs_a_22)) = 0;
perform_round * (a_rotr_22 - (rhs_a_22 * 2**10 + lhs_a_22)) = 0;
// (A_0 `rotr` 2) `xor` (A_0 `rotr` 13)
pol commit a_rotr_2_xor_a_rotr_13;
#[LOOKUP_S_0_XOR_0]
dummy_zero {a_rotr_2, a_rotr_13, a_rotr_2_xor_a_rotr_13, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit s_0;
#[LOOKUP_S_0_XOR_1]
dummy_zero {a_rotr_2_xor_a_rotr_13, a_rotr_22, s_0, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

// ====== Computing Maj =========
// pol MAJ_0 = (A_0 `and` B_0) `xor` (A_0 `and` C_0) `xor` (B_0 `and` C_0);
pol commit a_and_b;
#[LOOKUP_MAJ_AND_0]
dummy_zero {a, b, a_and_b, and_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit a_and_c;
#[LOOKUP_MAJ_AND_1]
dummy_zero {a, c, a_and_c, and_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit b_and_c;
#[LOOKUP_MAJ_AND_2]
dummy_zero {b, c, b_and_c, and_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit a_and_b_xor_a_and_c;
#[LOOKUP_MAJ_XOR_0]
dummy_zero {a_and_b, a_and_c, a_and_b_xor_a_and_c, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

pol commit maj;
#[LOOKUP_MAJ_XOR_1]
dummy_zero {a_and_b_xor_a_and_c, b_and_c, maj, xor_sel}
in
binary.start {binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id};

// ==== Compute TMP 2 ====
pol NEXT_A = s_0 + maj + TMP_1;

pol commit next_a_lhs;
pol commit next_a_rhs;
perform_round * ((next_a_lhs * 2**32 + next_a_rhs) - NEXT_A) = 0;

pol NEXT_E = d + TMP_1;

pol commit next_e_lhs;
pol commit next_e_rhs;
perform_round * ((next_e_lhs * 2**32 + next_e_rhs) - NEXT_E) = 0;

perform_round * (a' - next_a_rhs) = 0;
perform_round * (b' - a) = 0;
perform_round * (c' - b) = 0;
perform_round * (d' - c) = 0;
perform_round * (e' - next_e_rhs) = 0;
perform_round * (f' - e) = 0;
perform_round * (g' - f) = 0;
perform_round * (h' - g) = 0;
// Selector for Radix Operation
pol commit sel_sha256_compression;
sel_sha256_compression * (1 - sel_sha256_compression) = 0;

// TODO: These constraints could be better - we might have to reverse the order of the rounds
pol OUT_A = a + init_a;
LAST * (OUT_A - (output_a_lhs * 2**32 + output_a_rhs)) = 0;
pol OUT_B = b + init_b;
LAST * (OUT_B - (output_b_lhs * 2**32 + output_b_rhs)) = 0;
pol OUT_C = c + init_c;
LAST * (OUT_C - (output_c_lhs * 2**32 + output_c_rhs)) = 0;
pol OUT_D = d + init_d;
LAST * (OUT_D - (output_d_lhs * 2**32 + output_d_rhs)) = 0;
pol OUT_E = e + init_e;
LAST * (OUT_E - (output_e_lhs * 2**32 + output_e_rhs)) = 0;
pol OUT_F = f + init_f;
LAST * (OUT_F - (output_f_lhs * 2**32 + output_f_rhs)) = 0;
pol OUT_G = g + init_g;
LAST * (OUT_G - (output_g_lhs * 2**32 + output_g_rhs)) = 0;
pol OUT_H = h + init_h;
LAST * (OUT_H - (output_h_lhs * 2**32 + output_h_rhs)) = 0;
// These will all be arrays, but we just store the first element for permutation to the main trace for now
pol commit state;
pol commit input;
pol commit output;
Loading

0 comments on commit c6ffba9

Please sign in to comment.