8000 Client-side pairing parameters and curve operations by dtebbs · Pull Request #293 · clearmatics/zeth · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Client-side pairing parameters and curve operations #293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/.pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ disable=
duplicate-code,
fixme

good-names=a,b,c,e,g,h,i,k,m,x,y,z,cm,ic,rc,ek,ct,vk,sk,pk,X,Y,r,el,nf,g1,g2
good-names=a,b,c,e,g,h,i,k,m,q,r,x,y,z,cm,ic,rc,ek,ex,ct,vk,sk,pk,pp,X,Y,r,el,nf,g1,g2

max-attributes=10

Expand Down
139 changes: 89 additions & 50 deletions client/test_commands/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
#
# SPDX-License-Identifier: LGP 8000 L-3.0+

from zeth.core.zeth_address import ZethAddressPub
from zeth.core.mixer_client import MixerClient, OwnershipKeyPair, \
joinsplit_sign, encrypt_notes, get_dummy_input_and_address, \
compute_h_sig, JoinsplitSigVerificationKey
from zeth.core.zksnark import IZKSnarkProvider
compute_h_sig, JoinsplitSigVerificationKey, MixCallDescription, \
ComputeHSigCB, JoinsplitSigKeyPair
from zeth.core.zksnark import IZKSnarkProvider, ExtendedProof
import zeth.core.contracts as contracts
from zeth.core.constants import ZETH_PRIME, FIELD_CAPACITY
import zeth.core.signing as signing
from zeth.core.merkle_tree import MerkleTree, compute_merkle_path
from zeth.core.utils import EtherValue, to_zeth_units
from zeth.core.merkle_tree import MerkleTree
from zeth.core.utils import EtherValue
from zeth.api.zeth_messages_pb2 import ZethNote
import test_commands.mock as mock

Expand Down Expand Up @@ -52,6 +54,42 @@ def wait_for_tx_update_mk_tree(
return result


def get_mix_parameters_components(
zeth_client: MixerClient,
zksnark: IZKSnarkProvider,
mk_tree: MerkleTree,
sender_ownership_keypair: OwnershipKeyPair,
inputs: List[Tuple[int, ZethNote]],
outputs: List[Tuple[ZethAddressPub, EtherValue]],
v_in: EtherValue,
v_out: EtherValue,
compute_h_sig_cb: Optional[ComputeHSigCB] = None
) -> Tuple[ZethNote, ZethNote, ExtendedProof, JoinsplitSigKeyPair]:
"""
Manually create the components required for MixParameters. The tests below
manipulate these to create custom MixParameters as part of attacks.
"""
prover_client = zeth_client._prover_client \
# pylint: disable=protected-access
mix_call_desc = MixCallDescription(
mk_tree,
sender_ownership_keypair,
inputs,
outputs,
v_in,
v_out,
compute_h_sig_cb)
prover_inputs, signing_keypair = zeth_client.create_prover_inputs(
mix_call_desc)
ext_proof_proto = prover_client.get_proof(prover_inputs)
ext_proof = zksnark.extended_proof_from_proto(ext_proof_proto)
return (
prover_inputs.js_outputs[0],
prover_inputs.js_outputs[1],
ext_proof,
signing_keypair)


def bob_deposit(
zeth_client: MixerClient,
mk_tree: MerkleTree,
Expand Down Expand Up @@ -154,22 +192,20 @@ def charlie_double_withdraw(
Charlie tries to carry out a double spending by modifying the value of the
nullifier of the previous payment
"""
prover_client = zeth_client._prover_client \
# pylint: disable=protected-access

print(
f" === Charlie attempts to withdraw {CHARLIE_WITHDRAW_ETH}ETH once " +
"more (double spend) one of his note on the Mixer ===")

charlie_apk = keystore["Charlie"].addr_pk.a_pk
charlie_ask = keystore["Charlie"].addr_sk.a_sk

tree_depth = mk_tree.depth
mk_path1 = compute_merkle_path(input1[0], mk_tree)
mk_root = mk_tree.get_root()
charlie_addr = keystore["Charlie"]
charlie_apk = charlie_addr.addr_pk.a_pk

# Create the an additional dummy input for the MixerClient
input2 = get_dummy_input_and_address(charlie_apk)
dummy_mk_path = mock.get_dummy_merkle_path(tree_depth)

note1_value = to_zeth_units(EtherValue(CHARLIE_WITHDRAW_CHANGE_ETH))
note1_value = EtherValue(CHARLIE_WITHDRAW_CHANGE_ETH)
v_out = EtherValue(CHARLIE_WITHDRAW_ETH)

# ### ATTACK BLOCK
Expand Down Expand Up @@ -216,18 +252,17 @@ def compute_h_sig_attack_nf(
return compute_h_sig(
bytes.fromhex(attack_nf0), bytes.fromhex(attack_nf1), sign_vk)

(output_note1, output_note2, proof, signing_keypair) = \
zeth_client.get_proof_joinsplit_2_by_2(
mk_root,
input1,
mk_path1,
input2,
dummy_mk_path,
charlie_ask, # sender
(charlie_apk, note1_value), # recipient1
(charlie_apk, 0), # recipient2
to_zeth_units(EtherValue(0)), # v_in
to_zeth_units(v_out), # v_out
output_note1, output_note2, proof, signing_keypair = \
get_mix_parameters_components(
zeth_client,
zksnark,
mk_tree,
keystore["Charlie"].ownership_keypair(), # sender
[input1, input2],
[(charlie_addr.addr_pk, note1_value),
(charlie_addr.addr_pk, EtherValue(0))],
EtherValue(0),
v_out,
compute_h_sig_attack_nf)

# Update the primary inputs to the modified nullifiers, since libsnark
Expand All @@ -252,8 +287,10 @@ def compute_h_sig_attack_nf(
(output_note2, pk_charlie)])

# Compute the joinSplit signature
pp = prover_client.get_configuration().pairing_parameters
joinsplit_sig_charlie = joinsplit_sign(
zksnark,
pp,
signing_keypair,
charlie_eth_address,
ciphertexts,
Expand Down Expand Up @@ -307,36 +344,34 @@ def charlie_corrupt_bob_deposit(
f"=== Bob deposits {BOB_DEPOSIT_ETH} ETH for himself and split into " +
f"note1: {BOB_SPLIT_1_ETH}ETH, note2: {BOB_SPLIT_2_ETH}ETH " +
"but Charlie attempts to corrupt the transaction ===")
bob_apk = keystore["Bob"].addr_pk.a_pk
bob_ask = keystore["Bob"].addr_sk.a_sk
tree_depth = mk_tree.depth
mk_root = mk_tree.get_root()
# mk_tree_depth = zeth_client.mk_tree_depth
# mk_root = zeth_client.merkle_root
bob_addr_pk = keystore["Bob"]
bob_apk = bob_addr_pk.addr_pk.a_pk

# Get pairing parameters
prover_client = zeth_client._prover_client \
# pylint: disable=protected-access
pp = prover_client.get_configuration().pairing_parameters

# Create the JoinSplit dummy inputs for the deposit
input1 = get_dummy_input_and_address(bob_apk)
input2 = get_dummy_input_and_address(bob_apk)
dummy_mk_path = mock.get_dummy_merkle_path(tree_depth)

note1_value = to_zeth_units(EtherValue(BOB_SPLIT_1_ETH))
note2_value = to_zeth_units(EtherValue(BOB_SPLIT_2_ETH))

v_in = to_zeth_units(EtherValue(BOB_DEPOSIT_ETH))

(output_note1, output_note2, proof, joinsplit_keypair) = \
zeth_client.get_proof_joinsplit_2_by_2(
mk_root,
input1,
dummy_mk_path,
input2,
dummy_mk_path,
bob_ask, # sender
(bob_apk, note1_value), # recipient1
(bob_apk, note2_value), # recipient2
v_in, # v_in
to_zeth_units(EtherValue(0)) # v_out
)

note1_value = EtherValue(BOB_SPLIT_1_ETH)
note2_value = EtherValue(BOB_SPLIT_2_ETH)

v_in = EtherValue(BOB_DEPOSIT_ETH)

output_note1, output_note2, proof, joinsplit_keypair = \
get_mix_parameters_components(
zeth_client,
zksnark,
mk_tree,
keystore["Bob"].ownership_keypair(),
[input1, input2],
[(bob_addr_pk.addr_pk, note1_value),
(bob_addr_pk.addr_pk, note2_value)],
v_in,
EtherValue(0)) # v_out

# Encrypt the coins to bob
pk_bob = keystore["Bob"].addr_pk.k_pk
Expand All @@ -358,6 +393,7 @@ def charlie_corrupt_bob_deposit(
try:
joinsplit_sig_charlie = joinsplit_sign(
zksnark,
pp,
joinsplit_keypair,
charlie_eth_address,
ciphertexts,
Expand Down Expand Up @@ -397,6 +433,7 @@ def charlie_corrupt_bob_deposit(
try:
joinsplit_sig_charlie = joinsplit_sign(
zksnark,
pp,
new_joinsplit_keypair,
charlie_eth_address,
[fake_ciphertext0, fake_ciphertext1],
Expand Down Expand Up @@ -427,6 +464,7 @@ def charlie_corrupt_bob_deposit(
try:
joinsplit_sig_bob = joinsplit_sign(
zksnark,
pp,
joinsplit_keypair,
bob_eth_address,
ciphertexts,
Expand Down Expand Up @@ -456,6 +494,7 @@ def charlie_corrupt_bob_deposit(
# Bob transaction is finally mined
joinsplit_sig_bob = joinsplit_sign(
zksnark,
pp,
joinsplit_keypair,
bob_eth_address,
ciphertexts,
Expand Down
4 changes: 3 additions & 1 deletion client/test_commands/test_contract_base_mixer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from zeth.core.constants import \
JS_INPUTS, JS_OUTPUTS, PUBLIC_VALUE_LENGTH, ZETH_PUBLIC_UNIT_VALUE
from zeth.core.prover_client import ProverClient
from zeth.core.mixer_client import MixerClient
from typing import Any
import test_commands.mock as mock
Expand Down Expand Up @@ -127,8 +128,9 @@ def main() -> None:
# Ethereum addresses
deployer_eth_address = eth.accounts[0]

prover_client = ProverClient(mock.TEST_PROVER_SERVER_ENDPOINT)
zeth_client, _ = MixerClient.deploy(
web3, mock.TEST_PROVER_SERVER_ENDPOINT, deployer_eth_address, None)
web3, prover_client, deployer_eth_address, None)

mixer_instance = zeth_client.mixer_instance

Expand Down
14 changes: 9 additions & 5 deletions client/test_commands/test_erc_token_mixing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import zeth.core.merkle_tree
import zeth.core.utils
import zeth.core.constants as constants
from zeth.core.prover_client import ProverClient
from zeth.core.zeth_address import ZethAddressPriv
from zeth.core.contracts import MixOutputEvents
from zeth.core.mixer_client import MixerClient
Expand Down Expand Up @@ -54,8 +55,8 @@ def allowance(

def main() -> None:

zksnark = zeth.core.zksnark.get_zksnark_provider(
zeth.core.utils.parse_zksnark_arg())
zksnark_name = zeth.core.utils.parse_zksnark_arg()
zksnark = zeth.core.zksnark.get_zksnark_provider(zksnark_name)
web3, eth = mock.open_test_web3()

# Ethereum addresses
Expand All @@ -69,16 +70,19 @@ def main() -> None:
# Deploy the token contract
token_instance = deploy_token(web3, deployer_eth_address, None, 4000000)

# ProverClient
prover_client = ProverClient(mock.TEST_PROVER_SERVER_ENDPOINT)
assert prover_client.get_configuration().zksnark_name == zksnark_name

# Deploy Zeth contracts
tree_depth = constants.ZETH_MERKLE_TREE_DEPTH
zeth_client, _contract_desc = MixerClient.deploy(
web3,
mock.TEST_PROVER_SERVER_ENDPOINT,
prover_client,
deployer_eth_address,
None,
token_instance.address,
None,
zksnark)
None)
mk_tree = zeth.core.merkle_tree.MerkleTree.empty_with_depth(tree_depth)
mixer_instance = zeth_client.mixer_instance

Expand Down
14 changes: 9 additions & 5 deletions client/test_commands/test_ether_mixing.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import zeth.core.merkle_tree
import zeth.core.utils
import zeth.core.zksnark
from zeth.core.prover_client import ProverClient
from zeth.core.zeth_address import ZethAddressPriv
from zeth.core.contracts import MixOutputEvents
from zeth.core.mixer_client import MixerClient
Expand All @@ -31,8 +32,8 @@ def print_balances(


def main() -> None:
zksnark = zeth.core.zksnark.get_zksnark_provider(
zeth.core.utils.parse_zksnark_arg())
zksnark_name = zeth.core.utils.parse_zksnark_arg()
zksnark = zeth.core.zksnark.get_zksnark_provider(zksnark_name)

web3, eth = mock.open_test_web3()

Expand All @@ -44,16 +45,19 @@ def main() -> None:
alice_eth_address = eth.accounts[2]
charlie_eth_address = eth.accounts[3]

# ProverClient
prover_client = ProverClient(mock.TEST_PROVER_SERVER_ENDPOINT)
assert prover_client.get_configuration().zksnark_name == zksnark_name

# Deploy Zeth contracts
tree_depth = zeth.core.constants.ZETH_MERKLE_TREE_DEPTH
zeth_client, _contract_desc = MixerClient.deploy(
web3,
mock.TEST_PROVER_SERVER_ENDPOINT,
prover_client,
deployer_eth_address,
None,
None,
None,
zksnark)
None)

# Set up Merkle tree and Wallets. Note that each wallet holds an internal
# Merkle Tree, unused in this test. Instead, we keep an in-memory version
Expand Down
2 changes: 1 addition & 1 deletion client/tests/test_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_mix_parameters(self) -> None:
ext_proof = ExtendedProof(
proof=Groth16.proof_from_json_dict({
"a": ["1234", "2345"],
"minus_b": [["3456", "4567"], ["5678", "6789"]],
"b": [["3456", "4567"], ["5678", "6789"]],
"c": ["789a", "89ab"],
}),
inputs=[
Expand Down
Loading
0