Hi all, it's been a while :)
What's the most efficient way to check for underflows / overflows?
E.g. If I have a = b + c
, what's the neatest way to ensure b + c
doesn't overflow the field modulus?
E.g. If I have a = b  c
, what's the neatest way to ensure b > c
?
E.g. If I have a = b * c
, what's the neatest way to ensure b * c
doesn't overflow the field modulus?
E.g. If I have a = b / c
, is there a way to ensure c 'divides' b in the 'integer' sense? Like passing a, b, c
as inputs and asserting that c * a == b
and ensuring c * a
doesn't overflow the field modulus (somehow)?
Presumably I'd need to do the calculations in bits, to check for bits 'carrying over' 2**253?
Does anyone have any neat implementations? :)
Hi all,
I’m working on a bit of an edge case where I need to check if a field is a positive number by doing either assert(field > 0)
or assert(field < (field_prime1)/2)
. The problem here is that ZoKrates implements comparison operators such that the operands have to be strictly less than biggest power of 2 lower than p/2
. Let’s take the example of Bn128, the operands here will have to be lower than 2^252 even though the field elements can be greater than 2^252 and lower than bn128_prime of 2592827839077369332604021086610909215435616943586837466384278596745456903517. So assert(field > 0)
would fail during compute witness stage if field passed into witness is greater than 2^252 but less than bn128_prime. Andassert(field < (bn128_prime1)/2)
would fail at compile stage because (bn128_prime1)/2
is already greater than 2^252. Can this limitation be worked on in ZoKrates’s rust code ? Thank you
x < constant
check, the one we have now is x < y
for x and y both variables. We already use it internally (here https://github.com/Zokrates/ZoKrates/blob/master/zokrates_core/src/flatten/mod.rs#L204)
I made some small adjustments to get_hask.zok and please find attached my part of code, "import "hashes/sha256/512bit" as sha256
def main(u32[192] hashMe) > u32[96] result:
for field i in 0..12 do
u32[8] h = sha256(hashMe[16i..16i+8], hashMe[16i+8..16i+16])
result[8i..8i+8] = h
endfor
return result"
I get an error message "zokrates compile i get_hash.zok o get_hash light
Compiling get_hash.zok
Compilation failed:
get_hash.zok: > 3:36

3  def main(u32[192] hashMe) > u32[96] result:␊
 ^

= expected op_or, op_and, op_bit_xor, op_bit_and, op_bit_or, op_equal, op_not_equal, op_lt, op_lte, op_gt, op_gte, op_add, op_sub, op_mul, op_div, op_pow, op_left_shift, or op_right_shift"
I get an error message "zokrates compile i get_hash.zok o get_hash light
Compiling get_hash.zokCompilation failed:
get_hash.zok: > 3:36

3  def main(u32[192] hashMe) > u32[96] result:␊
 ^

= expected op_or, op_and, op_bit_xor, op_bit_and, op_bit_or, op_equal, op_not_equal, op_lt, op_lte, op_gt, op_gte, op_add, op_sub, op_mul, op_div, op_pow, op_left_shift, or op_right_shift"
Hi, Please let me know what I am doing wrong, I really need to know, it is important for me. Thanks !!
I get an error message "zokrates compile i get_hash.zok o get_hash light
Compiling get_hash.zokCompilation failed:
get_hash.zok: > 3:36

3  def main(u32[192] hashMe) > u32[96] result:␊
 ^

= expected op_or, op_and, op_bit_xor, op_bit_and, op_bit_or, op_equal, op_not_equal, op_lt, op_lte, op_gt, op_gte, op_add, op_sub, op_mul, op_div, op_pow, op_left_shift, or op_right_shift"Hi, Please let me know what I am doing wrong, I really need to know, it is important for me. Thanks !!
omit the name of the return value def main(u32[192] hashMe) > u32[96]:
I get an error message "zokrates compile i get_hash.zok o get_hash light
Compiling get_hash.zokCompilation failed:
get_hash.zok: > 3:36

3  def main(u32[192] hashMe) > u32[96] result:␊
 ^

= expected op_or, op_and, op_bit_xor, op_bit_and, op_bit_or, op_equal, op_not_equal, op_lt, op_lte, op_gt, op_gte, op_add, op_sub, op_mul, op_div, op_pow, op_left_shift, or op_right_shift"Hi, Please let me know what I am doing wrong, I really need to know, it is important for me. Thanks !!
omit the name of the return value
def main(u32[192] hashMe) > u32[96]:
Hi, I still get the error, namely, "Compiling get_hash.zok
Compilation failed:
get_hash.zok:5:27
Expected the lower bound of the range to be a constant field, found (16 * i)
get_hash.zok:8:8
Identifier "result" is undefined
". Am i supposed to give a fixed lower bound, can't I sort of move across the array ?? My current code "import "hashes/sha256/512bit" as sha256
def main(u32[192] hashMe) > u32[96]:
for field i in 0..12 do
u32[8] h = sha256(hashMe[16i..16i+8], hashMe[16i+8..16i+16])
result[8i..8i+8] = h
endfor
return result"
@smithsen maybe something like this?
import "hashes/sha256/IVconstants" as IVconstants
import "hashes/sha256/shaRound" as sha256
// u32[192] > u32[12][16] is the same because inputs are flattened
def main(u32[12][16] hashMe) > u32[8]:
u32[8] h = sha256(hashMe[0], IVconstants())
for field i in 1..12 do
h = sha256(hashMe[i], h)
endfor
return h
this might need a lot of ram memory to compile atm, so be sure to compile on a highmemory machine
Hey @dark64 , yeah no kidding, logic makes sense to me but when I tried running it on my PC, ubuntu 18.04, it ran for like 20 mins and killed it self
@smithsen this sounds like OOM to me, try to increase your swap space if you don't have enough ram
Oh it works now but it takes a while