txmempool.h \
ui_interface.h \
uint256.h \
+ uint252.h \
undo.h \
util.h \
utilmoneystr.h \
TEST(joinsplit, note_plaintexts)
{
- uint256 a_sk = uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516847e");
+ uint252 a_sk = uint252(uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516840e"));
uint256 a_pk = PRF_addr_a_pk(a_sk);
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
TEST(noteencryption, api)
{
- uint256 sk_enc = ZCNoteEncryption::generate_privkey(uint256S("21035d60bc1983e37950ce4803418a8fb33ea68d5b937ca382ecbae7564d6a77"));
+ uint256 sk_enc = ZCNoteEncryption::generate_privkey(uint252(uint256S("21035d60bc1983e37950ce4803418a8fb33ea68d5b937ca382ecbae7564d6a07")));
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
ZCNoteEncryption b = ZCNoteEncryption(uint256());
{
// Test wrong private key
- uint256 sk_enc_2 = ZCNoteEncryption::generate_privkey(uint256());
+ uint256 sk_enc_2 = ZCNoteEncryption::generate_privkey(uint252());
ZCNoteDecryption decrypter(sk_enc_2);
ASSERT_THROW(decrypter.decrypt(ciphertext, b.get_epk(), uint256(), i), std::runtime_error);
uint256 test_prf(
unsigned char distinguisher,
- uint256 x,
+ uint252 seed_x,
uint256 y
) {
+ uint256 x = seed_x.inner();
*x.begin() &= 0x0f;
*x.begin() |= distinguisher;
CSHA256 hasher;
TEST(noteencryption, prf_addr)
{
for (size_t i = 0; i < 100; i++) {
- uint256 a_sk = libzcash::random_uint256();
+ uint252 a_sk = libzcash::random_uint252();
uint256 rest;
ASSERT_TRUE(
test_prf(0xc0, a_sk, rest) == PRF_addr_a_pk(a_sk)
}
for (size_t i = 0; i < 100; i++) {
- uint256 a_sk = libzcash::random_uint256();
+ uint252 a_sk = libzcash::random_uint252();
uint256 rest;
*rest.begin() = 0x01;
ASSERT_TRUE(
TEST(noteencryption, prf_nf)
{
for (size_t i = 0; i < 100; i++) {
- uint256 a_sk = libzcash::random_uint256();
+ uint252 a_sk = libzcash::random_uint252();
uint256 rho = libzcash::random_uint256();
ASSERT_TRUE(
test_prf(0xe0, a_sk, rho) == PRF_nf(a_sk, rho)
TEST(noteencryption, prf_pk)
{
for (size_t i = 0; i < 100; i++) {
- uint256 a_sk = libzcash::random_uint256();
+ uint252 a_sk = libzcash::random_uint252();
uint256 h_sig = libzcash::random_uint256();
ASSERT_TRUE(
test_prf(0x00, a_sk, h_sig) == PRF_pk(a_sk, 0, h_sig)
}
for (size_t i = 0; i < 100; i++) {
- uint256 a_sk = libzcash::random_uint256();
+ uint252 a_sk = libzcash::random_uint252();
uint256 h_sig = libzcash::random_uint256();
ASSERT_TRUE(
test_prf(0x40, a_sk, h_sig) == PRF_pk(a_sk, 1, h_sig)
);
}
- uint256 dummy;
- ASSERT_THROW(PRF_pk(dummy, 2, dummy), std::domain_error);
+ uint252 dummy_a;
+ uint256 dummy_b;
+ ASSERT_THROW(PRF_pk(dummy_a, 2, dummy_b), std::domain_error);
}
TEST(noteencryption, prf_rho)
{
for (size_t i = 0; i < 100; i++) {
- uint256 phi = libzcash::random_uint256();
+ uint252 phi = libzcash::random_uint252();
uint256 h_sig = libzcash::random_uint256();
ASSERT_TRUE(
test_prf(0x20, phi, h_sig) == PRF_rho(phi, 0, h_sig)
}
for (size_t i = 0; i < 100; i++) {
- uint256 phi = libzcash::random_uint256();
+ uint252 phi = libzcash::random_uint252();
uint256 h_sig = libzcash::random_uint256();
ASSERT_TRUE(
test_prf(0x60, phi, h_sig) == PRF_rho(phi, 1, h_sig)
);
}
- uint256 dummy;
- ASSERT_THROW(PRF_rho(dummy, 2, dummy), std::domain_error);
+ uint252 dummy_a;
+ uint256 dummy_b;
+ ASSERT_THROW(PRF_rho(dummy_a, 2, dummy_b), std::domain_error);
}
+
+TEST(noteencryption, uint252)
+{
+ ASSERT_THROW(uint252(uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516847e")), std::domain_error);
+}
\ No newline at end of file
--- /dev/null
+#ifndef UINT252_H
+#define UINT252_H
+
+#include <vector>
+#include "uint256.h"
+#include "serialize.h"
+
+// Wrapper of uint256 with guarantee that first
+// four bits are zero.
+class uint252 {
+private:
+ uint256 contents;
+
+public:
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(contents);
+
+ if ((*contents.begin()) & 0xF0) {
+ throw std::ios_base::failure("spending key has invalid leading bits");
+ }
+ }
+
+ const unsigned char* begin() const
+ {
+ return contents.begin();
+ }
+
+ const unsigned char* end() const
+ {
+ return contents.end();
+ }
+
+ uint252() : contents() {};
+ explicit uint252(const uint256& in) : contents(in) {
+ if (*contents.begin() & 0xF0) {
+ throw std::domain_error("leading bits are set in argument given to uint252 constructor");
+ }
+ }
+
+ uint256 inner() const {
+ return contents;
+ }
+};
+
+#endif
}
SpendingKey SpendingKey::random() {
- return SpendingKey(random_uint256());
+ return SpendingKey(random_uint252());
}
PaymentAddress SpendingKey::address() {
#define _ZCADDRESS_H_
#include "uint256.h"
+#include "uint252.h"
#include "serialize.h"
namespace libzcash {
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();
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++) {
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());
#include "NoteEncryption.hpp"
#include "uint256.h"
+#include "uint252.h"
#include <boost/array.hpp>
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>
}
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);
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>;
#include <boost/array.hpp>
#include "uint256.h"
+#include "uint252.h"
#include "zcash/Zcash.h"
);
// 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);
};
uint256 random_uint256();
+uint252 random_uint252();
}
}
void generate_r1cs_witness(
- const uint256& phi,
+ const uint252& phi,
const uint256& rt,
const uint256& h_sig,
const boost::array<JSInput, NumInputs>& inputs,
// Witness phi
zk_phi->bits.fill_with_bits(
this->pb,
- trailing252(uint256_to_bool_vector(phi))
+ uint252_to_bool_vector(phi)
);
// Witness h_sig
// 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
+#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;
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(
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);
#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;
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;
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");
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");
#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_