Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions zok/Eg1/case_14.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

import "hashes/poseidon/poseidon" as poseidon

def main(field[14] arr) -> field:
field h3 = poseidon(arr[8..14])
field h2 = poseidon(arr[2..8])
field h1 = poseidon(arr[0..2])
field out = poseidon([h1,h2,h3])
return out
15 changes: 15 additions & 0 deletions zok/Eg1/case_41.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import "hashes/poseidon/poseidon" as poseidon

def main(field[41] arr) -> field:
field h7 = poseidon(arr[35..41])
field h6 = poseidon(arr[29..35])
field h5 = poseidon(arr[23..29])
field h4 = poseidon(arr[17..23])
field h3 = poseidon(arr[11..17])
field h2 = poseidon(arr[5..11])
field h1 = poseidon(arr[0..5])
field hh2 = poseidon([h2,h3,h4,h5,h6,h7])
field hh1 = poseidon([h1])
field out = poseidon([hh1,hh2])
return out
26 changes: 26 additions & 0 deletions zok/Eg1/case_99.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

import "hashes/poseidon/poseidon" as poseidon

def main(field[99] arr) -> field:
field h17 = poseidon(arr[93..99])
field h16 = poseidon(arr[87..93])
field h15 = poseidon(arr[81..87])
field h14 = poseidon(arr[75..81])
field h13 = poseidon(arr[69..75])
field h12 = poseidon(arr[63..69])
field h11 = poseidon(arr[57..63])
field h10 = poseidon(arr[51..57])
field h9 = poseidon(arr[45..51])
field h8 = poseidon(arr[39..45])
field h7 = poseidon(arr[33..39])
field h6 = poseidon(arr[27..33])
field h5 = poseidon(arr[21..27])
field h4 = poseidon(arr[15..21])
field h3 = poseidon(arr[9..15])
field h2 = poseidon(arr[3..9])
field h1 = poseidon(arr[0..3])
field hh3 = poseidon([h12,h13,h14,h15,h16,h17])
field hh2 = poseidon([h6,h7,h8,h9,h10,h11])
field hh1 = poseidon([h1,h2,h3,h4,h5])
field out = poseidon([hh1,hh2,hh3])
return out
31 changes: 31 additions & 0 deletions zok/Eg1/gen_pos_14.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import "hashes/poseidon/poseidon" as poseidon
import "utils/casts/u32_to_field" as u32_to_field
import "utils/casts/field_to_u32" as field_to_u32


const u32 N = 14
const u32 INTERNAL_NODES = 4
const u32[INTERNAL_NODES] HashSeq = [6, 6, 2, 3]

def main(field[N] OrigInp) -> field:
u32 HeapSz = INTERNAL_NODES+N
field[HeapSz] Heap = [0; HeapSz]
//Initialize to 0 field

u32 j = 0
for u32 i in 0..N do
j = (HeapSz-1)-i
Heap[j]=OrigInp[(N-1)-i]
endfor
//The last N nodes of the Heap field array are set to the input fields

u32 leftChildOffset = HeapSz
u32 parent = INTERNAL_NODES
for u32 i in 0..INTERNAL_NODES do
parent = parent-1
leftChildOffset = leftChildOffset-HashSeq[i]
Heap[parent] = poseidon(Heap[leftChildOffset..leftChildOffset+HashSeq[i]])
endfor
return Heap[0]

31 changes: 31 additions & 0 deletions zok/Eg1/gen_pos_41.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import "hashes/poseidon/poseidon" as poseidon
import "utils/casts/u32_to_field" as u32_to_field
import "utils/casts/field_to_u32" as field_to_u32


const u32 N = 41
const u32 INTERNAL_NODES = 10
const u32[INTERNAL_NODES] HashSeq = [6, 6, 6, 6, 6, 6, 5, 6, 1, 2]

def main(field[N] OrigInp) -> field:
u32 HeapSz = INTERNAL_NODES+N
field[HeapSz] Heap = [0; HeapSz]
//Initialize to 0 field

u32 j = 0
for u32 i in 0..N do
j = (HeapSz-1)-i
Heap[j]=OrigInp[(N-1)-i]
endfor
//The last N nodes of the Heap field array are set to the input fields

u32 leftChildOffset = HeapSz
u32 parent = INTERNAL_NODES
for u32 i in 0..INTERNAL_NODES do
parent = parent-1
leftChildOffset = leftChildOffset-HashSeq[i]
Heap[parent] = poseidon(Heap[leftChildOffset..leftChildOffset+HashSeq[i]])
endfor
return Heap[0]

31 changes: 31 additions & 0 deletions zok/Eg1/gen_pos_99.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import "hashes/poseidon/poseidon" as poseidon
import "utils/casts/u32_to_field" as u32_to_field
import "utils/casts/field_to_u32" as field_to_u32


const u32 N = 99
const u32 INTERNAL_NODES = 21
const u32[INTERNAL_NODES] HashSeq = [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 5, 3]

def main(field[N] OrigInp) -> field:
u32 HeapSz = INTERNAL_NODES+N
field[HeapSz] Heap = [0; HeapSz]
//Initialize to 0 field

u32 j = 0
for u32 i in 0..N do
j = (HeapSz-1)-i
Heap[j]=OrigInp[(N-1)-i]
endfor
//The last N nodes of the Heap field array are set to the input fields

u32 leftChildOffset = HeapSz
u32 parent = INTERNAL_NODES
for u32 i in 0..INTERNAL_NODES do
parent = parent-1
leftChildOffset = leftChildOffset-HashSeq[i]
Heap[parent] = poseidon(Heap[leftChildOffset..leftChildOffset+HashSeq[i]])
endfor
return Heap[0]

72 changes: 72 additions & 0 deletions zok/Eg1/generate_hash_zok.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env python

import sys
max_poseidon_arity = 6

#Zok program that given an N-field input OrigInp will generate
#a tree in which the N OrigInp fileds form the leaf-layer
#and each parent is a poseidon hash. The arity of each poseidon
#hash is governed by the HashSeq array, which is computed
#quite simply in the prepare_zok_args function

hashgen_zok = """
import "hashes/poseidon/poseidon" as poseidon
import "utils/casts/u32_to_field" as u32_to_field
import "utils/casts/field_to_u32" as field_to_u32


const u32 N = %s
const u32 INTERNAL_NODES = %s
const u32[INTERNAL_NODES] HashSeq = %s

def main(field[N] OrigInp) -> field:
u32 HeapSz = INTERNAL_NODES+N
field[HeapSz] Heap = [0; HeapSz]
//Initialize to 0 field

u32 j = 0
for u32 i in 0..N do
j = (HeapSz-1)-i
Heap[j]=OrigInp[(N-1)-i]
endfor
//The last N nodes of the Heap field array are set to the input fields

u32 leftChildOffset = HeapSz
u32 parent = INTERNAL_NODES
for u32 i in 0..INTERNAL_NODES do
parent = parent-1
leftChildOffset = leftChildOffset-HashSeq[i]
Heap[parent] = poseidon(Heap[leftChildOffset..leftChildOffset+HashSeq[i]])
endfor
return Heap[0]
"""

#function that takes the number of fields in the transaction that
#needs to be hashed and generates an appropriate Zok program from
#hashgen_zok.
def print_zok_program(NumInputs) :
levelSz=NumInputs
if levelSz <= max_poseidon_arity:
hash_seq = [levelSz]
else:
hash_seq = []
while levelSz > 1:
if levelSz%max_poseidon_arity==0:
nextLevelSz = levelSz//max_poseidon_arity
hash_seq += [max_poseidon_arity]*nextLevelSz
else:
nextLevelSz = levelSz//max_poseidon_arity+1
hash_seq += [max_poseidon_arity]*(levelSz//max_poseidon_arity)+[levelSz%max_poseidon_arity]
levelSz = nextLevelSz
#print(levelSz)
#print(hash_seq)
print(hashgen_zok%(str(NumInputs),str(len(hash_seq)),str(hash_seq)))



if __name__ == '__main__':
print_zok_program(int(sys.argv[1]))




Loading