Skip to content

Commit

Permalink
Merge branch 'fork_7' of github.com:0xPolygonHermez/zkevm-prover into…
Browse files Browse the repository at this point in the history
… fork_7
  • Loading branch information
fractasy committed Nov 21, 2023
2 parents 42dd1e5 + af0d7a9 commit dfd8a68
Show file tree
Hide file tree
Showing 10 changed files with 327 additions and 66 deletions.
76 changes: 50 additions & 26 deletions src/executor/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ void* PoseidonThread (void* arg)
return NULL;
}

void* KeccakSha256Thread (void* arg)
void* KeccakThread (void* arg)
{
// Get the context
ExecutorContext * pExecutorContext = (ExecutorContext *)arg;
Expand All @@ -354,18 +354,8 @@ void* KeccakSha256Thread (void* arg)
TimerStart(PADDING_KK_BIT_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->paddingKKBitExecutor.execute(pExecutorContext->pRequired->PaddingKKBit, pExecutorContext->pCommitPols->PaddingKKBit, pExecutorContext->pRequired->Bits2Field);
TimerStopAndLog(PADDING_KK_BIT_SM_EXECUTE_THREAD);

// Execute the Padding SHA256 State Machine
TimerStart(PADDING_SHA256_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->paddingSha256Executor.execute(pExecutorContext->pRequired->PaddingSha256, pExecutorContext->pCommitPols->PaddingSha256, pExecutorContext->pRequired->PaddingSha256Bit);
TimerStopAndLog(PADDING_SHA256_SM_EXECUTE_THREAD);

// Execute the PaddingKKBit State Machine
TimerStart(PADDING_SHA256_BIT_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->paddingSha256BitExecutor.execute(pExecutorContext->pRequired->PaddingSha256Bit, pExecutorContext->pCommitPols->PaddingSha256Bit, pExecutorContext->pRequired->Bits2Field);
TimerStopAndLog(PADDING_SHA256_BIT_SM_EXECUTE_THREAD);

// Execute the Poseidon G State Machine
// Execute the Bits2Field State Machine
TimerStart(BITS2FIELD_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->bits2FieldExecutor.execute(pExecutorContext->pRequired->Bits2Field, pExecutorContext->pCommitPols->Bits2Field, pExecutorContext->pRequired->KeccakF);
TimerStopAndLog(BITS2FIELD_SM_EXECUTE_THREAD);
Expand All @@ -374,6 +364,29 @@ void* KeccakSha256Thread (void* arg)
TimerStart(KECCAK_F_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->keccakFExecutor.execute(pExecutorContext->pRequired->KeccakF, pExecutorContext->pCommitPols->KeccakF);
TimerStopAndLog(KECCAK_F_SM_EXECUTE_THREAD);

return NULL;
}

void* Sha256Thread (void* arg)
{
// Get the context
ExecutorContext * pExecutorContext = (ExecutorContext *)arg;

// Execute the Padding SHA256 State Machine
TimerStart(PADDING_SHA256_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->paddingSha256Executor.execute(pExecutorContext->pRequired->PaddingSha256, pExecutorContext->pCommitPols->PaddingSha256, pExecutorContext->pRequired->PaddingSha256Bit);
TimerStopAndLog(PADDING_SHA256_SM_EXECUTE_THREAD);

// Execute the PaddingSha256Bit State Machine
TimerStart(PADDING_SHA256_BIT_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->paddingSha256BitExecutor.execute(pExecutorContext->pRequired->PaddingSha256Bit, pExecutorContext->pCommitPols->PaddingSha256Bit, pExecutorContext->pRequired->Bits2FieldSha256);
TimerStopAndLog(PADDING_SHA256_BIT_SM_EXECUTE_THREAD);

// Execute the Bits2FieldSha256 State Machine
TimerStart(BITS2FIELDSHA256_SM_EXECUTE_THREAD);
pExecutorContext->pExecutor->bits2FieldSha256Executor.execute(pExecutorContext->pRequired->Bits2FieldSha256, pExecutorContext->pCommitPols->Bits2FieldSha256, pExecutorContext->pRequired->Sha256F);
TimerStopAndLog(BITS2FIELDSHA256_SM_EXECUTE_THREAD);

// Execute the Sha256 F State Machine
TimerStart(SHA256_F_SM_EXECUTE_THREAD);
Expand Down Expand Up @@ -464,16 +477,6 @@ void Executor::execute (ProverRequest &proverRequest, PROVER_FORK_NAMESPACE::Com
paddingKKBitExecutor.execute(required.PaddingKKBit, commitPols.PaddingKKBit, required.Bits2Field);
TimerStopAndLog(PADDING_KK_BIT_SM_EXECUTE);

// Execute the PaddingSha256 State Machine
TimerStart(PADDING_SHA256_SM_EXECUTE);
paddingSha256Executor.execute(required.PaddingSha256, commitPols.PaddingSha256, required.PaddingSha256Bit);
TimerStopAndLog(PADDING_SHA256_SM_EXECUTE);

// Execute the PaddingSha256Bit State Machine
TimerStart(PADDING_SHA256_BIT_SM_EXECUTE);
paddingSha256BitExecutor.execute(required.PaddingSha256Bit, commitPols.PaddingSha256Bit, required.Bits2Field);
TimerStopAndLog(PADDING_SHA256_BIT_SM_EXECUTE);

// Execute the Bits2Field State Machine
TimerStart(BITS2FIELD_SM_EXECUTE);
bits2FieldExecutor.execute(required.Bits2Field, commitPols.Bits2Field, required.KeccakF);
Expand All @@ -484,6 +487,21 @@ void Executor::execute (ProverRequest &proverRequest, PROVER_FORK_NAMESPACE::Com
keccakFExecutor.execute(required.KeccakF, commitPols.KeccakF);
TimerStopAndLog(KECCAK_F_SM_EXECUTE);

// Execute the PaddingSha256 State Machine
TimerStart(PADDING_SHA256_SM_EXECUTE);
paddingSha256Executor.execute(required.PaddingSha256, commitPols.PaddingSha256, required.PaddingSha256Bit);
TimerStopAndLog(PADDING_SHA256_SM_EXECUTE);

// Execute the PaddingSha256Bit State Machine
TimerStart(PADDING_SHA256_BIT_SM_EXECUTE);
paddingSha256BitExecutor.execute(required.PaddingSha256Bit, commitPols.PaddingSha256Bit, required.Bits2FieldSha256);
TimerStopAndLog(PADDING_SHA256_BIT_SM_EXECUTE);

// Execute the Bits2FieldSha256 State Machine
TimerStart(BITS2FIELDSHA256_SM_EXECUTE);
bits2FieldSha256Executor.execute(required.Bits2FieldSha256, commitPols.Bits2FieldSha256, required.Sha256F);
TimerStopAndLog(BITS2FIELDSHA256_SM_EXECUTE);

// Excute the Sha256 F State Machine
TimerStart(SHA256_F_SM_EXECUTE);
sha256FExecutor.execute(required.Sha256F, commitPols.Sha256F);
Expand Down Expand Up @@ -550,16 +568,22 @@ void Executor::execute (ProverRequest &proverRequest, PROVER_FORK_NAMESPACE::Com
pthread_t memoryThread;
pthread_create(&memoryThread, NULL, MemoryThread, &executorContext);

// Execute the PaddingKK, PaddingKKBit, Bits2Field, Keccak F and NormGate9 State Machines
pthread_t keccakSha256Thread;
pthread_create(&keccakSha256Thread, NULL, KeccakSha256Thread, &executorContext);
// Execute the PaddingKK, PaddingKKBit, Bits2Field, Keccak F
pthread_t keccakThread;
pthread_create(&keccakThread, NULL, KeccakThread, &executorContext);

// Execute the PaddingSha256, PaddingSha256Bit, Bits2FieldSha256, Sha256 F
pthread_t sha256Thread;
pthread_create(&sha256Thread, NULL, Sha256Thread, &executorContext);

// Wait for the parallel SM threads
pthread_join(binaryThread, NULL);
pthread_join(memAlignThread, NULL);
pthread_join(memoryThread, NULL);
pthread_join(arithThread, NULL);
pthread_join(poseidonThread, NULL);
pthread_join(keccakSha256Thread, NULL);
pthread_join(keccakThread, NULL);
pthread_join(sha256Thread, NULL);

}
}
2 changes: 2 additions & 0 deletions src/executor/executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class Executor
KeccakFExecutor keccakFExecutor;
PaddingSha256Executor paddingSha256Executor;
PaddingSha256BitExecutor paddingSha256BitExecutor;
Bits2FieldSha256Executor bits2FieldSha256Executor;
Sha256FExecutor sha256FExecutor;
PaddingPGExecutor paddingPGExecutor;
PoseidonGExecutor poseidonGExecutor;
Expand Down Expand Up @@ -84,6 +85,7 @@ class Executor
keccakFExecutor(fr, config),
paddingSha256Executor(fr),
paddingSha256BitExecutor(fr),
bits2FieldSha256Executor(fr),
sha256FExecutor(fr, config),
paddingPGExecutor(fr, poseidon),
poseidonGExecutor(fr, poseidon),
Expand Down
5 changes: 4 additions & 1 deletion src/main_sm/fork_7/main/main_exec_required.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
#include "sm/padding_kk/padding_kk_executor.hpp"
#include "sm/padding_kkbit/padding_kkbit_executor.hpp"
#include "sm/bits2field/bits2field_executor.hpp"
#include "sm/keccak_f/keccak_f_executor.hpp"
#include "sm/padding_sha256/padding_sha256_executor.hpp"
#include "sm/padding_sha256bit/padding_sha256bit_executor.hpp"
#include "sm/keccak_f/keccak_f_executor.hpp"
#include "sm/bits2field_sha256/bits2field_sha256_executor.hpp"
#include "sm/sha256_f/sha256_f_executor.hpp"
#include "sm/memory/memory_executor.hpp"
#include "sm/padding_pg/padding_pg_executor.hpp"
#include "sm/mem_align/mem_align_executor.hpp"
Expand All @@ -34,6 +36,7 @@ class MainExecRequired
vector<vector<Goldilocks::Element>> KeccakF;
vector<PaddingSha256ExecutorInput> PaddingSha256;
vector<PaddingSha256BitExecutorInput> PaddingSha256Bit;
vector<Bits2FieldSha256ExecutorInput> Bits2FieldSha256;
vector<vector<Goldilocks::Element>> Sha256F;
vector<PaddingPGExecutorInput> PaddingPG;
vector<array<Goldilocks::Element, 17>> PoseidonG; // The 17th fe is the permutation
Expand Down
166 changes: 166 additions & 0 deletions src/sm/bits2field_sha256/bits2field_sha256_executor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#include "config.hpp"
#include "bits2field_sha256_executor.hpp"
#include "zkassert.hpp"
#include "utils.hpp"
#include "zklog.hpp"

/*
This SM inserts 44 bits of 44 different Keccak-f inputs/outputs in the lower bits of a field element.
The first evaluation is reserved to match the keccak-f gates topology.
The evaluations usage are: 1 (reserved) + 44 (one per bit0 of 44 inputs) + 44 + ...
As per PIL spec:
field44' = (1-FieldLatch)*field44 + bit*Factor;
Where FieldLatch and Factor are constant polynomials:
FieldLatch = 0, 43 zeros, 1, 43 zeros, 1, ...
Factor = 0, 1, 2, 4, ..., 1<<43, 1, 2, 4, ...
For example, if bit_0 of the first 44 inputs were alterned ones and zeros, and bit_N=bit_N-1:
Constant pols: Committed pols:
Pos 0: Factor=0 FieldLatch=0 bit=0 field44=0b0 (reserved)
Pos 1: Factor=1 FieldLatch=0 bit=1 field44=0b0
Pos 2: Factor=2 FieldLatch=0 bit=0 field44=0b1
Pos 3: Factor=4 FieldLatch=0 bit=1 field44=0b01
Pos 4: Factor=8 FieldLatch=0 bit=0 field44=0b101
Pos 5: Factor=16 FieldLatch=0 bit=1 field44=0b0101
Pos 6: Factor=32 FieldLatch=0 bit=0 field44=0b10101
...
Pos 44: Factor=1<<43 FieldLatch=0 bit=0 field44=0b1010101010101010101010101010101010101010101
Pos 45: Factor=1 FieldLatch=1 bit=1 field44=0b01010101010101010101010101010101010101010101 (completed field element)
Pos 46: Factor=2 FieldLatch=0 bit=0 field44=0b1
Pos 47: Factor=4 FieldLatch=0 bit=1 field44=0b01
Pos 48: Factor=8 FieldLatch=0 bit=0 field44=0b101
Pos 49: Factor=16 FieldLatch=0 bit=1 field44=0b0101
Pos 50: Factor=32 FieldLatch=0 bit=0 field44=0b10101
...
Pos 88: Factor=1<<43 FieldLatch=0 bit=0 field44=0b1010101010101010101010101010101010101010101
Pos 89: Factor=1 FieldLatch=1 bit=1 field44=0b01010101010101010101010101010101010101010101 (completed field element)
Pos 90: Factor=2 FieldLatch=0 bit=0 field44=0b1
etc.
*/

inline uint64_t getBitFromState ( const uint8_t (&state)[200], uint64_t i )
{
return (state[i/8] >> (i%8)) & 1;
}

void Bits2FieldSha256Executor::execute (vector<Bits2FieldSha256ExecutorInput> &input, Bits2FieldSha256CommitPols &pols, vector<vector<Goldilocks::Element>> &required)
{
#if 0
/* Check input size (the number of keccaks blocks to process) is not bigger than
the capacity of the SM (the number of slots that fit into the evaluations multiplied by the number of bits per field element) */
if (input.size() > nSlots*44)
{
zklog.error("Bits2FieldSha256Executor::execute() too many entries input.size()=" + to_string(input.size()) + " > nSlots*44=" + to_string(nSlots*44));
exitProcess();
}

/* Evaluation counter
The first position 0 is reserved since it will contain the Zero^One gate in Keccak-f SM, so we start at position 1 */
uint64_t p = 1;

/* Accumulator field element */
Goldilocks::Element accField = fr.zero();

/* For every slot i */
for (uint64_t i=0; i<nSlots; i++)
{
vector<Goldilocks::Element> keccakFSlot;

/* For every input bit */
for (uint64_t j=0; j<1600; j++)
{
/* For every field element bit */
for (uint64_t k=0; k<44; k++)
{
/* Get this input bit and store it in pols.bit[] */
pols.bit[p] = getBit(input, i*44 + k, false, j);

/* Store the accumulated field in pols.field44[] */
pols.field44[p] = accField;

/* Add this bit to accField, left-shifting the rest */
if (k == 0)
{
accField = pols.bit[p];
}
else
{
accField = fr.add( accField, fr.fromU64(fr.toU64(pols.bit[p]) << k) );
}

/* Increment the pol evaluation counter */
p++;
}

/* Store the accField in the input vector for the keccak-f SM */
keccakFSlot.push_back(accField);
}

/* For every output bit */
for (uint64_t j=0; j<1600; j++)
{
/* For every field element bit */
for (uint64_t k=0; k<44; k++)
{
/* Get this output bit and store it in pols.bit[] */
pols.bit[p] = getBit(input, i*44 + k, true, j);

/* Store the accumulated field in pols.field44[] */
pols.field44[p] = accField;

/* Add this bit to accField, left-shifting the rest */
if (k == 0)
{
accField = pols.bit[p];
}
else
{
accField = fr.add( accField, fr.fromU64((fr.toU64(pols.bit[p]) << k)) );
}

/* Increment the pol evaluation counter */
p++;
}
}

/* Add the accumulated field elements as a required input for the keccak-f SM */
required.push_back(keccakFSlot);

/* Store the accumulated field into pols.field44[] */
pols.field44[p] = accField;
accField = fr.zero();
p++;

/* Skip the rest of the gates of the keccak-f SM: slot size minus the consumed evaluations */
p += slotSize - (3200*44+1);
}

/* Sanity check */
zkassert(p <= N);

zklog.info("Bits2FieldSha256Executor successfully processed " + to_string(input.size()) + " Keccak hashes (" + to_string((double(input.size())*slotSize*100)/(44*N)) + "%)");
#endif
}

Goldilocks::Element Bits2FieldSha256Executor::getBit (vector<Bits2FieldSha256ExecutorInput> &input, uint64_t block, bool isOutput, uint64_t pos)
{
/* If we run out of input, simply return zero */
if (block >= input.size())
{
return fr.zero();
}

/* Return the bit "pos" of the input or output part of the state */
if (isOutput)
{
return fr.fromU64(getBitFromState(input[block].outputState, pos));
}
else
{
return fr.fromU64(getBitFromState(input[block].inputState, pos));
}
}
52 changes: 52 additions & 0 deletions src/sm/bits2field_sha256/bits2field_sha256_executor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef BITS2FIELD_SHA256_EXECUTOR_HPP
#define BITS2FIELD_SHA256_EXECUTOR_HPP

#include <vector>
#include "definitions.hpp"
#include "sm/pols_generated/commit_pols.hpp"

USING_PROVER_FORK_NAMESPACE;

using namespace std;

class Bits2FieldSha256ExecutorInput
{
public:

/* Input and output states */
uint8_t inputState[200];
uint8_t outputState[200];
};

class Bits2FieldSha256Executor
{
private:

/* Goldilocks reference */
Goldilocks &fr;

/* Constant values */
const uint64_t slotSize;
const uint64_t N;
const uint64_t nSlots;

public:

/* Constructor */
Bits2FieldSha256Executor(Goldilocks &fr) :
fr(fr),
slotSize(155286),
N(Bits2FieldSha256CommitPols::pilDegree()),
nSlots((N-1)/slotSize) {};

/* Executor */
void execute (vector<Bits2FieldSha256ExecutorInput> &input, Bits2FieldSha256CommitPols &pols, vector<vector<Goldilocks::Element>> &required);

private:

/* Gets bit "pos" from input vector position "block" */
Goldilocks::Element getBit (vector<Bits2FieldSha256ExecutorInput> &input, uint64_t block, bool isOutput, uint64_t pos);

};

#endif
1 change: 1 addition & 0 deletions src/sm/padding_kk/padding_kk_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ uint64_t PaddingKKExecutor::prepareInput (vector<PaddingKKExecutorInput> &input)

for (uint64_t i=0; i<input.size(); i++)
{
input[i].dataBytes.clear();
if (input[i].data.length() > 0)
{
// Make sure we got an even number of characters
Expand Down
Loading

0 comments on commit dfd8a68

Please sign in to comment.