scipr-lab / libsnark

C++ library for zkSNARKs
Other
1.82k stars 583 forks source link

sha256_compression_function_gadget misunderstanding? #141

Closed filippodp closed 5 years ago

filippodp commented 5 years ago

I am working with sha256_compression_function_gadget, in this way, I created the protoboard, two digest_variable, the first for the input, the second for the output. Token variable is composed by three bit_vector variables piped. I assigned the value of the token to the input digest_variable (in the witness) and then I compress it.

typedef libff::default_ec_pp ppT;
typedef libff::Fr<default_ec_pp> FieldT;
default_ec_pp::init_public_params();

bit_vector a = libff::convert_field_element_to_bit_vector<FieldT>(12345);
bit_vector b = libff::convert_field_element_to_bit_vector<FieldT>(678910);
bit_vector c = libff::convert_field_element_to_bit_vector<FieldT>(111213);

bit_vector token;
token.insert(token.end(), a.begin(), a.end());
token.insert(token.end(), b.begin(), b.end());
token.insert(token.end(), c.begin(), c.end());

// Protoboard Declaration
protoboard<FieldT> pb;

// Primary input size
pb.set_input_sizes( 0 );

// Protoboard Variables and Gadgets
digest_variable<FieldT> token_hash_input (pb, (SHA256_digest_size * 3), "token_hash_input");
digest_variable<FieldT> token_hash_output(pb, SHA256_digest_size, "token_hash_output");

sha256_compression_function_gadget<FieldT> sha256_compression_gadget
    (pb, SHA256_default_IV<FieldT>(pb), token_hash_input.bits, token_hash_output, 
    "sha256_compression_gadget");

// Enforce Constraints
token_hash_input.generate_r1cs_constraints();
sha256_compression_gadget.generate_r1cs_constraints();

// Generate Witness
token_hash_input.generate_r1cs_witness(token);
sha256_compression_gadget.generate_r1cs_witness();

At the end I print the value (in bits) of both digest_variable,up to now there are no problems.

// Print input bits
bit_vector input = token_hash_input.get_digest();
for (bit_vector::iterator it = input.begin() ; it != input.end(); ++it)
    std::cout << *it;
std::cout << std::endl;

// Print output bits
bit_vector output = token_hash_output.get_digest();
for (bit_vector::iterator it = output.begin() ; it != output.end(); ++it)
    std::cout << *it;
std::cout << std::endl;

If I change the value of bit_vector a from 12345 to 5, I recompile and re-run (pretty stupid I know), the bits stored into token_hash_output did not change (input did), I got exactly the same output. There are some problem with the library or am I doing something wrong?

NB. If the token was composed only piping a and b the program works; change SHA256_digest_size * 2 accordingly.

NB2. If I change the value of bit_vector c from 111213 to 1, token_hash_output bits change, seems that this gadget tooks only the last 512 bits.

SRCoughlin commented 5 years ago

This is just the "compress" function of SHA256 protocol, not the entire protocol, and requires input to be 512 bits. (The full protocol can take in any size input but also must run the compress function twice so it less efficient.)

If you need the full protocol, look at https://github.com/kobigurk/sha256_ethereum

filippodp commented 5 years ago

Thanks!