def vc_check_circuit_final(v_input, witness):

    (
        root,
        nonce,
        hmacG,
        hmacG_key,
        first_hmac_key,
        h2,
        inds_s,
        last_hmac_key,
        hmac0,
        hmacN,
        m,
        puzstr,
        public_value,
        secret_exponent,
        secret_value,
    ) = witness

    d = string_to_long(puzstr[:4])
    puzid = puzstr[4:]

    # Recompute h1 and check indices
    h1 = sha1_fixed(rzfill(puzid + root + nonce, 64))
    q1inds = select_hash(h1, Q1, TREE1_HEIGHT - 1)

    # Recompute the entire inds hash
    hm = hash(h2 + m)
    q2inds = []
    iters = int(ceil(float(4 * Q2) / (k / (TREE1_HEIGHT - 1))))
    for i in range(iters):
        hm = hash(hm + m)
        q2inds += select_hash(hm, (k / (TREE1_HEIGHT - 1)), TREE1_HEIGHT - 1)

    inds = []
    for j in range(Q1 + Q2):
        inds.append(string_to_long(inds_s[j * 2 : (j + 1) * 2]))
    inds = tuple(inds)
    assert inds[:Q1] == q1inds

    # TODO: check that Q2 is a subset of q2inds
    assert len(inds[Q1 : Q1 + Q2]) == Q2

    # Check the diffie hellman value for enc_key and secret_value
    gu = elgamal.g_raised_to(secret_exponent)
    hu = elgamal.h_raised_to(secret_exponent)
    assert secret_value == hu
    enc_key = sha1_fixed(elgamal.group_element_to_string(secret_value))
    print "h1", binascii.hexlify(h1)
    # Check v_input
    assert hmac0 == sha1_fixed(rzfill(first_hmac_key + h1 + "\0" * 20, 64))
    assert hmacN == sha1_fixed(rzfill(last_hmac_key + h2 + root, 64))

    assert hmacG == hash(hmacG_key + root + enc_key + inds_s)

    # Check the verifier input
    assert v_input == hash(hmac0 + hmacN + m + puzstr + elgamal.group_element_to_string(gu))

    # Check winning condition
    assert long(binascii.hexlify(h2), 16) < 2 ** (k - d)

    return True
def write_inputs(output_dir, puz, vcticket, witnesses):
    import os
    import scratch_pb2

    output_dir = output_dir + "B_c%02d_h%02d_q1%02d_q2%02d" % (HASHES_PER_CIRCUIT, TREE1_HEIGHT, Q1, Q2)
    try:
        os.makedirs(output_dir)
    except OSError:
        pass  # directory already exists

    class CircuitInput(object):
        def __init__(self, f):
            self.f = f
            self.wirecount = 0

        def write(self, s):
            assert len(s) % 4 == 0, "Only writing multiples of 32 bits"
            for i in range(len(s) / 4):
                b = s[i * 4 : (i + 1) * 4]
                ss = binascii.hexlify(b)
                self.f.write("%d %s\n" % (self.wirecount, ss))
                # print 'wrote:', self.wirecount
                self.wirecount += 1

        def close(self):
            self.f.write("%d 1\n" % (self.wirecount,))

    d, puzid = puz
    ciphertext_sets, hmacs, public_value, hmacG = vcticket

    for i, witness in enumerate(witnesses[:-1]):

        # Inner witness
        (
            root,
            bi_s,
            lbhere,
            hmacG_key,
            old_hmac,
            new_hmac,
            cblocks,
            ciphertexts,
            old_state,
            old_hmac_key,
            old_merkle_state,
            new_state,
            hmac_key,
            enc_key,
            inds_s,
        ) = witness

        # Local indices
        b = string_to_long(bi_s) >> 16
        z = (string_to_long(bi_s)) & 0xFFFF

        # Verifier input
        v_input = hash((hmacs[i] + hmacs[i + 1] + cblocks + bi_s + hmacG))

        print "inner witness[%d]: v_input:%s old_hmac:%s new_hmac:%s" % (
            i,
            binascii.hexlify(v_input),
            binascii.hexlify(old_hmac),
            binascii.hexlify(new_hmac),
        )

        # Encryptions
        ciphertexts = ciphertext_sets[i]
        cblocks = sha1_fixed(rzfill(ciphertexts, 64 * ENC_BLOCKS_PER_CIRCUIT))

        # Write the wire inputs file
        with open(os.path.join(output_dir, "wire_input_%02d.in" % i), "w") as f:
            cf = CircuitInput(f)
            # Verifier's input
            cf.write(v_input)
            # Prover's inputs
            cf.write(root)
            cf.write(enc_key)
            assert len(inds_s) == 48
            cf.write(inds_s)
            cf.write(bi_s)
            cf.write(rzfill("".join(lbhere), 20 * (HASHES_PER_CIRCUIT)))
            print binascii.hexlify(rzfill("".join(lbhere), 20 * (HASHES_PER_CIRCUIT)))
            cf.write(old_hmac)
            cf.write(new_hmac)
            cf.write(hmacG)
            cf.write(old_merkle_state)
            cf.write(hmacG_key)
            cf.write(cblocks)
            cf.write(old_state)
            cf.write(old_hmac_key)
            cf.write(new_state)
            cf.write(hmac_key)
            cf.close()
            print "hmacG", binascii.hexlify(hmacG)

    # Final Witness
    for _ in [1]:
        (
            root,
            nonce,
            hmacG,
            hmacG_key,
            first_hmac_key,
            h2,
            inds_s,
            last_hmac_key,
            hmac0,
            hmacN,
            m,
            puzstr,
            public_value,
            secret_exponent,
            secret_value,
        ) = witnesses[-1]

        gu = elgamal.g_raised_to(secret_exponent)
        hu = elgamal.h_raised_to(secret_exponent)
        assert public_value == gu
        assert secret_value == hu
        enc_key = sha1_fixed(elgamal.group_element_to_string(secret_value))

        # Check the verifier input
        v_input = hash(hmac0 + hmacN + m + puzstr + elgamal.group_element_to_string(gu))

        # Write the wire inputs file
        with open(os.path.join(output_dir, "wire_input_final.in"), "w") as f:
            cf = CircuitInput(f)
            # Verifier's input
            # cf.write(v_input)
            assert len(v_input) == 20
            # Prover's inputs
            cf.write(hmacG)
            cf.write(hmac0)
            cf.write(hmacN)
            cf.write(m)
            assert len(m) == 20
            cf.write(puzstr)
            assert len(puzstr) == 24

            cf.write(root)
            cf.write(nonce)
            cf.write(hmacG_key)
            cf.write(first_hmac_key)
            cf.write(h2)
            assert len(inds_s) == 48
            cf.write(inds_s)
            cf.write(last_hmac_key)
            print "root", binascii.hexlify(root)
            print "nonce", binascii.hexlify(nonce)
            print "hmac0", binascii.hexlify(hmac0)
            print "hmacN", binascii.hexlify(hmacN)
            # cf.write(elgamal.group_element_to_string(gu))
            # assert len(elgamal.group_element_to_string(gu)) == 128
            cf.write(elgamal.group_element_to_string(hu))
            assert len(elgamal.group_element_to_string(hu)) == 128
            bitstring = bin(secret_exponent)[2:]
            bitstring = "0" * (512 - len(bitstring)) + bitstring
            for bit in map(int, bitstring[::-1]):
                cf.write(long_to_string(bit, 4))
            cf.close()
def transform(puz, ticket, m, hmac_keys, secret_exponent):
    d, puzid = puz
    root, nonce, leavesbranches, chosen = ticket

    secret_value = elgamal.h_raised_to(secret_exponent)
    public_value = elgamal.g_raised_to(secret_exponent)
    enc_key = sha1_fixed(elgamal.group_element_to_string(secret_value))

    # A) Need to encrypt the root, nonce, leaves, and branches, in chunks
    # B) Need to make HMAC commitments to the internal state
    # C) Need to break the leavesQ1/branchesQ1 into chunks to be verified

    # Build an iterator over the randomness rather than counting for now
    assert len(hmac_keys) == 2 + N_CIRCUITS

    # These need to be coalesced into group elements!
    ciphertexts = []
    assert len(leavesbranches) == Q1 + Q2

    h1 = sha1_fixed(rzfill(puzid + root + nonce, 64))
    inds = select_hash(h1, Q1, TREE1_HEIGHT - 1) + tuple(chosen)
    assert len(inds) == Q1 + Q2
    inds_s = rzfill("".join(long_to_string(ind, 2) for ind in inds), 48)

    # The first randomness is used as IV for the hashchain over leaves
    state = h1

    # Ciphertext accumulators, as well as the set of ciphertexts
    cipher_accs = []
    ciphertext_sets = []

    # Commitments to local state
    hmacs = []

    # Initialize hmacs with root, empty state/inds
    hmac = sha1_fixed(rzfill(hmac_keys[0] + h1 + "\0" * 20, 64))
    hmacs.append(hmac)

    # Commitments to glob
    hmacG = hash((hmac_keys[-1] + root + enc_key + inds_s))

    # Witnesses
    witnesses = []
    merkle_state = "\0" * 20
    # First prepare the encryptions
    for b in range(Q1 + Q2):
        leaf, branch = leavesbranches[b]
        leafbranch = [leaf] + branch
        ind = inds[b]
        for i in range(CIRCUITS_PER_BRANCH):
            # qhere is the number of branches to process here
            lbhere = leafbranch[HASHES_PER_CIRCUIT * i : HASHES_PER_CIRCUIT * (i + 1)]
            stream = rzfill(state + "".join(lbhere), ENC_BLOCKS_PER_CIRCUIT * 64)

            # Update the state
            old_state = state
            if b < Q1:
                state = sha1_fixed(stream)
            # Encrypt using SHACAL, then pad to multiple of 512 bits
            stream = rzfill("".join(lbhere), HASHES_PER_CIRCUIT * 20)
            ciphertexts = shacal_encrypt(
                stream, b * HASHES_PER_CIRCUIT * CIRCUITS_PER_BRANCH + i * HASHES_PER_CIRCUIT, enc_key
            )
            assert len(ciphertexts) == HASHES_PER_CIRCUIT * 20
            ciphertext_sets.append(ciphertexts)

            # Now we need to hash over the ciphertexts used in this circuit
            cipher_accs.append(sha1_fixed(rzfill(ciphertexts, ENC_BLOCKS_PER_CIRCUIT * 64)))

            # Finally we need to prepare the auxiliary merkle tree information
            if i > 0:
                ind_copy = ind >> (i * HASHES_PER_CIRCUIT - 1)
            else:
                ind_copy = ind

            old_merkle_state = merkle_state
            for j in range(HASHES_PER_CIRCUIT):
                if i * HASHES_PER_CIRCUIT + j >= TREE1_HEIGHT:
                    continue
                sibling = lbhere[j]
                if i == 0 and j == 0:
                    merkle_state = hash(sibling)  # It's actually the leaf
                else:
                    if not ind_copy % 2:  # left node select, sibling to the right
                        merkle_state = hash(merkle_state + sibling)
                    else:
                        merkle_state = hash(sibling + merkle_state)
                    ind_copy >>= 1
                if i * HASHES_PER_CIRCUIT + j == TREE1_HEIGHT - 1:
                    assert merkle_state == root
            # Finally, we must collect the root, state, index accumulator, into
            # an hmac commitment

            hmac = sha1_fixed(rzfill(hmac_keys[b * CIRCUITS_PER_BRANCH + i + 1] + state + merkle_state, 64))
            hmacs.append(hmac)

            witness = (
                root,
                long_to_string((b << 16) + i, 4),
                lbhere,
                hmac_keys[-1],
                hmacs[-2],
                hmacs[-1],
                cipher_accs[-1],
                ciphertexts,
                old_state,
                hmac_keys[b * CIRCUITS_PER_BRANCH + i],
                old_merkle_state,
                state,
                hmac_keys[b * CIRCUITS_PER_BRANCH + i + 1],
                enc_key,
                inds_s,
            )
            witnesses.append(witness)

    # Verifier information
    verifier_data = ciphertext_sets, hmacs, public_value, hmacG

    # Witness information
    puzstr = long_to_string(d, 4) + puzid
    last_witness = (
        root,
        nonce,
        hmacG,
        hmac_keys[-1],
        hmac_keys[0],
        state,
        inds_s,
        hmac_keys[-2],
        hmacs[0],
        hmacs[-1],
        m,
        puzstr,
        public_value,
        secret_exponent,
        secret_value,
    )
    witnesses.append(last_witness)
    return verifier_data, witnesses