@@ -112,8 +112,9 @@ To obtain a signature _S_ of structured data _D_ using private key _K_:
112
112
` secp256k1 ` signature of a message hash using private key _ K_ ; and,
113
113
114
114
- ` messageHash(D) = sha256(structuredDataPrefix || domainHash || structuredDataHash(D)) ` ;
115
- where ` structuredDataPrefix ` is a static value of ` "\xC0" ` , and ` domainHash `
116
- and ` structuredDataHash ` are as described below.
115
+ where ` structuredDataPrefix ` is a static value of ` "\x53\x49\x50\x30\x31\x38" `
116
+ (which spells "SIP018" in ASCII), and ` domainHash ` and ` structuredDataHash `
117
+ are as described below.
117
118
118
119
** Definition of** ` domainHash `
119
120
@@ -178,17 +179,19 @@ A future SIP may define standard types of Structured Data.
178
179
179
180
Structured Data hashes do not collide with _ presign-sighashes_ as currently no
180
181
Clarity Value in wire format forms a valid Stacks transaction. Furthermore, the
181
- ` 0xC0 ` byte prefix ensures that the input always differs in the first byte, as
182
- Stacks transactions start with a version byte of ` 0x00 ` (mainnet) or ` 0x80 `
183
- (testnet). A Clarity Value in wire format starts with a byte in the range of
184
- ` [0x00, 0x0C] ` .
182
+ ` 0x534950303138 ` byte prefix ensures that the input always differs in the first
183
+ six bytes, as Stacks transactions start with a version byte of ` 0x00 ` (mainnet)
184
+ or ` 0x80 ` (testnet), a four byte chain ID, and end with an authorisation type
185
+ that must be ` 0x04 ` or ` 0x05 ` in order to be valid. A Clarity Value in wire
186
+ format starts with a byte in the range of ` [0x00, 0x0C] ` . The prefix is easy to
187
+ remember because it spells "SIP018" in ASCII.
185
188
186
189
Replay attacks across applications, forks, and other signature-compatible chains
187
190
are mitigated by prepending a ` domainHash ` to the ` messageHash ` . A ` domainHash `
188
191
is calculated by hashing a ` domain ` Clarity Value tuple containing the
189
192
application name, version, and chain ID.
190
193
191
- This SIP is about signing and verifying application and chain specific
194
+ This SIP is about signing and verifying application and chain- specific
192
195
structured data. Replay protection on the application level is out of scope for
193
196
the standard. Application developers need to make sure that their applications
194
197
behave properly when they receive the same signed structured data more than
@@ -212,7 +215,7 @@ import {
212
215
} from " @stacks/transactions" ;
213
216
import { createHash } from " crypto" ;
214
217
215
- const structuredDataPrefix = Buffer .from ([0xC0 ]);
218
+ const structuredDataPrefix = Buffer .from ([0x53 , 0x49 , 0x50 , 0x30 , 0x31 , 0x38 ]);
216
219
217
220
const chainIds = {
218
221
mainnet: 1 ,
@@ -256,7 +259,7 @@ whether the signature is valid.
256
259
257
260
``` clojure
258
261
(define-constant chain-id u1 )
259
- (define-constant structured-data-prefix 0xc0 )
262
+ (define-constant structured-data-prefix 0x534950303138 )
260
263
261
264
(define-constant message-domain-hash (sha256 (to-consensus-buff
262
265
{
@@ -346,12 +349,12 @@ Using `structuredDataHash(CV)` with an input Clarity Value.
346
349
Using ` messageHash(CV) ` , which is
347
350
` sha256(Prefix || structuredDataHash(Domain) || structuredDataHash(CV)) ` .
348
351
349
- - Prefix = ` 0xC0 ` (constant value)
352
+ - Prefix = ` 0x534950303138 ` (constant value)
350
353
- Domain =
351
354
` tupleCV({"name": asciiCV("Test App"), "version": asciiCV("1.0.0"), "chain-id": uintCV(1)}) `
352
355
- CV = ` asciiCV("Hello World") `
353
356
- Message hash:
354
- ` c6ace1349f59b024dec0925df0a15baf8d27fc43a357ce61f48fdc8fa461e7b9 `
357
+ ` 1bfdab6d4158313ce34073fbb8d6b0fc32c154d439def12247a0f44bb2225259 `
355
358
356
359
## Message signing
357
360
@@ -369,15 +372,15 @@ And the following inputs to obtain the message hash for signing:
369
372
` tupleCV({"name": asciiCV("Test App"), "version": asciiCV("1.0.0"), "chain-id": uintCV(1)}) `
370
373
- CV = ` asciiCV("Hello World") `
371
374
- (Message hash:
372
- ` c6ace1349f59b024dec0925df0a15baf8d27fc43a357ce61f48fdc8fa461e7b9 ` )
375
+ ` 1bfdab6d4158313ce34073fbb8d6b0fc32c154d439def12247a0f44bb2225259 ` )
373
376
374
377
Produces the following signature:
375
378
376
- - ` fd1c62aae1b12c07571d6c7e379a20c3858005877306914da80ae6ee8c748a6d133fcd9169cac5684fe635a5a375960827bf2184849f6cde6ed828b370c72d1b00 `
379
+ - ` 8b94e45701d857c9f1d1d70e8b2ca076045dae4920fb0160be0642a68cd78de072ab527b5c5277a593baeb2a8b657c216b99f7abb5d14af35b4bf12ba6460ba401 `
377
380
378
381
Which can be verified in Clarity:
379
382
380
383
``` clarity
381
- (secp256k1-verify 0xc6ace1349f59b024dec0925df0a15baf8d27fc43a357ce61f48fdc8fa461e7b9 0xfd1c62aae1b12c07571d6c7e379a20c3858005877306914da80ae6ee8c748a6d133fcd9169cac5684fe635a5a375960827bf2184849f6cde6ed828b370c72d1b00 0x0390a5cac7c33fda49f70bc1b0866fa0ba7a9440d9de647fecb8132ceb76a94dfa)
384
+ (secp256k1-verify 0x1bfdab6d4158313ce34073fbb8d6b0fc32c154d439def12247a0f44bb2225259 0x8b94e45701d857c9f1d1d70e8b2ca076045dae4920fb0160be0642a68cd78de072ab527b5c5277a593baeb2a8b657c216b99f7abb5d14af35b4bf12ba6460ba401 0x0390a5cac7c33fda49f70bc1b0866fa0ba7a9440d9de647fecb8132ceb76a94dfa)
382
385
true
383
386
```
0 commit comments