or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

account-management.mdcryptographic-primitives.mderror-handling.mdindex.mdnetwork-sysvars.mdrpc-functionality.mdsystem-programs.mdtesting-infrastructure.mdtoken-operations.mdtransaction-construction.mdtransaction-status.md

cryptographic-primitives.mddocs/

0

# Cryptographic Primitives

1

2

Core blockchain cryptography implementations providing Ed25519 keypairs, signatures, public keys, and SHA-256 hashing. These primitives form the foundation for all Solana operations including account identification, transaction signing, and data integrity verification.

3

4

## Capabilities

5

6

### Public Key Operations

7

8

Solana addresses and program identifiers represented as 32-byte Ed25519 public keys with derivation and validation capabilities.

9

10

```python { .api }

11

class Pubkey:

12

"""

13

Represents a 32-byte Solana public key used for addresses and program IDs.

14

"""

15

def __init__(self, value: bytes):

16

"""

17

Create a Pubkey from 32 bytes.

18

19

Parameters:

20

- value: bytes, exactly 32 bytes representing the public key

21

22

Raises:

23

- ValueError: if value is not exactly 32 bytes

24

"""

25

26

@classmethod

27

def from_string(cls, s: str) -> 'Pubkey':

28

"""

29

Parse a base58-encoded string into a Pubkey.

30

31

Parameters:

32

- s: str, base58-encoded public key string

33

34

Returns:

35

Pubkey object

36

37

Raises:

38

- ValueError: if string is not valid base58 or wrong length

39

"""

40

41

@classmethod

42

def from_bytes(cls, data: bytes) -> 'Pubkey':

43

"""

44

Create Pubkey from byte array.

45

46

Parameters:

47

- data: bytes, public key data

48

49

Returns:

50

Pubkey object

51

"""

52

53

@staticmethod

54

def find_program_address(seeds: List[bytes], program_id: 'Pubkey') -> Tuple['Pubkey', int]:

55

"""

56

Find a program derived address (PDA) with bump seed.

57

58

Parameters:

59

- seeds: List[bytes], seed components for derivation

60

- program_id: Pubkey, program that owns the derived address

61

62

Returns:

63

Tuple of (derived_pubkey, bump_seed)

64

"""

65

66

@staticmethod

67

def create_program_address(seeds: List[bytes], program_id: 'Pubkey') -> 'Pubkey':

68

"""

69

Create program address from seeds (must not be on Ed25519 curve).

70

71

Parameters:

72

- seeds: List[bytes], seed components including bump

73

- program_id: Pubkey, program that owns the derived address

74

75

Returns:

76

Pubkey object

77

78

Raises:

79

- ValueError: if derived address is on Ed25519 curve

80

"""

81

82

def __str__(self) -> str:

83

"""Return base58 string representation."""

84

85

def __bytes__(self) -> bytes:

86

"""Return 32-byte representation."""

87

88

def __eq__(self, other) -> bool:

89

"""Compare equality with another Pubkey."""

90

```

91

92

### Keypair Management

93

94

Ed25519 keypair generation and management for transaction signing and account ownership.

95

96

```python { .api }

97

class Keypair:

98

"""

99

Ed25519 key pair for signing transactions and proving account ownership.

100

"""

101

def __init__(self):

102

"""Generate a new random keypair."""

103

104

@classmethod

105

def from_seed(cls, seed: bytes) -> 'Keypair':

106

"""

107

Create keypair from a 32-byte seed for deterministic generation.

108

109

Parameters:

110

- seed: bytes, exactly 32 bytes for deterministic key generation

111

112

Returns:

113

Keypair object

114

115

Raises:

116

- ValueError: if seed is not exactly 32 bytes

117

"""

118

119

@classmethod

120

def from_secret_key_bytes(cls, secret_key: bytes) -> 'Keypair':

121

"""

122

Create keypair from 64-byte secret key.

123

124

Parameters:

125

- secret_key: bytes, 64-byte Ed25519 secret key

126

127

Returns:

128

Keypair object

129

"""

130

131

@classmethod

132

def from_base58_string(cls, s: str) -> 'Keypair':

133

"""

134

Create keypair from base58-encoded secret key string.

135

136

Parameters:

137

- s: str, base58-encoded secret key

138

139

Returns:

140

Keypair object

141

"""

142

143

def pubkey(self) -> Pubkey:

144

"""

145

Get the public key component.

146

147

Returns:

148

Pubkey object representing the public key

149

"""

150

151

def secret(self) -> bytes:

152

"""

153

Get the secret key bytes.

154

155

Returns:

156

bytes, 64-byte secret key (private key + public key)

157

"""

158

159

def sign_message(self, message: bytes) -> 'Signature':

160

"""

161

Sign a message with this keypair.

162

163

Parameters:

164

- message: bytes, message to sign

165

166

Returns:

167

Signature object

168

"""

169

170

def to_base58_string(self) -> str:

171

"""

172

Export secret key as base58 string.

173

174

Returns:

175

str, base58-encoded secret key

176

"""

177

```

178

179

### Digital Signatures

180

181

Ed25519 signature creation and verification for transaction authentication.

182

183

```python { .api }

184

class Signature:

185

"""

186

Represents a 64-byte Ed25519 signature for transaction authentication.

187

"""

188

def __init__(self, signature_bytes: bytes):

189

"""

190

Create signature from 64 bytes.

191

192

Parameters:

193

- signature_bytes: bytes, exactly 64 bytes representing the signature

194

195

Raises:

196

- ValueError: if signature_bytes is not exactly 64 bytes

197

"""

198

199

@classmethod

200

def from_string(cls, s: str) -> 'Signature':

201

"""

202

Parse a base58-encoded signature string.

203

204

Parameters:

205

- s: str, base58-encoded signature string

206

207

Returns:

208

Signature object

209

210

Raises:

211

- ValueError: if string is not valid base58 or wrong length

212

"""

213

214

@classmethod

215

def default() -> 'Signature':

216

"""

217

Create a default (all zeros) signature.

218

219

Returns:

220

Signature object with all zero bytes

221

"""

222

223

def __str__(self) -> str:

224

"""Return base58 string representation."""

225

226

def __bytes__(self) -> bytes:

227

"""Return 64-byte signature."""

228

229

def __eq__(self, other) -> bool:

230

"""Compare equality with another Signature."""

231

232

def verify(self, pubkey: Pubkey, message: bytes) -> bool:

233

"""

234

Verify signature against public key and message.

235

236

Parameters:

237

- pubkey: Pubkey, public key to verify against

238

- message: bytes, original message that was signed

239

240

Returns:

241

bool, True if signature is valid

242

"""

243

```

244

245

### Hash Operations

246

247

SHA-256 hashing for blockhashes, transaction IDs, and data integrity verification.

248

249

```python { .api }

250

class Hash:

251

"""

252

Represents a 32-byte SHA-256 hash used for blockhashes and transaction IDs.

253

"""

254

def __init__(self, value: bytes):

255

"""

256

Create hash from 32 bytes.

257

258

Parameters:

259

- value: bytes, exactly 32 bytes representing the hash

260

261

Raises:

262

- ValueError: if value is not exactly 32 bytes

263

"""

264

265

@classmethod

266

def from_string(cls, s: str) -> 'Hash':

267

"""

268

Parse a base58-encoded hash string.

269

270

Parameters:

271

- s: str, base58-encoded hash string

272

273

Returns:

274

Hash object

275

276

Raises:

277

- ParseHashError: if string is not valid base58 or wrong length

278

"""

279

280

@classmethod

281

def default() -> 'Hash':

282

"""

283

Create a default (all zeros) hash.

284

285

Returns:

286

Hash object with all zero bytes

287

"""

288

289

@staticmethod

290

def hash(data: bytes) -> 'Hash':

291

"""

292

Compute SHA-256 hash of data.

293

294

Parameters:

295

- data: bytes, data to hash

296

297

Returns:

298

Hash object containing the SHA-256 digest

299

"""

300

301

@staticmethod

302

def hashv(data: List[bytes]) -> 'Hash':

303

"""

304

Compute SHA-256 hash of multiple byte arrays.

305

306

Parameters:

307

- data: List[bytes], list of byte arrays to hash together

308

309

Returns:

310

Hash object containing the SHA-256 digest

311

"""

312

313

def __str__(self) -> str:

314

"""Return base58 string representation."""

315

316

def __bytes__(self) -> bytes:

317

"""Return 32-byte hash."""

318

319

def __eq__(self, other) -> bool:

320

"""Compare equality with another Hash."""

321

```

322

323

### Alternative Signers

324

325

Non-standard signer implementations for specialized use cases.

326

327

```python { .api }

328

class NullSigner:

329

"""

330

No-op signer for read-only operations and simulation.

331

"""

332

def __init__(self, pubkey: Pubkey):

333

"""

334

Create null signer with specified public key.

335

336

Parameters:

337

- pubkey: Pubkey, public key this signer represents

338

"""

339

340

def pubkey(self) -> Pubkey:

341

"""

342

Get the public key.

343

344

Returns:

345

Pubkey object

346

"""

347

348

class Presigner:

349

"""

350

Container for pre-computed signatures.

351

"""

352

def __init__(self, pubkey: Pubkey, signature: Signature):

353

"""

354

Create presigner with public key and signature.

355

356

Parameters:

357

- pubkey: Pubkey, public key that created the signature

358

- signature: Signature, pre-computed signature

359

"""

360

361

def pubkey(self) -> Pubkey:

362

"""

363

Get the public key.

364

365

Returns:

366

Pubkey object

367

"""

368

369

def signature(self) -> Signature:

370

"""

371

Get the pre-computed signature.

372

373

Returns:

374

Signature object

375

"""

376

```

377

378

## Usage Examples

379

380

### Basic Keypair Operations

381

382

```python

383

from solders.keypair import Keypair

384

from solders.pubkey import Pubkey

385

386

# Generate new keypair

387

keypair = Keypair()

388

pubkey = keypair.pubkey()

389

print(f"Public key: {pubkey}")

390

print(f"Secret key: {keypair.to_base58_string()}")

391

392

# Create from seed for deterministic generation

393

seed = b'my_deterministic_seed_32_bytes!'

394

deterministic_keypair = Keypair.from_seed(seed)

395

396

# Sign and verify a message

397

message = b"Hello, Solana!"

398

signature = keypair.sign_message(message)

399

is_valid = signature.verify(keypair.pubkey(), message)

400

print(f"Signature valid: {is_valid}")

401

```

402

403

### Program Derived Addresses

404

405

```python

406

from solders.pubkey import Pubkey

407

408

# Find PDA for token metadata

409

mint_pubkey = Pubkey.from_string("So11111111111111111111111111111111111111112")

410

metadata_program_id = Pubkey.from_string("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s")

411

412

seeds = [

413

b"metadata",

414

bytes(metadata_program_id),

415

bytes(mint_pubkey)

416

]

417

418

pda, bump = Pubkey.find_program_address(seeds, metadata_program_id)

419

print(f"Metadata PDA: {pda}, bump: {bump}")

420

421

# Create the actual address with bump

422

seeds_with_bump = seeds + [bytes([bump])]

423

actual_pda = Pubkey.create_program_address(seeds_with_bump, metadata_program_id)

424

assert pda == actual_pda

425

```

426

427

### Hash Operations

428

429

```python

430

from solders.hash import Hash

431

432

# Hash single data

433

data = b"transaction_data"

434

hash_result = Hash.hash(data)

435

print(f"SHA-256 hash: {hash_result}")

436

437

# Hash multiple pieces of data

438

hash_multiple = Hash.hashv([b"part1", b"part2", b"part3"])

439

print(f"Multi-part hash: {hash_multiple}")

440

441

# Parse from string

442

hash_from_string = Hash.from_string("11111111111111111111111111111112")

443

```

444

445

## Constants and Identifiers

446

447

### Well-Known Public Keys

448

449

```python { .api }

450

# System Program ID

451

SYSTEM_PROGRAM_ID: Final[Pubkey] = Pubkey.from_string("11111111111111111111111111111112")

452

453

# Native SOL Token Mint

454

NATIVE_MINT: Final[Pubkey] = Pubkey.from_string("So11111111111111111111111111111111111111112")

455

456

# SPL Token Program ID

457

TOKEN_PROGRAM_ID: Final[Pubkey] = Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")

458

```

459

460

### Default Values

461

462

```python { .api }

463

# Default signature (all zeros)

464

DEFAULT_SIGNATURE: Final[Signature] = Signature.default()

465

466

# Default hash (all zeros)

467

DEFAULT_HASH: Final[Hash] = Hash.default()

468

```

469

470

## Error Handling

471

472

### Parse Errors

473

474

```python { .api }

475

class ParseHashError(Exception):

476

"""

477

Exception raised when hash string parsing fails.

478

479

Raised by:

480

- Hash.from_string() with invalid base58 or wrong length

481

"""

482

```

483

484

Common error scenarios:

485

486

```python

487

from solders.hash import Hash, ParseHashError

488

from solders.pubkey import Pubkey

489

490

try:

491

# Invalid base58 string

492

invalid_hash = Hash.from_string("invalid_base58_string!!!")

493

except ParseHashError as e:

494

print(f"Hash parse error: {e}")

495

496

try:

497

# Wrong length bytes

498

invalid_pubkey = Pubkey(b"too_short")

499

except ValueError as e:

500

print(f"Pubkey creation error: {e}")

501

502

try:

503

# Invalid seed length

504

invalid_keypair = Keypair.from_seed(b"wrong_length")

505

except ValueError as e:

506

print(f"Keypair creation error: {e}")

507

```