template class PRF_gadget : gadget { private: std::shared_ptr> block; std::shared_ptr> hasher; std::shared_ptr> result; public: PRF_gadget( protoboard& pb, pb_variable& ZERO, bool a, bool b, bool c, bool d, pb_variable_array x, pb_variable_array y, std::shared_ptr> result ) : gadget(pb), result(result) { pb_linear_combination_array IV = SHA256_default_IV(pb); pb_variable_array discriminants; discriminants.emplace_back(a ? ONE : ZERO); discriminants.emplace_back(b ? ONE : ZERO); discriminants.emplace_back(c ? ONE : ZERO); discriminants.emplace_back(d ? ONE : ZERO); block.reset(new block_variable(pb, { discriminants, x, y }, "PRF_block")); hasher.reset(new sha256_compression_function_gadget( pb, IV, block->bits, *result, "PRF_hasher")); } void generate_r1cs_constraints() { hasher->generate_r1cs_constraints(); } void generate_r1cs_witness() { hasher->generate_r1cs_witness(); } }; template pb_variable_array gen256zeroes(pb_variable& ZERO) { pb_variable_array ret; while (ret.size() < 256) { ret.emplace_back(ZERO); } return ret; } template class PRF_addr_a_pk_gadget : public PRF_gadget { public: PRF_addr_a_pk_gadget( protoboard& pb, pb_variable& ZERO, pb_variable_array& a_sk, std::shared_ptr> result ) : PRF_gadget(pb, ZERO, 1, 1, 0, 0, a_sk, gen256zeroes(ZERO), result) {} }; template class PRF_nf_gadget : public PRF_gadget { public: PRF_nf_gadget( protoboard& pb, pb_variable& ZERO, pb_variable_array& a_sk, pb_variable_array& rho, std::shared_ptr> result ) : PRF_gadget(pb, ZERO, 1, 1, 1, 0, a_sk, rho, result) {} }; template class PRF_pk_gadget : public PRF_gadget { public: PRF_pk_gadget( protoboard& pb, pb_variable& ZERO, pb_variable_array& a_sk, pb_variable_array& h_sig, bool nonce, std::shared_ptr> result ) : PRF_gadget(pb, ZERO, 0, nonce, 0, 0, a_sk, h_sig, result) {} }; template class PRF_rho_gadget : public PRF_gadget { public: PRF_rho_gadget( protoboard& pb, pb_variable& ZERO, pb_variable_array& phi, pb_variable_array& h_sig, bool nonce, std::shared_ptr> result ) : PRF_gadget(pb, ZERO, 0, nonce, 1, 0, phi, h_sig, result) {} };