Skip to content

Commit

Permalink
Merge pull request #721 from 0xPolygonHermez/fork_7_SMSHA256
Browse files Browse the repository at this point in the history
Fork 7: Sha256 Padding SM completed
  • Loading branch information
rickb80 authored Nov 20, 2023
2 parents b47e091 + b3fe36f commit af0d7a9
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 37 deletions.
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
77 changes: 43 additions & 34 deletions src/sm/padding_sha256/padding_sha256_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "utils.hpp"
#include "goldilocks_precomputed.hpp"
#include "zklog.hpp"
#include "zkassert.hpp"

using namespace std;

Expand All @@ -13,12 +14,13 @@ uint64_t PaddingSha256Executor::prepareInput (vector<PaddingSha256ExecutorInput>

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
if ((input[i].data.length()%2) != 0)
{
zklog.error("PaddingKKExecutor::prepareInput() detected at entry i=" + to_string(i) + " a odd data string length=" + to_string(input[i].data.length()));
zklog.error("PaddingSha256Executor::prepareInput() detected at entry i=" + to_string(i) + " a odd data string length=" + to_string(input[i].data.length()));
exitProcess();
}

Expand All @@ -31,14 +33,24 @@ uint64_t PaddingSha256Executor::prepareInput (vector<PaddingSha256ExecutorInput>
}
}

keccak256(input[i].dataBytes, input[i].hash);
SHA256(input[i].dataBytes.data(), input[i].dataBytes.size(), input[i].hash);

input[i].realLen = input[i].dataBytes.size();
if(input[i].realLen > 1ULL<<30){
zklog.error("PaddingSha256Executor::prepareInput() detected at entry i=" + to_string(i) + " a data string length=" + to_string(input[i].realLen) + " > 2^30");
exitProcess();
}

// Add padding
input[i].dataBytes.push_back(0x1);
while (input[i].dataBytes.size() % bytesPerBlock) input[i].dataBytes.push_back(0);
input[i].dataBytes[ input[i].dataBytes.size() - 1] |= 0x80;
input[i].dataBytes.push_back(0x80);
while (input[i].dataBytes.size() % bytesPerBlock != 56) input[i].dataBytes.push_back(0);
for(uint64_t j=0; j<4; j++) input[i].dataBytes.push_back(0);

uint64_t bitLen = input[i].realLen*8;
for(uint64_t e=3; e>=0; e--)
{
input[i].dataBytes.push_back(bitLen >> (8*e) && 0xFF);
}

totalInputBytes += input[i].dataBytes.size();
}
Expand All @@ -51,9 +63,9 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,
uint64_t totalInputBytes = prepareInput(input);

// Check input size
if (totalInputBytes > (44*bytesPerBlock*(N/blockSize)))
if (totalInputBytes > (bitsPerElement*bytesPerBlock*(N/blockSize)))
{
zklog.error("PaddingKKExecutor::execute() Too many entries input.size()=" + to_string(input.size()) + " totalInputBytes=" + to_string(totalInputBytes) + " > 44*bytesPerBlock*(N/blockSize)=" + to_string(44*bytesPerBlock*(N/blockSize)));
zklog.error("PaddingKKExecutor::execute() Too many entries input.size()=" + to_string(input.size()) + " totalInputBytes=" + to_string(totalInputBytes) + " > bitsPerElement*bytesPerBlock*(N/blockSize)=" + to_string(bitsPerElement*bytesPerBlock*(N/blockSize)));
exitProcess();
}

Expand All @@ -66,7 +78,7 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,

CommitPol crV[8] = { pols.crV0, pols.crV1, pols.crV2, pols.crV3, pols.crV4, pols.crV5, pols.crV6, pols.crV7 };

/*for (uint64_t k=0; k<8; k++)
/*for (uint64_t k=0; k<8; k++) // polynomials already initialized to 0
{
crV[k][p] = 0;
}*/
Expand All @@ -81,22 +93,19 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,
{

pols.freeIn[p] = fr.fromU64(input[i].dataBytes[j]);

pols.len[p] = fr.fromU64(input[i].realLen);
pols.addr[p] = fr.fromU64(addr);
if (j >= bytesPerBlock) pols.connected[p] = fr.one();
pols.rem[p] = fr.sub(fr.fromU64(input[i].realLen), fr.fromU64(j));
if (!fr.isZero(pols.rem[p]))
{
pols.remInv[p] = glp.inv(pols.rem[p]);
if (fr.toS64(pols.rem[p]) < 0)
{
pols.spare[p] = fr.one();
}
}
pols.rem[p] = fr.sub(fr.fromU64(input[i].realLen), fr.fromU64(j));
if (!fr.isZero(pols.rem[p])) pols.remInv[p] = glp.inv(pols.rem[p]);

if (fr.toS64(pols.rem[p]) < 0) pols.spare[p] = fr.one(); // padding bytes if rem == 0 or spare == 1
pols.incCounter[p] = fr.fromU64((j / bytesPerBlock) +1);


uint64_t s=input[i].dataBytes.size()-1-j;
if(s < 8) pols.lengthSection[p] = fr.one();
if(s < 4) pols.accLength[p] = fr.fromU64((input[i].realLen*8)&&(0xFFFFFFFF<<(s*8))); //rick: ??

bool lastBlock = (p % bytesPerBlock) == (bytesPerBlock - 1);
bool lastHash = lastBlock && ((!fr.isZero(pols.spare[p])) || fr.isZero(pols.rem[p]));
if (lastHash)
Expand Down Expand Up @@ -151,7 +160,7 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,
paddingSha256BitExecutorInput.connected = (j < bytesPerBlock) ? false : true;
required.push_back(paddingSha256BitExecutorInput);

if (j == input[i].dataBytes.size() - 1)
if (j == input[i].dataBytes.size() - 1)
{
scalar2fea(fr, input[i].hash,
pols.hash0[p],
Expand Down Expand Up @@ -185,12 +194,12 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,

pDone = p;

uint64_t nTotalBlocks = 44*(N/blockSize);
uint64_t nTotalBlocks = bitsPerElement*(N/blockSize);
uint64_t nUsedBlocks = p/bytesPerBlock;

if (nUsedBlocks > nTotalBlocks)
{
zklog.error("PaddingKKExecutor::execute() Too many keccak blocks nUsedBlocks=" + to_string(nUsedBlocks) + " > nTotalBlocks=" + to_string(nTotalBlocks) + " BlockSize=" + to_string(blockSize));
zklog.error("PaddingKKExecutor::execute() Too many Sha256 blocks nUsedBlocks=" + to_string(nUsedBlocks) + " > nTotalBlocks=" + to_string(nTotalBlocks) + " BlockSize=" + to_string(blockSize));
exitProcess();
}

Expand All @@ -199,7 +208,7 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,
uint8_t bytes0[bytesPerBlock];
for (uint64_t i=0; i<bytesPerBlock; i++)
{
bytes0[i] = (i==0) ? 1 : ( (i==bytesPerBlock-1) ? 0x80 : 0);
bytes0[i] = (i==0) ? 0x80 : 0;
}

for (uint64_t i=0; i<nFullUnused; i++)
Expand All @@ -209,22 +218,19 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,
pols.addr[p] = fr.fromU64(addr);
if (j == 0)
{
pols.freeIn[p] = fr.one();
pols.freeIn[p] = fr.fromU64(0x80);
}
else
{
if (j == (bytesPerBlock - 1)) pols.freeIn[p] = fr.fromU64(0x80);
pols.rem[p] = fr.neg(fr.fromU64(j));
pols.remInv[p] = glp.inv(pols.rem[p]);
if (fr.toS64(pols.rem[p]) < 0)
{
pols.spare[p] = fr.one();
}
pols.spare[p] = fr.one();
}

pols.incCounter[p] = fr.one();
if(j>=56) pols.lengthSection[p] = fr.one();

pols.crLen[p] = fr.one();

crF[0][p] = fr.one();

if (j % bytesPerBlock == (bytesPerBlock -1) )
Expand Down Expand Up @@ -267,22 +273,25 @@ void PaddingSha256Executor::execute (vector<PaddingSha256ExecutorInput> &input,
uint64_t fp = p;
while (p<N)
{

pols.addr[p] = fr.fromU64(addr);

pols.incCounter[p] = fr.one();


if (p != fp)
{
pols.rem[p] = fr.sub(pols.rem[p-1], fr.one());
if (!fr.isZero(pols.rem[p])) pols.remInv[p] = glp.inv(pols.rem[p]);
pols.spare[p] = fr.one();
} else{
pols.freeIn[p] = fr.fromU64(0x80);
}

pols.incCounter[p] = fr.one();
if(N-p <= 8) pols.lengthSection[p] = fr.one();
pols.crLen[p] = fr.one();
crF[0][p] = fr.one();

p += 1;
}

zklog.info("PaddingKKExecutor successfully processed " + to_string(input.size()) + " Keccak hashes p=" + to_string(p) + " pDone=" + to_string(pDone) + " (" + to_string((double(pDone)*100)/N) + "%)");
zklog.info("PaddingSha256Executor successfully processed " + to_string(input.size()) + " Sha256 hashes p=" + to_string(p) + " pDone=" + to_string(pDone) + " (" + to_string((double(pDone)*100)/N) + "%)");
}
9 changes: 6 additions & 3 deletions src/sm/padding_sha256/padding_sha256_executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "goldilocks_base_field.hpp"
#include "padding_sha256bit_executor.hpp"
#include "scalar.hpp"
#include "sha256.hpp"

USING_PROVER_FORK_NAMESPACE;

Expand Down Expand Up @@ -36,6 +37,7 @@ class PaddingSha256Executor
/* Constant values */
const uint64_t blockSize;
const uint64_t bytesPerBlock;
const uint64_t bitsPerElement;
const uint64_t N;

/* Hash of an empty/zero message */
Expand All @@ -49,11 +51,12 @@ uint64_t prepareInput (vector<PaddingSha256ExecutorInput> &input);
/* Constructor */
PaddingSha256Executor(Goldilocks &fr) :
fr(fr),
blockSize(155286),
bytesPerBlock(136),
blockSize(31487),
bytesPerBlock(64),
bitsPerElement(6),
N(PROVER_FORK_NAMESPACE::PaddingSha256CommitPols::pilDegree())
{
keccak256(NULL, 0, hashZeroScalar);
SHA256(NULL, 0, hashZeroScalar);
scalar2fea(fr, hashZeroScalar, hash0);
};

Expand Down

0 comments on commit af0d7a9

Please sign in to comment.