walletpair-sdk 1.0.2 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/ble/framing.d.ts.map +1 -1
- package/dist/ble/framing.js +2 -2
- package/dist/ble/framing.js.map +1 -1
- package/dist/ble/index.d.ts +2 -2
- package/dist/ble/index.d.ts.map +1 -1
- package/dist/ble/index.js +2 -2
- package/dist/ble/index.js.map +1 -1
- package/dist/ble/web-ble-transport.d.ts +1 -1
- package/dist/ble/web-ble-transport.d.ts.map +1 -1
- package/dist/ble/web-ble-transport.js +23 -12
- package/dist/ble/web-ble-transport.js.map +1 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +29 -12
- package/dist/crypto.js.map +1 -1
- package/dist/dapp-session.d.ts.map +1 -1
- package/dist/dapp-session.js +15 -5
- package/dist/dapp-session.js.map +1 -1
- package/dist/emitter.d.ts +1 -3
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +4 -2
- package/dist/emitter.js.map +1 -1
- package/dist/evm/eip1193.d.ts +2 -2
- package/dist/evm/eip1193.d.ts.map +1 -1
- package/dist/evm/eip1193.js +32 -18
- package/dist/evm/eip1193.js.map +1 -1
- package/dist/evm/index.d.ts +2 -2
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js.map +1 -1
- package/dist/wallet-session.d.ts.map +1 -1
- package/dist/wallet-session.js +4 -3
- package/dist/wallet-session.js.map +1 -1
- package/dist/ws-transport.d.ts +3 -2
- package/dist/ws-transport.d.ts.map +1 -1
- package/dist/ws-transport.js +13 -4
- package/dist/ws-transport.js.map +1 -1
- package/package.json +20 -1
- package/src/__tests__/adversarial/crypto-attacks.test.ts +240 -233
- package/src/__tests__/adversarial/malicious-dapp.test.ts +228 -194
- package/src/__tests__/adversarial/malicious-relay.test.ts +292 -220
- package/src/__tests__/adversarial/malicious-wallet.test.ts +246 -180
- package/src/__tests__/spec-compliance/canonical-json.test.ts +105 -105
- package/src/__tests__/spec-compliance/crypto-vectors.test.ts +149 -154
- package/src/__tests__/spec-compliance/message-format.test.ts +180 -151
- package/src/__tests__/spec-compliance/sequence-numbers.test.ts +142 -149
- package/src/__tests__/spec-compliance/state-machine.test.ts +203 -180
- package/src/ble/framing.test.ts +122 -114
- package/src/ble/framing.ts +48 -51
- package/src/ble/index.ts +7 -7
- package/src/ble/web-ble-transport.test.ts +93 -84
- package/src/ble/web-ble-transport.ts +70 -57
- package/src/ble/web-bluetooth.d.ts +19 -19
- package/src/canonical-json.test.ts +301 -285
- package/src/crypto-directional.test.ts +155 -129
- package/src/crypto-hardening.test.ts +292 -283
- package/src/crypto.test.ts +364 -346
- package/src/crypto.ts +185 -175
- package/src/dapp-session.test.ts +522 -385
- package/src/dapp-session.ts +17 -11
- package/src/emitter.test.ts +122 -122
- package/src/emitter.ts +20 -18
- package/src/evm/eip1193.test.ts +283 -205
- package/src/evm/eip1193.ts +162 -138
- package/src/evm/index.ts +5 -5
- package/src/evm/wagmi.test.ts +1 -1
- package/src/integration.test.ts +329 -201
- package/src/security.test.ts +331 -238
- package/src/sequence-validation.test.ts +6 -9
- package/src/test-helpers.ts +102 -78
- package/src/types.test.ts +45 -50
- package/src/wallet-session.test.ts +611 -383
- package/src/wallet-session.ts +7 -9
- package/src/ws-transport.test.ts +141 -139
- package/src/ws-transport.ts +52 -41
|
@@ -5,15 +5,8 @@
|
|
|
5
5
|
* classes, using pure functions that any implementation can replicate.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { describe, expect, it } from 'vitest'
|
|
9
|
-
import {
|
|
10
|
-
b64urlDecode,
|
|
11
|
-
bytesToHex,
|
|
12
|
-
hexToBytes,
|
|
13
|
-
sealPayload,
|
|
14
|
-
unsealPayload,
|
|
15
|
-
generateChannelId,
|
|
16
|
-
} from '../../crypto.js';
|
|
8
|
+
import { describe, expect, it } from 'vitest'
|
|
9
|
+
import { b64urlDecode, bytesToHex, sealPayload, unsealPayload } from '../../crypto.js'
|
|
17
10
|
|
|
18
11
|
// ---------------------------------------------------------------------------
|
|
19
12
|
// Sequence number validator (pure model per Section 6.6.1)
|
|
@@ -26,21 +19,21 @@ import {
|
|
|
26
19
|
*/
|
|
27
20
|
class SequenceValidator {
|
|
28
21
|
/** Highest accepted sequence number. -1 means none accepted yet. */
|
|
29
|
-
private lastAccepted = -1
|
|
22
|
+
private lastAccepted = -1
|
|
30
23
|
|
|
31
24
|
/**
|
|
32
25
|
* Attempt to accept a sequence number.
|
|
33
26
|
* Returns true if accepted, false if rejected (replay/non-increasing).
|
|
34
27
|
*/
|
|
35
28
|
accept(seq: number): boolean {
|
|
36
|
-
if (seq <= this.lastAccepted) return false
|
|
37
|
-
this.lastAccepted = seq
|
|
38
|
-
return true
|
|
29
|
+
if (seq <= this.lastAccepted) return false
|
|
30
|
+
this.lastAccepted = seq
|
|
31
|
+
return true
|
|
39
32
|
}
|
|
40
33
|
|
|
41
34
|
/** Current high watermark. */
|
|
42
35
|
get highWatermark(): number {
|
|
43
|
-
return this.lastAccepted
|
|
36
|
+
return this.lastAccepted
|
|
44
37
|
}
|
|
45
38
|
}
|
|
46
39
|
|
|
@@ -50,22 +43,22 @@ class SequenceValidator {
|
|
|
50
43
|
* Limit at 2^31.
|
|
51
44
|
*/
|
|
52
45
|
class SendSequence {
|
|
53
|
-
private seq = 0
|
|
46
|
+
private seq = 0
|
|
54
47
|
|
|
55
48
|
/** Get the next sequence number for sending, or null if limit reached. */
|
|
56
49
|
next(): number | null {
|
|
57
|
-
if (this.seq >= 2 ** 31) return null
|
|
58
|
-
return this.seq
|
|
50
|
+
if (this.seq >= 2 ** 31) return null
|
|
51
|
+
return this.seq++
|
|
59
52
|
}
|
|
60
53
|
|
|
61
54
|
/** Current value (next seq that will be used). */
|
|
62
55
|
get current(): number {
|
|
63
|
-
return this.seq
|
|
56
|
+
return this.seq
|
|
64
57
|
}
|
|
65
58
|
|
|
66
59
|
/** Set the counter to a specific value (for testing). */
|
|
67
60
|
setTo(n: number): void {
|
|
68
|
-
this.seq = n
|
|
61
|
+
this.seq = n
|
|
69
62
|
}
|
|
70
63
|
}
|
|
71
64
|
|
|
@@ -75,34 +68,34 @@ class SendSequence {
|
|
|
75
68
|
|
|
76
69
|
describe('Section 6.6.1 — Sequence number starts at 0', () => {
|
|
77
70
|
it('first send sequence is 0', () => {
|
|
78
|
-
const send = new SendSequence()
|
|
79
|
-
expect(send.next()).toBe(0)
|
|
80
|
-
})
|
|
71
|
+
const send = new SendSequence()
|
|
72
|
+
expect(send.next()).toBe(0)
|
|
73
|
+
})
|
|
81
74
|
|
|
82
75
|
it('first accepted receive sequence can be 0', () => {
|
|
83
|
-
const recv = new SequenceValidator()
|
|
84
|
-
expect(recv.accept(0)).toBe(true)
|
|
85
|
-
expect(recv.highWatermark).toBe(0)
|
|
86
|
-
})
|
|
87
|
-
})
|
|
76
|
+
const recv = new SequenceValidator()
|
|
77
|
+
expect(recv.accept(0)).toBe(true)
|
|
78
|
+
expect(recv.highWatermark).toBe(0)
|
|
79
|
+
})
|
|
80
|
+
})
|
|
88
81
|
|
|
89
82
|
describe('Section 6.6.1 — Increments by 1', () => {
|
|
90
83
|
it('send counter increments by 1 per message', () => {
|
|
91
|
-
const send = new SendSequence()
|
|
92
|
-
expect(send.next()).toBe(0)
|
|
93
|
-
expect(send.next()).toBe(1)
|
|
94
|
-
expect(send.next()).toBe(2)
|
|
95
|
-
expect(send.next()).toBe(3)
|
|
96
|
-
})
|
|
84
|
+
const send = new SendSequence()
|
|
85
|
+
expect(send.next()).toBe(0)
|
|
86
|
+
expect(send.next()).toBe(1)
|
|
87
|
+
expect(send.next()).toBe(2)
|
|
88
|
+
expect(send.next()).toBe(3)
|
|
89
|
+
})
|
|
97
90
|
|
|
98
91
|
it('receive validator accepts strictly increasing sequence', () => {
|
|
99
|
-
const recv = new SequenceValidator()
|
|
100
|
-
expect(recv.accept(0)).toBe(true)
|
|
101
|
-
expect(recv.accept(1)).toBe(true)
|
|
102
|
-
expect(recv.accept(2)).toBe(true)
|
|
103
|
-
expect(recv.accept(3)).toBe(true)
|
|
104
|
-
})
|
|
105
|
-
})
|
|
92
|
+
const recv = new SequenceValidator()
|
|
93
|
+
expect(recv.accept(0)).toBe(true)
|
|
94
|
+
expect(recv.accept(1)).toBe(true)
|
|
95
|
+
expect(recv.accept(2)).toBe(true)
|
|
96
|
+
expect(recv.accept(3)).toBe(true)
|
|
97
|
+
})
|
|
98
|
+
})
|
|
106
99
|
|
|
107
100
|
// ---------------------------------------------------------------------------
|
|
108
101
|
// Replay rejection (non-increasing)
|
|
@@ -110,34 +103,34 @@ describe('Section 6.6.1 — Increments by 1', () => {
|
|
|
110
103
|
|
|
111
104
|
describe('Section 6.6.1 — Reject non-increasing (replay)', () => {
|
|
112
105
|
it('rejects the same sequence number twice', () => {
|
|
113
|
-
const recv = new SequenceValidator()
|
|
114
|
-
expect(recv.accept(0)).toBe(true)
|
|
115
|
-
expect(recv.accept(0)).toBe(false)
|
|
116
|
-
})
|
|
106
|
+
const recv = new SequenceValidator()
|
|
107
|
+
expect(recv.accept(0)).toBe(true)
|
|
108
|
+
expect(recv.accept(0)).toBe(false) // replay
|
|
109
|
+
})
|
|
117
110
|
|
|
118
111
|
it('rejects a lower sequence number after a higher one', () => {
|
|
119
|
-
const recv = new SequenceValidator()
|
|
120
|
-
expect(recv.accept(5)).toBe(true)
|
|
121
|
-
expect(recv.accept(3)).toBe(false)
|
|
122
|
-
expect(recv.accept(4)).toBe(false)
|
|
123
|
-
expect(recv.accept(5)).toBe(false)
|
|
124
|
-
})
|
|
112
|
+
const recv = new SequenceValidator()
|
|
113
|
+
expect(recv.accept(5)).toBe(true)
|
|
114
|
+
expect(recv.accept(3)).toBe(false) // lower than watermark
|
|
115
|
+
expect(recv.accept(4)).toBe(false) // still lower
|
|
116
|
+
expect(recv.accept(5)).toBe(false) // equal to watermark
|
|
117
|
+
})
|
|
125
118
|
|
|
126
119
|
it('rejects seq=0 replay after initial acceptance', () => {
|
|
127
|
-
const recv = new SequenceValidator()
|
|
128
|
-
recv.accept(0)
|
|
129
|
-
recv.accept(1)
|
|
130
|
-
expect(recv.accept(0)).toBe(false)
|
|
131
|
-
})
|
|
120
|
+
const recv = new SequenceValidator()
|
|
121
|
+
recv.accept(0)
|
|
122
|
+
recv.accept(1)
|
|
123
|
+
expect(recv.accept(0)).toBe(false)
|
|
124
|
+
})
|
|
132
125
|
|
|
133
126
|
it('multiple replays are all rejected', () => {
|
|
134
|
-
const recv = new SequenceValidator()
|
|
135
|
-
recv.accept(0)
|
|
127
|
+
const recv = new SequenceValidator()
|
|
128
|
+
recv.accept(0)
|
|
136
129
|
for (let i = 0; i < 10; i++) {
|
|
137
|
-
expect(recv.accept(0)).toBe(false)
|
|
130
|
+
expect(recv.accept(0)).toBe(false)
|
|
138
131
|
}
|
|
139
|
-
})
|
|
140
|
-
})
|
|
132
|
+
})
|
|
133
|
+
})
|
|
141
134
|
|
|
142
135
|
// ---------------------------------------------------------------------------
|
|
143
136
|
// Gaps are valid (after reconnect)
|
|
@@ -145,79 +138,79 @@ describe('Section 6.6.1 — Reject non-increasing (replay)', () => {
|
|
|
145
138
|
|
|
146
139
|
describe('Section 6.6.1 — Gaps valid (expected after reconnect)', () => {
|
|
147
140
|
it('accepts seq=0 then seq=5 (gap of 4)', () => {
|
|
148
|
-
const recv = new SequenceValidator()
|
|
149
|
-
expect(recv.accept(0)).toBe(true)
|
|
150
|
-
expect(recv.accept(5)).toBe(true)
|
|
151
|
-
expect(recv.highWatermark).toBe(5)
|
|
152
|
-
})
|
|
141
|
+
const recv = new SequenceValidator()
|
|
142
|
+
expect(recv.accept(0)).toBe(true)
|
|
143
|
+
expect(recv.accept(5)).toBe(true)
|
|
144
|
+
expect(recv.highWatermark).toBe(5)
|
|
145
|
+
})
|
|
153
146
|
|
|
154
147
|
it('accepts large gaps', () => {
|
|
155
|
-
const recv = new SequenceValidator()
|
|
156
|
-
expect(recv.accept(0)).toBe(true)
|
|
157
|
-
expect(recv.accept(1000)).toBe(true)
|
|
158
|
-
expect(recv.accept(500000)).toBe(true)
|
|
159
|
-
})
|
|
148
|
+
const recv = new SequenceValidator()
|
|
149
|
+
expect(recv.accept(0)).toBe(true)
|
|
150
|
+
expect(recv.accept(1000)).toBe(true)
|
|
151
|
+
expect(recv.accept(500000)).toBe(true)
|
|
152
|
+
})
|
|
160
153
|
|
|
161
154
|
it('rejects values within a gap after the gap is established', () => {
|
|
162
|
-
const recv = new SequenceValidator()
|
|
163
|
-
recv.accept(0)
|
|
164
|
-
recv.accept(10)
|
|
155
|
+
const recv = new SequenceValidator()
|
|
156
|
+
recv.accept(0)
|
|
157
|
+
recv.accept(10)
|
|
165
158
|
// All values 0-10 are now below the watermark
|
|
166
159
|
for (let i = 0; i <= 10; i++) {
|
|
167
|
-
expect(recv.accept(i)).toBe(false)
|
|
160
|
+
expect(recv.accept(i)).toBe(false)
|
|
168
161
|
}
|
|
169
162
|
// 11 and above are accepted
|
|
170
|
-
expect(recv.accept(11)).toBe(true)
|
|
171
|
-
})
|
|
163
|
+
expect(recv.accept(11)).toBe(true)
|
|
164
|
+
})
|
|
172
165
|
|
|
173
166
|
it('gap from initial state (first message is not 0)', () => {
|
|
174
|
-
const recv = new SequenceValidator()
|
|
167
|
+
const recv = new SequenceValidator()
|
|
175
168
|
// After reconnect, the first message might not be seq=0
|
|
176
|
-
expect(recv.accept(42)).toBe(true)
|
|
177
|
-
expect(recv.highWatermark).toBe(42)
|
|
178
|
-
})
|
|
179
|
-
})
|
|
169
|
+
expect(recv.accept(42)).toBe(true)
|
|
170
|
+
expect(recv.highWatermark).toBe(42)
|
|
171
|
+
})
|
|
172
|
+
})
|
|
180
173
|
|
|
181
174
|
// ---------------------------------------------------------------------------
|
|
182
175
|
// Limit at 2^31
|
|
183
176
|
// ---------------------------------------------------------------------------
|
|
184
177
|
|
|
185
178
|
describe('Section 6.6.1 — Limit at 2^31', () => {
|
|
186
|
-
const LIMIT = 2 ** 31
|
|
179
|
+
const LIMIT = 2 ** 31 // 2,147,483,648
|
|
187
180
|
|
|
188
181
|
it('send counter allows 2^31 - 1 as the last valid sequence', () => {
|
|
189
|
-
const send = new SendSequence()
|
|
190
|
-
send.setTo(LIMIT - 1)
|
|
191
|
-
expect(send.next()).toBe(LIMIT - 1)
|
|
192
|
-
})
|
|
182
|
+
const send = new SendSequence()
|
|
183
|
+
send.setTo(LIMIT - 1)
|
|
184
|
+
expect(send.next()).toBe(LIMIT - 1)
|
|
185
|
+
})
|
|
193
186
|
|
|
194
187
|
it('send counter returns null (overflow) at 2^31', () => {
|
|
195
|
-
const send = new SendSequence()
|
|
196
|
-
send.setTo(LIMIT)
|
|
197
|
-
expect(send.next()).toBeNull()
|
|
198
|
-
})
|
|
188
|
+
const send = new SendSequence()
|
|
189
|
+
send.setTo(LIMIT)
|
|
190
|
+
expect(send.next()).toBeNull()
|
|
191
|
+
})
|
|
199
192
|
|
|
200
193
|
it('receive validator accepts up to 2^31 - 1', () => {
|
|
201
|
-
const recv = new SequenceValidator()
|
|
202
|
-
expect(recv.accept(LIMIT - 1)).toBe(true)
|
|
203
|
-
})
|
|
194
|
+
const recv = new SequenceValidator()
|
|
195
|
+
expect(recv.accept(LIMIT - 1)).toBe(true)
|
|
196
|
+
})
|
|
204
197
|
|
|
205
198
|
it('send counter reaches limit after 2^31 messages', () => {
|
|
206
199
|
// Verify the math: starting at 0, after LIMIT sends, next() returns null
|
|
207
|
-
const send = new SendSequence()
|
|
208
|
-
send.setTo(LIMIT - 1)
|
|
209
|
-
const lastValid = send.next()
|
|
210
|
-
expect(lastValid).toBe(LIMIT - 1)
|
|
211
|
-
expect(send.next()).toBeNull()
|
|
212
|
-
})
|
|
200
|
+
const send = new SendSequence()
|
|
201
|
+
send.setTo(LIMIT - 1)
|
|
202
|
+
const lastValid = send.next()
|
|
203
|
+
expect(lastValid).toBe(LIMIT - 1)
|
|
204
|
+
expect(send.next()).toBeNull() // overflow
|
|
205
|
+
})
|
|
213
206
|
|
|
214
207
|
it('the limit is 2^31 not 2^32-1 (signed integer safety)', () => {
|
|
215
208
|
// Section 6.6.1: "The limit is 2^31 rather than 2^32 - 1 to avoid
|
|
216
209
|
// signed integer overflow in languages where 32-bit integers are signed."
|
|
217
|
-
expect(LIMIT).toBe(2147483648)
|
|
218
|
-
expect(LIMIT).toBeLessThan(2 ** 32 - 1)
|
|
219
|
-
})
|
|
220
|
-
})
|
|
210
|
+
expect(LIMIT).toBe(2147483648)
|
|
211
|
+
expect(LIMIT).toBeLessThan(2 ** 32 - 1)
|
|
212
|
+
})
|
|
213
|
+
})
|
|
221
214
|
|
|
222
215
|
// ---------------------------------------------------------------------------
|
|
223
216
|
// Sequence persistence across reconnects
|
|
@@ -225,76 +218,76 @@ describe('Section 6.6.1 — Limit at 2^31', () => {
|
|
|
225
218
|
|
|
226
219
|
describe('Section 6.6.1 — Counters persist across reconnects', () => {
|
|
227
220
|
it('simulated reconnect preserves send counter', () => {
|
|
228
|
-
const send = new SendSequence()
|
|
229
|
-
send.next()
|
|
230
|
-
send.next()
|
|
231
|
-
send.next()
|
|
232
|
-
const savedSeq = send.current
|
|
221
|
+
const send = new SendSequence()
|
|
222
|
+
send.next() // 0
|
|
223
|
+
send.next() // 1
|
|
224
|
+
send.next() // 2
|
|
225
|
+
const savedSeq = send.current // 3
|
|
233
226
|
|
|
234
227
|
// Simulate reconnect: new SendSequence initialized from persisted state
|
|
235
|
-
const restored = new SendSequence()
|
|
236
|
-
restored.setTo(savedSeq)
|
|
237
|
-
expect(restored.next()).toBe(3)
|
|
238
|
-
expect(restored.next()).toBe(4)
|
|
239
|
-
})
|
|
228
|
+
const restored = new SendSequence()
|
|
229
|
+
restored.setTo(savedSeq)
|
|
230
|
+
expect(restored.next()).toBe(3) // continues from where we left off
|
|
231
|
+
expect(restored.next()).toBe(4)
|
|
232
|
+
})
|
|
240
233
|
|
|
241
234
|
it('simulated reconnect preserves receive watermark', () => {
|
|
242
|
-
const recv = new SequenceValidator()
|
|
243
|
-
recv.accept(0)
|
|
244
|
-
recv.accept(1)
|
|
245
|
-
recv.accept(2)
|
|
246
|
-
const savedWatermark = recv.highWatermark
|
|
235
|
+
const recv = new SequenceValidator()
|
|
236
|
+
recv.accept(0)
|
|
237
|
+
recv.accept(1)
|
|
238
|
+
recv.accept(2)
|
|
239
|
+
const savedWatermark = recv.highWatermark // 2
|
|
247
240
|
|
|
248
241
|
// Simulate reconnect: new SequenceValidator initialized from persisted state
|
|
249
|
-
const restored = new SequenceValidator()
|
|
242
|
+
const restored = new SequenceValidator()
|
|
250
243
|
// Set watermark by accepting the saved value
|
|
251
|
-
restored.accept(savedWatermark)
|
|
244
|
+
restored.accept(savedWatermark)
|
|
252
245
|
// Old sequences are rejected
|
|
253
|
-
expect(restored.accept(0)).toBe(false)
|
|
254
|
-
expect(restored.accept(1)).toBe(false)
|
|
255
|
-
expect(restored.accept(2)).toBe(false)
|
|
246
|
+
expect(restored.accept(0)).toBe(false)
|
|
247
|
+
expect(restored.accept(1)).toBe(false)
|
|
248
|
+
expect(restored.accept(2)).toBe(false)
|
|
256
249
|
// New sequences are accepted
|
|
257
|
-
expect(restored.accept(3)).toBe(true)
|
|
258
|
-
})
|
|
259
|
-
})
|
|
250
|
+
expect(restored.accept(3)).toBe(true)
|
|
251
|
+
})
|
|
252
|
+
})
|
|
260
253
|
|
|
261
254
|
// ---------------------------------------------------------------------------
|
|
262
255
|
// seq_bytes encoding in sealed messages
|
|
263
256
|
// ---------------------------------------------------------------------------
|
|
264
257
|
|
|
265
258
|
describe('Section 6.6 — seq_bytes is 4-byte big-endian in sealed messages', () => {
|
|
266
|
-
const key = new Uint8Array(32).fill(0xaa)
|
|
267
|
-
const ch = 'bb'.repeat(32)
|
|
259
|
+
const key = new Uint8Array(32).fill(0xaa)
|
|
260
|
+
const ch = 'bb'.repeat(32)
|
|
268
261
|
|
|
269
262
|
it('seq=0 encodes as 00000000', () => {
|
|
270
|
-
const sealed = sealPayload(key, ch, 0, { test: true })
|
|
271
|
-
const bytes = b64urlDecode(sealed)
|
|
272
|
-
expect(bytesToHex(bytes.slice(0, 4))).toBe('00000000')
|
|
273
|
-
})
|
|
263
|
+
const sealed = sealPayload(key, ch, 0, { test: true })
|
|
264
|
+
const bytes = b64urlDecode(sealed)
|
|
265
|
+
expect(bytesToHex(bytes.slice(0, 4))).toBe('00000000')
|
|
266
|
+
})
|
|
274
267
|
|
|
275
268
|
it('seq=1 encodes as 00000001', () => {
|
|
276
|
-
const sealed = sealPayload(key, ch, 1, { test: true })
|
|
277
|
-
const bytes = b64urlDecode(sealed)
|
|
278
|
-
expect(bytesToHex(bytes.slice(0, 4))).toBe('00000001')
|
|
279
|
-
})
|
|
269
|
+
const sealed = sealPayload(key, ch, 1, { test: true })
|
|
270
|
+
const bytes = b64urlDecode(sealed)
|
|
271
|
+
expect(bytesToHex(bytes.slice(0, 4))).toBe('00000001')
|
|
272
|
+
})
|
|
280
273
|
|
|
281
274
|
it('seq=256 encodes as 00000100', () => {
|
|
282
|
-
const sealed = sealPayload(key, ch, 256, { test: true })
|
|
283
|
-
const bytes = b64urlDecode(sealed)
|
|
284
|
-
expect(bytesToHex(bytes.slice(0, 4))).toBe('00000100')
|
|
285
|
-
})
|
|
275
|
+
const sealed = sealPayload(key, ch, 256, { test: true })
|
|
276
|
+
const bytes = b64urlDecode(sealed)
|
|
277
|
+
expect(bytesToHex(bytes.slice(0, 4))).toBe('00000100')
|
|
278
|
+
})
|
|
286
279
|
|
|
287
280
|
it('seq=2^31-1 encodes as 7fffffff', () => {
|
|
288
|
-
const sealed = sealPayload(key, ch, 2 ** 31 - 1, { test: true })
|
|
289
|
-
const bytes = b64urlDecode(sealed)
|
|
290
|
-
expect(bytesToHex(bytes.slice(0, 4))).toBe('7fffffff')
|
|
291
|
-
})
|
|
281
|
+
const sealed = sealPayload(key, ch, 2 ** 31 - 1, { test: true })
|
|
282
|
+
const bytes = b64urlDecode(sealed)
|
|
283
|
+
expect(bytesToHex(bytes.slice(0, 4))).toBe('7fffffff')
|
|
284
|
+
})
|
|
292
285
|
|
|
293
286
|
it('round-trip: seq is correctly extracted from sealed payload', () => {
|
|
294
287
|
for (const seq of [0, 1, 42, 1000, 65535, 2 ** 31 - 1]) {
|
|
295
|
-
const sealed = sealPayload(key, ch, seq, { n: seq })
|
|
296
|
-
const result = unsealPayload(key, ch, sealed)
|
|
297
|
-
expect(result.seq).toBe(seq)
|
|
288
|
+
const sealed = sealPayload(key, ch, seq, { n: seq })
|
|
289
|
+
const result = unsealPayload(key, ch, sealed)
|
|
290
|
+
expect(result.seq).toBe(seq)
|
|
298
291
|
}
|
|
299
|
-
})
|
|
300
|
-
})
|
|
292
|
+
})
|
|
293
|
+
})
|