Skip to content

Commit 2c0463c

Browse files
committed
update string encryption/decryption
1 parent bdbac79 commit 2c0463c

2 files changed

Lines changed: 69 additions & 26 deletions

File tree

README.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,30 @@ int_cipher_text, signature = build_input_text(plaintext, user_aes_key, sender, c
223223
- `int_cipher_text`: The integer representation of the ciphertext.
224224
- `signature`: The generated signature.
225225

226-
### 8. `generate_rsa_keypair()`
226+
### 8. `build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key)`
227+
228+
**Purpose:** Builds input text by encrypting the plaintext and signing it.
229+
230+
**Usage:**
231+
232+
```python
233+
int_cipher_text, signature = build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key)
234+
```
235+
236+
**Parameters:**
237+
238+
- `plaintext`: The plaintext message.
239+
- `user_aes_key`: The user's AES key.
240+
- `sender`: The sender's address.
241+
- `contract`: The contract address.
242+
- `func_sig`: The function signature.
243+
- `signing_key`: The private key used for signing.
244+
245+
**Returns:**
246+
247+
- `input_text`: A dictionary of the form { "ciphertext": { "value": int[] }, "signature": bytes[] }
248+
249+
### 9. `generate_rsa_keypair()`
227250

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

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

241-
### 9. `encrypt_rsa(public_key_bytes, plaintext)`
264+
### 10. `encrypt_rsa(public_key_bytes, plaintext)`
242265

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

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

258281
- `ciphertext`: The encrypted message.
259282

260-
### 10. `decrypt_rsa(private_key_bytes, ciphertext)`
283+
### 11. `decrypt_rsa(private_key_bytes, ciphertext)`
261284

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

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

277300
- `plaintext`: The decrypted message.
278301

279-
### 11. `keccak256(data)`
302+
### 12. `keccak256(data)`
280303

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

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

295318
- `hash_value`: The computed hash.
296319

297-
### 12. `get_func_sig(function_signature)`
320+
### 13. `get_func_sig(function_signature)`
298321

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

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

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

315-
### 13. `decrypt_uint(ciphertext, user_key)`
338+
### 14. `decrypt_uint(ciphertext, user_key)`
316339

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

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

332355
- `result`: The decrypted value.
333356

334-
### 14. `decrypt_string(ciphertext, user_key)`
357+
### 15. `decrypt_string(ciphertext, user_key)`
335358

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

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

344367
**Parameters:**
345368

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

349372
**Returns:**

coti/crypto_utils.py

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import binascii
2-
from array import array
3-
41
from Crypto.Cipher import AES
52
from Crypto.Hash import keccak
63
from Crypto.Random import get_random_bytes
@@ -9,6 +6,7 @@
96
from cryptography.hazmat.primitives.asymmetric import padding
107
from cryptography.hazmat.primitives.asymmetric import rsa
118
from eth_keys import keys
9+
from math import ceil
1210

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

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

2928
# Create a new AES cipher block using the provided key
@@ -126,14 +125,34 @@ def build_input_text(plaintext, user_aes_key, sender, contract, func_sig, signin
126125

127126

128127
def build_string_input_text(plaintext, user_aes_key, sender, contract, func_sig, signing_key):
129-
encoded_plaintext = array('B', plaintext.encode('utf-8'))
130-
encrypted_str = [{'ciphertext': 0, 'signature': b''} for _ in range(len(encoded_plaintext))]
131-
for i in range(len(encoded_plaintext)):
132-
ct_int, signature = build_input_text(int(encoded_plaintext[i]), user_aes_key, sender, contract,
133-
func_sig, signing_key)
134-
encrypted_str[i] = {'ciphertext': ct_int, 'signature': signature}
128+
input_text = {
129+
'ciphertext': {
130+
'value': []
131+
},
132+
'signature': []
133+
}
134+
135+
encoded_plaintext = bytearray(list(plaintext.encode('utf-8')))
136+
137+
for i in range(ceil(len(encoded_plaintext) / 8)):
138+
start_idx = i * 8
139+
end_idx = min(start_idx + 8, len(encoded_plaintext))
140+
141+
byte_arr = encoded_plaintext[start_idx:end_idx] + bytearray(8 - (end_idx - start_idx))
142+
143+
ct_int, sig = build_input_text(
144+
int.from_bytes(byte_arr, 'big'),
145+
user_aes_key,
146+
sender,
147+
contract,
148+
func_sig,
149+
signing_key
150+
)
135151

136-
return encrypted_str
152+
input_text['ciphertext']['value'].append(ct_int)
153+
input_text['signature'].append(sig)
154+
155+
return input_text
137156

138157

139158
def decrypt_uint(ciphertext, user_key):
@@ -154,18 +173,19 @@ def decrypt_uint(ciphertext, user_key):
154173

155174

156175
def decrypt_string(ciphertext, user_key):
157-
string_from_input_tx = ""
158-
for input_text_from_tx in ciphertext:
159-
decrypted_input_from_tx = decrypt_uint(input_text_from_tx, user_key)
160-
byte_length = (decrypted_input_from_tx.bit_length() + 7) // 8 # calculate the byte length
176+
decrypted_string = ""
177+
178+
for value in ciphertext['value']:
179+
decrypted = decrypt_uint(value, user_key)
180+
byte_length = (decrypted.bit_length() + 7) // 8 # calculate the byte length
161181

162182
# Convert the integer to bytes
163-
decrypted_bytes = decrypted_input_from_tx.to_bytes(byte_length, byteorder='big')
183+
decrypted_bytes = decrypted.to_bytes(byte_length, byteorder='big')
164184

165185
# Decode the bytes to a string
166-
string_from_input_tx += decrypted_bytes.decode('utf-8')
167-
168-
return string_from_input_tx
186+
decrypted_string += decrypted_bytes.decode('utf-8')
187+
188+
return decrypted_string.strip('\0')
169189

170190

171191
def generate_rsa_keypair():

0 commit comments

Comments
 (0)