or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cryptographic-hashing.mdcryptographic-protocols.mddigital-signatures.mdindex.mdinput-output-operations.mdmathematical-primitives.mdpublic-key-cryptography.mdsymmetric-encryption.mdutility-functions.md

mathematical-primitives.mddocs/

0

# Mathematical Primitives

1

2

Mathematical operations and data structures that form the foundation of PyCryptodome's cryptographic implementations. Provides big integer arithmetic, primality testing, and mathematical utilities optimized for cryptographic computations.

3

4

## Capabilities

5

6

### Big Integer Arithmetic

7

8

High-precision integer arithmetic supporting arbitrarily large numbers with optimized implementations for cryptographic operations.

9

10

```python { .api }

11

class Integer:

12

"""

13

Big integer class with cryptographic optimizations.

14

Auto-selects best available implementation (GMP, custom, or native).

15

"""

16

17

def __init__(self, value):

18

"""

19

Initialize Integer from various sources.

20

21

Parameters:

22

- value: int, bytes, hex string, or another Integer

23

"""

24

25

# Arithmetic operations

26

def __add__(self, other) -> 'Integer':

27

"""Addition: self + other"""

28

29

def __sub__(self, other) -> 'Integer':

30

"""Subtraction: self - other"""

31

32

def __mul__(self, other) -> 'Integer':

33

"""Multiplication: self * other"""

34

35

def __pow__(self, exponent, modulus=None) -> 'Integer':

36

"""

37

Exponentiation: self ** exponent [mod modulus]

38

Optimized for cryptographic use with Montgomery ladder.

39

"""

40

41

def __floordiv__(self, other) -> 'Integer':

42

"""Floor division: self // other"""

43

44

def __mod__(self, other) -> 'Integer':

45

"""Modulus: self % other"""

46

47

def __divmod__(self, other) -> tuple:

48

"""Division with remainder: divmod(self, other)"""

49

50

# Bitwise operations

51

def __and__(self, other) -> 'Integer':

52

"""Bitwise AND: self & other"""

53

54

def __or__(self, other) -> 'Integer':

55

"""Bitwise OR: self | other"""

56

57

def __xor__(self, other) -> 'Integer':

58

"""Bitwise XOR: self ^ other"""

59

60

def __lshift__(self, n: int) -> 'Integer':

61

"""Left shift: self << n"""

62

63

def __rshift__(self, n: int) -> 'Integer':

64

"""Right shift: self >> n"""

65

66

# Comparison operations

67

def __eq__(self, other) -> bool:

68

"""Equality: self == other"""

69

70

def __lt__(self, other) -> bool:

71

"""Less than: self < other"""

72

73

def __le__(self, other) -> bool:

74

"""Less than or equal: self <= other"""

75

76

# Modular arithmetic

77

def inverse(self, modulus) -> 'Integer':

78

"""

79

Compute modular multiplicative inverse.

80

81

Parameters:

82

- modulus (Integer): Modulus value

83

84

Returns:

85

Integer: self^(-1) mod modulus

86

87

Raises:

88

ValueError: If inverse doesn't exist (gcd(self, modulus) != 1)

89

"""

90

91

def gcd(self, other) -> 'Integer':

92

"""

93

Compute greatest common divisor using Euclidean algorithm.

94

95

Parameters:

96

- other (Integer): Other integer

97

98

Returns:

99

Integer: gcd(self, other)

100

"""

101

102

def lcm(self, other) -> 'Integer':

103

"""

104

Compute least common multiple.

105

106

Parameters:

107

- other (Integer): Other integer

108

109

Returns:

110

Integer: lcm(self, other)

111

"""

112

113

# Utility methods

114

def size_in_bits(self) -> int:

115

"""Number of bits needed to represent this integer."""

116

117

def size_in_bytes(self) -> int:

118

"""Number of bytes needed to represent this integer."""

119

120

def is_odd(self) -> bool:

121

"""Check if integer is odd."""

122

123

def is_even(self) -> bool:

124

"""Check if integer is even."""

125

126

# Conversion methods

127

def to_bytes(self, length=None, byteorder='big') -> bytes:

128

"""

129

Convert to bytes representation.

130

131

Parameters:

132

- length (int): Target byte length (None for minimal)

133

- byteorder (str): 'big' or 'little' endian

134

135

Returns:

136

bytes: Binary representation

137

"""

138

139

@staticmethod

140

def from_bytes(data: bytes, byteorder='big') -> 'Integer':

141

"""

142

Create Integer from bytes.

143

144

Parameters:

145

- data (bytes): Binary data

146

- byteorder (str): 'big' or 'little' endian

147

148

Returns:

149

Integer: Integer representation of bytes

150

"""

151

152

def __int__(self) -> int:

153

"""Convert to Python int (may lose precision for very large numbers)."""

154

155

def __str__(self) -> str:

156

"""Decimal string representation."""

157

158

def __repr__(self) -> str:

159

"""Representation string."""

160

161

def __hex__(self) -> str:

162

"""Hexadecimal string representation."""

163

164

def __bool__(self) -> bool:

165

"""Boolean value (False only for zero)."""

166

```

167

168

### Primality Testing

169

170

Probabilistic and deterministic algorithms for testing whether integers are prime, essential for key generation and validation.

171

172

```python { .api }

173

def miller_rabin_test(candidate, iterations, randfunc=None):

174

"""

175

Miller-Rabin probabilistic primality test.

176

177

Parameters:

178

- candidate (int): Integer to test for primality

179

- iterations (int): Number of test iterations (higher = more accurate)

180

- randfunc (callable): Random function for choosing test bases

181

182

Returns:

183

int: 0 if composite, 1 if probably prime

184

"""

185

186

def lucas_test(candidate):

187

"""

188

Lucas probabilistic primality test.

189

190

Parameters:

191

- candidate (int): Odd integer to test (must be > 2)

192

193

Returns:

194

int: 0 if composite, 1 if probably prime

195

"""

196

197

def test_probable_prime(candidate, randfunc=None):

198

"""

199

Combined primality test using multiple algorithms.

200

201

Parameters:

202

- candidate (int): Integer to test

203

- randfunc (callable): Random function

204

205

Returns:

206

int: PROBABLY_PRIME if likely prime, COMPOSITE if definitely composite

207

"""

208

209

# Primality test result constants

210

COMPOSITE = 0

211

PROBABLY_PRIME = 1

212

```

213

214

## Usage Examples

215

216

### Big Integer Operations

217

```python

218

from Crypto.Math.Numbers import Integer

219

220

# Create integers from different sources

221

a = Integer(12345)

222

b = Integer("0xABCDEF", 16) # From hex string

223

c = Integer(b"Hello", 256) # From bytes

224

225

# Arithmetic operations

226

sum_val = a + b

227

product = a * b

228

power = a ** 100

229

230

# Modular arithmetic (common in cryptography)

231

modulus = Integer(2**256 - 1) # Large prime-like number

232

mod_power = pow(a, b, modulus) # Fast modular exponentiation

233

inverse = a.inverse(modulus) # Modular inverse

234

235

# Bitwise operations

236

xor_result = a ^ b

237

shifted = a << 10

238

239

# Size operations

240

print(f"Bits needed: {a.size_in_bits()}")

241

print(f"Bytes needed: {a.size_in_bytes()}")

242

```

243

244

### RSA Key Generation Mathematics

245

```python

246

from Crypto.Math.Numbers import Integer

247

from Crypto.Math.Primality import test_probable_prime

248

from Crypto.Random import get_random_bytes

249

250

def generate_rsa_primes(bits):

251

"""Generate two RSA primes of specified bit length."""

252

while True:

253

# Generate random candidate

254

random_bytes = get_random_bytes(bits // 8)

255

candidate = Integer.from_bytes(random_bytes)

256

257

# Ensure odd and correct bit length

258

candidate |= (1 << (bits - 1)) # Set MSB

259

candidate |= 1 # Set LSB (make odd)

260

261

# Test for primality

262

if test_probable_prime(candidate) == PROBABLY_PRIME:

263

return candidate

264

265

# Generate 1024-bit RSA primes

266

p = generate_rsa_primes(1024)

267

q = generate_rsa_primes(1024)

268

n = p * q # RSA modulus

269

270

# Compute private exponent

271

e = Integer(65537) # Common public exponent

272

phi_n = (p - 1) * (q - 1)

273

d = e.inverse(phi_n) # Private exponent

274

275

print(f"Public key: (n={n}, e={e})")

276

print(f"Private key: (n={n}, d={d})")

277

```

278

279

### Modular Exponentiation for Encryption

280

```python

281

from Crypto.Math.Numbers import Integer

282

283

# RSA encryption/decryption example

284

n = Integer("0x9A7B2C3D...") # RSA modulus

285

e = Integer(65537) # Public exponent

286

d = Integer("0x1F2E3D...") # Private exponent

287

288

# Message as integer (after proper padding)

289

message = Integer(b"Hello, World!")

290

291

# Encryption: ciphertext = message^e mod n

292

ciphertext = pow(message, e, n)

293

294

# Decryption: plaintext = ciphertext^d mod n

295

decrypted = pow(ciphertext, d, n)

296

297

assert decrypted == message

298

```

299

300

### Elliptic Curve Point Operations

301

```python

302

from Crypto.Math.Numbers import Integer

303

304

# Simplified elliptic curve point addition (conceptual)

305

class ECPoint:

306

def __init__(self, x, y, curve_p):

307

self.x = Integer(x)

308

self.y = Integer(y)

309

self.p = Integer(curve_p) # Prime modulus

310

311

def double(self):

312

"""Point doubling on elliptic curve."""

313

# Simplified formula: slope = (3*x^2) / (2*y) mod p

314

numerator = (Integer(3) * self.x * self.x) % self.p

315

denominator = (Integer(2) * self.y) % self.p

316

slope = (numerator * denominator.inverse(self.p)) % self.p

317

318

# New coordinates

319

x3 = (slope * slope - Integer(2) * self.x) % self.p

320

y3 = (slope * (self.x - x3) - self.y) % self.p

321

322

return ECPoint(x3, y3, self.p)

323

324

# Example with P-256 curve

325

p256_prime = Integer(2**256 - 2**224 + 2**192 + 2**96 - 1)

326

point = ECPoint(

327

0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296,

328

0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5,

329

p256_prime

330

)

331

doubled_point = point.double()

332

```

333

334

### Primality Testing in Practice

335

```python

336

from Crypto.Math.Primality import miller_rabin_test, test_probable_prime

337

from Crypto.Math.Numbers import Integer

338

339

# Generate and test potential primes

340

def find_next_prime(start_value):

341

"""Find next probable prime after start_value."""

342

candidate = Integer(start_value)

343

if candidate.is_even():

344

candidate += 1 # Make odd

345

346

while True:

347

# Quick test with small iterations

348

if miller_rabin_test(candidate, 10) == PROBABLY_PRIME:

349

# More thorough test

350

if test_probable_prime(candidate) == PROBABLY_PRIME:

351

return candidate

352

candidate += 2 # Check next odd number

353

354

# Find large prime

355

large_prime = find_next_prime(2**512)

356

print(f"Found prime: {large_prime}")

357

print(f"Bit length: {large_prime.size_in_bits()}")

358

```

359

360

### Number Conversion and Encoding

361

```python

362

from Crypto.Math.Numbers import Integer

363

364

# Various ways to create and convert integers

365

num = Integer(12345)

366

367

# Convert to different formats

368

hex_string = hex(num) # "0x3039"

369

decimal_string = str(num) # "12345"

370

bytes_big = num.to_bytes(4, 'big') # b'\x00\x009'

371

bytes_little = num.to_bytes(4, 'little') # b'9\x00\x00'

372

373

# Reconstruct from bytes

374

from_big = Integer.from_bytes(bytes_big, 'big')

375

from_little = Integer.from_bytes(bytes_little, 'little')

376

377

assert from_big == num

378

assert from_little == num

379

380

# Handle large numbers

381

large_num = Integer(2**1024 - 1)

382

large_bytes = large_num.to_bytes() # Minimal byte representation

383

print(f"Large number byte length: {len(large_bytes)}")

384

```

385

386

## Performance Considerations

387

388

### Implementation Selection

389

PyCryptodome automatically selects the best available big integer implementation:

390

391

1. **GMP (GNU Multiple Precision)**: Fastest, requires libgmp

392

2. **Custom C**: Fast, pure C implementation included with PyCryptodome

393

3. **Pure Python**: Fallback, slower but always available

394

395

### Optimization Tips

396

- Use modular exponentiation `pow(base, exp, mod)` instead of `(base ** exp) % mod`

397

- Prefer `Integer` objects for repeated operations to avoid conversion overhead

398

- Use appropriate bit sizes for your security requirements

399

- Cache frequently used constants (like moduli) as `Integer` objects

400

401

### Memory Management

402

- `Integer` objects handle memory automatically

403

- Very large numbers may consume significant memory

404

- Consider the trade-off between precision and memory usage

405

406

## Security Considerations

407

408

### Cryptographic Quality

409

- Primality tests are probabilistic with configurable accuracy

410

- Use sufficient iterations for security-critical applications

411

- Miller-Rabin test with 64+ iterations provides high confidence

412

413

### Side-Channel Resistance

414

- Modular exponentiation uses Montgomery ladder for timing attack resistance

415

- Constant-time operations where possible

416

- Consider implementation-specific side-channel protections

417

418

### Random Number Dependencies

419

- Primality tests require cryptographically secure randomness

420

- Use system-provided randomness or `Crypto.Random`

421

- Ensure proper entropy for key generation

422

423

## Error Handling

424

425

- `ValueError`: Invalid mathematical operations (e.g., division by zero, no modular inverse)

426

- `TypeError`: Incompatible types for operations

427

- `OverflowError`: Results too large for representation (rare with arbitrary precision)

428

- `ZeroDivisionError`: Division or modulus by zero