From 14bab04b197f28f51cb0e8af160b5d0552243da3 Mon Sep 17 00:00:00 2001 From: Balazs Komuves Date: Fri, 18 Oct 2024 17:39:34 +0200 Subject: [PATCH] it almost compiles (but does not link/builds) after the big hack refactoring --- reference/nim/proof_input/.gitignore | 2 +- reference/nim/proof_input/proof_input.nimble | 6 +- .../src/{blocks.nim => blocks/bn254.nim} | 43 ++++--- .../nim/proof_input/src/blocks/goldilocks.nim | 76 ++++++++++++ reference/nim/proof_input/src/cli.nim | 49 +++++--- reference/nim/proof_input/src/gen_input.nim | 73 ----------- .../nim/proof_input/src/gen_input/bn254.nim | 81 +++++++++++++ .../proof_input/src/gen_input/goldilocks.nim | 87 ++++++++++++++ reference/nim/proof_input/src/json.nim | 113 ++---------------- reference/nim/proof_input/src/json/bn254.nim | 81 +++++++++++++ .../nim/proof_input/src/json/goldilocks.nim | 86 +++++++++++++ reference/nim/proof_input/src/json/shared.nim | 27 +++++ reference/nim/proof_input/src/merkle.nim | 105 +++++----------- .../nim/proof_input/src/merkle/bn254.nim | 65 ++++++++++ .../src/merkle/goldilocks/monolith.nim | 65 ++++++++++ .../src/merkle/goldilocks/poseidon2.nim | 65 ++++++++++ reference/nim/proof_input/src/sample.nim | 43 ------- .../nim/proof_input/src/sample/bn254.nim | 29 +++++ .../nim/proof_input/src/sample/goldilocks.nim | 40 +++++++ reference/nim/proof_input/src/slot.nim | 2 + reference/nim/proof_input/src/types.nim | 82 +++++++------ reference/nim/proof_input/src/types/bn254.nim | 59 +++++++++ .../nim/proof_input/src/types/goldilocks.nim | 44 +++++++ 23 files changed, 955 insertions(+), 368 deletions(-) rename reference/nim/proof_input/src/{blocks.nim => blocks/bn254.nim} (51%) create mode 100644 reference/nim/proof_input/src/blocks/goldilocks.nim delete mode 100644 reference/nim/proof_input/src/gen_input.nim create mode 100644 reference/nim/proof_input/src/gen_input/bn254.nim create mode 100644 reference/nim/proof_input/src/gen_input/goldilocks.nim create mode 100644 reference/nim/proof_input/src/json/bn254.nim create mode 100644 reference/nim/proof_input/src/json/goldilocks.nim create mode 100644 reference/nim/proof_input/src/json/shared.nim create mode 100644 reference/nim/proof_input/src/merkle/bn254.nim create mode 100644 reference/nim/proof_input/src/merkle/goldilocks/monolith.nim create mode 100644 reference/nim/proof_input/src/merkle/goldilocks/poseidon2.nim delete mode 100644 reference/nim/proof_input/src/sample.nim create mode 100644 reference/nim/proof_input/src/sample/bn254.nim create mode 100644 reference/nim/proof_input/src/sample/goldilocks.nim create mode 100644 reference/nim/proof_input/src/types/bn254.nim create mode 100644 reference/nim/proof_input/src/types/goldilocks.nim diff --git a/reference/nim/proof_input/.gitignore b/reference/nim/proof_input/.gitignore index e2cf927..e8d9984 100644 --- a/reference/nim/proof_input/.gitignore +++ b/reference/nim/proof_input/.gitignore @@ -2,4 +2,4 @@ testmain cli *.json -json/ \ No newline at end of file +json_tmp/ \ No newline at end of file diff --git a/reference/nim/proof_input/proof_input.nimble b/reference/nim/proof_input/proof_input.nimble index 0bb004b..cf8ac91 100644 --- a/reference/nim/proof_input/proof_input.nimble +++ b/reference/nim/proof_input/proof_input.nimble @@ -4,9 +4,11 @@ author = "Balazs Komuves" description = "reference implementation for generating the proof inputs" license = "MIT or Apache-2.0" srcDir = "src" -bin = @["cli","testmain"] +bin = @["cli"] +#bin = @["cli","testmain"] requires "nim >= 1.6.0" requires "https://github.com/mratsim/constantine#ab6fa6ae1bbbd1b10071a92ec209b381b5d82511" requires "https://github.com/codex-storage/nim-poseidon2#8a54c69032a741160bbc097d009e45a8b5e4d718" -requires "https://github.com/codex-storage/nim-goldilocks-hash" +requires "https://github.com/codex-storage/nim-goldilocks-hash#0d12b1429345c3f359df47171332e8966dc94ed3" +#requires "../../../../nim-goldilocks-hash/" diff --git a/reference/nim/proof_input/src/blocks.nim b/reference/nim/proof_input/src/blocks/bn254.nim similarity index 51% rename from reference/nim/proof_input/src/blocks.nim rename to reference/nim/proof_input/src/blocks/bn254.nim index 7b695cd..ca1b830 100644 --- a/reference/nim/proof_input/src/blocks.nim +++ b/reference/nim/proof_input/src/blocks/bn254.nim @@ -5,18 +5,28 @@ import std/sequtils #import poseidon2/types import poseidon2/io import poseidon2/sponge -import poseidon2/merkle +#import poseidon2/merkle -import types -import merkle +import ../types +import ../types/bn254 +#import ../merkle +import ../merkle/bn254 #------------------------------------------------------------------------------- -func hashCellOpen( globcfg: GlobalConfig, cellData: openArray[byte] ): Hash = +func merkleTree*( hashcfg: HashConfig, what: openarray[Hash]): MerkleTree[Hash] = + assert( hashcfg.combo == BN254_Poseidon2 ) + return merkleTreeBN254( what ) + +#------------------------------------------------------------------------------- + +func hashCellOpen( hashcfg: HashConfig, globcfg: GlobalConfig, cellData: openArray[byte] ): Hash = + assert( hashcfg.field == BN254 ) + assert( hashcfg.hashFun == Poseidon2 ) assert( cellData.len == globcfg.cellSize , ("cells are expected to be exactly " & $globcfg.cellSize & " bytes") ) return Sponge.digest( cellData, rate=2 ) -func hashCell*( globcfg: GlobalConfig, cellData: Cell): Hash = hashCellOpen(globcfg, cellData) +func hashCell*(hashcfg: HashConfig, globcfg: GlobalConfig, cellData: Cell): Hash = hashCellOpen(hashcfg, globcfg, cellData) #------------------------------------------------------------------------------- @@ -36,23 +46,24 @@ func splitBlockIntoCells( globcfg: GlobalConfig, blockData: openArray[byte] ): s # returns the special hash of a network block (this is a Merkle root built on the # top of the hashes of the 32 cells inside the block) -func hashNetworkBlockOpen( globcfg: GlobalConfig, blockData: openArray[byte] ): Hash = +func hashNetworkBlockOpen( hashcfg: HashConfig, globcfg: GlobalConfig, blockData: openArray[byte] ): Hash = let cells = splitBlockIntoCells(globcfg, blockData) - let leaves = collect( newSeq , (for i in 0..= 0 and index < nleaves ) - var path : seq[Hash] = newSeq[Hash](depth) + var path : seq[H] = newSeq[H](depth) var k = index var m = nleaves for i in 0..0 and k<=64 ) - var r : uint64 = 0 - for i in 0.. Seed -> CellIdx -> CellData genFakeCell cfg (Seed seed) (CellIdx idx) = (mkCellData cfg $ B.pack list) where list = go (fromIntegral $ _cellSize cfg) 1 diff --git a/reference/nim/proof_input/src/types.nim b/reference/nim/proof_input/src/types.nim index 6ef2a5e..6bc68aa 100644 --- a/reference/nim/proof_input/src/types.nim +++ b/reference/nim/proof_input/src/types.nim @@ -2,25 +2,6 @@ import std/strutils import std/sequtils -from constantine/math/io/io_fields import toDecimal - -import poseidon2/types -export types - -#------------------------------------------------------------------------------- - -type Entropy* = F -type Hash* = F -type Root* = Hash - -#------------------------------------------------------------------------------- - -func toDecimalF*(a : F): string = - var s : string = toDecimal(a) - s = s.strip( leading=true, trailing=false, chars={'0'} ) - if s.len == 0: s="0" - return s - #------------------------------------------------------------------------------- type Cell* = seq[byte] @@ -30,27 +11,30 @@ type Block* = seq[byte] type - MerkleProof* = object + MerkleProof*[H] = object leafIndex* : int # linear index of the leaf, starting from 0 - leafValue* : Hash # value of the leaf - merklePath* : seq[Hash] # order: from the bottom to the top + leafValue* : H # value of the leaf + merklePath* : seq[H] # order: from the bottom to the top numberOfLeaves* : int # number of leaves in the tree (=size of input) - MerkleTree* = object - layers*: seq[seq[Hash]] + MerkleTree*[H] = object + layers*: seq[seq[H]] # ^^^ note: the first layer is the bottom layer, and the last layer is the root #------------------------------------------------------------------------------- # the circuit expect merkle path of statically known length, so we need to pad them -func padMerkleProof*( old: MerkleProof, newlen: int ): MerkleProof = +func padMerkleProof*[H]( old: MerkleProof[H], newlen: int ): MerkleProof[H] = let pad = newlen - old.merklePath.len assert( pad >= 0 ) - return MerkleProof( leafIndex: old.leafIndex - , leafValue: old.leafValue - , merklePath: old.merklePath & repeat(zero,pad) - , numberOfLeaves: old.numberOfLeaves - ) + + var zero : H # hackety hack hack, it should be initialized to zero + + return MerkleProof[H]( leafIndex: old.leafIndex + , leafValue: old.leafValue + , merklePath: old.merklePath & repeat(zero,pad) + , numberOfLeaves: old.numberOfLeaves + ) #------------------------------------------------------------------------------- @@ -61,19 +45,19 @@ type BlockIdx* = int SlotIdx* = int - CellProofInput* = object + CellProofInput*[H] = object cellData*: Cell - merkleProof*: MerkleProof + merkleProof*: MerkleProof[H] - SlotProofInput* = object - dataSetRoot*: Root - entropy*: Entropy + SlotProofInput*[H] = object + dataSetRoot*: H # Root + entropy*: H # Entropy nSlots*: int nCells*: int - slotRoot*: Root + slotRoot*: H # Root slotIndex*: SlotIdx - slotProof*: MerkleProof - proofInputs*: seq[CellProofInput] + slotProof*: MerkleProof[H] + proofInputs*: seq[CellProofInput[H]] #------------------------------------------------------------------------------- @@ -109,6 +93,7 @@ type HashConfig* = object field* : FieldSelect hashFun* : HashSelect + combo* : FieldHashCombo FieldSelect* = enum BN254, @@ -118,6 +103,11 @@ type Poseidon2, Monolith + FieldHashCombo* = enum + BN254_Poseidon2, + Goldilocks_Poseidon2, + Goldilocks_Monolith + #------------------------------------------------------------------------------- func cellsPerBlock*(glob: GlobalConfig): int = @@ -142,3 +132,19 @@ func parseHashFun*(str0: string): HashSelect = else: raiseAssert("parsefield: unrecognized hash function `" & str0 & "`") #------------------------------------------------------------------------------- + +{. warning[UnreachableElse]:off .} +func toFieldHashCombo*( field: FieldSelect, hash: HashSelect ): FieldHashCombo = + let msg = "invalid hash function `" & ($hash) & "` choice for field `" & ($field) & "`" + case field: + of BN254: + case hash: + of Poseidon2: return BN254_Poseidon2 + else: raiseAssert(msg) + of Goldilocks: + case hash: + of Poseidon2: return Goldilocks_Poseidon2 + of Monolith: return Goldilocks_Monolith + else: raiseAssert(msg) + +#------------------------------------------------------------------------------- diff --git a/reference/nim/proof_input/src/types/bn254.nim b/reference/nim/proof_input/src/types/bn254.nim new file mode 100644 index 0000000..fac932a --- /dev/null +++ b/reference/nim/proof_input/src/types/bn254.nim @@ -0,0 +1,59 @@ + +import std/strutils +import std/bitops +import std/streams + +import + constantine/math/arithmetic, + constantine/math/io/io_fields, + constantine/math/io/io_bigints, + constantine/math/config/curves + +#from constantine/math/io/io_fields import toDecimal + +import poseidon2/types +import poseidon2/io +export types + +#------------------------------------------------------------------------------- + +type BN254_T* = F +type Entropy* = F +type Hash* = F +type Root* = Hash + +#------------------------------------------------------------------------------- + +func intToBN254*(x: int): F = toF(x) + +func toDecimalF*(a : F): string = + var s : string = toDecimal(a) + s = s.strip( leading=true, trailing=false, chars={'0'} ) + if s.len == 0: s="0" + return s + +func toQuotedDecimalF*(x: F): string = + let s : string = toDecimalF(x) + return ("\"" & s & "\"") + +proc writeF*(h: Stream, prefix: string, x: F) = + h.writeLine(prefix & toQuotedDecimalF(x)) + +#------------------------------------------------------------------------------- + +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..0 and k<=56 ) + let val : uint64 = fromF(fld) + let mask : uint64 = (1'u64 shl k) - 1 + return bitand(val, mask) + +#------------------------------------------------------------------------------- + +func digestToJsonString*( d: Digest ): string = + let xs: F4 = fromDigest(d) + return "[ " & toDecimalF(xs[0]) & ", " & + toDecimalF(xs[1]) & ", " & + toDecimalF(xs[2]) & ", " & + toDecimalF(xs[3]) & " ]" \ No newline at end of file