diff --git a/prover/zkevm/prover/ecdsa/antichamber_test.go b/prover/zkevm/prover/ecdsa/antichamber_test.go index e9faa3128..f65ce646b 100644 --- a/prover/zkevm/prover/ecdsa/antichamber_test.go +++ b/prover/zkevm/prover/ecdsa/antichamber_test.go @@ -167,5 +167,5 @@ func generateDeterministicSignature(txHash []byte) (pk *ecdsa.PublicKey, r, s, v var testCaseAntiChamber = makeTestCase{ HashNum: []int{1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2}, - ToHash: []int{1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1}, + ToHash: []int{1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1}, } diff --git a/prover/zkevm/prover/hash/generic/gen_byte_module.go b/prover/zkevm/prover/hash/generic/gen_byte_module.go index 4d1a67cc7..fdfb443eb 100644 --- a/prover/zkevm/prover/hash/generic/gen_byte_module.go +++ b/prover/zkevm/prover/hash/generic/gen_byte_module.go @@ -46,6 +46,7 @@ func (gdm *GenDataModule) ScanStreams(run *wizard.ProverRuntime) [][]byte { var ( numRow = gdm.Limb.Size() + index = gdm.Index.GetColAssignment(run).IntoRegVecSaveAlloc() limbs = gdm.Limb.GetColAssignment(run).IntoRegVecSaveAlloc() toHash = gdm.ToHash.GetColAssignment(run).IntoRegVecSaveAlloc() hashNum = gdm.HashNum.GetColAssignment(run).IntoRegVecSaveAlloc() @@ -61,7 +62,7 @@ func (gdm *GenDataModule) ScanStreams(run *wizard.ProverRuntime) [][]byte { continue } - if hashNum[row] != currHashNum { + if index[row].IsZero() { if !currHashNum.IsZero() { streams = append(streams, buffer.Bytes()) buffer = &bytes.Buffer{} diff --git a/prover/zkevm/prover/hash/generic/gen_byte_module_test.go b/prover/zkevm/prover/hash/generic/gen_byte_module_test.go index b5057ad7d..03dc16b25 100644 --- a/prover/zkevm/prover/hash/generic/gen_byte_module_test.go +++ b/prover/zkevm/prover/hash/generic/gen_byte_module_test.go @@ -32,6 +32,7 @@ func TestScanByteStream(t *testing.T) { Limb: build.RegisterCommit("B", 32), ToHash: build.RegisterCommit("C", 32), NBytes: build.RegisterCommit("D", 32), + Index: build.RegisterCommit("E", 32), } }) @@ -57,9 +58,11 @@ func assignGdbFromStream(run *wizard.ProverRuntime, gdm *GenDataModule, stream [ hashNum = common.NewVectorBuilder(gdm.HashNum) nbBytes = common.NewVectorBuilder(gdm.NBytes) toHash = common.NewVectorBuilder(gdm.ToHash) + index = common.NewVectorBuilder(gdm.Index) ) for hashID := range stream { + ctr := 0 currStream := stream[hashID] for i := 0; i < len(currStream); i += 2 { @@ -73,8 +76,10 @@ func assignGdbFromStream(run *wizard.ProverRuntime, gdm *GenDataModule, stream [ copy(currLimbLA[16:], currLimb[:currNbBytes]) limbs.PushLo(currLimbLA) hashNum.PushInt(hashID + 1) + index.PushInt(ctr) nbBytes.PushInt(currNbBytes) toHash.PushOne() + ctr++ } } @@ -83,4 +88,5 @@ func assignGdbFromStream(run *wizard.ProverRuntime, gdm *GenDataModule, stream [ hashNum.PadAndAssign(run, field.Zero()) nbBytes.PadAndAssign(run, field.Zero()) toHash.PadAndAssign(run, field.Zero()) + index.PadAndAssign(run) } diff --git a/prover/zkevm/prover/hash/importpad/import_pad.go b/prover/zkevm/prover/hash/importpad/import_pad.go index 48b24fe4f..80d3bcd38 100644 --- a/prover/zkevm/prover/hash/importpad/import_pad.go +++ b/prover/zkevm/prover/hash/importpad/import_pad.go @@ -251,11 +251,11 @@ func (imp *importation) Run(run *wizard.ProverRuntime) { sha2Count++ - if i > 0 && currHashNum != hashNum[i] && !currHashNum.IsZero() { + if index[i].IsZero() && !currHashNum.IsZero() { imp.padder.pushPaddingRows(currByteSize, &iab) } - if currHashNum != hashNum[i] { + if index[i].IsZero() { currHashNum = hashNum[i] currByteSize = 0 iab.IsNewHash.PushOne() diff --git a/prover/zkevm/prover/hash/importpad/import_pad_test.go b/prover/zkevm/prover/hash/importpad/import_pad_test.go index c0b4fd1cd..0387fbd8d 100644 --- a/prover/zkevm/prover/hash/importpad/import_pad_test.go +++ b/prover/zkevm/prover/hash/importpad/import_pad_test.go @@ -114,6 +114,7 @@ func checkPaddingAssignment(t *testing.T, run *wizard.ProverRuntime, paddingFunc Limb: mod.Limbs, NBytes: mod.NBytes, ToHash: mod.IsActive, + Index: mod.Index, } inputStreams = mod.Inputs.Src.Data.ScanStreams(run) diff --git a/prover/zkevm/prover/statemanager/mimccodehash/assign.go b/prover/zkevm/prover/statemanager/mimccodehash/assign.go index 3184b1ba0..a16113833 100644 --- a/prover/zkevm/prover/statemanager/mimccodehash/assign.go +++ b/prover/zkevm/prover/statemanager/mimccodehash/assign.go @@ -91,109 +91,115 @@ func (mh *Module) Assign(run *wizard.ProverRuntime) { builder.codeSize = append(builder.codeSize, codeSize[i]) } - // Initialize the first row of the remaining columns - builder.isNewHash = append(builder.isNewHash, field.One()) - - // Detect if it is a one limb segment (at the begining) and assign IsHashEnd accordingly - if builder.cfi[1] != builder.cfi[0] { - builder.isHashEnd = append(builder.isHashEnd, field.One()) - } else { - builder.isHashEnd = append(builder.isHashEnd, field.Zero()) - } - - builder.prevState = append(builder.prevState, field.Zero()) - builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[0], builder.limb[0])) + // The content of this statement is constructing isNewHash and isHashEnd + // prevState and newState. However, it is only needed when there is any + // codehash to hash in the first place. + if len(builder.cfi) > 0 { - // Assign other rows of the remaining columns - for i := 1; i < len(builder.cfi); i++ { + // Initialize the first row of the remaining columns + builder.isNewHash = append(builder.isNewHash, field.One()) - // We do not need to continue if we are in the inactive area - if builder.isActive[i].IsZero() { - break + // Detect if it is a one limb segment (at the begining) and assign IsHashEnd accordingly + if builder.cfi[1] != builder.cfi[0] { + builder.isHashEnd = append(builder.isHashEnd, field.One()) + } else { + builder.isHashEnd = append(builder.isHashEnd, field.Zero()) } - var ( - cfiPrev = builder.cfi[i-1] - cfiCurr = builder.cfi[i] - cfiNext = builder.cfi[i+1] - isSegmentBegin = false - isSegmentMiddle = false - isSegmentEnd = false - isOneLimbSegment = false - ) - - if cfiPrev.Equal(&cfiCurr) && cfiCurr.Equal(&cfiNext) { - isSegmentMiddle = true - } + builder.prevState = append(builder.prevState, field.Zero()) + builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[0], builder.limb[0])) - if !cfiPrev.Equal(&cfiCurr) && cfiCurr.Equal(&cfiNext) { - isSegmentBegin = true - } + // Assign other rows of the remaining columns + for i := 1; i < len(builder.cfi); i++ { - if cfiPrev.Equal(&cfiCurr) && !cfiCurr.Equal((&cfiNext)) { - isSegmentEnd = true - } + // We do not need to continue if we are in the inactive area + if builder.isActive[i].IsZero() { + break + } - if !cfiPrev.Equal(&cfiCurr) && !cfiCurr.Equal((&cfiNext)) { - isOneLimbSegment = true - } + var ( + cfiPrev = builder.cfi[i-1] + cfiCurr = builder.cfi[i] + cfiNext = builder.cfi[i+1] + isSegmentBegin = false + isSegmentMiddle = false + isSegmentEnd = false + isOneLimbSegment = false + ) + + if cfiPrev.Equal(&cfiCurr) && cfiCurr.Equal(&cfiNext) { + isSegmentMiddle = true + } - // Assign for begining of a segment - if isSegmentBegin { - builder.isNewHash = append(builder.isNewHash, field.One()) - builder.isHashEnd = append(builder.isHashEnd, field.Zero()) - builder.prevState = append(builder.prevState, field.Zero()) - builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) - continue - } + if !cfiPrev.Equal(&cfiCurr) && cfiCurr.Equal(&cfiNext) { + isSegmentBegin = true + } - // Assign for middle of a segment - if isSegmentMiddle { - builder.isNewHash = append(builder.isNewHash, field.Zero()) - builder.isHashEnd = append(builder.isHashEnd, field.Zero()) - builder.prevState = append(builder.prevState, builder.newState[i-1]) - builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) - continue - } + if cfiPrev.Equal(&cfiCurr) && !cfiCurr.Equal((&cfiNext)) { + isSegmentEnd = true + } - // Assign for end of a segment - if isSegmentEnd { - builder.isNewHash = append(builder.isNewHash, field.Zero()) - builder.isHashEnd = append(builder.isHashEnd, field.One()) - builder.prevState = append(builder.prevState, builder.newState[i-1]) - builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) - continue - } + if !cfiPrev.Equal(&cfiCurr) && !cfiCurr.Equal((&cfiNext)) { + isOneLimbSegment = true + } - // Assign for a one limb segment - if isOneLimbSegment { - builder.isNewHash = append(builder.isNewHash, field.One()) - builder.isHashEnd = append(builder.isHashEnd, field.One()) - builder.prevState = append(builder.prevState, field.Zero()) - builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) - continue - } - } + // Assign for begining of a segment + if isSegmentBegin { + builder.isNewHash = append(builder.isNewHash, field.One()) + builder.isHashEnd = append(builder.isHashEnd, field.Zero()) + builder.prevState = append(builder.prevState, field.Zero()) + builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) + continue + } - // Assign codehash from the romLex input - for i := 0; i < len(builder.cfi); i++ { + // Assign for middle of a segment + if isSegmentMiddle { + builder.isNewHash = append(builder.isNewHash, field.Zero()) + builder.isHashEnd = append(builder.isHashEnd, field.Zero()) + builder.prevState = append(builder.prevState, builder.newState[i-1]) + builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) + continue + } - // We do not need to continue if we are in the inactive area - if builder.isActive[i].IsZero() { - break + // Assign for end of a segment + if isSegmentEnd { + builder.isNewHash = append(builder.isNewHash, field.Zero()) + builder.isHashEnd = append(builder.isHashEnd, field.One()) + builder.prevState = append(builder.prevState, builder.newState[i-1]) + builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) + continue + } + + // Assign for a one limb segment + if isOneLimbSegment { + builder.isNewHash = append(builder.isNewHash, field.One()) + builder.isHashEnd = append(builder.isHashEnd, field.One()) + builder.prevState = append(builder.prevState, field.Zero()) + builder.newState = append(builder.newState, mimc.BlockCompression(builder.prevState[i], builder.limb[i])) + continue + } } - currCFI := builder.cfi[i] + // Assign codehash from the romLex input + for i := 0; i < len(builder.cfi); i++ { - // For each currCFI, we look over all the CFIs in the Romlex input, - // and append only that codehash for which the cfi matches with currCFI - for j := 0; j < len(cfiRomLex); j++ { - if currCFI == cfiRomLex[j] { - builder.codeHashHi = append(builder.codeHashHi, codeHashHi[j]) - builder.codeHashLo = append(builder.codeHashLo, codeHashLo[j]) + // We do not need to continue if we are in the inactive area + if builder.isActive[i].IsZero() { break } - continue + + currCFI := builder.cfi[i] + + // For each currCFI, we look over all the CFIs in the Romlex input, + // and append only that codehash for which the cfi matches with currCFI + for j := 0; j < len(cfiRomLex); j++ { + if currCFI == cfiRomLex[j] { + builder.codeHashHi = append(builder.codeHashHi, codeHashHi[j]) + builder.codeHashLo = append(builder.codeHashLo, codeHashLo[j]) + break + } + continue + } } } diff --git a/prover/zkevm/prover/statemanager/mimccodehash/define.go b/prover/zkevm/prover/statemanager/mimccodehash/define.go index 37bb7451e..15fe1df39 100644 --- a/prover/zkevm/prover/statemanager/mimccodehash/define.go +++ b/prover/zkevm/prover/statemanager/mimccodehash/define.go @@ -113,7 +113,7 @@ func (mh *Module) checkConsistency(comp *wizard.CompiledIOP) { symbolic.Sub(1, mh.IsNewHash))) // Local constraint IsNewHash starts with 1 - comp.InsertLocal(mh.inputs.Round, mh.qname("IS_NEW_HASH_LOCAL"), symbolic.Sub(mh.IsNewHash, 1)) + comp.InsertLocal(mh.inputs.Round, mh.qname("IS_NEW_HASH_LOCAL"), symbolic.Sub(mh.IsNewHash, mh.IsActive)) // if CFI[i+1] - CFI[i] != 0, IsHashEnd[i] = 1, e.g., IsActive[i] * (CFI[i+1] - CFI[i]) * (1 - IsHashEnd[i]) = 0 comp.InsertGlobal(mh.inputs.Round, mh.qname("IS_HASH_END_CONSISTENCY_1"),