Skip to content

Commit

Permalink
contracts: improve memory use in digest unpacking
Browse files Browse the repository at this point in the history
  • Loading branch information
dtebbs committed Dec 18, 2019
1 parent 06797ac commit 209a069
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 21 deletions.
34 changes: 16 additions & 18 deletions zeth-contracts/contracts/BaseMixer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -139,28 +139,29 @@ contract BaseMixer is MerkleTreeMiMC7, ERC223ReceivingContract {
"Invalid root: This root doesn't exist"
);

// 2. We re-assemble the nullifiers (JSInputs) and check they were not already seen
// 2. We re-assemble the nullifiers (JSInputs) and check they were not
// already seen
bytes32[jsIn] memory nfs;
uint256[] memory digest_inputs = new uint[](2);
uint nf_idx = 0;
for(uint i = 1; i < 1 + 2*jsIn; i += 2) {
digest_inputs[0] = primary_inputs[i];
digest_inputs[1] = primary_inputs[i+1];
nfs[(i-1)/2] = Bytes.sha256_digest_from_field_elements(digest_inputs);
bytes32 nullifier = Bytes.sha256_digest_from_field_elements(
primary_inputs[i], primary_inputs[i+1]);
nfs[nf_idx] = nullifier;
require(
!nullifiers[nfs[(i-1)/2]],
!nullifiers[nullifier],
"Invalid nullifier: This nullifier has already been used"
);
nullifiers[nfs[(i-1)/2]] = true;
nullifiers[nullifier] = true;
++nf_idx;
}

// 3. We re-compute h_sig, re-assemble the expected h_sig and check they
// are equal (i.e. that h_sig re-assembled was correctly generated from
// vk)
bytes32 expected_hsig = sha256(abi.encodePacked(nfs, vk));

digest_inputs[0] = primary_inputs[1 + 2 * (jsIn + jsOut) + 1 + 1];
digest_inputs[1] = primary_inputs[1 + 2 * (jsIn + jsOut + 1) + 1];
bytes32 hsig = Bytes.sha256_digest_from_field_elements(digest_inputs);
bytes32 hsig = Bytes.sha256_digest_from_field_elements(
primary_inputs[1 + 2 * (jsIn + jsOut) + 1 + 1],
primary_inputs[1 + 2 * (jsIn + jsOut + 1) + 1]);
require(
expected_hsig == hsig,
"Invalid hsig: This hsig does not correspond to the hash of vk and the nfs"
Expand All @@ -170,15 +171,12 @@ contract BaseMixer is MerkleTreeMiMC7, ERC223ReceivingContract {
function assemble_commitments_and_append_to_state(
uint[] memory primary_inputs) internal {
// We re-assemble the commitments (JSOutputs)
uint256[] memory digest_inputs = new uint[](2);
for(uint i = 1 + 2 * jsIn ; i < 1 + 2*(jsIn + jsOut); i += 2) {
// See the way the inputs are ordered in the extended proof
digest_inputs[0] = primary_inputs[i];
digest_inputs[1] = primary_inputs[i+1];
bytes32 current_commitment =
Bytes.sha256_digest_from_field_elements(digest_inputs);
uint commitmentAddress = insert(current_commitment);
emit LogAddress(commitmentAddress);
bytes32 commitment = Bytes.sha256_digest_from_field_elements(
primary_inputs[i], primary_inputs[i+1]);
uint commitment_address = insert(commitment);
emit LogAddress(commitment_address);
}
}

Expand Down
6 changes: 3 additions & 3 deletions zeth-contracts/contracts/Bytes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ pragma solidity ^0.5.0;

library Bytes {

function sha256_digest_from_field_elements(uint[] memory input)
function sha256_digest_from_field_elements(uint input0, uint input1)
internal pure returns (bytes32) {

// We know that input[0] is a field element. Thus, it is encoded on 253
// bits, and it should be the biggest between inputs[0] and inputs[1].
// Inputs[0] actually contains 253 bits from the digest
bytes32 inverted_input1 = flip_endianness_bytes32(bytes32(input[0]));
bytes32 inverted_input1 = flip_endianness_bytes32(bytes32(input0));

// As opposed to inputs[0], inputs[1] is encoded on 253 bits (because it
// is a field element) but contains ONLY 3 bits from the digest (it is a
Expand All @@ -34,7 +34,7 @@ library Bytes {
// input[1] is a very small number only represented on 3 field bits, so
// the meaningful data we want to manipulate is only on the last bytes
// of this bytes32 input
bytes1 last_byte_suffix = get_last_byte(bytes32(input[1]));
bytes1 last_byte_suffix = get_last_byte(bytes32(input1));

// After selecting the last byte of input[1], we inverse only this byte
// and we shift 5 times because we have somehting like: 0x4 initally,
Expand Down

0 comments on commit 209a069

Please sign in to comment.