or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bls-signatures.mdbls12-381.mdbn128.mdfields.mdindex.mdoptimized.mdsecp256k1.md

bls-signatures.mddocs/

0

# BLS Signatures

1

2

BLS (Boneh-Lynn-Shacham) signature schemes according to IETF standards, providing digital signatures with aggregation capabilities. These schemes are particularly important for blockchain applications where signature aggregation can significantly reduce data size and verification costs.

3

4

## Capabilities

5

6

### G2Basic Signature Scheme

7

8

The basic BLS signature scheme using G2 elements for signatures. This is the most commonly used BLS signature variant.

9

10

```python { .api }

11

class G2Basic:

12

DST: bytes # Domain separation tag

13

14

@classmethod

15

def SkToPk(cls, sk: int) -> bytes:

16

"""

17

Convert a secret key to a public key.

18

19

Args:

20

sk (int): Secret key as integer

21

22

Returns:

23

bytes: 48-byte compressed public key

24

"""

25

26

@staticmethod

27

def KeyValidate(pk: bytes) -> bool:

28

"""

29

Validate a public key.

30

31

Args:

32

pk (bytes): 48-byte public key to validate

33

34

Returns:

35

bool: True if key is valid, False otherwise

36

"""

37

38

@classmethod

39

def Sign(cls, sk: int, message: bytes) -> bytes:

40

"""

41

Sign a message with a secret key.

42

43

Args:

44

sk (int): Secret key as integer

45

message (bytes): Message to sign

46

47

Returns:

48

bytes: 96-byte signature

49

"""

50

51

@classmethod

52

def Verify(cls, pk: bytes, message: bytes, signature: bytes) -> bool:

53

"""

54

Verify a signature.

55

56

Args:

57

pk (bytes): 48-byte public key

58

message (bytes): Original message

59

signature (bytes): 96-byte signature to verify

60

61

Returns:

62

bool: True if signature is valid, False otherwise

63

"""

64

65

@classmethod

66

def Aggregate(cls, signatures: Sequence[bytes]) -> bytes:

67

"""

68

Aggregate multiple signatures into one.

69

70

Args:

71

signatures (Sequence[bytes]): List of 96-byte signatures

72

73

Returns:

74

bytes: 96-byte aggregated signature

75

"""

76

77

@classmethod

78

def AggregateVerify(cls, pks: Sequence[bytes], messages: Sequence[bytes], signature: bytes) -> bool:

79

"""

80

Verify an aggregated signature against multiple public keys and messages.

81

82

Args:

83

pks (Sequence[bytes]): List of 48-byte public keys

84

messages (Sequence[bytes]): List of messages (one per public key)

85

signature (bytes): 96-byte aggregated signature

86

87

Returns:

88

bool: True if aggregated signature is valid, False otherwise

89

"""

90

91

@classmethod

92

def FastAggregateVerify(cls, pks: Sequence[bytes], message: bytes, signature: bytes) -> bool:

93

"""

94

Fast verification of aggregated signature when all messages are identical.

95

96

Args:

97

pks (Sequence[bytes]): List of 48-byte public keys

98

message (bytes): Single message signed by all keys

99

signature (bytes): 96-byte aggregated signature

100

101

Returns:

102

bool: True if aggregated signature is valid, False otherwise

103

"""

104

```

105

106

### G2MessageAugmentation Signature Scheme

107

108

BLS signature scheme with message augmentation to prevent rogue key attacks without requiring proof of possession.

109

110

```python { .api }

111

class G2MessageAugmentation:

112

DST: bytes # Domain separation tag

113

114

@classmethod

115

def SkToPk(cls, sk: int) -> bytes:

116

"""Convert secret key to public key."""

117

118

@staticmethod

119

def KeyValidate(pk: bytes) -> bool:

120

"""Validate a public key."""

121

122

@classmethod

123

def Sign(cls, sk: int, message: bytes) -> bytes:

124

"""Sign a message with message augmentation."""

125

126

@classmethod

127

def Verify(cls, pk: bytes, message: bytes, signature: bytes) -> bool:

128

"""Verify a signature with message augmentation."""

129

130

@classmethod

131

def Aggregate(cls, signatures: Sequence[bytes]) -> bytes:

132

"""Aggregate multiple signatures."""

133

134

@classmethod

135

def AggregateVerify(cls, pks: Sequence[bytes], messages: Sequence[bytes], signature: bytes) -> bool:

136

"""Verify aggregated signature with message augmentation."""

137

```

138

139

### G2ProofOfPossession Signature Scheme

140

141

BLS signature scheme with proof of possession, providing the most secure aggregation capabilities.

142

143

```python { .api }

144

class G2ProofOfPossession:

145

DST: bytes # Domain separation tag

146

POP_DST: bytes # Proof of possession domain separation tag

147

148

@staticmethod

149

def SkToPk(sk: int) -> bytes:

150

"""Convert secret key to public key."""

151

152

@staticmethod

153

def KeyValidate(pk: bytes) -> bool:

154

"""Validate a public key."""

155

156

@classmethod

157

def Sign(cls, sk: int, message: bytes) -> bytes:

158

"""Sign a message."""

159

160

@classmethod

161

def Verify(cls, pk: bytes, message: bytes, signature: bytes) -> bool:

162

"""Verify a signature."""

163

164

@classmethod

165

def Aggregate(cls, signatures: Sequence[bytes]) -> bytes:

166

"""Aggregate multiple signatures."""

167

168

@classmethod

169

def AggregateVerify(cls, pks: Sequence[bytes], messages: Sequence[bytes], signature: bytes) -> bool:

170

"""Verify aggregated signature."""

171

172

@staticmethod

173

def FastAggregateVerify(pks: Sequence[bytes], message: bytes, signature: bytes) -> bool:

174

"""Fast verification when all messages are identical."""

175

176

@staticmethod

177

def PopProve(sk: int) -> bytes:

178

"""

179

Generate proof of possession for a secret key.

180

181

Args:

182

sk (int): Secret key

183

184

Returns:

185

bytes: 96-byte proof of possession

186

"""

187

188

@staticmethod

189

def PopVerify(pk: bytes, proof: bytes) -> bool:

190

"""

191

Verify proof of possession for a public key.

192

193

Args:

194

pk (bytes): 48-byte public key

195

proof (bytes): 96-byte proof of possession

196

197

Returns:

198

bool: True if proof is valid, False otherwise

199

"""

200

```

201

202

## Usage Examples

203

204

### Basic Signing and Verification

205

206

```python

207

from py_ecc.bls import G2Basic

208

209

# Generate key pair

210

private_key = 12345

211

public_key = G2Basic.SkToPk(private_key)

212

213

# Sign message

214

message = b"Hello, BLS signatures!"

215

signature = G2Basic.Sign(private_key, message)

216

217

# Verify signature

218

is_valid = G2Basic.Verify(public_key, message, signature)

219

assert is_valid

220

```

221

222

### Signature Aggregation

223

224

```python

225

from py_ecc.bls import G2Basic

226

227

# Multiple signers

228

private_keys = [123, 456, 789]

229

public_keys = [G2Basic.SkToPk(sk) for sk in private_keys]

230

messages = [b"Message 1", b"Message 2", b"Message 3"]

231

232

# Each signer signs their message

233

signatures = [G2Basic.Sign(sk, msg) for sk, msg in zip(private_keys, messages)]

234

235

# Aggregate signatures

236

aggregated_sig = G2Basic.Aggregate(signatures)

237

238

# Verify aggregated signature

239

is_valid = G2Basic.AggregateVerify(public_keys, messages, aggregated_sig)

240

assert is_valid

241

```

242

243

### Fast Aggregate Verification

244

245

```python

246

from py_ecc.bls import G2Basic

247

248

# Multiple signers signing the same message

249

private_keys = [111, 222, 333]

250

public_keys = [G2Basic.SkToPk(sk) for sk in private_keys]

251

message = b"Same message for all"

252

253

# Each signer signs the same message

254

signatures = [G2Basic.Sign(sk, message) for sk in private_keys]

255

256

# Aggregate signatures

257

aggregated_sig = G2Basic.Aggregate(signatures)

258

259

# Fast verification (more efficient when all messages are identical)

260

is_valid = G2Basic.FastAggregateVerify(public_keys, message, aggregated_sig)

261

assert is_valid

262

```

263

264

### Proof of Possession

265

266

```python

267

from py_ecc.bls import G2ProofOfPossession

268

269

# Generate key pair

270

private_key = 54321

271

public_key = G2ProofOfPossession.SkToPk(private_key)

272

273

# Generate proof of possession

274

pop_proof = G2ProofOfPossession.PopProve(private_key)

275

276

# Verify proof of possession

277

is_valid_pop = G2ProofOfPossession.PopVerify(public_key, pop_proof)

278

assert is_valid_pop

279

280

# Now the public key can be safely used in aggregation

281

message = b"Secure aggregation message"

282

signature = G2ProofOfPossession.Sign(private_key, message)

283

is_valid = G2ProofOfPossession.Verify(public_key, message, signature)

284

assert is_valid

285

```

286

287

## Error Handling

288

289

All BLS signature functions may raise `ValidationError` from `eth_utils` for invalid inputs:

290

291

- Invalid key formats or lengths

292

- Invalid signature formats or lengths

293

- Points not in the correct subgroups

294

- Invalid curve points

295

296

Always validate inputs when working with untrusted data:

297

298

```python

299

from py_ecc.bls import G2Basic

300

from eth_utils import ValidationError

301

302

try:

303

is_valid_key = G2Basic.KeyValidate(untrusted_public_key)

304

if is_valid_key:

305

result = G2Basic.Verify(untrusted_public_key, message, signature)

306

else:

307

print("Invalid public key")

308

except ValidationError as e:

309

print(f"Validation error: {e}")

310

```