Browse Source

zkSNARK: Authenticate h_sig with a_sk

pull/145/head
Sean Bowe 8 years ago
parent
commit
e52f40e839
  1. 32
      src/zcash/circuit/gadget.tcc
  2. 5
      src/zcash/circuit/note.tcc
  3. 21
      src/zcash/circuit/prfs.tcc

32
src/zcash/circuit/gadget.tcc

@ -23,8 +23,13 @@ private:
// Input note gadgets // Input note gadgets
boost::array<std::shared_ptr<input_note_gadget<FieldT>>, NumInputs> zk_input_notes; boost::array<std::shared_ptr<input_note_gadget<FieldT>>, NumInputs> zk_input_notes;
boost::array<std::shared_ptr<PRF_pk_gadget<FieldT>>, NumInputs> zk_hmac_authentication;
public: public:
// PRF_pk only has a 1-bit domain separation "nonce"
// for different hmacs.
BOOST_STATIC_ASSERT(NumInputs <= 2);
joinsplit_gadget(protoboard<FieldT> &pb) : gadget<FieldT>(pb) { joinsplit_gadget(protoboard<FieldT> &pb) : gadget<FieldT>(pb) {
// Verification // Verification
{ {
@ -80,6 +85,17 @@ public:
ZERO, ZERO,
zk_input_nullifiers[i] zk_input_nullifiers[i]
)); ));
// The input keys authenticate h_sig to prevent
// malleability.
zk_hmac_authentication[i].reset(new PRF_pk_gadget<FieldT>(
pb,
ZERO,
zk_input_notes[i]->a_sk->bits,
zk_h_sig->bits,
i ? true : false,
zk_input_hmacs[i]
));
} }
} }
@ -94,6 +110,9 @@ public:
for (size_t i = 0; i < NumInputs; i++) { for (size_t i = 0; i < NumInputs; i++) {
// Constrain the JoinSplit input constraints. // Constrain the JoinSplit input constraints.
zk_input_notes[i]->generate_r1cs_constraints(); zk_input_notes[i]->generate_r1cs_constraints();
// Authenticate h_sig with a_sk
zk_hmac_authentication[i]->generate_r1cs_constraints();
} }
} }
@ -109,9 +128,18 @@ public:
// Witness `zero` // Witness `zero`
this->pb.val(ZERO) = FieldT::zero(); this->pb.val(ZERO) = FieldT::zero();
// Witness h_sig
zk_h_sig->bits.fill_with_bits(
this->pb,
uint256_to_bool_vector(h_sig)
);
for (size_t i = 0; i < NumInputs; i++) { for (size_t i = 0; i < NumInputs; i++) {
// Witness the input information. // Witness the input information.
zk_input_notes[i]->generate_r1cs_witness(inputs[i].key, inputs[i].note); zk_input_notes[i]->generate_r1cs_witness(inputs[i].key, inputs[i].note);
// Witness hmacs
zk_hmac_authentication[i]->generate_r1cs_witness();
} }
// This happens last, because only by now are all the // This happens last, because only by now are all the
@ -131,11 +159,11 @@ public:
std::vector<bool> verify_inputs; std::vector<bool> verify_inputs;
insert_uint256(verify_inputs, uint256()); // TODO: rt insert_uint256(verify_inputs, uint256()); // TODO: rt
insert_uint256(verify_inputs, uint256()); // TODO: h_sig insert_uint256(verify_inputs, h_sig);
for (size_t i = 0; i < NumInputs; i++) { for (size_t i = 0; i < NumInputs; i++) {
insert_uint256(verify_inputs, nullifiers[i]); insert_uint256(verify_inputs, nullifiers[i]);
insert_uint256(verify_inputs, uint256()); // TODO: hmac insert_uint256(verify_inputs, hmacs[i]);
} }
for (size_t i = 0; i < NumOutputs; i++) { for (size_t i = 0; i < NumOutputs; i++) {

5
src/zcash/circuit/note.tcc

@ -29,13 +29,14 @@ public:
template<typename FieldT> template<typename FieldT>
class input_note_gadget : public note_gadget<FieldT> { class input_note_gadget : public note_gadget<FieldT> {
public: private:
std::shared_ptr<digest_variable<FieldT>> a_sk;
std::shared_ptr<digest_variable<FieldT>> a_pk; std::shared_ptr<digest_variable<FieldT>> a_pk;
std::shared_ptr<digest_variable<FieldT>> rho; std::shared_ptr<digest_variable<FieldT>> rho;
std::shared_ptr<PRF_addr_a_pk_gadget<FieldT>> spend_authority; std::shared_ptr<PRF_addr_a_pk_gadget<FieldT>> spend_authority;
std::shared_ptr<PRF_nf_gadget<FieldT>> expose_nullifiers; std::shared_ptr<PRF_nf_gadget<FieldT>> expose_nullifiers;
public:
std::shared_ptr<digest_variable<FieldT>> a_sk;
input_note_gadget( input_note_gadget(
protoboard<FieldT>& pb, protoboard<FieldT>& pb,

21
src/zcash/circuit/prfs.tcc

@ -95,3 +95,24 @@ public:
PRF_gadget<FieldT>::generate_r1cs_witness(); PRF_gadget<FieldT>::generate_r1cs_witness();
} }
}; };
template<typename FieldT>
class PRF_pk_gadget : public PRF_gadget<FieldT> {
public:
PRF_pk_gadget(
protoboard<FieldT>& pb,
pb_variable<FieldT>& ZERO,
pb_variable_array<FieldT>& a_sk,
pb_variable_array<FieldT>& h_sig,
bool nonce,
std::shared_ptr<digest_variable<FieldT>> result
) : PRF_gadget<FieldT>(pb, ZERO, 0, nonce, 0, 0, a_sk, h_sig, result) {}
void generate_r1cs_constraints() {
PRF_gadget<FieldT>::generate_r1cs_constraints();
}
void generate_r1cs_witness() {
PRF_gadget<FieldT>::generate_r1cs_witness();
}
};

Loading…
Cancel
Save