/ reference / nim / proof_input / src / gen_input / goldilocks.nim
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  #-------------------------------------------------------------------------------