5
663800000
879000000
{"functions": ["privacy_transfer", "privacy_update", "privacy_init", "privacy_withdraw", "privacy_deposit"], "snippet": "# Paillier helpers + privacy transfer flow (ZIP23)\n\ndef _egcd(a, b):\n x0, y0 = 1, 0\n x1, y1 = 0, 1\n while b != 0:\n q = a // b\n a, b = b, a % b\n x0, x1 = x1, x0 - q * x1\n y0, y1 = y1, y0 - q * y1\n return a, x0, y0\n\ndef _modinv(a, n):\n g, x, _ = _egcd(a, n)\n assert g == 1\n return x % n\n\ndef _homomorphic_add(pub, c1, c2):\n n = pub\n n2 = n * n\n return (c1 * c2) % n2\n\ndef _homomorphic_sub(pub, c1, c2):\n n = pub\n n2 = n * n\n inv = _modinv(c2, n2)\n return (c1 * inv) % n2\n\n\n# Elliptic Curve parameters for secp256k1\nP = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\nA = 0\nB = 7\nGx = 55066263022277343669578718895168534326250603453777594175500187360389116729240\nGy = 32670510020758816978083085130507043184471273380659243275938904335757337482424\nG = (Gx, Gy)\nN = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\n\ndef _inverse_mod(k, p):\n if k == 0:\n raise\n return pow(k, p - 2, p)\n\ndef _is_on_curve(point):\n if point is None:\n return True\n x, y = point\n return (y * y - (x * x * x + A * x + B)) % P == 0\n\ndef _point_add(point1, point2):\n if point1 is None:\n return point2\n if point2 is None:\n return point1\n x1, y1 = point1\n x2, y2 = point2\n if x1 == x2 and y1 != y2:\n return None\n if x1 == x2:\n m = (3 * x1 * x1 + A) * _inverse_mod(2 * y1, P)\n else:\n m = (y2 - y1) * _inverse_mod(x2 - x1, P)\n m %= P\n x3 = (m * m - x1 - x2) % P\n y3 = (m * (x1 - x3) - y1) % P\n return (x3, y3)\n\ndef _scalar_mult(k, point):\n result = None\n addend = point\n while k:\n if k & 1:\n result = _point_add(result, addend)\n addend = _point_add(addend, addend)\n k >>= 1\n return result\n\ndef _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n assert public_key_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n if not (1 <= r < N and 1 <= s < N):\n return False\n point = (int(public_key_hex[2:66], 16), int(public_key_hex[66:], 16))\n e = int(msg_hash_hex[2:], 16)\n w = _inverse_mod(s, N)\n u1 = (e * w) % N\n u2 = (r * w) % N\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n if q is None:\n return False\n x, y = q\n return r == x % N\n\ndef _ecdsa_recover(msg_hash_hex, signature_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n z = int(msg_hash_hex[2:], 16)\n\n if len(signature_hex[2:]) == 130:\n v = int(signature_hex[130:], 16)\n if v >= 27:\n recovery_id = v - 27\n else:\n recovery_id = v\n recovery_ids = [recovery_id]\n else:\n recovery_ids = [0, 1]\n\n for recovery_id in recovery_ids:\n for j in range(2):\n x = r + j * N\n if x >= P:\n continue\n\n y_squared = (pow(x, 3, P) + A * x + B) % P\n y = pow(y_squared, (P + 1) // 4, P)\n\n if y % 2 != recovery_id:\n y = P - y\n\n point = (x, y)\n if not _is_on_curve(point):\n continue\n\n r_inv = _inverse_mod(r, N)\n u1 = (-z * r_inv) % N\n u2 = (s * r_inv) % N\n\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n\n if q is None:\n continue\n\n public_key_hex = f\"0x{q[0]:064x}{q[1]:064x}\"\n if _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n return public_key_hex\n\n return None\n\ndef _pubkey_to_address(public_key_hex):\n public_key_bytes = bytes.fromhex(public_key_hex[2:])\n address_bytes = keccak(public_key_bytes)[-20:]\n return '0x' + address_bytes.hex()\n\ndef _message_hash(payload):\n payload_hash = keccak(text=payload)\n prefix = b\"\\x19Ethereum Signed Message:\\n32\"\n return keccak(prefix + payload_hash)\n\ndef _addr_recover(msg, signature_hex):\n if not signature_hex.startswith('0x'):\n signature_hex = '0x' + signature_hex\n msg_hash = _message_hash(msg)\n msg_hash_hex = msg_hash.hex()\n if not msg_hash_hex.startswith('0x'):\n msg_hash_hex = '0x' + msg_hash_hex\n public_key_hex = _ecdsa_recover(msg_hash_hex, signature_hex)\n if not public_key_hex:\n return False\n recovered = _pubkey_to_address(public_key_hex)\n return recovered.lower()\n\ndef _resolve_account(addr):\n addr = addr.lower()\n assert len(addr) <= 42\n if len(addr) == 42:\n assert addr.startswith('0x')\n assert set(addr[2:]) <= set(string.digits + 'abcdef')\n else:\n assert len(addr) > 4\n\n if len(addr) == 42:\n return handle_lookup(addr)\n return addr\n\ndef _check_tick(tick):\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase + string.digits + '_')\n\n\ndef _get_pubkey(privacy_tick):\n pub, _ = get(privacy_tick, 'privacy_pub', None)\n if pub is None:\n return None\n return int(pub)\n\n\ndef privacy_init(info, args):\n assert args['f'] == 'privacy_init'\n\n tick = args['a'][0]\n _check_tick(tick)\n privacy_tick = args['a'][1]\n _check_tick(privacy_tick)\n provider_addr = args['a'][2]\n paillier_pub = int(args['a'][3])\n\n sender = info['sender']\n\n existing_provider, _ = get(privacy_tick, 'privacy_provider', None)\n assert existing_provider is None, \"Provider already initialized\"\n\n put(provider_addr, privacy_tick, 'tick', tick)\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr)\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n\n\ndef privacy_update(info, args):\n assert args['f'] == 'privacy_update'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n owner, _ = get('asset', 'owner', None, privacy_tick)\n assert owner.lower() == info['sender'].lower(), f\"Only owner can update {privacy_tick}\"\n\n provider_addr = args['a'][1]\n assert provider_addr.startswith('0x') and len(provider_addr) == 42\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr.lower())\n\n paillier_pub = int(args['a'][3])\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n event('PrivacyUpdate', [privacy_tick, provider_addr])\n\n\ndef privacy_deposit(info, args):\n assert args['f'] == 'privacy_deposit'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n functions, _ = get('asset', 'functions', [], tick)\n assert args['f'] in functions\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n sender = info['sender']\n addr = handle_lookup(sender)\n\n amount = int(args['a'][1])\n assert amount >= 0\n\n amount_cipher = int(args['a'][2])\n assert amount_cipher >= 0\n\n nonce = int(args['a'][3])\n assert nonce >= 0\n\n signature_hex = args['a'][4]\n assert signature_hex.startswith('0x')\n\n stored_nonce, _ = get(privacy_tick,'privacy_nonce', 0, sender)\n assert nonce == stored_nonce + 1\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n msg_to_sign = f'{privacy_tick},privacy_deposit,{str(amount)},{str(amount_cipher)},{str(nonce)}'\n\n recovered_addr = _addr_recover(msg_to_sign, signature_hex)\n assert provider_addr.lower() == recovered_addr, \"Invalid signature\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n put(provider_addr, privacy_tick, 'total_supply', int(total_supply) + amount)\n\n balance, _ = get(tick, 'balance', 0, f'{sender}')\n assert balance >= amount\n balance_updated = balance - amount\n put(addr, tick, 'balance', balance_updated, addr)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) + amount, privacy_tick)\n\n balance_cipher, _ = get(privacy_tick, 'privacy_balance', 1, addr)\n balance_cipher_updated = _homomorphic_add(pub, int(balance_cipher), amount_cipher)\n put(sender, privacy_tick, 'privacy_balance', balance_cipher_updated, sender)\n event('PrivacyDeposit', [privacy_tick, addr, amount, amount_cipher, nonce])\n\n\ndef privacy_withdraw(info, args):\n assert args['f'] == 'privacy_withdraw'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n amount = int(args['a'][1])\n assert amount > 0\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n old_balance_cipher = int(args['a'][3])\n assert old_balance_cipher > 0\n nonce = int(args['a'][4]) \n signature = args['a'][5]\n\n sender = info['sender'].lower()\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n\n stored_nonce, _ = get(privacy_tick,'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n msg = f\"{privacy_tick},privacy_withdraw,{sender},{nonce},{amount},{amount_cipher},{old_balance_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid signature\"\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n stored_balance, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n assert int(stored_balance) == old_balance_cipher, \"State mismatch\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n new_total = int(total_supply) - amount\n assert new_total >= 0, \"Insufficent total supply\"\n\n new_balance_cipher = _homomorphic_sub(pub, int(stored_balance), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_balance_cipher, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(provider_addr, privacy_tick, 'total_supply', new_total)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) - amount, privacy_tick)\n\n user_balance, _ = get(tick, 'balance', 0, sender)\n put(sender, tick, 'balance', int(user_balance) + amount, sender)\n\n event('PrivacyWithdraw', [sender, amount, new_balance_cipher, nonce])\n\n\ndef privacy_transfer(info,args):\n assert args['f'] == 'privacy_transfer'\n privacy_tick= args['a'][0]\n _check_tick(privacy_tick)\n\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n to_addr = args['a'][1].lower()\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n\n nonce = int(args['a'][3])\n assert nonce > 0\n signature = args['a'][4]\n assert signature.startswith('0x')\n\n sender = info['sender'].lower() \n assert sender != to_addr, \"Self-transfer not allowed\"\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n msg = f\"{privacy_tick},privacy_transfer,{sender},{to_addr},{nonce},{amount_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid provider signature\"\n\n current_sender_bal, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n current_receiver_bal, _ = get(privacy_tick, 'privacy_balance', 1, to_addr)\n\n stored_nonce, _ = get(privacy_tick, 'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n new_sender_bal = _homomorphic_sub(pub, int(current_sender_bal), amount_cipher)\n new_receiver_bal = _homomorphic_add(pub, int(current_receiver_bal), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_sender_bal, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(to_addr, privacy_tick, 'privacy_balance', new_receiver_bal, to_addr)\n\n event('PrivacyTransfer', [sender, to_addr, amount_cipher, nonce])\n\n"}
{"votes": [], "snippets": ["c1258f735d7d3928490e6008dcaebdd308a55ac77dab1818d6a480cf3c6d360e"], "functions": ["privacy_init", "privacy_update", "privacy_deposit", "privacy_transfer", "privacy_withdraw"]}
{"functions": ["privacy_transfer", "privacy_update", "privacy_init", "privacy_withdraw", "privacy_deposit"], "snippet": "# Paillier helpers + privacy transfer flow (ZIP23)\n\ndef _egcd(a, b):\n x0, y0 = 1, 0\n x1, y1 = 0, 1\n while b != 0:\n q = a // b\n a, b = b, a % b\n x0, x1 = x1, x0 - q * x1\n y0, y1 = y1, y0 - q * y1\n return a, x0, y0\n\ndef _modinv(a, n):\n g, x, _ = _egcd(a, n)\n assert g == 1\n return x % n\n\ndef _homomorphic_add(pub, c1, c2):\n n = pub\n n2 = n * n\n return (c1 * c2) % n2\n\ndef _homomorphic_sub(pub, c1, c2):\n n = pub\n n2 = n * n\n inv = _modinv(c2, n2)\n return (c1 * inv) % n2\n\n\n# Elliptic Curve parameters for secp256k1\nP = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\nA = 0\nB = 7\nGx = 55066263022277343669578718895168534326250603453777594175500187360389116729240\nGy = 32670510020758816978083085130507043184471273380659243275938904335757337482424\nG = (Gx, Gy)\nN = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\n\ndef _inverse_mod(k, p):\n if k == 0:\n raise\n return pow(k, p - 2, p)\n\ndef _is_on_curve(point):\n if point is None:\n return True\n x, y = point\n return (y * y - (x * x * x + A * x + B)) % P == 0\n\ndef _point_add(point1, point2):\n if point1 is None:\n return point2\n if point2 is None:\n return point1\n x1, y1 = point1\n x2, y2 = point2\n if x1 == x2 and y1 != y2:\n return None\n if x1 == x2:\n m = (3 * x1 * x1 + A) * _inverse_mod(2 * y1, P)\n else:\n m = (y2 - y1) * _inverse_mod(x2 - x1, P)\n m %= P\n x3 = (m * m - x1 - x2) % P\n y3 = (m * (x1 - x3) - y1) % P\n return (x3, y3)\n\ndef _scalar_mult(k, point):\n result = None\n addend = point\n while k:\n if k & 1:\n result = _point_add(result, addend)\n addend = _point_add(addend, addend)\n k >>= 1\n return result\n\ndef _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n assert public_key_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n if not (1 <= r < N and 1 <= s < N):\n return False\n point = (int(public_key_hex[2:66], 16), int(public_key_hex[66:], 16))\n e = int(msg_hash_hex[2:], 16)\n w = _inverse_mod(s, N)\n u1 = (e * w) % N\n u2 = (r * w) % N\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n if q is None:\n return False\n x, y = q\n return r == x % N\n\ndef _ecdsa_recover(msg_hash_hex, signature_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n z = int(msg_hash_hex[2:], 16)\n\n if len(signature_hex[2:]) == 130:\n v = int(signature_hex[130:], 16)\n if v >= 27:\n recovery_id = v - 27\n else:\n recovery_id = v\n recovery_ids = [recovery_id]\n else:\n recovery_ids = [0, 1]\n\n for recovery_id in recovery_ids:\n for j in range(2):\n x = r + j * N\n if x >= P:\n continue\n\n y_squared = (pow(x, 3, P) + A * x + B) % P\n y = pow(y_squared, (P + 1) // 4, P)\n\n if y % 2 != recovery_id:\n y = P - y\n\n point = (x, y)\n if not _is_on_curve(point):\n continue\n\n r_inv = _inverse_mod(r, N)\n u1 = (-z * r_inv) % N\n u2 = (s * r_inv) % N\n\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n\n if q is None:\n continue\n\n public_key_hex = f\"0x{q[0]:064x}{q[1]:064x}\"\n if _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n return public_key_hex\n\n return None\n\ndef _pubkey_to_address(public_key_hex):\n public_key_bytes = bytes.fromhex(public_key_hex[2:])\n address_bytes = keccak(public_key_bytes)[-20:]\n return '0x' + address_bytes.hex()\n\ndef _message_hash(payload):\n payload_hash = keccak(text=payload)\n prefix = b\"\\x19Ethereum Signed Message:\\n32\"\n return keccak(prefix + payload_hash)\n\ndef _addr_recover(msg, signature_hex):\n if not signature_hex.startswith('0x'):\n signature_hex = '0x' + signature_hex\n msg_hash = _message_hash(msg)\n msg_hash_hex = msg_hash.hex()\n if not msg_hash_hex.startswith('0x'):\n msg_hash_hex = '0x' + msg_hash_hex\n public_key_hex = _ecdsa_recover(msg_hash_hex, signature_hex)\n if not public_key_hex:\n return False\n recovered = _pubkey_to_address(public_key_hex)\n return recovered.lower()\n\ndef _resolve_account(addr):\n addr = addr.lower()\n assert len(addr) <= 42\n if len(addr) == 42:\n assert addr.startswith('0x')\n assert set(addr[2:]) <= set(string.digits + 'abcdef')\n else:\n assert len(addr) > 4\n\n if len(addr) == 42:\n return handle_lookup(addr)\n return addr\n\ndef _check_tick(tick):\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase + string.digits + '_')\n\n\ndef _get_pubkey(privacy_tick):\n pub, _ = get(privacy_tick, 'privacy_pub', None)\n if pub is None:\n return None\n return int(pub)\n\n\ndef privacy_init(info, args):\n assert args['f'] == 'privacy_init'\n\n tick = args['a'][0]\n _check_tick(tick)\n privacy_tick = args['a'][1]\n _check_tick(privacy_tick)\n provider_addr = args['a'][2]\n paillier_pub = int(args['a'][3])\n\n sender = info['sender']\n\n existing_provider, _ = get(privacy_tick, 'privacy_provider', None)\n assert existing_provider is None, \"Provider already initialized\"\n\n put(provider_addr, privacy_tick, 'tick', tick)\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr)\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n\n\ndef privacy_update(info, args):\n assert args['f'] == 'privacy_update'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n owner, _ = get('asset', 'owner', None, privacy_tick)\n assert owner.lower() == info['sender'].lower(), f\"Only owner can update {privacy_tick}\"\n\n provider_addr = args['a'][1]\n assert provider_addr.startswith('0x') and len(provider_addr) == 42\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr.lower())\n\n paillier_pub = int(args['a'][2])\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n event('PrivacyUpdate', [privacy_tick, provider_addr])\n\n\ndef privacy_deposit(info, args):\n assert args['f'] == 'privacy_deposit'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n functions, _ = get('asset', 'functions', [], tick)\n assert args['f'] in functions\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n sender = info['sender']\n addr = handle_lookup(sender)\n\n amount = int(args['a'][1])\n assert amount >= 0\n\n amount_cipher = int(args['a'][2])\n assert amount_cipher >= 0\n\n nonce = int(args['a'][3])\n assert nonce >= 0\n\n signature_hex = args['a'][4]\n assert signature_hex.startswith('0x')\n\n stored_nonce, _ = get(privacy_tick,'privacy_nonce', 0, sender)\n assert nonce == stored_nonce + 1\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n msg_to_sign = f'{privacy_tick},privacy_deposit,{str(amount)},{str(amount_cipher)},{str(nonce)}'\n\n recovered_addr = _addr_recover(msg_to_sign, signature_hex)\n assert provider_addr.lower() == recovered_addr, \"Invalid signature\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n put(provider_addr, privacy_tick, 'total_supply', int(total_supply) + amount)\n\n balance, _ = get(tick, 'balance', 0, f'{sender}')\n assert balance >= amount\n balance_updated = balance - amount\n put(addr, tick, 'balance', balance_updated, addr)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) + amount, privacy_tick)\n\n balance_cipher, _ = get(privacy_tick, 'privacy_balance', 1, addr)\n balance_cipher_updated = _homomorphic_add(pub, int(balance_cipher), amount_cipher)\n put(sender, privacy_tick, 'privacy_balance', balance_cipher_updated, sender)\n event('PrivacyDeposit', [privacy_tick, addr, amount, amount_cipher, nonce])\n\n\ndef privacy_withdraw(info, args):\n assert args['f'] == 'privacy_withdraw'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n amount = int(args['a'][1])\n assert amount > 0\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n old_balance_cipher = int(args['a'][3])\n assert old_balance_cipher > 0\n nonce = int(args['a'][4]) \n signature = args['a'][5]\n\n sender = info['sender'].lower()\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n\n stored_nonce, _ = get(privacy_tick,'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n msg = f\"{privacy_tick},privacy_withdraw,{sender},{nonce},{amount},{amount_cipher},{old_balance_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid signature\"\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n stored_balance, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n assert int(stored_balance) == old_balance_cipher, \"State mismatch\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n new_total = int(total_supply) - amount\n assert new_total >= 0, \"Insufficent total supply\"\n\n new_balance_cipher = _homomorphic_sub(pub, int(stored_balance), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_balance_cipher, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(provider_addr, privacy_tick, 'total_supply', new_total)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) - amount, privacy_tick)\n\n user_balance, _ = get(tick, 'balance', 0, sender)\n put(sender, tick, 'balance', int(user_balance) + amount, sender)\n\n event('PrivacyWithdraw', [sender, amount, new_balance_cipher, nonce])\n\n\ndef privacy_transfer(info,args):\n assert args['f'] == 'privacy_transfer'\n privacy_tick= args['a'][0]\n _check_tick(privacy_tick)\n\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n to_addr = args['a'][1].lower()\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n\n nonce = int(args['a'][3])\n assert nonce > 0\n signature = args['a'][4]\n assert signature.startswith('0x')\n\n sender = info['sender'].lower() \n assert sender != to_addr, \"Self-transfer not allowed\"\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n msg = f\"{privacy_tick},privacy_transfer,{sender},{to_addr},{nonce},{amount_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid provider signature\"\n\n current_sender_bal, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n current_receiver_bal, _ = get(privacy_tick, 'privacy_balance', 1, to_addr)\n\n stored_nonce, _ = get(privacy_tick, 'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n new_sender_bal = _homomorphic_sub(pub, int(current_sender_bal), amount_cipher)\n new_receiver_bal = _homomorphic_add(pub, int(current_receiver_bal), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_sender_bal, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(to_addr, privacy_tick, 'privacy_balance', new_receiver_bal, to_addr)\n\n event('PrivacyTransfer', [sender, to_addr, amount_cipher, nonce])\n\n"}
{"votes": [], "snippets": ["87d011c775bee494ce3352db264d3c99bbef8dd4c51344d5e3055c15821bedda"], "functions": ["privacy_init", "privacy_update", "privacy_deposit", "privacy_transfer", "privacy_withdraw"]}
3554729946816065451449909223834710818395202868864361440328846739117822991878280366995582758429124526886866753516236579328571744061035999882198319000190949448728869764779889358585489833855490868303850840385478003375155524272836405785260043676557263439964433831537779483850775878905878562157090395545418472411352190760456835358046704722168407513955716938839893051102170009887890018177014704337658393586726265283277763975500989180765999290779953976669655232349215083920654072418153997169230529668456984237632884062996529173850110819031518537626514513530912334599263745618461904579592695055315506525980078510494854008334
10
{"functions": ["privacy_transfer", "privacy_update", "privacy_init", "privacy_withdraw", "privacy_deposit"], "snippet": "# Paillier helpers + privacy transfer flow (ZIP23)\n\ndef _egcd(a, b):\n x0, y0 = 1, 0\n x1, y1 = 0, 1\n while b != 0:\n q = a // b\n a, b = b, a % b\n x0, x1 = x1, x0 - q * x1\n y0, y1 = y1, y0 - q * y1\n return a, x0, y0\n\ndef _modinv(a, n):\n g, x, _ = _egcd(a, n)\n assert g == 1\n return x % n\n\ndef _homomorphic_add(pub, c1, c2):\n n = pub\n n2 = n * n\n return (c1 * c2) % n2\n\ndef _homomorphic_sub(pub, c1, c2):\n n = pub\n n2 = n * n\n inv = _modinv(c2, n2)\n return (c1 * inv) % n2\n\n\n# Elliptic Curve parameters for secp256k1\nP = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\nA = 0\nB = 7\nGx = 55066263022277343669578718895168534326250603453777594175500187360389116729240\nGy = 32670510020758816978083085130507043184471273380659243275938904335757337482424\nG = (Gx, Gy)\nN = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\n\ndef _inverse_mod(k, p):\n if k == 0:\n raise\n return pow(k, p - 2, p)\n\ndef _is_on_curve(point):\n if point is None:\n return True\n x, y = point\n return (y * y - (x * x * x + A * x + B)) % P == 0\n\ndef _point_add(point1, point2):\n if point1 is None:\n return point2\n if point2 is None:\n return point1\n x1, y1 = point1\n x2, y2 = point2\n if x1 == x2 and y1 != y2:\n return None\n if x1 == x2:\n m = (3 * x1 * x1 + A) * _inverse_mod(2 * y1, P)\n else:\n m = (y2 - y1) * _inverse_mod(x2 - x1, P)\n m %= P\n x3 = (m * m - x1 - x2) % P\n y3 = (m * (x1 - x3) - y1) % P\n return (x3, y3)\n\ndef _scalar_mult(k, point):\n result = None\n addend = point\n while k:\n if k & 1:\n result = _point_add(result, addend)\n addend = _point_add(addend, addend)\n k >>= 1\n return result\n\ndef _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n assert public_key_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n if not (1 <= r < N and 1 <= s < N):\n return False\n point = (int(public_key_hex[2:66], 16), int(public_key_hex[66:], 16))\n e = int(msg_hash_hex[2:], 16)\n w = _inverse_mod(s, N)\n u1 = (e * w) % N\n u2 = (r * w) % N\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n if q is None:\n return False\n x, y = q\n return r == x % N\n\ndef _ecdsa_recover(msg_hash_hex, signature_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n z = int(msg_hash_hex[2:], 16)\n\n if len(signature_hex[2:]) == 130:\n v = int(signature_hex[130:], 16)\n if v >= 27:\n recovery_id = v - 27\n else:\n recovery_id = v\n recovery_ids = [recovery_id]\n else:\n recovery_ids = [0, 1]\n\n for recovery_id in recovery_ids:\n for j in range(2):\n x = r + j * N\n if x >= P:\n continue\n\n y_squared = (pow(x, 3, P) + A * x + B) % P\n y = pow(y_squared, (P + 1) // 4, P)\n\n if y % 2 != recovery_id:\n y = P - y\n\n point = (x, y)\n if not _is_on_curve(point):\n continue\n\n r_inv = _inverse_mod(r, N)\n u1 = (-z * r_inv) % N\n u2 = (s * r_inv) % N\n\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n\n if q is None:\n continue\n\n public_key_hex = f\"0x{q[0]:064x}{q[1]:064x}\"\n if _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n return public_key_hex\n\n return None\n\ndef _pubkey_to_address(public_key_hex):\n public_key_bytes = bytes.fromhex(public_key_hex[2:])\n address_bytes = keccak(public_key_bytes)[-20:]\n return '0x' + address_bytes.hex()\n\ndef _message_hash(payload):\n payload_hash = keccak(text=payload)\n prefix = b\"\\x19Ethereum Signed Message:\\n32\"\n return keccak(prefix + payload_hash)\n\ndef _addr_recover(msg, signature_hex):\n if not signature_hex.startswith('0x'):\n signature_hex = '0x' + signature_hex\n msg_hash = _message_hash(msg)\n msg_hash_hex = msg_hash.hex()\n if not msg_hash_hex.startswith('0x'):\n msg_hash_hex = '0x' + msg_hash_hex\n public_key_hex = _ecdsa_recover(msg_hash_hex, signature_hex)\n if not public_key_hex:\n return False\n recovered = _pubkey_to_address(public_key_hex)\n return recovered.lower()\n\ndef _resolve_account(addr):\n addr = addr.lower()\n assert len(addr) <= 42\n if len(addr) == 42:\n assert addr.startswith('0x')\n assert set(addr[2:]) <= set(string.digits + 'abcdef')\n else:\n assert len(addr) > 4\n\n if len(addr) == 42:\n return handle_lookup(addr)\n return addr\n\ndef _check_tick(tick):\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase + string.digits + '_')\n\n\ndef _get_pubkey(privacy_tick):\n pub, _ = get(privacy_tick, 'privacy_pub', None)\n if pub is None:\n return None\n return int(pub)\n\n\ndef privacy_init(info, args):\n assert args['f'] == 'privacy_init'\n\n tick = args['a'][0]\n _check_tick(tick)\n privacy_tick = args['a'][1]\n _check_tick(privacy_tick)\n provider_addr = args['a'][2]\n paillier_pub = int(args['a'][3])\n\n sender = info['sender']\n\n existing_provider, _ = get(privacy_tick, 'privacy_provider', None)\n assert existing_provider is None, \"Provider already initialized\"\n\n put(provider_addr, privacy_tick, 'tick', tick)\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr)\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n\n\ndef privacy_update(info, args):\n assert args['f'] == 'privacy_update'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n owner, _ = get('asset', 'owner', None, privacy_tick)\n assert owner.lower() == info['sender'].lower(), f\"Only owner can update {privacy_tick}\"\n\n provider_addr = args['a'][1]\n assert provider_addr.startswith('0x') and len(provider_addr) == 42\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr.lower())\n\n paillier_pub = int(args['a'][2])\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n event('PrivacyUpdate', [privacy_tick, provider_addr])\n\n\ndef privacy_deposit(info, args):\n assert args['f'] == 'privacy_deposit'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n functions, _ = get('asset', 'functions', [], tick)\n assert args['f'] in functions\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n sender = info['sender']\n addr = handle_lookup(sender)\n\n amount = int(args['a'][1])\n assert amount >= 0\n\n amount_cipher = int(args['a'][2])\n assert amount_cipher >= 0\n\n nonce = int(args['a'][3])\n assert nonce >= 0\n\n signature_hex = args['a'][4]\n assert signature_hex.startswith('0x')\n\n stored_nonce, _ = get(privacy_tick,'privacy_nonce', 0, sender)\n assert nonce == stored_nonce + 1\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n msg_to_sign = f'{privacy_tick},privacy_deposit,{sender},{nonce},{amount},{amount_cipher}'\n\n recovered_addr = _addr_recover(msg_to_sign, signature_hex)\n assert provider_addr.lower() == recovered_addr, \"Invalid signature\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n put(provider_addr, privacy_tick, 'total_supply', int(total_supply) + amount)\n\n balance, _ = get(tick, 'balance', 0, f'{sender}')\n assert balance >= amount\n balance_updated = balance - amount\n put(addr, tick, 'balance', balance_updated, addr)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) + amount, privacy_tick)\n\n balance_cipher, _ = get(privacy_tick, 'privacy_balance', 1, addr)\n balance_cipher_updated = _homomorphic_add(pub, int(balance_cipher), amount_cipher)\n put(sender, privacy_tick, 'privacy_balance', balance_cipher_updated, sender)\n event('PrivacyDeposit', [privacy_tick, addr, amount, amount_cipher, nonce])\n\n\ndef privacy_withdraw(info, args):\n assert args['f'] == 'privacy_withdraw'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n amount = int(args['a'][1])\n assert amount > 0\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n old_balance_cipher = int(args['a'][3])\n assert old_balance_cipher > 0\n nonce = int(args['a'][4]) \n signature = args['a'][5]\n\n sender = info['sender'].lower()\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n\n stored_nonce, _ = get(privacy_tick,'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n msg = f\"{privacy_tick},privacy_withdraw,{sender},{nonce},{amount},{amount_cipher},{old_balance_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid signature\"\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n stored_balance, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n assert int(stored_balance) == old_balance_cipher, \"State mismatch\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n new_total = int(total_supply) - amount\n assert new_total >= 0, \"Insufficent total supply\"\n\n new_balance_cipher = _homomorphic_sub(pub, int(stored_balance), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_balance_cipher, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(provider_addr, privacy_tick, 'total_supply', new_total)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) - amount, privacy_tick)\n\n user_balance, _ = get(tick, 'balance', 0, sender)\n put(sender, tick, 'balance', int(user_balance) + amount, sender)\n\n event('PrivacyWithdraw', [sender, amount, new_balance_cipher, nonce])\n\n\ndef privacy_transfer(info,args):\n assert args['f'] == 'privacy_transfer'\n privacy_tick= args['a'][0]\n _check_tick(privacy_tick)\n\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n to_addr = args['a'][1].lower()\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n\n nonce = int(args['a'][3])\n assert nonce > 0\n signature = args['a'][4]\n assert signature.startswith('0x')\n\n sender = info['sender'].lower() \n assert sender != to_addr, \"Self-transfer not allowed\"\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n msg = f\"{privacy_tick},privacy_transfer,{sender},{to_addr},{nonce},{amount_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid provider signature\"\n\n current_sender_bal, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n current_receiver_bal, _ = get(privacy_tick, 'privacy_balance', 1, to_addr)\n\n stored_nonce, _ = get(privacy_tick, 'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n new_sender_bal = _homomorphic_sub(pub, int(current_sender_bal), amount_cipher)\n new_receiver_bal = _homomorphic_add(pub, int(current_receiver_bal), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_sender_bal, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(to_addr, privacy_tick, 'privacy_balance', new_receiver_bal, to_addr)\n\n event('PrivacyTransfer', [sender, to_addr, amount_cipher, nonce])\n\n"}
{"votes": [], "snippets": ["a019cf76656b7d0f127f65846453fa43f9d911cfefafb464f71663b42c162256"], "functions": ["privacy_init", "privacy_update", "privacy_deposit", "privacy_transfer", "privacy_withdraw"]}
187540438059189178949956043233412598570314728414621668700939635697347010498285430105204330661386095439043853602852381374316556647309090766481566634593826581619596688275005624985435845317507203638619109340234051165824353560520970744013636777667604206094690614317967492967777771913176370424548770043915938146807021636851745860461041209239058362428380604405448000567760962786482465877211474103612370674553129046230797685197606994634512496763345557674597692658259779891087376577951448113806733879196449580338438366851021756681092032368836114327164976119965142011891631707699860542812678763524731450423016913550908540498
7
7302827671933097236547191099500253183267063520274643492425836419437905374839379682759529317367184188740601337816082689384369667309503100733440954632282786453653547260327294139613591188722989254063011848353564658056073504473384699016696484030796845304863218770282520076119837100310021841652296612855784282119460490866176789595017282332258317976401622096259514772774553574619808120810359763788462837901222975293717135642910479624480939373595158332070047938520239647973166309211591113409887923002088389784575576663312870709013650930550006085507633033770410531372582776485935627696129426954040768260399491379068033417531
908391980727662011068164246351664974012495171489202498379338629949654505074756116220790329416500473035385651481227323442478292373198590919848762744063381059729729644228791510556852281135708886225956350530228638147301415293037386292477372507972596753920948780767767384411412720495982628074236675972548844302854923185263832928690184972606600436885922038651187466203957787428573863231945038561756357322483986953676407779028661329785579839954787557408227191294551915442531250829244232724951152967106437277593314838456932425025431448871978147532363819425911081876241499746991766088874595176601974073816870132908146954048
7
8572848564658558359013525302541691589440897905436619663065157999599691397787841898763514331143369366679107992036472936541535531076823752805463103308726164579129893497981599738654585344357176897126888390672443290059973601968977726684100006149979159598580494331324937063493130301428041527253661583906851277942342243828703468312169961169121361637722536950316347972690337879124809354425002551439831100598034144272573521978858593919532664485937933009629112512773546918002376992441254006225034661335691258941339681449494684700255359919408728395497752441404538304910311625859430852490163631616433451030376745278876449300528
6573164788780546612778410034627960467517810535539084118377131833441994922742650761173460724015969804547582011685274061833971620640461948019293889008635754510154220602046845323886123228914870217745091289455312499800310477484502017129551929767599077499818966931223791386624835654455386900765006749618557483441197289146651256458717610836754186293517712339449562191718373516601057834737192420756341832458225093480882122632835489517974915934761200718556179591157442497865668687157312392630498262210263087445261982503166592849876074267773120630635744279506179500193254323988169162262802644694937266257076234536392102027567
7677363471448119172314777302874082700866756799270701610868495573209350867895642903600846048783283496777735322104178456380295165458702171922924609219692925043580118008512771933720857834522477701769140902962642710616160892419703326703383246168203058702279708863375128956635908188196231833089877359227266286627681562448874247216521370461689701425975619726376007163699889916216661051748076994203213054927559223990832495136744407946372158286623304223253280377222039099184679597141437088728846842740340368167491717812811711991068348001580266772865454108225853912651587958939769931483290744016765004322990604552012183650431
2
{"functions": ["privacy_transfer", "privacy_reset", "privacy_update", "privacy_init", "privacy_withdraw", "privacy_deposit"], "snippet": "# Paillier helpers + privacy transfer flow (ZIP23)\n\ndef _egcd(a, b):\n x0, y0 = 1, 0\n x1, y1 = 0, 1\n while b != 0:\n q = a // b\n a, b = b, a % b\n x0, x1 = x1, x0 - q * x1\n y0, y1 = y1, y0 - q * y1\n return a, x0, y0\n\ndef _modinv(a, n):\n g, x, _ = _egcd(a, n)\n assert g == 1\n return x % n\n\ndef _homomorphic_add(pub, c1, c2):\n n = pub\n n2 = n * n\n return (c1 * c2) % n2\n\ndef _homomorphic_sub(pub, c1, c2):\n n = pub\n n2 = n * n\n inv = _modinv(c2, n2)\n return (c1 * inv) % n2\n\n\n# Elliptic Curve parameters for secp256k1\nP = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\nA = 0\nB = 7\nGx = 55066263022277343669578718895168534326250603453777594175500187360389116729240\nGy = 32670510020758816978083085130507043184471273380659243275938904335757337482424\nG = (Gx, Gy)\nN = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\n\ndef _inverse_mod(k, p):\n if k == 0:\n raise\n return pow(k, p - 2, p)\n\ndef _is_on_curve(point):\n if point is None:\n return True\n x, y = point\n return (y * y - (x * x * x + A * x + B)) % P == 0\n\ndef _point_add(point1, point2):\n if point1 is None:\n return point2\n if point2 is None:\n return point1\n x1, y1 = point1\n x2, y2 = point2\n if x1 == x2 and y1 != y2:\n return None\n if x1 == x2:\n m = (3 * x1 * x1 + A) * _inverse_mod(2 * y1, P)\n else:\n m = (y2 - y1) * _inverse_mod(x2 - x1, P)\n m %= P\n x3 = (m * m - x1 - x2) % P\n y3 = (m * (x1 - x3) - y1) % P\n return (x3, y3)\n\ndef _scalar_mult(k, point):\n result = None\n addend = point\n while k:\n if k & 1:\n result = _point_add(result, addend)\n addend = _point_add(addend, addend)\n k >>= 1\n return result\n\ndef _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n assert public_key_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n if not (1 <= r < N and 1 <= s < N):\n return False\n point = (int(public_key_hex[2:66], 16), int(public_key_hex[66:], 16))\n e = int(msg_hash_hex[2:], 16)\n w = _inverse_mod(s, N)\n u1 = (e * w) % N\n u2 = (r * w) % N\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n if q is None:\n return False\n x, y = q\n return r == x % N\n\ndef _ecdsa_recover(msg_hash_hex, signature_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n z = int(msg_hash_hex[2:], 16)\n\n if len(signature_hex[2:]) == 130:\n v = int(signature_hex[130:], 16)\n if v >= 27:\n recovery_id = v - 27\n else:\n recovery_id = v\n recovery_ids = [recovery_id]\n else:\n recovery_ids = [0, 1]\n\n for recovery_id in recovery_ids:\n for j in range(2):\n x = r + j * N\n if x >= P:\n continue\n\n y_squared = (pow(x, 3, P) + A * x + B) % P\n y = pow(y_squared, (P + 1) // 4, P)\n\n if y % 2 != recovery_id:\n y = P - y\n\n point = (x, y)\n if not _is_on_curve(point):\n continue\n\n r_inv = _inverse_mod(r, N)\n u1 = (-z * r_inv) % N\n u2 = (s * r_inv) % N\n\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n\n if q is None:\n continue\n\n public_key_hex = f\"0x{q[0]:064x}{q[1]:064x}\"\n if _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n return public_key_hex\n\n return None\n\ndef _pubkey_to_address(public_key_hex):\n public_key_bytes = bytes.fromhex(public_key_hex[2:])\n address_bytes = keccak(public_key_bytes)[-20:]\n return '0x' + address_bytes.hex()\n\ndef _message_hash(payload):\n payload_hash = keccak(text=payload)\n prefix = b\"\\x19Ethereum Signed Message:\\n32\"\n return keccak(prefix + payload_hash)\n\ndef _addr_recover(msg, signature_hex):\n if not signature_hex.startswith('0x'):\n signature_hex = '0x' + signature_hex\n msg_hash = _message_hash(msg)\n msg_hash_hex = msg_hash.hex()\n if not msg_hash_hex.startswith('0x'):\n msg_hash_hex = '0x' + msg_hash_hex\n public_key_hex = _ecdsa_recover(msg_hash_hex, signature_hex)\n if not public_key_hex:\n return False\n recovered = _pubkey_to_address(public_key_hex)\n return recovered.lower()\n\ndef _resolve_account(addr):\n addr = addr.lower()\n assert len(addr) <= 42\n if len(addr) == 42:\n assert addr.startswith('0x')\n assert set(addr[2:]) <= set(string.digits + 'abcdef')\n else:\n assert len(addr) > 4\n\n if len(addr) == 42:\n return handle_lookup(addr)\n return addr\n\ndef _check_tick(tick):\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase + string.digits + '_')\n\n\ndef _get_pubkey(privacy_tick):\n pub, _ = get(privacy_tick, 'privacy_pub', None)\n if pub is None:\n return None\n return int(pub)\n\n\ndef privacy_init(info, args):\n assert args['f'] == 'privacy_init'\n\n tick = args['a'][0]\n _check_tick(tick)\n privacy_tick = args['a'][1]\n _check_tick(privacy_tick)\n provider_addr = args['a'][2]\n paillier_pub = int(args['a'][3])\n\n sender = info['sender']\n\n existing_provider, _ = get(privacy_tick, 'privacy_provider', None)\n assert existing_provider is None, \"Provider already initialized\"\n\n put(provider_addr, privacy_tick, 'tick', tick)\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr)\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n\n\ndef privacy_update(info, args):\n assert args['f'] == 'privacy_update'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n owner, _ = get('asset', 'owner', None, privacy_tick)\n assert owner.lower() == info['sender'].lower(), f\"Only owner can update {privacy_tick}\"\n\n provider_addr = args['a'][1]\n assert provider_addr.startswith('0x') and len(provider_addr) == 42\n put(provider_addr, privacy_tick, 'privacy_provider', provider_addr.lower())\n\n paillier_pub = int(args['a'][2])\n put(provider_addr, privacy_tick, 'privacy_pub', int(paillier_pub))\n event('PrivacyUpdate', [privacy_tick, provider_addr])\n\n\ndef privacy_deposit(info, args):\n assert args['f'] == 'privacy_deposit'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n functions, _ = get('asset', 'functions', [], tick)\n assert args['f'] in functions\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n sender = info['sender']\n addr = handle_lookup(sender)\n\n amount = int(args['a'][1])\n assert amount >= 0\n\n amount_cipher = int(args['a'][2])\n assert amount_cipher >= 0\n\n nonce = int(args['a'][3])\n assert nonce >= 0\n\n signature_hex = args['a'][4]\n assert signature_hex.startswith('0x')\n\n stored_nonce, _ = get(privacy_tick, 'privacy_nonce', 0, sender)\n assert nonce == stored_nonce + 1\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n msg_to_sign = f'{privacy_tick},privacy_deposit,{sender},{nonce},{amount},{amount_cipher}'\n\n recovered_addr = _addr_recover(msg_to_sign, signature_hex)\n assert provider_addr.lower() == recovered_addr, \"Invalid signature\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n put(provider_addr, privacy_tick, 'total_supply', int(total_supply) + amount)\n\n balance, _ = get(tick, 'balance', 0, f'{sender}')\n assert balance >= amount\n balance_updated = balance - amount\n put(addr, tick, 'balance', balance_updated, addr)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) + amount, privacy_tick)\n\n balance_cipher, _ = get(privacy_tick, 'privacy_balance', 1, addr)\n balance_cipher_updated = _homomorphic_add(pub, int(balance_cipher), amount_cipher)\n put(sender, privacy_tick, 'privacy_balance', balance_cipher_updated, sender)\n event('PrivacyDeposit', [privacy_tick, addr, amount, amount_cipher, nonce])\n\n\ndef privacy_withdraw(info, args):\n assert args['f'] == 'privacy_withdraw'\n\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n tick, _ = get(privacy_tick, 'tick', None)\n _check_tick(tick)\n\n amount = int(args['a'][1])\n assert amount > 0\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n old_balance_cipher = int(args['a'][3])\n assert old_balance_cipher > 0\n nonce = int(args['a'][4]) \n signature = args['a'][5]\n\n sender = info['sender']\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n\n stored_nonce, _ = get(privacy_tick,'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n msg = f\"{privacy_tick},privacy_withdraw,{sender},{nonce},{amount},{amount_cipher},{old_balance_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid signature\"\n\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n stored_balance, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n assert int(stored_balance) == old_balance_cipher, \"State mismatch\"\n\n total_supply, _ = get(privacy_tick, 'total_supply', 0)\n new_total = int(total_supply) - amount\n assert new_total >= 0, \"Insufficent total supply\"\n\n new_balance_cipher = _homomorphic_sub(pub, int(stored_balance), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_balance_cipher, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(provider_addr, privacy_tick, 'total_supply', new_total)\n\n pool_balance, _ = get(tick, 'balance', 0, privacy_tick)\n put(privacy_tick, tick, 'balance', int(pool_balance) - amount, privacy_tick)\n\n user_balance, _ = get(tick, 'balance', 0, sender)\n put(sender, tick, 'balance', int(user_balance) + amount, sender)\n\n event('PrivacyWithdraw', [sender, amount, new_balance_cipher, nonce])\n\n\ndef privacy_transfer(info,args):\n assert args['f'] == 'privacy_transfer'\n privacy_tick = args['a'][0]\n _check_tick(privacy_tick)\n\n functions, _ = get('asset', 'functions', [], privacy_tick)\n assert args['f'] in functions\n\n to_addr = args['a'][1].lower()\n amount_cipher = int(args['a'][2])\n assert amount_cipher > 0\n\n nonce = int(args['a'][3])\n assert nonce > 0\n signature = args['a'][4]\n assert signature.startswith('0x')\n\n sender = info['sender']\n assert sender != to_addr, \"Self-transfer not allowed\"\n\n provider_addr, _ = get(privacy_tick, 'privacy_provider', None)\n assert provider_addr is not None, \"Provider not initialized\"\n pub = _get_pubkey(privacy_tick)\n assert pub is not None\n\n msg = f\"{privacy_tick},privacy_transfer,{sender},{to_addr},{nonce},{amount_cipher}\"\n recovered_addr = _addr_recover(msg, signature)\n assert recovered_addr == provider_addr.lower(), \"Invalid provider signature\"\n\n current_sender_bal, _ = get(privacy_tick, 'privacy_balance', 1, sender)\n current_receiver_bal, _ = get(privacy_tick, 'privacy_balance', 1, to_addr)\n\n stored_nonce, _ = get(privacy_tick, 'privacy_nonce', 0, sender)\n assert nonce == int(stored_nonce) + 1, \"Invalid nonce\"\n\n new_sender_bal = _homomorphic_sub(pub, int(current_sender_bal), amount_cipher)\n new_receiver_bal = _homomorphic_add(pub, int(current_receiver_bal), amount_cipher)\n\n put(sender, privacy_tick, 'privacy_balance', new_sender_bal, sender)\n put(sender, privacy_tick, 'privacy_nonce', nonce, sender)\n put(to_addr, privacy_tick, 'privacy_balance', new_receiver_bal, to_addr)\n\n event('PrivacyTransfer', [sender, to_addr, amount_cipher, nonce])\n\n"}
{"functions": ["privacy_transfer", "privacy_reset", "privacy_update", "privacy_init", "privacy_withdraw", "privacy_deposit"], "snippet": "\ndef privacy_reset(info, args):\n assert args['f'] == 'privacy_reset'\n sender = info['sender']\n put(sender, 'PUSDC', 'privacy_balance', 1, sender)\n event('PrivacyReset', [sender])\n\n"}
{"votes": [], "snippets": ["2e3f7fcf48f9c178aa5520c60d147ef15c69272048a10138f6fee7db4741981b", "b6335de3a510c47060240296fc5f433024a727ebb2e63fb5c7c8f5ee3ce7c871"], "functions": ["privacy_init", "privacy_update", "privacy_deposit", "privacy_transfer", "privacy_withdraw", "privacy_reset"]}
{"snippets": ["2e3f7fcf48f9c178aa5520c60d147ef15c69272048a10138f6fee7db4741981b", "b6335de3a510c47060240296fc5f433024a727ebb2e63fb5c7c8f5ee3ce7c871"]}
7277221498323894117996865645382314574012950483900946516131069162442666142001632965613058264573115227571003615021051890563186219962218017147123381528517790106726207019292408953803143191736932699308781419485276485160416780962889173134744224636656246222974368817151478382381802475584259972681619923346147844912920830519792951886326264843564940811190073276774318184149039203175989053629386864567523154745146440433199318473315114596376969878438647684264690364492093834566038391234498706213701365266326156095498710418220024643285633145531316234747616378201020949598081663029961960584221404057330138251696615331888245643618
1
9876500