Skip to content

Commit

Permalink
remove function selector computation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-xyz committed Aug 18, 2024
1 parent 2c0463c commit 99af9f8
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 45 deletions.
56 changes: 20 additions & 36 deletions coti/crypto_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from attributedict.collections import AttributeDict
from Crypto.Cipher import AES
from Crypto.Hash import keccak
from Crypto.Random import get_random_bytes
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
Expand All @@ -10,7 +10,7 @@

block_size = AES.block_size
address_size = 20
func_sig_size = 4
function_selector_size = 4
ct_size = 32
key_size = 32

Expand Down Expand Up @@ -74,22 +74,24 @@ def generate_aes_key():
return key


def sign_input_text(sender, addr, func_sig, ct, key):
def sign_input_text(sender, addr, function_selector, ct, key):
function_selector_bytes = bytes.fromhex(function_selector[2:])

# Ensure all input sizes are the correct length
if len(sender) != address_size:
raise ValueError(f"Invalid sender address length: {len(sender)} bytes, must be {address_size} bytes")
if len(addr) != address_size:
raise ValueError(f"Invalid contract address length: {len(addr)} bytes, must be {address_size} bytes")
if len(func_sig) != func_sig_size:
raise ValueError(f"Invalid signature size: {len(func_sig)} bytes, must be {func_sig_size} bytes")
if len(function_selector_bytes) != function_selector_size:
raise ValueError(f"Invalid signature size: {len(function_selector_bytes)} bytes, must be {function_selector_size} bytes")
if len(ct) != ct_size:
raise ValueError(f"Invalid ct length: {len(ct)} bytes, must be {ct_size} bytes")
# Ensure the key is the correct length
if len(key) != key_size:
raise ValueError(f"Invalid key length: {len(key)} bytes, must be {key_size} bytes")

# Create the message to be signed by appending all inputs
message = sender + addr + func_sig + ct
message = sender + addr + function_selector_bytes + ct

return sign(message, key)

Expand All @@ -102,7 +104,7 @@ def sign(message, key):
return signature


def build_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key):
def build_input_text(plaintext, user_aes_key, sender, contract, function_selector, signing_key):
sender_address_bytes = bytes.fromhex(sender.address[2:])
contract_address_bytes = bytes.fromhex(contract.address[2:])

Expand All @@ -113,18 +115,16 @@ def build_input_text(plaintext, user_aes_key, sender, contract, func_sig, signin
ciphertext, r = encrypt(user_aes_key, plaintext_bytes)
ct = ciphertext + r

# Create the function signature
func_hash = get_func_sig(func_sig)
# Sign the message
signature = sign_input_text(sender_address_bytes, contract_address_bytes, func_hash, ct, signing_key)
signature = sign_input_text(sender_address_bytes, contract_address_bytes, function_selector, ct, signing_key)

# Convert the ct to an integer
int_cipher_text = int.from_bytes(ct, byteorder='big')

return int_cipher_text, signature


def build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key):
def build_string_input_text(plaintext, user_aes_key, sender, contract, function_selector, signing_key):
input_text = {
'ciphertext': {
'value': []
Expand All @@ -145,7 +145,7 @@ def build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig,
user_aes_key,
sender,
contract,
func_sig,
function_selector,
signing_key
)

Expand Down Expand Up @@ -173,9 +173,16 @@ def decrypt_uint(ciphertext, user_key):


def decrypt_string(ciphertext, user_key):
if isinstance(ciphertext, tuple): # format when ciphertext is read from a state variable
__ciphertext = ciphertext[0]
elif hasattr(ciphertext, 'value'): # format when ciphertext is read from an event
__ciphertext = ciphertext['value']
else:
__ciphertext = ciphertext

decrypted_string = ""

for value in ciphertext['value']:
for value in __ciphertext:
decrypted = decrypt_uint(value, user_key)
byte_length = (decrypted.bit_length() + 7) // 8 # calculate the byte length

Expand Down Expand Up @@ -225,26 +232,3 @@ def decrypt_rsa(private_key_bytes, ciphertext):
)
)
return plaintext


# Function to compute Keccak-256 hash
def keccak256(data):
# Create Keccak-256 hash object
hash_obj = keccak.new(digest_bits=256)

# Update hash object with data
hash_obj.update(data)

# Compute hash and return
return hash_obj.digest()


def get_func_sig(function_signature):
# Convert function signature to bytes
function_signature_bytes = function_signature.encode('utf-8')

# Compute Keccak-256 hash on the function signature
function_signature_bytes_hash = keccak256(function_signature_bytes)

# Take first 4 bytes of the hash
return function_signature_bytes_hash[:4]
8 changes: 0 additions & 8 deletions coti/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,6 @@ def is_gas_units_estimation_valid(web3, tx):
return False, estimate_gas


def get_function_signature(function_abi):
# Extract the input types from the ABI
input_types = ','.join([param['type'] for param in function_abi.get('inputs', [])])

# Generate the function signature
return f"{function_abi['name']}({input_types})"


def deploy_contract(contract, kwargs, tx_params):
func = contract.constructor(**kwargs)
return exec_func_via_transaction(func, tx_params)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
url='https://github.com/coti-io/coti-sdk-python',
keywords='COTI SDK Privacy',
install_requires=[
'pycryptodome==3.19.0', 'cryptography==3.4.8', 'eth-keys==0.4.0', 'eth-account==0.10.0', 'web3==6.11.2'
'pycryptodome==3.19.0', 'cryptography==3.4.8', 'eth-keys==0.4.0', 'eth-account==0.10.0', 'web3==6.11.2', 'attributedict==0.3.0'
],
python_requires=">=3.9",
)

0 comments on commit 99af9f8

Please sign in to comment.