or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

address.mdbase-encoding.mdcrypto-init.mdethereum.mdhashing.mdindex.mdjson-encryption.mdkey-derivation-pbkdf.mdkey-derivation.mdkeypairs.mdmnemonic.mdrandom.mdsignatures.md

signatures.mddocs/

0

# Digital Signatures

1

2

Signing and verification functions for multiple cryptographic schemes with automatic signature format detection. Supports sr25519, ed25519, secp256k1, and Ethereum-style signatures.

3

4

## Capabilities

5

6

### Sr25519 Signatures

7

8

Sr25519 signing and verification with support for Schnorr signatures and VRF.

9

10

```typescript { .api }

11

/**

12

* Sign a message using sr25519

13

* @param message - Message string or bytes to sign

14

* @param keypair - Keypair object with publicKey and secretKey

15

* @returns 64-byte signature

16

*/

17

function sr25519Sign(message: string | Uint8Array, keypair: Partial<Keypair>): Uint8Array;

18

19

/**

20

* Verify sr25519 signature

21

* @param message - Original message bytes

22

* @param signature - 64-byte signature to verify

23

* @param publicKey - 32-byte public key

24

* @returns true if signature is valid

25

*/

26

function sr25519Verify(message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean;

27

```

28

29

**Usage Example:**

30

31

```typescript

32

import { sr25519PairFromSeed, sr25519Sign, sr25519Verify } from "@polkadot/util-crypto";

33

34

const seed = new Uint8Array(32);

35

const pair = sr25519PairFromSeed(seed);

36

const message = new TextEncoder().encode("Hello Polkadot");

37

38

// Sign message

39

const signature = sr25519Sign(message, pair);

40

41

// Verify signature

42

const isValid = sr25519Verify(message, signature, pair.publicKey);

43

console.log("Signature valid:", isValid);

44

```

45

46

### Sr25519 VRF (Verifiable Random Functions)

47

48

VRF signing and verification for randomness generation with proof.

49

50

```typescript { .api }

51

/**

52

* Generate VRF signature and proof

53

* @param secretKey - 64-byte secret key

54

* @param context - Context bytes for VRF

55

* @param message - Message to sign

56

* @param extra - Optional extra randomness

57

* @returns VRF signature and proof

58

*/

59

function sr25519VrfSign(secretKey: Uint8Array, context: Uint8Array, message: Uint8Array, extra?: Uint8Array): Uint8Array;

60

61

/**

62

* Verify VRF signature and proof

63

* @param publicKey - 32-byte public key

64

* @param context - Context bytes for VRF

65

* @param message - Original message

66

* @param proof - VRF proof to verify

67

* @param extra - Optional extra randomness

68

* @returns true if VRF proof is valid

69

*/

70

function sr25519VrfVerify(publicKey: Uint8Array, context: Uint8Array, message: Uint8Array, proof: Uint8Array, extra?: Uint8Array): boolean;

71

```

72

73

### Ed25519 Signatures

74

75

Ed25519 signing and verification with deterministic signatures.

76

77

```typescript { .api }

78

/**

79

* Sign a message using ed25519

80

* @param publicKey - 32-byte public key

81

* @param secretKey - 32 or 64-byte secret key

82

* @param message - Message bytes to sign

83

* @returns 64-byte signature

84

*/

85

function ed25519Sign(publicKey: Uint8Array, secretKey: Uint8Array, message: Uint8Array): Uint8Array;

86

87

/**

88

* Verify ed25519 signature

89

* @param message - Original message bytes

90

* @param signature - 64-byte signature to verify

91

* @param publicKey - 32-byte public key

92

* @returns true if signature is valid

93

*/

94

function ed25519Verify(message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean;

95

```

96

97

**Usage Example:**

98

99

```typescript

100

import { ed25519PairFromSeed, ed25519Sign, ed25519Verify } from "@polkadot/util-crypto";

101

102

const seed = new Uint8Array(32);

103

const pair = ed25519PairFromSeed(seed);

104

const message = new TextEncoder().encode("Hello World");

105

106

// Sign message

107

const signature = ed25519Sign(pair.publicKey, pair.secretKey, message);

108

109

// Verify signature

110

const isValid = ed25519Verify(message, signature, pair.publicKey);

111

```

112

113

### Secp256k1 Signatures

114

115

Secp256k1 signing, verification, and public key recovery for Ethereum compatibility.

116

117

```typescript { .api }

118

/**

119

* Sign message hash using secp256k1

120

* @param msgHash - 32-byte message hash

121

* @param secretKey - 32-byte private key

122

* @returns Signature with recovery info

123

*/

124

function secp256k1Sign(msgHash: Uint8Array, secretKey: Uint8Array): Uint8Array;

125

126

/**

127

* Verify secp256k1 signature

128

* @param msgHash - 32-byte message hash

129

* @param signature - Signature bytes

130

* @param publicKey - Public key for verification

131

* @returns true if signature is valid

132

*/

133

function secp256k1Verify(msgHash: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean;

134

135

/**

136

* Recover public key from signature

137

* @param msgHash - 32-byte message hash

138

* @param signature - Signature bytes

139

* @param recovery - Recovery parameter (0-3)

140

* @returns Recovered public key

141

*/

142

function secp256k1Recover(msgHash: Uint8Array, signature: Uint8Array, recovery: number): Uint8Array;

143

144

/**

145

* Compress secp256k1 public key from uncompressed (65 bytes) to compressed (33 bytes)

146

* @param publicKey - Public key to compress (33 or 65 bytes)

147

* @param onlyJs - Force JavaScript implementation

148

* @returns Compressed public key (33 bytes)

149

*/

150

function secp256k1Compress(publicKey: Uint8Array, onlyJs?: boolean): Uint8Array;

151

152

/**

153

* Expand secp256k1 public key from compressed (33 bytes) to uncompressed coordinates (64 bytes)

154

* @param publicKey - Public key to expand (33 or 65 bytes)

155

* @param onlyJs - Force JavaScript implementation

156

* @returns Uncompressed public key coordinates (64 bytes, without 0x04 prefix)

157

*/

158

function secp256k1Expand(publicKey: Uint8Array, onlyJs?: boolean): Uint8Array;

159

160

/**

161

* Add a tweak to a secp256k1 private key

162

* @param seckey - Private key (32 bytes)

163

* @param tweak - Tweak value (32 bytes)

164

* @param onlyBn - Force BN.js implementation

165

* @returns Modified private key (32 bytes)

166

*/

167

function secp256k1PrivateKeyTweakAdd(seckey: Uint8Array, tweak: Uint8Array, onlyBn?: boolean): Uint8Array;

168

```

169

170

**Usage Example:**

171

172

```typescript

173

import {

174

secp256k1PairFromSeed,

175

secp256k1Sign,

176

secp256k1Verify,

177

secp256k1Recover,

178

secp256k1Compress,

179

secp256k1Expand,

180

secp256k1PrivateKeyTweakAdd,

181

keccak256AsU8a

182

} from "@polkadot/util-crypto";

183

184

const seed = new Uint8Array(32);

185

const pair = secp256k1PairFromSeed(seed);

186

const message = new TextEncoder().encode("Hello Ethereum");

187

const messageHash = keccak256AsU8a(message);

188

189

// Sign message hash

190

const signature = secp256k1Sign(messageHash, pair.secretKey);

191

192

// Verify signature

193

const isValid = secp256k1Verify(messageHash, signature, pair.publicKey);

194

195

// Recover public key

196

const recoveredKey = secp256k1Recover(messageHash, signature, 0);

197

198

// Compress public key

199

const compressedKey = secp256k1Compress(pair.publicKey);

200

201

// Expand compressed key to coordinates

202

const expandedKey = secp256k1Expand(compressedKey);

203

204

// Add tweak to private key

205

const tweak = new Uint8Array(32);

206

const tweakedPrivateKey = secp256k1PrivateKeyTweakAdd(pair.secretKey, tweak);

207

```

208

209

### Universal Signature Verification

210

211

Automatic detection and verification of different signature formats.

212

213

```typescript { .api }

214

/**

215

* Verify signature with automatic format detection

216

* @param message - Original message bytes

217

* @param signature - Signature in any supported format

218

* @param addressOrPublicKey - Address string or public key bytes

219

* @returns Verification result with details

220

*/

221

function signatureVerify(

222

message: Uint8Array,

223

signature: Uint8Array | string,

224

addressOrPublicKey: string | Uint8Array

225

): VerifyResult;

226

227

interface VerifyResult {

228

/** The detected crypto interface, or 'none' if not detected */

229

crypto: 'none' | KeypairType;

230

/** The validity for this result, false if invalid */

231

isValid: boolean;

232

/** Flag to indicate if the passed data was wrapped in <Bytes>...</Bytes> */

233

isWrapped: boolean;

234

/** The extracted publicKey */

235

publicKey: Uint8Array;

236

}

237

```

238

239

**Usage Example:**

240

241

```typescript

242

import { signatureVerify } from "@polkadot/util-crypto";

243

244

const message = new TextEncoder().encode("Test message");

245

const signature = "0x..."; // Any signature format

246

const address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";

247

248

const result = signatureVerify(message, signature, address);

249

250

console.log("Crypto scheme:", result.crypto);

251

console.log("Is valid:", result.isValid);

252

console.log("Public key:", result.publicKey);

253

```

254

255

## Key Derivation and Signing

256

257

### Sr25519 Key Derivation

258

259

Hard and soft key derivation for hierarchical signing.

260

261

```typescript { .api }

262

/**

263

* Derive sr25519 public key (soft derivation)

264

* @param publicKey - Parent public key

265

* @param chainCode - Chain code for derivation

266

* @returns Derived public key

267

*/

268

function sr25519DerivePublic(publicKey: Uint8Array, chainCode: Uint8Array): Uint8Array;

269

270

/**

271

* Derive sr25519 key pair (soft derivation)

272

* @param pair - Parent key pair

273

* @param chainCode - Chain code for derivation

274

* @returns Derived key pair

275

*/

276

function sr25519DeriveSoft(pair: Keypair, chainCode: Uint8Array): Keypair;

277

278

/**

279

* Hard derivation for sr25519

280

* @param seed - Parent seed

281

* @param chainCode - Chain code for derivation

282

* @returns Derived seed

283

*/

284

function sr25519DeriveHard(seed: Uint8Array, chainCode: Uint8Array): Uint8Array;

285

286

/**

287

* Sr25519 Diffie-Hellman agreement

288

* @param publicKey - Other party's public key

289

* @param secretKey - Own secret key

290

* @returns Shared secret

291

*/

292

function sr25519Agreement(publicKey: Uint8Array, secretKey: Uint8Array): Uint8Array;

293

```

294

295

### Ed25519 Key Derivation

296

297

```typescript { .api }

298

/**

299

* Hard derivation for ed25519

300

* @param seed - Parent seed

301

* @param chainCode - Chain code for derivation

302

* @returns Derived seed

303

*/

304

function ed25519DeriveHard(seed: Uint8Array, chainCode: Uint8Array): Uint8Array;

305

```

306

307

## Signature Format Notes

308

309

- **Sr25519**: 64-byte signatures, supports batch verification

310

- **Ed25519**: 64-byte deterministic signatures, very fast verification

311

- **Secp256k1**: Variable length with recovery, Ethereum-compatible

312

- **Multi-format**: `signatureVerify` handles automatic detection

313

314

## Security Considerations

315

316

- Always verify signatures before trusting signed data

317

- Use appropriate hash functions for each signature scheme

318

- Be careful with signature malleability in secp256k1

319

- VRF provides both signature and verifiable randomness

320

- Store private keys securely and never reuse nonces