Skip to content

Commit

Permalink
update string encryption/decryption
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-xyz committed Aug 13, 2024
1 parent bdbac79 commit 2114b14
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 26 deletions.
39 changes: 31 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,30 @@ int_cipher_text, signature = build_input_text(plaintext, user_aes_key, sender, c
- `int_cipher_text`: The integer representation of the ciphertext.
- `signature`: The generated signature.

### 8. `generate_rsa_keypair()`
### 8. `build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key)`

**Purpose:** Builds input text by encrypting the plaintext and signing it.

**Usage:**

```python
int_cipher_text, signature = build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key)
```

**Parameters:**

- `plaintext`: The plaintext message.
- `user_aes_key`: The user's AES key.
- `sender`: The sender's address.
- `contract`: The contract address.
- `func_sig`: The function signature.
- `signing_key`: The private key used for signing.

**Returns:**

- `input_text`: A dictionary of the form { "ciphertext": int[], "signature": bytes[] }

### 9. `generate_rsa_keypair()`

**Purpose:** Generates an RSA key pair.

Expand All @@ -238,7 +261,7 @@ private_key_bytes, public_key_bytes = generate_rsa_keypair()
- `private_key_bytes`: The serialized private key.
- `public_key_bytes`: The serialized public key.

### 9. `encrypt_rsa(public_key_bytes, plaintext)`
### 10. `encrypt_rsa(public_key_bytes, plaintext)`

**Purpose:** Encrypts plaintext using RSA encryption with a provided public key.

Expand All @@ -257,7 +280,7 @@ ciphertext = encrypt_rsa(public_key_bytes, plaintext)

- `ciphertext`: The encrypted message.

### 10. `decrypt_rsa(private_key_bytes, ciphertext)`
### 11. `decrypt_rsa(private_key_bytes, ciphertext)`

**Purpose:** Decrypts ciphertext using RSA decryption with a provided private key.

Expand All @@ -276,7 +299,7 @@ plaintext = decrypt_rsa(private_key_bytes, ciphertext)

- `plaintext`: The decrypted message.

### 11. `keccak256(data)`
### 12. `keccak256(data)`

**Purpose:** Computes the Keccak-256 hash of the provided data.

Expand All @@ -294,7 +317,7 @@ hash_value = keccak256(data)

- `hash_value`: The computed hash.

### 12. `get_func_sig(function_signature)`
### 13. `get_func_sig(function_signature)`

**Purpose:** Computes the function signature hash using Keccak-256.

Expand All @@ -312,7 +335,7 @@ func_sig_hash = get_func_sig(function_signature)

- `func_sig_hash`: The first 4 bytes of the computed hash.

### 13. `decrypt_uint(ciphertext, user_key)`
### 14. `decrypt_uint(ciphertext, user_key)`

**Purpose:** Decrypts a value stored in a contract using a user key

Expand All @@ -331,7 +354,7 @@ plaintext = decrypt_uint(ciphertext, user_key)

- `result`: The decrypted value.

### 14. `decrypt_string(ciphertext, user_key)`
### 15. `decrypt_string(ciphertext, user_key)`

**Purpose:** Decrypts a value stored in a contract using a user key

Expand All @@ -343,7 +366,7 @@ plaintext = decrypt_string(ciphertext, user_key)

**Parameters:**

- `ciphertext`: The value to be decrypted.
- `ciphertext`: A dictionary of the form { "value": int[] } where each cell holds up to 8 characters (padded at the end with zeroes) encrypted
- `userKey`: The user's AES key.

**Returns:**
Expand Down
54 changes: 36 additions & 18 deletions coti/crypto_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import binascii
from array import array

from Crypto.Cipher import AES
from Crypto.Hash import keccak
from Crypto.Random import get_random_bytes
Expand All @@ -9,6 +6,7 @@
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import rsa
from eth_keys import keys
from math import ceil

block_size = AES.block_size
address_size = 20
Expand All @@ -24,6 +22,7 @@ def encrypt(key, plaintext):

# Ensure key size is 128 bits (16 bytes)
if len(key) != block_size:
print(len(key), block_size)
raise ValueError("Key size must be 128 bits.")

# Create a new AES cipher block using the provided key
Expand Down Expand Up @@ -126,14 +125,32 @@ def build_input_text(plaintext, user_aes_key, sender, contract, func_sig, signin


def build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key):
encoded_plaintext = array('B', plaintext.encode('utf-8'))
encrypted_str = [{'ciphertext': 0, 'signature': b''} for _ in range(len(encoded_plaintext))]
for i in range(len(encoded_plaintext)):
ct_int, signature = build_input_text(int(encoded_plaintext[i]), user_aes_key, sender, contract,
func_sig, signing_key)
encrypted_str[i] = {'ciphertext': ct_int, 'signature': signature}
input_text = {
'ciphertext': [],
'signature': []
}

encoded_plaintext = bytearray(list(plaintext.encode('utf-8')))

for i in range(ceil(len(encoded_plaintext) / 8)):
start_idx = i * 8
end_idx = min(start_idx + 8, len(encoded_plaintext))

byte_arr = encoded_plaintext[start_idx:end_idx] + bytearray(8 - (end_idx - start_idx))

ct_int, signature = build_input_text(
int.from_bytes(byte_arr, 'big'),
user_aes_key,
sender,
contract,
func_sig,
signing_key
)

return encrypted_str
input_text['ciphertext'].append(ct_int)
input_text['signature'].append(signature)

return input_text


def decrypt_uint(ciphertext, user_key):
Expand All @@ -154,18 +171,19 @@ def decrypt_uint(ciphertext, user_key):


def decrypt_string(ciphertext, user_key):
string_from_input_tx = ""
for input_text_from_tx in ciphertext:
decrypted_input_from_tx = decrypt_uint(input_text_from_tx, user_key)
byte_length = (decrypted_input_from_tx.bit_length() + 7) // 8 # calculate the byte length
decrypted_string = ""

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

# Convert the integer to bytes
decrypted_bytes = decrypted_input_from_tx.to_bytes(byte_length, byteorder='big')
decrypted_bytes = decrypted.to_bytes(byte_length, byteorder='big')

# Decode the bytes to a string
string_from_input_tx += decrypted_bytes.decode('utf-8')

return string_from_input_tx
decrypted_string += decrypted_bytes.decode('utf-8')
return decrypted_string.strip('\0')


def generate_rsa_keypair():
Expand Down

0 comments on commit 2114b14

Please sign in to comment.