0
# Secp256k1 ECDSA Operations
1
2
Secp256k1 elliptic curve cryptography functions including key generation, signing, signature recovery, and public key compression/expansion operations. This is the same curve used by Bitcoin and Ethereum.
3
4
## Capabilities
5
6
### Generate Keypair from Seed
7
8
Generates a secp256k1 keypair from a secret key seed.
9
10
```typescript { .api }
11
/**
12
* Generates secp256k1 keypair from secret key
13
* @param seckey - 32-byte secret key as Uint8Array
14
* @returns 64-byte uncompressed public key as Uint8Array
15
*/
16
function secp256k1FromSeed(seckey: Uint8Array): Uint8Array;
17
```
18
19
**Usage Example:**
20
21
```typescript
22
import { waitReady, secp256k1FromSeed } from "@polkadot/wasm-crypto";
23
24
await waitReady();
25
26
const secretKey = new Uint8Array(32).fill(1); // Example secret key
27
const publicKey = secp256k1FromSeed(secretKey);
28
29
console.log("Secret key length:", secretKey.length); // 32
30
console.log("Public key length:", publicKey.length); // 64 (uncompressed)
31
```
32
33
### Sign Message Hash
34
35
Signs a message hash using secp256k1 ECDSA.
36
37
```typescript { .api }
38
/**
39
* Signs a message hash using secp256k1 ECDSA
40
* @param msgHash - 32-byte message hash as Uint8Array
41
* @param seckey - 32-byte secret key as Uint8Array
42
* @returns 65-byte signature as Uint8Array (64-byte signature + 1-byte recovery ID)
43
*/
44
function secp256k1Sign(msgHash: Uint8Array, seckey: Uint8Array): Uint8Array;
45
```
46
47
**Usage Example:**
48
49
```typescript
50
import { waitReady, secp256k1FromSeed, secp256k1Sign, sha256 } from "@polkadot/wasm-crypto";
51
52
await waitReady();
53
54
const secretKey = new Uint8Array(32).fill(1);
55
const publicKey = secp256k1FromSeed(secretKey);
56
57
// Hash the message first
58
const message = new TextEncoder().encode("Hello, secp256k1!");
59
const messageHash = sha256(message);
60
61
const signature = secp256k1Sign(messageHash, secretKey);
62
console.log("Signature length:", signature.length); // 65
63
```
64
65
### Recover Public Key from Signature
66
67
Recovers the public key from a secp256k1 signature and message hash.
68
69
```typescript { .api }
70
/**
71
* Recovers public key from secp256k1 signature
72
* @param msgHash - 32-byte message hash as Uint8Array
73
* @param sig - 64-byte signature as Uint8Array (without recovery ID)
74
* @param recovery - Recovery ID (0, 1, 2, or 3)
75
* @returns 64-byte uncompressed public key as Uint8Array
76
*/
77
function secp256k1Recover(msgHash: Uint8Array, sig: Uint8Array, recovery: number): Uint8Array;
78
```
79
80
**Usage Example:**
81
82
```typescript
83
import {
84
waitReady,
85
secp256k1FromSeed,
86
secp256k1Sign,
87
secp256k1Recover,
88
sha256
89
} from "@polkadot/wasm-crypto";
90
91
await waitReady();
92
93
const secretKey = new Uint8Array(32).fill(1);
94
const originalPublicKey = secp256k1FromSeed(secretKey);
95
96
const message = new TextEncoder().encode("Hello, secp256k1!");
97
const messageHash = sha256(message);
98
99
const fullSignature = secp256k1Sign(messageHash, secretKey);
100
const signature = fullSignature.slice(0, 64); // Remove recovery ID
101
const recoveryId = fullSignature[64]; // Extract recovery ID
102
103
const recoveredPublicKey = secp256k1Recover(messageHash, signature, recoveryId);
104
105
// Compare original and recovered public keys
106
const keysMatch = Array.from(originalPublicKey).join(',') ===
107
Array.from(recoveredPublicKey).join(',');
108
console.log("Keys match:", keysMatch); // true
109
```
110
111
### Compress Public Key
112
113
Compresses a secp256k1 public key from 64 bytes to 33 bytes.
114
115
```typescript { .api }
116
/**
117
* Compresses secp256k1 public key
118
* @param pubkey - 64-byte uncompressed public key as Uint8Array
119
* @returns 33-byte compressed public key as Uint8Array
120
*/
121
function secp256k1Compress(pubkey: Uint8Array): Uint8Array;
122
```
123
124
**Usage Example:**
125
126
```typescript
127
import { waitReady, secp256k1FromSeed, secp256k1Compress } from "@polkadot/wasm-crypto";
128
129
await waitReady();
130
131
const secretKey = new Uint8Array(32).fill(1);
132
const uncompressedPublicKey = secp256k1FromSeed(secretKey);
133
const compressedPublicKey = secp256k1Compress(uncompressedPublicKey);
134
135
console.log("Uncompressed length:", uncompressedPublicKey.length); // 64
136
console.log("Compressed length:", compressedPublicKey.length); // 33
137
```
138
139
### Expand Public Key
140
141
Expands a compressed secp256k1 public key from 33 bytes to 64 bytes.
142
143
```typescript { .api }
144
/**
145
* Expands compressed secp256k1 public key
146
* @param pubkey - 33-byte compressed public key as Uint8Array
147
* @returns 64-byte uncompressed public key as Uint8Array
148
*/
149
function secp256k1Expand(pubkey: Uint8Array): Uint8Array;
150
```
151
152
**Usage Example:**
153
154
```typescript
155
import {
156
waitReady,
157
secp256k1FromSeed,
158
secp256k1Compress,
159
secp256k1Expand
160
} from "@polkadot/wasm-crypto";
161
162
await waitReady();
163
164
const secretKey = new Uint8Array(32).fill(1);
165
const originalPublicKey = secp256k1FromSeed(secretKey);
166
167
// Compress then expand
168
const compressedPublicKey = secp256k1Compress(originalPublicKey);
169
const expandedPublicKey = secp256k1Expand(compressedPublicKey);
170
171
// Keys should match after compression/expansion cycle
172
const keysMatch = Array.from(originalPublicKey).join(',') ===
173
Array.from(expandedPublicKey).join(',');
174
console.log("Compression/expansion cycle preserves key:", keysMatch); // true
175
```
176
177
## Complete Secp256k1 Workflow
178
179
```typescript
180
import {
181
waitReady,
182
secp256k1FromSeed,
183
secp256k1Sign,
184
secp256k1Recover,
185
secp256k1Compress,
186
secp256k1Expand,
187
sha256
188
} from "@polkadot/wasm-crypto";
189
190
async function demonstrateSecp256k1() {
191
await waitReady();
192
193
// Generate keypair
194
const secretKey = new Uint8Array(32);
195
crypto.getRandomValues(secretKey); // Use random secret in production
196
197
const publicKey = secp256k1FromSeed(secretKey);
198
199
// Test compression/expansion
200
const compressedPubKey = secp256k1Compress(publicKey);
201
const expandedPubKey = secp256k1Expand(compressedPubKey);
202
203
console.log("Compression/expansion works:",
204
Array.from(publicKey).join(',') === Array.from(expandedPubKey).join(',')
205
);
206
207
// Sign and recover
208
const message = new TextEncoder().encode("Test message for secp256k1");
209
const messageHash = sha256(message);
210
211
const fullSignature = secp256k1Sign(messageHash, secretKey);
212
const signature = fullSignature.slice(0, 64);
213
const recoveryId = fullSignature[64];
214
215
const recoveredPubKey = secp256k1Recover(messageHash, signature, recoveryId);
216
217
console.log("Key recovery works:",
218
Array.from(publicKey).join(',') === Array.from(recoveredPubKey).join(',')
219
);
220
221
return {
222
secretKey,
223
publicKey,
224
compressedPubKey,
225
signature,
226
recoveredPubKey
227
};
228
}
229
230
demonstrateSecp256k1();
231
```