akosba / jsnark

A Java library for zk-SNARK circuits
MIT License
207 stars 85 forks source link

Clarifying the use of the input parameter 'bitwidthPerInputElement' in SHA256 gadget #13

Closed hasinitg closed 5 years ago

hasinitg commented 5 years ago

Hi Ahmed @akosba

Could you please clarify why 'bitwidthPerInputElement' is given as user input in SHA256 gadget? Shouldn't it always be 8 bits? Are there any use cases where it could be different than 8 bits?

I actually tried to make use of this parameter to set 16 hexdigits long words to an input wire (i.e bitwidthPerInputElement=64bits) of the SHA256 gadget. However, the output digest I got in that case is different from the case where I set 2 hexdigits long words (i.e bitwidthPerInputElement=8bits) to an input wire of the SHA256 gadget. In both the cases, I used the same hexdigit string (of length 128) derived from the same character string (of length 64).

Could you please clarify if it is valid to set 'bitwidthPerInputElement' to any value other than 8 and if so, is it expected that the output digest changes for different 'bitwidthPerInputElement' values, although we use the same original string?

Thank you very much!

akosba commented 5 years ago

Hi @hasinitg

The reason I added this parameter is to make testing and benchmarking easier in some situations, e.g. when using an output digest from a previous hash gadget as an input to another hashing gadget, as in a Merkle tree for example.

The output digest should not change when you do the grouping, but the grouping has to be done in a way that is consistent with how the gadget processes the input wires, or you could modify the way the gadget processes the input to make it consistent with your format. For example, for an input string "abcd", if the bitwidth param is 8, then you expect 4 wires each has 1 byte, but if it's 16, then you will expect 2 wires having the values of "ab" and "cd". The way the current implementation assumes: the values will be: 'b'256 + 'a' and 'd'256+'c'.

There is another case that was not tested before: when the input string size is not divisible by the number of bytes per input wire while padding is enabled. I just posted a fix for that. This won't affect any performance benchmarking done before using this gadget under this scenario.

I also added a test here showing the above cases and illustrating the format the gadget currently accepts. As mentioned above, you can change the gadget internally to make the input processing consistent with your format or any specific standard. Please let me know if you're still facing issues. Thanks!

hasinitg commented 5 years ago

Hi @akosba,

Thank you very much for the detailed reply, and also for providing a fix. I appreciate it a lot! From your example, I now understand how to provide inputs with different bit lengths.

Could you please clarify, in the above example of input string: "abcd" and bitwidth : 16, why the values of 'b' and 'd' are multiplied by 256 (i.e: left shifted by 8 bits positions in the code)?

Thank you very much.

hasinitg commented 5 years ago

Please ignore my previous question. Following your example, I was able to figure out how to provide input to SHA256 in hexadecimal format, using different word sizes, as in https://github.com/akosba/jsnark/pull/14.

Thank you.