or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdkey-management.mdpoint-operations.mdsignatures.mdutilities.md

signatures.mddocs/

0

# Digital Signatures

1

2

RFC8032-compliant signing and verification operations with both async and sync variants. Supports ZIP215 consensus-friendly verification and provides strong unforgeability under chosen message attacks (SUF-CMA).

3

4

## Capabilities

5

6

### Message Signing

7

8

Creates ed25519 signatures for messages using a secret key, following RFC8032 section 5.1.6.

9

10

```typescript { .api }

11

/**

12

* Sign a message asynchronously using ed25519

13

* @param message - Message to sign as Uint8Array

14

* @param secretKey - 32-byte secret key

15

* @returns Promise resolving to 64-byte signature

16

*/

17

function signAsync(message: Bytes, secretKey: Bytes): Promise<Bytes>;

18

19

/**

20

* Sign a message synchronously using ed25519 (requires hashes.sha512 to be set)

21

* @param message - Message to sign as Uint8Array

22

* @param secretKey - 32-byte secret key

23

* @returns 64-byte signature

24

*/

25

function sign(message: Bytes, secretKey: Bytes): Bytes;

26

```

27

28

**Usage Examples:**

29

30

```typescript

31

import * as ed from '@noble/ed25519';

32

33

// Generate keys

34

const { secretKey, publicKey } = await ed.keygenAsync();

35

36

// Sign a message (async)

37

const message = new TextEncoder().encode('Hello, World!');

38

const signature = await ed.signAsync(message, secretKey);

39

console.log(signature.length); // 64

40

41

// Sign with raw bytes

42

const rawMessage = new Uint8Array([1, 2, 3, 4, 5]);

43

const rawSignature = await ed.signAsync(rawMessage, secretKey);

44

45

// Sync version (requires setting hash function first)

46

import { sha512 } from '@noble/hashes/sha512';

47

ed.hashes.sha512 = sha512;

48

const syncSignature = ed.sign(message, secretKey);

49

```

50

51

### Signature Verification

52

53

Verifies ed25519 signatures against messages and public keys, following RFC8032 section 5.1.7 with optional ZIP215 compliance.

54

55

```typescript { .api }

56

/**

57

* Verify a signature asynchronously

58

* @param signature - 64-byte signature to verify

59

* @param message - Original message that was signed

60

* @param publicKey - 32-byte public key

61

* @param opts - Verification options

62

* @returns Promise resolving to true if signature is valid

63

*/

64

function verifyAsync(

65

signature: Bytes,

66

message: Bytes,

67

publicKey: Bytes,

68

opts?: EdDSAVerifyOpts

69

): Promise<boolean>;

70

71

/**

72

* Verify a signature synchronously (requires hashes.sha512 to be set)

73

* @param signature - 64-byte signature to verify

74

* @param message - Original message that was signed

75

* @param publicKey - 32-byte public key

76

* @param opts - Verification options

77

* @returns True if signature is valid

78

*/

79

function verify(

80

signature: Bytes,

81

message: Bytes,

82

publicKey: Bytes,

83

opts?: EdDSAVerifyOpts

84

): boolean;

85

86

/**

87

* Verification options for signature validation

88

*/

89

type EdDSAVerifyOpts = {

90

/** Enable ZIP215 compliance for consensus-friendly verification (default: true) */

91

zip215?: boolean

92

};

93

```

94

95

**Usage Examples:**

96

97

```typescript

98

import * as ed from '@noble/ed25519';

99

100

// Complete signing and verification flow

101

const { secretKey, publicKey } = await ed.keygenAsync();

102

const message = new TextEncoder().encode('Important message');

103

const signature = await ed.signAsync(message, secretKey);

104

105

// Verify signature (async)

106

const isValid = await ed.verifyAsync(signature, message, publicKey);

107

console.log(isValid); // true

108

109

// Verify with ZIP215 disabled (strict RFC8032 compliance)

110

const strictValid = await ed.verifyAsync(signature, message, publicKey, { zip215: false });

111

112

// Invalid signature verification

113

const tampered = new Uint8Array(signature);

114

tampered[0] = tampered[0] ^ 1; // Flip one bit

115

const invalidResult = await ed.verifyAsync(tampered, message, publicKey);

116

console.log(invalidResult); // false

117

118

// Sync version

119

import { sha512 } from '@noble/hashes/sha512';

120

ed.hashes.sha512 = sha512;

121

const syncValid = ed.verify(signature, message, publicKey);

122

```

123

124

### Compliance Modes

125

126

The library supports different verification compliance modes:

127

128

**ZIP215 Mode (Default)**

129

- Consensus-friendly verification

130

- Accepts non-canonical point encodings

131

- Suitable for blockchain and consensus applications

132

- Matches behavior expected by many crypto protocols

133

134

**RFC8032 Strict Mode**

135

- Strict compliance with RFC8032 specification

136

- Rejects non-canonical point encodings

137

- More restrictive validation

138

- Use `{ zip215: false }` in verification options

139

140

**Usage Example:**

141

142

```typescript

143

import * as ed from '@noble/ed25519';

144

145

const { secretKey, publicKey } = await ed.keygenAsync();

146

const message = new TextEncoder().encode('test message');

147

const signature = await ed.signAsync(message, secretKey);

148

149

// ZIP215 mode (default, consensus-friendly)

150

const zip215Valid = await ed.verifyAsync(signature, message, publicKey);

151

const zip215Explicit = await ed.verifyAsync(signature, message, publicKey, { zip215: true });

152

153

// RFC8032 strict mode

154

const strictValid = await ed.verifyAsync(signature, message, publicKey, { zip215: false });

155

156

console.log(zip215Valid, zip215Explicit, strictValid); // All should be true for valid signatures

157

```

158

159

## Error Handling

160

161

The signing and verification functions throw errors for invalid inputs:

162

163

- Invalid secret key length (must be 32 bytes)

164

- Invalid public key length (must be 32 bytes)

165

- Invalid signature length (must be 64 bytes)

166

- Invalid public key point (not on curve)

167

- Missing hash function for sync operations

168

169

```typescript

170

import * as ed from '@noble/ed25519';

171

172

try {

173

// This will throw - invalid key length

174

const invalidKey = new Uint8Array(31); // Should be 32

175

await ed.signAsync(new Uint8Array(10), invalidKey);

176

} catch (error) {

177

console.log('Invalid key length error');

178

}

179

```

180

181

## Types

182

183

```typescript { .api }

184

type Bytes = Uint8Array;

185

type EdDSAVerifyOpts = { zip215?: boolean };

186

```