Skip to content

Commit

Permalink
Merge pull request #63 from clearmatics/blake2s
Browse files Browse the repository at this point in the history
Blake2s update
  • Loading branch information
AntoineRondelet committed Oct 21, 2019
2 parents 118b8d9 + 8f8f61f commit 27296bc
Show file tree
Hide file tree
Showing 63 changed files with 2,436 additions and 466 deletions.
116 changes: 81 additions & 35 deletions pyClient/zethGRPC.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from Crypto import Random
import os
import json
import hashlib
import sys

# Access the encoding functions
# Access the encoding and hash functions
from eth_abi import encode_single, encode_abi
from hashlib import blake2s, sha256

# Access the gRPC service and the proto messages
import grpc
Expand Down Expand Up @@ -55,7 +55,7 @@ def hex32bytes(element):
res = "00"*int((64-len(res))/2) + res
return res

# Compute h_sig = sha256(randomSeed, nf0, nf1, joinSplitPubKey)
# Compute h_sig = blake2s(randomSeed, nf0, nf1, joinSplitPubKey)
def computeHSig(randomSeed, nf0, nf1, joinSplitPubKey):
# Flatten the verification key
JSPubKeyHex = [item for sublist in joinSplitPubKey for item in sublist]
Expand All @@ -65,8 +65,16 @@ def computeHSig(randomSeed, nf0, nf1, joinSplitPubKey):
# For each element of the list, convert it to an hex and append it
vk_hex += hex32bytes( "{0:0>4X}".format(int(item)) )

h_sig = hashlib.sha256(
encode_abi(['bytes32', 'bytes32', 'bytes32', 'bytes'], (bytes.fromhex(randomSeed), bytes.fromhex(nf0), bytes.fromhex(nf1), bytes.fromhex(vk_hex)) )
h_sig = blake2s(
encode_abi(
['bytes32', 'bytes32', 'bytes32', 'bytes'],
(
bytes.fromhex(randomSeed),
bytes.fromhex(nf0),
bytes.fromhex(nf1),
bytes.fromhex(vk_hex)
)
)
).hexdigest()

return h_sig
Expand All @@ -82,7 +90,7 @@ def transactionRandomness():
return rand_phi

# Compute the note randomness: the trapdoor trapR and rho.
# Starting the Non-Maleability update, rho is computed from phi (see above),
# Starting the Non-Malleability update, rho is computed from phi (see above),
# the rho generated in this function is thus obsolete except for dummy input notes.
def noteRandomness():
rand_rho = bytes(Random.get_random_bytes(32)).hex()
Expand Down Expand Up @@ -153,40 +161,60 @@ def hexFmt(string):
# Used by the recipient of a payment to recompute the commitment and check the membership in the tree
# to confirm the validity of a payment
def computeCommitment(zethNoteGRPCObj):
# inner_k = sha256(a_pk || rho)
inner_k = hashlib.sha256(
encode_abi(['bytes32', 'bytes32'], (bytes.fromhex(zethNoteGRPCObj.aPK), bytes.fromhex(zethNoteGRPCObj.rho)))
# inner_k = blake2s(a_pk || rho)
inner_k = blake2s(
encode_abi(['bytes32', 'bytes32'],
(
bytes.fromhex(zethNoteGRPCObj.aPK),
bytes.fromhex(zethNoteGRPCObj.rho)
)
)
).hexdigest()

# outer_k = sha256(r || [inner_k]_128)
# outer_k = blake2s(r || [inner_k]_128)
first128InnerComm = inner_k[0:128]
outer_k = hashlib.sha256(
encode_abi(['bytes', 'bytes'], (bytes.fromhex(zethNoteGRPCObj.trapR), bytes.fromhex(first128InnerComm)))
outer_k = blake2s(
encode_abi(['bytes', 'bytes'],
(
bytes.fromhex(zethNoteGRPCObj.trapR),
bytes.fromhex(first128InnerComm)
)
)
).hexdigest()

# cm = sha256(outer_k || 0^192 || value_v)
# cm = blake2s(outer_k || 0^192 || value_v)
frontPad = "000000000000000000000000000000000000000000000000"
cm = hashlib.sha256(
encode_abi(["bytes32", "bytes32"], (bytes.fromhex(outer_k), bytes.fromhex(frontPad + zethNoteGRPCObj.value)))
cm = blake2s(
encode_abi(["bytes32", "bytes32"],
(
bytes.fromhex(outer_k),
bytes.fromhex(frontPad + zethNoteGRPCObj.value)
)
)
).hexdigest()
return cm

def hexadecimalDigestToBinaryString(digest):
binary = lambda x: "".join(reversed( [i+j for i,j in zip( *[ ["{0:04b}".format(int(c,16)) for c in reversed("0"+x)][n::2] for n in [1,0]])]))
return binary(digest)

# Returns nf = sha256(1110 || [a_sk]_252 || rho)
# Returns nf = blake2s(1110 || [a_sk]_252 || rho)
def computeNullifier(zethNote, spendingAuthAsk):
binaryAsk = hexadecimalDigestToBinaryString(spendingAuthAsk)
first252Ask = binaryAsk[:252]
leftLegBin = "1110" + first252Ask
leftLegHex = "{0:0>4X}".format(int(leftLegBin, 2))
nullifier = hashlib.sha256(
encode_abi(["bytes32", "bytes32"], [bytes.fromhex(leftLegHex), bytes.fromhex(zethNote.rho)])
nullifier = blake2s(
encode_abi(["bytes32", "bytes32"],
(
bytes.fromhex(leftLegHex),
bytes.fromhex(zethNote.rho)
)
)
).hexdigest()
return nullifier

# Returns h_i = sha256(0 || i || 00 || [a_sk]_252 || hsig)
# Returns h_i = blake2s(0 || i || 00 || [a_sk]_252 || hsig)
# See: Zcash protocol spec p. 57, Section 5.4.2 Pseudo Random Functions
def computeHi(ask, hsig, i):
# [SANITY CHECK] make sure i is in the interval [0, 1]
Expand All @@ -200,13 +228,17 @@ def computeHi(ask, hsig, i):
leftLegBin = "0" + str(i) + "00" + first252Ask
leftLegHex = "{0:0>4X}".format(int(leftLegBin, 2))

print(encode_abi(["bytes32", "bytes32"], [bytes.fromhex(leftLegHex), bytes.fromhex(hsig)]))
h_i = hashlib.sha256(
encode_abi(["bytes32", "bytes32"], [bytes.fromhex(leftLegHex), bytes.fromhex(hsig)])
h_i = blake2s(
encode_abi(["bytes32", "bytes32"],
(
bytes.fromhex(leftLegHex),
bytes.fromhex(hsig)
)
)
).hexdigest()
return h_i

# Returns rho_i = sha256(0 || i || 10 || [phi]_252 || hsig)
# Returns rho_i = blake2s(0 || i || 10 || [phi]_252 || hsig)
# See: Zcash protocol spec p. 57, Section 5.4.2 Pseudo Random Functions
def computeRhoi(phi, hsig, i):
# [SANITY CHECK] make sure i is in the interval [0, 1]
Expand All @@ -220,23 +252,33 @@ def computeRhoi(phi, hsig, i):
leftLegBin = "0" + str(i) + "10" + first252Phi
leftLegHex = "{0:0>4X}".format(int(leftLegBin, 2))

rho_i = hashlib.sha256(
encode_abi(["bytes32", "bytes32"], [bytes.fromhex(leftLegHex), bytes.fromhex(hsig)])
rho_i = blake2s(
encode_abi(["bytes32", "bytes32"],
(
bytes.fromhex(leftLegHex),
bytes.fromhex(hsig)
)
)
).hexdigest()
return rho_i

def int64ToHexadecimal(number):
return '{:016x}'.format(number)

# Returns a_pk = sha256(1100 || [a_sk]_252 || 0^256)
# Returns a_pk = blake2s(1100 || [a_sk]_252 || 0^256)
def deriveAPK(ask):
binaryAsk = hexadecimalDigestToBinaryString(ask)
first252Ask = binaryAsk[:252]
leftLegBin = "1100" + first252Ask
leftLegHex = "{0:0>4X}".format(int(leftLegBin, 2))
zeroes = "0000000000000000000000000000000000000000000000000000000000000000"
a_pk = hashlib.sha256(
encode_abi(["bytes32", "bytes32"], [bytes.fromhex(leftLegHex), bytes.fromhex(zeroes)])
a_pk = blake2s(
encode_abi(["bytes32", "bytes32"],
(
bytes.fromhex(leftLegHex),
bytes.fromhex(zeroes)
)
)
).hexdigest()
return a_pk

Expand Down Expand Up @@ -406,13 +448,17 @@ def sign(keypair, hash_ciphers, hash_proof, hash_inputs):
y1_hex = hex32bytes( "{0:0>4X}".format(int(vk[1][1])) )

# Encode and hash the verifying key and input hashes
data_to_sign = encode_abi(["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"],
[bytes.fromhex(y0_hex),
bytes.fromhex(y1_hex),
bytes.fromhex(hash_ciphers),
bytes.fromhex(hash_proof),
bytes.fromhex(hash_inputs)])
data_hex = hashlib.sha256(data_to_sign).hexdigest()
data_to_sign = encode_abi(
["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"],
(
bytes.fromhex(y0_hex),
bytes.fromhex(y1_hex),
bytes.fromhex(hash_ciphers),
bytes.fromhex(hash_proof),
bytes.fromhex(hash_inputs)
)
)
data_hex = sha256(data_to_sign).hexdigest()

# Convert the hex digest into a field element
h = int(data_hex, 16) % constants.ZETH_PRIME
Expand Down
15 changes: 10 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,19 @@ endfunction(zeth_test)
zeth_test(test_simple test/simple_test.cpp TRUE)
zeth_test(test_addition test/packed_addition_test.cpp TRUE)
zeth_test(test_hex_to_field test/hex_to_field_test.cpp TRUE)
zeth_test(test_note test/note_test.cpp TRUE)
zeth_test(test_prfs test/prfs_test.cpp TRUE)
zeth_test(test_commitments test/commitments_test.cpp TRUE)
zeth_test(test_round test/round_test.cpp TRUE)
zeth_test(test_binary_operation test/binary_operation_test.cpp TRUE)
zeth_test(test_blake2s test/blake2s_test.cpp TRUE)
zeth_test(test_mimc_round test/mimc_round_test.cpp TRUE)
zeth_test(test_mimc test/mimc_test.cpp TRUE)
zeth_test(test_mimc_mp test/mimc_mp_test.cpp TRUE)
zeth_test(test_prfs test/prfs_test.cpp TRUE)
zeth_test(test_commitments test/commitments_test.cpp TRUE)
zeth_test(test_merkle_tree test/merkle_tree_test.cpp TRUE)
zeth_test(test_prover test/prover_test.cpp FALSE)
zeth_test(test_note test/note_test.cpp TRUE)
zeth_test(test_prover test/prover_test.cpp TRUE)

# Old Tests
# zeth_test(test_sha256 test/test_sha256.cpp TRUE)

# prover test has extra dependencies
target_link_libraries(
Expand Down
2 changes: 1 addition & 1 deletion src/circuit-wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ class CircuitWrapper
} // namespace libzeth
#include "circuit-wrapper.tcc"

#endif // __ZETH_CIRCUIT_WRAPPER_HPP__
#endif // __ZETH_CIRCUIT_WRAPPER_HPP__
4 changes: 2 additions & 2 deletions src/circuit-wrapper.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ extended_proof<ppT> CircuitWrapper<

// Compute the sum on the left hand side of the joinsplit
for (size_t i = 0; i < NumInputs; i++) {
lhs_value = binaryAddition<64>(lhs_value, inputs[i].note.value());
lhs_value = binary_addition<64>(lhs_value, inputs[i].note.value());
}

// Compute the sum on the right hand side of the joinsplit
for (size_t i = 0; i < NumOutputs; i++) {
rhs_value = binaryAddition<64>(rhs_value, outputs[i].value());
rhs_value = binary_addition<64>(rhs_value, outputs[i].value());
}

// [CHECK] Make sure that the balance between rhs and lfh is respected
Expand Down
112 changes: 112 additions & 0 deletions src/circuits/binary_operation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#ifndef __ZETH_CIRCUITS_BINARY_OPERATION_HPP__
#define __ZETH_CIRCUITS_BINARY_OPERATION_HPP__

#include "circuits/circuits-utils.hpp"
#include "math.h"
#include "types/bits.hpp"

#include <libsnark/gadgetlib1/gadget.hpp>
#include <libsnark/gadgetlib1/gadgets/basic_gadgets.hpp>

namespace libzeth
{

/// xor_gadget computes res = a XOR b
template<typename FieldT> class xor_gadget : public libsnark::gadget<FieldT>
{

private:
const libsnark::pb_variable_array<FieldT> a;
const libsnark::pb_variable_array<FieldT> b;

public:
libsnark::pb_variable_array<FieldT> res;

xor_gadget(
libsnark::protoboard<FieldT> &pb,
const libsnark::pb_variable_array<FieldT> a,
const libsnark::pb_variable_array<FieldT> b,
libsnark::pb_variable_array<FieldT> res,
const std::string &annotation_prefix = "xor_gadget");

void generate_r1cs_constraints();
void generate_r1cs_witness();
};

/// xor_constant_gadget computes res = a XOR b XOR c with c constant
template<typename FieldT>
class xor_constant_gadget : public libsnark::gadget<FieldT>
{

private:
const libsnark::pb_variable_array<FieldT> a;
const libsnark::pb_variable_array<FieldT> b;
const std::vector<FieldT> c;

public:
libsnark::pb_variable_array<FieldT> res;

xor_constant_gadget(
libsnark::protoboard<FieldT> &pb,
const libsnark::pb_variable_array<FieldT> a,
const libsnark::pb_variable_array<FieldT> b,
const std::vector<FieldT> c,
libsnark::pb_variable_array<FieldT> res,
const std::string &annotation_prefix = "xor_constant_gadget");

void generate_r1cs_constraints();
void generate_r1cs_witness();
};

/// xor_rot_gadget computes a XOR b and rotate it by shift
template<typename FieldT> class xor_rot_gadget : public libsnark::gadget<FieldT>
{

private:
const libsnark::pb_variable_array<FieldT> a;
const libsnark::pb_variable_array<FieldT> b;
const size_t shift;

public:
libsnark::pb_variable_array<FieldT> res;

xor_rot_gadget(
libsnark::protoboard<FieldT> &pb,
const libsnark::pb_variable_array<FieldT> a,
const libsnark::pb_variable_array<FieldT> b,
const size_t &shift,
libsnark::pb_variable_array<FieldT> res,
const std::string &annotation_prefix = "xor_rot_gadget");

void generate_r1cs_constraints();
void generate_r1cs_witness();
};

/// double_bit32_sum_eq_gadget checks that res = a + b % 2**32
/// with a, b and res being 32-bit long arrays
template<typename FieldT>
class double_bit32_sum_eq_gadget : public libsnark::gadget<FieldT>
{

private:
libsnark::pb_variable_array<FieldT> a;
libsnark::pb_variable_array<FieldT> b;

public:
libsnark::pb_variable_array<FieldT> res;

double_bit32_sum_eq_gadget(
libsnark::protoboard<FieldT> &pb,
libsnark::pb_variable_array<FieldT> a,
libsnark::pb_variable_array<FieldT> b,
libsnark::pb_variable_array<FieldT> res,
const std::string &annotation_prefix = "double_bit32_sum_eq_gadget");

void generate_r1cs_constraints(bool enforce_boolean = true);
void generate_r1cs_witness();
};

} // namespace libzeth
#include "binary_operation.tcc"

#endif // __ZETH_CIRCUITS_BINARY_OPERATION_HPP__
Loading

0 comments on commit 27296bc

Please sign in to comment.