diff --git a/reference/nim/proof_input/.gitignore b/reference/nim/proof_input/.gitignore new file mode 100644 index 0000000..43668ec --- /dev/null +++ b/reference/nim/proof_input/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +testmain +*.json \ No newline at end of file diff --git a/reference/nim/proof_input/proof_input.nimble b/reference/nim/proof_input/proof_input.nimble new file mode 100644 index 0000000..325f5e4 --- /dev/null +++ b/reference/nim/proof_input/proof_input.nimble @@ -0,0 +1,11 @@ + +version = "0.0.1" +author = "Balazs Komuves" +description = "reference implementation for generating the proof inputs" +license = "MIT or Apache-2.0" +srcDir = "src" +bin = @["testmain"] + +requires "nim >= 1.6.0" +requires "https://github.com/mratsim/constantine" +requires "https://github.com/codex-storage/nim-poseidon2#596f7b18070b44ca0bf305bf9bdf1dc4f6011181" diff --git a/reference/nim/proof_input/src/blocks.nim b/reference/nim/proof_input/src/blocks.nim new file mode 100644 index 0000000..4db714d --- /dev/null +++ b/reference/nim/proof_input/src/blocks.nim @@ -0,0 +1,56 @@ + +import sugar +import std/sequtils + +#import poseidon2/types +import poseidon2/io +import poseidon2/sponge +import poseidon2/merkle + +import types +import merkle + +#------------------------------------------------------------------------------- + +func hashCellOpen( cellData: openArray[byte] ): Hash = + assert( cellData.len == cellSize , "cells are expected to be exactly 2048 bytes" ) + return Sponge.digest( cellData, rate=2 ) + +func hashCell*(cellData: Cell): Hash = hashCellOpen(cellData) + +#------------------------------------------------------------------------------- + +func splitBlockIntoCells( blockData: openArray[byte] ): seq[Cell] = + assert( blockData.len == blockSize , "network blocks are expected to be exactly 65536 bytes" ) + + var cells : seq[seq[byte]] = newSeq[seq[byte]]( cellsPerBlock ) + + let start = low(blockData) + var leaves : seq[Hash] = newSeq[Hash]( cellsPerBlock ) + for i in 0..= 0 and index < nleaves ) + + var path : seq[Hash] = newSeq[Hash](depth) + var k = index + var m = nleaves + for i in 0.. odd node + let key = bottomFlag + 2 + h = compressWithKey( key , h , p ) + else: + # even node + let key = bottomFlag + h = compressWithKey( key , h , p ) + bottomFlag = 0 + j = j shr 1 + m = (m+1) shr 1 + return h + +func checkMerkleProof*(root: Root, proof: MerkleProof): bool = + return bool(root == reconstructRoot(proof)) + +#------------------------------------------------------------------------------- +# TODO: maybe move this (and the rest?) into poseidon2-nim + +const KeyNone = F.fromHex("0x0") +const KeyBottomLayer = F.fromHex("0x1") +const KeyOdd = F.fromHex("0x2") +const KeyOddAndBottomLayer = F.fromhex("0x3") + +func merkleTreeWorker(xs: openArray[F], isBottomLayer: static bool) : seq[seq[F]] = + let a = low(xs) + let b = high(xs) + let m = b-a+1 + + when not isBottomLayer: + if m==1: + return @[ xs.toSeq() ] + + let halfn : int = m div 2 + let n : int = 2*halfn + let isOdd : bool = (n != m) + + var ys : seq[F] + if not isOdd: + ys = newSeq[F](halfn) + else: + ys = newSeq[F](halfn+1) + + for i in 0.. 0): + k += 1 + y = y shr 1 + return k + +func ceilingLog2* (x : int) : int = + if (x==0): + return -1 + else: + return (floorLog2(x-1) + 1) + +#------------------------------------------------------------------------------- diff --git a/reference/nim/proof_input/src/sample.nim b/reference/nim/proof_input/src/sample.nim new file mode 100644 index 0000000..9e04c6a --- /dev/null +++ b/reference/nim/proof_input/src/sample.nim @@ -0,0 +1,43 @@ + +import sugar +import std/bitops + +import constantine/math/arithmetic + +import poseidon2/types +import poseidon2/io +import poseidon2/sponge + +import types +import misc + +#------------------------------------------------------------------------------- + +func extractLowBits[n: static int]( A: BigInt[n], k: int): uint64 = + assert( k>0 and k<=64 ) + var r : uint64 = 0 + for i in 0..