goldilocks.nim
1 2 # 3 # generate the input data for the proof 4 # see `json.nim` to export it in Snarkjs-compatible format 5 # 6 7 import sugar 8 import std/sequtils 9 10 import ../blocks/goldilocks 11 import ../slot 12 import ../dataset 13 import ../sample/goldilocks 14 import ../merkle 15 import ../merkle/goldilocks/poseidon2 16 import ../merkle/goldilocks/monolith 17 import ../types 18 import ../types/goldilocks 19 20 #------------------------------------------------------------------------------- 21 22 proc buildSlotTreeFull( hashcfg: HashConfig, globcfg: GlobalConfig, slotCfg: SlotConfig ): (seq[MerkleTree[Digest]], MerkleTree[Digest]) = 23 24 let ncells = slotCfg.nCells 25 let nblocks = ncells div cellsPerBlock(globcfg) 26 assert( nblocks * cellsPerBlock(globcfg) == ncells ) 27 let blocks : seq[Block] = collect( newSeq, (for i in 0..<nblocks: slotLoadBlockData(globcfg, slotCfg, i) )) 28 let miniTrees : seq[MerkleTree[Digest]] = collect( newSeq, (for blk in blocks: networkBlockTree(hashcfg, globcfg, blk) )) 29 let blockHashes : seq[Root] = map( miniTrees , treeRoot ) 30 let bigTree = merkleTree( hashcfg, blockHashes ) 31 return (miniTrees, bigTree) 32 33 proc buildSlotTree( hashcfg: HashConfig, globcfg: GlobalConfig, slotCfg: SlotConfig ): MerkleTree[Digest] = 34 return buildSlotTreeFull(hashcfg, globcfg, slotCfg)[1] 35 36 proc generateProofInput*( hashCfg: HashConfig, globCfg: GlobalConfig, dsetCfg: DataSetConfig, slotIdx: SlotIdx, entropy: Entropy ): SlotProofInput[Digest] = 37 let nslots = dsetCfg.nSlots 38 let ncells = dsetCfg.nCells 39 let nblocks = ncells div cellsPerBlock(globCfg) 40 assert( nblocks * cellsPerBlock(globcfg) == ncells ) 41 42 let slotCfgs = collect( newSeq , (for i in 0..<nslots: slotCfgFromDataSetCfg(dsetcfg, i) )) 43 let slotTrees = collect( newSeq , (for scfg in slotcfgs: buildSlotTree(hashCfg, globCfg, scfg) )) 44 let slotRoots = map( slotTrees, treeRoot ) 45 46 let ourSlotCfg = slotCfgs[slotIdx] 47 let ourSlotRoot = slotRoots[slotIdx] 48 let ourSlotTree = slotTrees[slotIdx] 49 50 let dsetTree = merkleTree( hashcfg, slotRoots ) 51 let dsetRoot = treeRoot( dsetTree ) 52 let slotProof = merkleProof( dsetTree , slotIdx ) 53 54 let indices = cellIndices(hashCfg, entropy, ourSlotRoot, ncells, dsetCfg.nSamples) 55 56 var inputs : seq[CellProofInput[Digest]] 57 for cellIdx in indices: 58 let (miniTrees, bigTree) = buildSlotTreeFull( hashCfg, globCfg, ourSlotCfg ) 59 let blockIdx = cellIdx div cellsPerBlock(globcfg) 60 let blockTree = miniTrees[ blockIdx ] 61 let cellData = slotLoadCellData( globCfg, ourSlotCfg, cellIdx ) 62 let botProof = merkleProof( blockTree , cellIdx mod cellsPerBlock(globcfg) ) 63 let topProof = merkleProof( bigTree , blockIdx ) 64 65 var prf : MerkleProof[Digest] 66 case hashCfg.hashFun: 67 of Poseidon2: prf = padMerkleProof( mergeMerkleProofs( poseidon2.compressWithKey, botProof, topProof ), globCfg.maxDepth ) 68 of Monolith: prf = padMerkleProof( mergeMerkleProofs( monolith.compressWithKey , botProof, topProof ), globCfg.maxDepth ) 69 70 inputs.add( CellProofInput[Digest](cellData: cellData, merkleProof: prf) ) 71 72 return SlotProofInput[Digest]( dataSetRoot: dsetRoot 73 , entropy: entropy 74 , nCells: ncells 75 , nSlots: nslots 76 , slotIndex: slotIdx 77 , slotRoot: ourSlotRoot 78 , slotProof: padMerkleProof( slotProof, globCfg.maxLog2NSlots ) 79 , proofInputs: inputs 80 ) 81 82 #--------------------------------------- 83 84 proc generateProofInputGoldilocks*( hashCfg: HashConfig, globCfg: GlobalConfig, dsetCfg: DataSetConfig, slotIdx: SlotIdx, entropy: Entropy ): SlotProofInput[Digest] = 85 generateProofInput( hashCfg, globCfg, dsetCfg, slotIdx, entropy) 86 87 #-------------------------------------------------------------------------------