Enforce first four bits are zero for all spending keys and phi.

This commit is contained in:
Sean Bowe
2016-05-16 09:50:31 -06:00
parent 4ac1841614
commit defe37a6d4
15 changed files with 123 additions and 42 deletions

View File

@@ -13,7 +13,7 @@ ViewingKey SpendingKey::viewing_key() {
}
SpendingKey SpendingKey::random() {
return SpendingKey(random_uint256());
return SpendingKey(random_uint252());
}
PaymentAddress SpendingKey::address() {

View File

@@ -2,6 +2,7 @@
#define _ZCADDRESS_H_
#include "uint256.h"
#include "uint252.h"
#include "serialize.h"
namespace libzcash {
@@ -37,10 +38,10 @@ public:
uint256 pk_enc();
};
class SpendingKey : public uint256 {
class SpendingKey : public uint252 {
public:
SpendingKey() : uint256() { }
SpendingKey(uint256 a_sk) : uint256(a_sk) { }
SpendingKey() : uint252() { }
SpendingKey(uint252 a_sk) : uint252(a_sk) { }
static SpendingKey random();

View File

@@ -191,7 +191,7 @@ public:
uint256 h_sig = this->h_sig(out_randomSeed, out_nullifiers, pubKeyHash);
// Sample phi
uint256 phi = random_uint256();
uint252 phi = random_uint252();
// Compute notes for outputs
for (size_t i = 0; i < NumOutputs; i++) {
@@ -320,19 +320,19 @@ uint256 JoinSplit<NumInputs, NumOutputs>::h_sig(
return output;
}
Note JSOutput::note(const uint256& phi, const uint256& r, size_t i, const uint256& h_sig) const {
Note JSOutput::note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const {
uint256 rho = PRF_rho(phi, i, h_sig);
return Note(addr.a_pk, value, rho, r);
}
JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) {
SpendingKey a_sk(random_uint256());
SpendingKey a_sk = SpendingKey::random();
addr = a_sk.address();
}
JSInput::JSInput() : witness(ZCIncrementalMerkleTree().witness()),
key(random_uint256()) {
key(SpendingKey::random()) {
note = Note(key.address().a_pk, 0, random_uint256(), random_uint256());
ZCIncrementalMerkleTree dummy_tree;
dummy_tree.append(note.cm());

View File

@@ -8,6 +8,7 @@
#include "NoteEncryption.hpp"
#include "uint256.h"
#include "uint252.h"
#include <boost/array.hpp>
@@ -37,7 +38,7 @@ public:
JSOutput();
JSOutput(PaymentAddress addr, uint64_t value) : addr(addr), value(value) { }
Note note(const uint256& phi, const uint256& r, size_t i, const uint256& h_sig) const;
Note note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const;
};
template<size_t NumInputs, size_t NumOutputs>

View File

@@ -136,7 +136,7 @@ typename NoteDecryption<MLEN>::Plaintext NoteDecryption<MLEN>::decrypt
}
template<size_t MLEN>
uint256 NoteEncryption<MLEN>::generate_privkey(const uint256 &a_sk)
uint256 NoteEncryption<MLEN>::generate_privkey(const uint252 &a_sk)
{
uint256 sk = PRF_addr_sk_enc(a_sk);
@@ -165,6 +165,14 @@ uint256 random_uint256()
return ret;
}
uint252 random_uint252()
{
uint256 rand = random_uint256();
(*rand.begin()) &= 0x0F;
return uint252(rand);
}
template class NoteEncryption<ZC_NOTEPLAINTEXT_LEADING + ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE>;
template class NoteDecryption<ZC_NOTEPLAINTEXT_LEADING + ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE>;

View File

@@ -8,6 +8,7 @@ https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
#include <boost/array.hpp>
#include "uint256.h"
#include "uint252.h"
#include "zcash/Zcash.h"
@@ -43,7 +44,7 @@ public:
);
// Creates a NoteEncryption private key
static uint256 generate_privkey(const uint256 &a_sk);
static uint256 generate_privkey(const uint252 &a_sk);
// Creates a NoteEncryption public key from a private key
static uint256 generate_pubkey(const uint256 &sk_enc);
@@ -70,6 +71,7 @@ public:
};
uint256 random_uint256();
uint252 random_uint252();
}

View File

@@ -187,7 +187,7 @@ public:
}
void generate_r1cs_witness(
const uint256& phi,
const uint252& phi,
const uint256& rt,
const uint256& h_sig,
const boost::array<JSInput, NumInputs>& inputs,
@@ -234,7 +234,7 @@ public:
// Witness phi
zk_phi->bits.fill_with_bits(
this->pb,
trailing252(uint256_to_bool_vector(phi))
uint252_to_bool_vector(phi)
);
// Witness h_sig

View File

@@ -131,7 +131,7 @@ public:
// Witness a_sk for the input
a_sk->bits.fill_with_bits(
this->pb,
trailing252(uint256_to_bool_vector(key))
uint252_to_bool_vector(key)
);
// Witness a_pk for a_sk with PRF_addr

View File

@@ -1,3 +1,5 @@
#include "uint252.h"
template<typename FieldT>
pb_variable_array<FieldT> from_bits(std::vector<bool> bits, pb_variable<FieldT>& ZERO) {
pb_variable_array<FieldT> acc;
@@ -17,7 +19,8 @@ std::vector<bool> trailing252(std::vector<bool> input) {
return std::vector<bool>(input.begin() + 4, input.end());
}
std::vector<bool> uint256_to_bool_vector(uint256 input) {
template<typename T>
std::vector<bool> to_bool_vector(T input) {
std::vector<unsigned char> input_v(input.begin(), input.end());
std::vector<bool> output_bv(256, 0);
libzerocash::convertBytesVectorToVector(
@@ -28,6 +31,14 @@ std::vector<bool> uint256_to_bool_vector(uint256 input) {
return output_bv;
}
std::vector<bool> uint256_to_bool_vector(uint256 input) {
return to_bool_vector(input);
}
std::vector<bool> uint252_to_bool_vector(uint252 input) {
return trailing252(to_bool_vector(input));
}
std::vector<bool> uint64_to_bool_vector(uint64_t input) {
auto num_bv = convertIntToVectorLE(input);
std::vector<bool> num_v(64, 0);

View File

@@ -2,7 +2,7 @@
#include "crypto/sha256.h"
uint256 PRF(bool a, bool b, bool c, bool d,
const uint256& x,
const uint252& x,
const uint256& y)
{
uint256 res;
@@ -21,7 +21,7 @@ uint256 PRF(bool a, bool b, bool c, bool d,
return res;
}
uint256 PRF_addr(const uint256& a_sk, unsigned char t)
uint256 PRF_addr(const uint252& a_sk, unsigned char t)
{
uint256 y;
*(y.begin()) = t;
@@ -29,22 +29,22 @@ uint256 PRF_addr(const uint256& a_sk, unsigned char t)
return PRF(1, 1, 0, 0, a_sk, y);
}
uint256 PRF_addr_a_pk(const uint256& a_sk)
uint256 PRF_addr_a_pk(const uint252& a_sk)
{
return PRF_addr(a_sk, 0);
}
uint256 PRF_addr_sk_enc(const uint256& a_sk)
uint256 PRF_addr_sk_enc(const uint252& a_sk)
{
return PRF_addr(a_sk, 1);
}
uint256 PRF_nf(const uint256& a_sk, const uint256& rho)
uint256 PRF_nf(const uint252& a_sk, const uint256& rho)
{
return PRF(1, 1, 1, 0, a_sk, rho);
}
uint256 PRF_pk(const uint256& a_sk, size_t i0, const uint256& h_sig)
uint256 PRF_pk(const uint252& a_sk, size_t i0, const uint256& h_sig)
{
if ((i0 != 0) && (i0 != 1)) {
throw std::domain_error("PRF_pk invoked with index out of bounds");
@@ -53,7 +53,7 @@ uint256 PRF_pk(const uint256& a_sk, size_t i0, const uint256& h_sig)
return PRF(0, i0, 0, 0, a_sk, h_sig);
}
uint256 PRF_rho(const uint256& phi, size_t i0, const uint256& h_sig)
uint256 PRF_rho(const uint252& phi, size_t i0, const uint256& h_sig)
{
if ((i0 != 0) && (i0 != 1)) {
throw std::domain_error("PRF_rho invoked with index out of bounds");

View File

@@ -7,11 +7,12 @@ within the zkSNARK circuit.
#define _PRF_H_
#include "uint256.h"
#include "uint252.h"
uint256 PRF_addr_a_pk(const uint256& a_sk);
uint256 PRF_addr_sk_enc(const uint256& a_sk);
uint256 PRF_nf(const uint256& a_sk, const uint256& rho);
uint256 PRF_pk(const uint256& a_sk, size_t i0, const uint256& h_sig);
uint256 PRF_rho(const uint256& phi, size_t i0, const uint256& h_sig);
uint256 PRF_addr_a_pk(const uint252& a_sk);
uint256 PRF_addr_sk_enc(const uint252& a_sk);
uint256 PRF_nf(const uint252& a_sk, const uint256& rho);
uint256 PRF_pk(const uint252& a_sk, size_t i0, const uint256& h_sig);
uint256 PRF_rho(const uint252& phi, size_t i0, const uint256& h_sig);
#endif // _PRF_H_