zkSNARK: Enforce disclosure of input note nullifiers
This commit is contained in:
@@ -77,7 +77,8 @@ public:
|
|||||||
// and spend authority.
|
// and spend authority.
|
||||||
zk_input_notes[i].reset(new input_note_gadget<FieldT>(
|
zk_input_notes[i].reset(new input_note_gadget<FieldT>(
|
||||||
pb,
|
pb,
|
||||||
ZERO
|
ZERO,
|
||||||
|
zk_input_nullifiers[i]
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +134,7 @@ public:
|
|||||||
insert_uint256(verify_inputs, uint256()); // TODO: h_sig
|
insert_uint256(verify_inputs, uint256()); // TODO: h_sig
|
||||||
|
|
||||||
for (size_t i = 0; i < NumInputs; i++) {
|
for (size_t i = 0; i < NumInputs; i++) {
|
||||||
insert_uint256(verify_inputs, uint256()); // TODO: nullifier
|
insert_uint256(verify_inputs, nullifiers[i]);
|
||||||
insert_uint256(verify_inputs, uint256()); // TODO: hmac
|
insert_uint256(verify_inputs, uint256()); // TODO: hmac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,33 +32,48 @@ class input_note_gadget : public note_gadget<FieldT> {
|
|||||||
public:
|
public:
|
||||||
std::shared_ptr<digest_variable<FieldT>> a_sk;
|
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<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;
|
||||||
|
|
||||||
input_note_gadget(
|
input_note_gadget(
|
||||||
protoboard<FieldT>& pb,
|
protoboard<FieldT>& pb,
|
||||||
pb_variable<FieldT>& ZERO
|
pb_variable<FieldT>& ZERO,
|
||||||
|
std::shared_ptr<digest_variable<FieldT>> nullifier
|
||||||
) : note_gadget<FieldT>(pb) {
|
) : note_gadget<FieldT>(pb) {
|
||||||
a_sk.reset(new digest_variable<FieldT>(pb, 252, ""));
|
a_sk.reset(new digest_variable<FieldT>(pb, 252, ""));
|
||||||
a_pk.reset(new digest_variable<FieldT>(pb, 256, ""));
|
a_pk.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||||
|
rho.reset(new digest_variable<FieldT>(pb, 256, ""));
|
||||||
|
|
||||||
spend_authority.reset(new PRF_addr_a_pk_gadget<FieldT>(
|
spend_authority.reset(new PRF_addr_a_pk_gadget<FieldT>(
|
||||||
pb,
|
pb,
|
||||||
ZERO,
|
ZERO,
|
||||||
a_sk->bits,
|
a_sk->bits,
|
||||||
a_pk
|
a_pk
|
||||||
));
|
));
|
||||||
|
|
||||||
|
expose_nullifiers.reset(new PRF_nf_gadget<FieldT>(
|
||||||
|
pb,
|
||||||
|
ZERO,
|
||||||
|
a_sk->bits,
|
||||||
|
rho->bits,
|
||||||
|
nullifier
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_r1cs_constraints() {
|
void generate_r1cs_constraints() {
|
||||||
note_gadget<FieldT>::generate_r1cs_constraints();
|
note_gadget<FieldT>::generate_r1cs_constraints();
|
||||||
|
|
||||||
a_sk->generate_r1cs_constraints();
|
a_sk->generate_r1cs_constraints();
|
||||||
|
rho->generate_r1cs_constraints();
|
||||||
|
|
||||||
// TODO: This constraint may not be necessary if SHA256
|
// TODO: This constraint may not be necessary if SHA256
|
||||||
// already boolean constrains its outputs.
|
// already boolean constrains its outputs.
|
||||||
a_pk->generate_r1cs_constraints();
|
a_pk->generate_r1cs_constraints();
|
||||||
|
|
||||||
spend_authority->generate_r1cs_constraints();
|
spend_authority->generate_r1cs_constraints();
|
||||||
|
expose_nullifiers->generate_r1cs_constraints();
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_r1cs_witness(const SpendingKey& key, const Note& note) {
|
void generate_r1cs_witness(const SpendingKey& key, const Note& note) {
|
||||||
@@ -78,5 +93,14 @@ public:
|
|||||||
this->pb,
|
this->pb,
|
||||||
uint256_to_bool_vector(note.a_pk)
|
uint256_to_bool_vector(note.a_pk)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Witness rho for the input note
|
||||||
|
rho->bits.fill_with_bits(
|
||||||
|
this->pb,
|
||||||
|
uint256_to_bool_vector(note.rho)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Witness the nullifier for the input note
|
||||||
|
expose_nullifiers->generate_r1cs_witness();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -75,3 +75,23 @@ public:
|
|||||||
PRF_gadget<FieldT>::generate_r1cs_witness();
|
PRF_gadget<FieldT>::generate_r1cs_witness();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename FieldT>
|
||||||
|
class PRF_nf_gadget : public PRF_gadget<FieldT> {
|
||||||
|
public:
|
||||||
|
PRF_nf_gadget(
|
||||||
|
protoboard<FieldT>& pb,
|
||||||
|
pb_variable<FieldT>& ZERO,
|
||||||
|
pb_variable_array<FieldT>& a_sk,
|
||||||
|
pb_variable_array<FieldT>& rho,
|
||||||
|
std::shared_ptr<digest_variable<FieldT>> result
|
||||||
|
) : PRF_gadget<FieldT>(pb, ZERO, 1, 1, 1, 0, a_sk, rho, result) {}
|
||||||
|
|
||||||
|
void generate_r1cs_constraints() {
|
||||||
|
PRF_gadget<FieldT>::generate_r1cs_constraints();
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate_r1cs_witness() {
|
||||||
|
PRF_gadget<FieldT>::generate_r1cs_witness();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user