or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

abi-processing.mdaddress-operations.mdcrypto-functions.mdcurrency-units.mddata-conversions.mddata-formatting.mdfunctional-programming.mdhexadecimal-utilities.mdindex.mdlogging-debugging.mdnetwork-information.mdtype-checking.md

crypto-functions.mddocs/

0

# Cryptographic Functions

1

2

Cryptographic utilities centered around Keccak-256 hashing with flexible input handling. Essential for Ethereum hash computations including transaction hashes, block hashes, and Merkle tree operations.

3

4

## Capabilities

5

6

### Keccak-256 Hashing

7

8

Compute Keccak-256 hash with flexible input formats.

9

10

```python { .api }

11

def keccak(primitive=None, hexstr=None, text=None) -> bytes:

12

"""

13

Compute Keccak-256 hash of input data.

14

15

Args:

16

primitive: Bytes, integer, or other primitive value

17

hexstr (str): Hex string input (with or without 0x prefix)

18

text (str): UTF-8 text string input

19

20

Returns:

21

bytes: 32-byte Keccak-256 hash

22

23

Raises:

24

ValidationError: If no input provided or invalid format

25

TypeError: If multiple inputs provided

26

"""

27

```

28

29

## Usage Examples

30

31

### Basic Hashing Operations

32

33

```python

34

from eth_utils import keccak, encode_hex

35

36

# Hash text string

37

text_hash = keccak(text="Hello, Ethereum!")

38

print(encode_hex(text_hash))

39

# 0x7a7b5f8d8e4f6c8a2d3e4f5a6b7c8d9e0f123456789abcdef0123456789abcdef

40

41

# Hash bytes directly

42

data = b"Hello, Ethereum!"

43

bytes_hash = keccak(primitive=data)

44

print(encode_hex(bytes_hash)) # Same as above

45

46

# Hash hex string

47

hex_data = "0x48656c6c6f2c20457468657265756d21" # "Hello, Ethereum!" in hex

48

hex_hash = keccak(hexstr=hex_data)

49

print(encode_hex(hex_hash)) # Same as above

50

51

# Hash integer

52

number = 12345

53

int_hash = keccak(primitive=number)

54

print(encode_hex(int_hash))

55

```

56

57

### Ethereum Address Generation

58

59

```python

60

from eth_utils import keccak, encode_hex, to_bytes

61

62

def generate_address_from_pubkey(public_key_hex):

63

"""Generate Ethereum address from public key."""

64

# Remove 0x04 prefix if present (uncompressed public key indicator)

65

if public_key_hex.startswith('0x04'):

66

public_key_hex = public_key_hex[4:]

67

elif public_key_hex.startswith('04'):

68

public_key_hex = public_key_hex[2:]

69

70

# Keccak-256 hash of public key

71

pubkey_hash = keccak(hexstr=public_key_hex)

72

73

# Take last 20 bytes as address

74

address = pubkey_hash[-20:]

75

return encode_hex(address)

76

77

# Example (mock public key)

78

pubkey = "0x04" + "a" * 128 # 64-byte public key

79

address = generate_address_from_pubkey(pubkey)

80

print(f"Generated address: {address}")

81

```

82

83

### Transaction Hash Calculation

84

85

```python

86

from eth_utils import keccak, encode_hex, to_bytes

87

88

def calculate_transaction_hash(transaction_data):

89

"""Calculate transaction hash for Ethereum transaction."""

90

# In real implementation, this would be RLP-encoded transaction data

91

# This is a simplified example

92

93

# Concatenate transaction fields (simplified)

94

nonce = to_bytes(primitive=transaction_data['nonce'])

95

gas_price = to_bytes(primitive=transaction_data['gasPrice'])

96

gas_limit = to_bytes(primitive=transaction_data['gasLimit'])

97

to_address = bytes.fromhex(transaction_data['to'][2:]) # Remove 0x

98

value = to_bytes(primitive=transaction_data['value'])

99

data = bytes.fromhex(transaction_data['data'][2:]) # Remove 0x

100

101

# Combine all fields (in real RLP encoding, this would be structured)

102

combined = nonce + gas_price + gas_limit + to_address + value + data

103

104

# Hash the combined data

105

tx_hash = keccak(primitive=combined)

106

return encode_hex(tx_hash)

107

108

# Example transaction

109

tx = {

110

'nonce': 0,

111

'gasPrice': 20000000000, # 20 gwei

112

'gasLimit': 21000,

113

'to': '0x742d35cc6634c0532925a3b8c17b1e8b4e1d1123',

114

'value': 1000000000000000000, # 1 ether in wei

115

'data': '0x'

116

}

117

118

tx_hash = calculate_transaction_hash(tx)

119

print(f"Transaction hash: {tx_hash}")

120

```

121

122

### Smart Contract Events

123

124

```python

125

from eth_utils import keccak, encode_hex

126

127

def calculate_event_topic(event_signature):

128

"""Calculate topic hash for smart contract event."""

129

topic_hash = keccak(text=event_signature)

130

return encode_hex(topic_hash)

131

132

# ERC-20 event signatures

133

transfer_topic = calculate_event_topic("Transfer(address,address,uint256)")

134

approval_topic = calculate_event_topic("Approval(address,address,uint256)")

135

136

print(f"Transfer topic: {transfer_topic}")

137

print(f"Approval topic: {approval_topic}")

138

139

# Use in event filtering

140

event_filter = {

141

"topics": [

142

[transfer_topic, approval_topic] # Either Transfer or Approval

143

]

144

}

145

```

146

147

### Merkle Tree Operations

148

149

```python

150

from eth_utils import keccak, encode_hex

151

152

def hash_pair(left_hash, right_hash):

153

"""Hash a pair of hashes for Merkle tree construction."""

154

# Ensure consistent ordering (left < right)

155

if left_hash > right_hash:

156

left_hash, right_hash = right_hash, left_hash

157

158

# Concatenate and hash

159

combined = left_hash + right_hash

160

return keccak(primitive=combined)

161

162

def build_merkle_root(leaf_hashes):

163

"""Build Merkle root from leaf hashes."""

164

if not leaf_hashes:

165

return b'\x00' * 32

166

167

if len(leaf_hashes) == 1:

168

return leaf_hashes[0]

169

170

# Build tree level by level

171

current_level = leaf_hashes[:]

172

173

while len(current_level) > 1:

174

next_level = []

175

176

# Process pairs

177

for i in range(0, len(current_level), 2):

178

left = current_level[i]

179

right = current_level[i + 1] if i + 1 < len(current_level) else left

180

parent_hash = hash_pair(left, right)

181

next_level.append(parent_hash)

182

183

current_level = next_level

184

185

return current_level[0]

186

187

# Example: Build Merkle tree from transaction hashes

188

tx_data = ["tx1", "tx2", "tx3", "tx4"]

189

leaf_hashes = [keccak(text=tx) for tx in tx_data]

190

merkle_root = build_merkle_root(leaf_hashes)

191

192

print(f"Merkle root: {encode_hex(merkle_root)}")

193

```

194

195

### Contract Creation Address

196

197

```python

198

from eth_utils import keccak, encode_hex, to_bytes

199

200

def create_contract_address(sender_address, nonce):

201

"""Calculate contract address using CREATE opcode rules."""

202

# Convert address to bytes (remove 0x prefix)

203

sender_bytes = bytes.fromhex(sender_address[2:])

204

205

# RLP encode sender + nonce (simplified)

206

if nonce == 0:

207

# RLP encoding of [address, 0]

208

rlp_data = sender_bytes + b'\x80' # 0x80 is RLP encoding of 0

209

else:

210

nonce_bytes = to_bytes(primitive=nonce)

211

# Simplified RLP encoding

212

rlp_data = sender_bytes + nonce_bytes

213

214

# Hash and take last 20 bytes

215

hash_result = keccak(primitive=rlp_data)

216

contract_address = hash_result[-20:]

217

218

return encode_hex(contract_address)

219

220

def create2_contract_address(sender_address, salt, bytecode_hash):

221

"""Calculate contract address using CREATE2 opcode rules."""

222

# CREATE2 address = keccak256(0xff + sender + salt + keccak256(bytecode))[12:]

223

prefix = b'\xff'

224

sender_bytes = bytes.fromhex(sender_address[2:])

225

salt_bytes = bytes.fromhex(salt[2:]) if isinstance(salt, str) else to_bytes(primitive=salt)

226

bytecode_hash_bytes = bytes.fromhex(bytecode_hash[2:]) if isinstance(bytecode_hash, str) else bytecode_hash

227

228

# Combine all components

229

combined = prefix + sender_bytes + salt_bytes + bytecode_hash_bytes

230

231

# Hash and take last 20 bytes

232

hash_result = keccak(primitive=combined)

233

contract_address = hash_result[-20:]

234

235

return encode_hex(contract_address)

236

237

# Examples

238

sender = "0x742d35cc6634c0532925a3b8c17b1e8b4e1d1123"

239

240

# CREATE address

241

create_addr = create_contract_address(sender, 0)

242

print(f"CREATE address: {create_addr}")

243

244

# CREATE2 address

245

salt = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"

246

bytecode_hash = keccak(text="contract bytecode")

247

create2_addr = create2_contract_address(sender, salt, bytecode_hash)

248

print(f"CREATE2 address: {create2_addr}")

249

```

250

251

### Data Integrity Verification

252

253

```python

254

from eth_utils import keccak, encode_hex

255

256

def create_data_hash(data):

257

"""Create hash for data integrity verification."""

258

if isinstance(data, str):

259

return keccak(text=data)

260

elif isinstance(data, bytes):

261

return keccak(primitive=data)

262

else:

263

# Convert to string representation

264

return keccak(text=str(data))

265

266

def verify_data_integrity(data, expected_hash):

267

"""Verify data integrity against expected hash."""

268

computed_hash = create_data_hash(data)

269

expected_bytes = bytes.fromhex(expected_hash[2:]) if expected_hash.startswith('0x') else bytes.fromhex(expected_hash)

270

return computed_hash == expected_bytes

271

272

# Example usage

273

original_data = "Important blockchain data"

274

data_hash = create_data_hash(original_data)

275

hash_hex = encode_hex(data_hash)

276

277

print(f"Data hash: {hash_hex}")

278

279

# Later, verify integrity

280

is_valid = verify_data_integrity(original_data, hash_hex)

281

print(f"Data integrity valid: {is_valid}") # True

282

283

# Check tampered data

284

tampered_data = "Important blockchain data!" # Added exclamation

285

is_valid_tampered = verify_data_integrity(tampered_data, hash_hex)

286

print(f"Tampered data valid: {is_valid_tampered}") # False

287

```

288

289

## Security Considerations

290

291

### Input Validation

292

293

```python

294

from eth_utils import keccak, ValidationError

295

296

def secure_hash(data_input):

297

"""Securely hash input with validation."""

298

try:

299

if isinstance(data_input, str):

300

# Ensure text is properly encoded

301

return keccak(text=data_input)

302

elif isinstance(data_input, bytes):

303

return keccak(primitive=data_input)

304

else:

305

raise TypeError(f"Unsupported input type: {type(data_input)}")

306

except ValidationError as e:

307

raise ValueError(f"Invalid input for hashing: {e}")

308

309

# Safe usage

310

try:

311

result = secure_hash("valid input")

312

print(f"Hash: {encode_hex(result)}")

313

except (TypeError, ValueError) as e:

314

print(f"Error: {e}")

315

```

316

317

## Common Patterns

318

319

### Hash Comparison

320

321

```python

322

from eth_utils import keccak

323

324

def hash_equal(data1, data2):

325

"""Compare two pieces of data by their hashes."""

326

hash1 = keccak(text=data1) if isinstance(data1, str) else keccak(primitive=data1)

327

hash2 = keccak(text=data2) if isinstance(data2, str) else keccak(primitive=data2)

328

return hash1 == hash2

329

330

# Constant-time comparison for security

331

def secure_hash_compare(hash1, hash2):

332

"""Securely compare two hashes in constant time."""

333

if len(hash1) != len(hash2):

334

return False

335

336

result = 0

337

for a, b in zip(hash1, hash2):

338

result |= a ^ b

339

340

return result == 0

341

```