@@ -14,6 +14,7 @@ import {
1414 HandshakeSuccessV2 ,
1515 HandshakeSuccessV2Legacy ,
1616 HandshakeSuccessV2_v021 ,
17+ HandshakeSuccessV2_v022 ,
1718 MetadataKey ,
1819 VersionedHandshakeProposal ,
1920 VersionedHandshakeResponse ,
@@ -24,6 +25,7 @@ import {
2425const fixedChatPrivateKey = new Uint8Array ( 32 ) . fill ( 0xdd ) ;
2526const fixedChatPublicKey = p256 . getPublicKey ( fixedChatPrivateKey , false ) ;
2627const fixedSsoEncPubKey = new Uint8Array ( 65 ) . fill ( 0x06 ) ;
28+ const fixedRootEntropySource = new Uint8Array ( 32 ) . fill ( 0x07 ) ;
2729
2830const makeDevice = ( ) => ( {
2931 statementAccountId : new Uint8Array ( 32 ) . fill ( 0xa1 ) ,
@@ -95,26 +97,53 @@ describe('VersionedHandshakeProposal', () => {
9597 } ) ;
9698} ) ;
9799
98- describe ( 'HandshakeSuccessV2 (spec v0.2.2, 226 bytes )' , ( ) => {
99- it ( 'round-trips identityAccountId, rootAccountId, identityChatPrivateKey, ssoEncPubKey, deviceEncPubKey' , ( ) => {
100+ describe ( 'HandshakeSuccessV2 (258 bytes, with rootEntropySource )' , ( ) => {
101+ it ( 'round-trips identityAccountId, rootAccountId, identityChatPrivateKey, ssoEncPubKey, deviceEncPubKey, rootEntropySource ' , ( ) => {
100102 const input = {
101103 identityAccountId : new Uint8Array ( 32 ) . fill ( 0xa1 ) ,
102104 rootAccountId : new Uint8Array ( 32 ) . fill ( 0xa2 ) ,
103105 identityChatPrivateKey : fixedChatPrivateKey ,
104106 ssoEncPubKey : fixedSsoEncPubKey ,
105107 deviceEncPubKey : new Uint8Array ( 65 ) . fill ( 0x04 ) ,
108+ rootEntropySource : fixedRootEntropySource ,
106109 } ;
107110 const decoded = HandshakeSuccessV2 . dec ( HandshakeSuccessV2 . enc ( input ) ) ;
108111 expect ( decoded ) . toEqual ( input ) ;
109112 } ) ;
110113
111- it ( 'encodes to exactly 226 bytes' , ( ) => {
114+ it ( 'encodes to exactly 258 bytes' , ( ) => {
112115 const encoded = HandshakeSuccessV2 . enc ( {
113116 identityAccountId : new Uint8Array ( 32 ) . fill ( 0xa1 ) ,
114117 rootAccountId : new Uint8Array ( 32 ) . fill ( 0xa2 ) ,
115118 identityChatPrivateKey : fixedChatPrivateKey ,
116119 ssoEncPubKey : fixedSsoEncPubKey ,
117120 deviceEncPubKey : new Uint8Array ( 65 ) . fill ( 0x04 ) ,
121+ rootEntropySource : fixedRootEntropySource ,
122+ } ) ;
123+ expect ( encoded . length ) . toBe ( 258 ) ;
124+ } ) ;
125+ } ) ;
126+
127+ describe ( 'HandshakeSuccessV2_v022 (spec v0.2.2, 226 bytes)' , ( ) => {
128+ it ( 'round-trips identityAccountId, rootAccountId, identityChatPrivateKey, ssoEncPubKey, deviceEncPubKey' , ( ) => {
129+ const input = {
130+ identityAccountId : new Uint8Array ( 32 ) . fill ( 0xa1 ) ,
131+ rootAccountId : new Uint8Array ( 32 ) . fill ( 0xa2 ) ,
132+ identityChatPrivateKey : fixedChatPrivateKey ,
133+ ssoEncPubKey : fixedSsoEncPubKey ,
134+ deviceEncPubKey : new Uint8Array ( 65 ) . fill ( 0x04 ) ,
135+ } ;
136+ const decoded = HandshakeSuccessV2_v022 . dec ( HandshakeSuccessV2_v022 . enc ( input ) ) ;
137+ expect ( decoded ) . toEqual ( input ) ;
138+ } ) ;
139+
140+ it ( 'encodes to exactly 226 bytes' , ( ) => {
141+ const encoded = HandshakeSuccessV2_v022 . enc ( {
142+ identityAccountId : new Uint8Array ( 32 ) . fill ( 0xa1 ) ,
143+ rootAccountId : new Uint8Array ( 32 ) . fill ( 0xa2 ) ,
144+ identityChatPrivateKey : fixedChatPrivateKey ,
145+ ssoEncPubKey : fixedSsoEncPubKey ,
146+ deviceEncPubKey : new Uint8Array ( 65 ) . fill ( 0x04 ) ,
118147 } ) ;
119148 expect ( encoded . length ) . toBe ( 226 ) ;
120149 } ) ;
@@ -170,13 +199,34 @@ describe('decodeEncryptedHandshakeResponseV2 (length-dispatched plaintext decode
170199 expect ( decoded ) . toEqual ( { tag : 'Pending' , value : { tag : 'AllowanceAllocation' , value : undefined } } ) ;
171200 } ) ;
172201
173- it ( 'decodes a 226 -byte v0.2.2 Success body with ssoEncPubKey ' , ( ) => {
202+ it ( 'decodes a 258 -byte Success body with rootEntropySource ' , ( ) => {
174203 const body = HandshakeSuccessV2 . enc ( {
175204 identityAccountId : new Uint8Array ( 32 ) . fill ( 0xa1 ) ,
176205 rootAccountId : new Uint8Array ( 32 ) . fill ( 0xa2 ) ,
177206 identityChatPrivateKey : fixedChatPrivateKey ,
178207 ssoEncPubKey : fixedSsoEncPubKey ,
179208 deviceEncPubKey : new Uint8Array ( 65 ) . fill ( 0x04 ) ,
209+ rootEntropySource : fixedRootEntropySource ,
210+ } ) ;
211+ const bytes = new Uint8Array ( 1 + body . length ) ;
212+ bytes [ 0 ] = 0x01 ;
213+ bytes . set ( body , 1 ) ;
214+ const decoded = decodeEncryptedHandshakeResponseV2 ( bytes ) ;
215+ expect ( decoded . tag ) . toBe ( 'Success' ) ;
216+ if ( decoded . tag !== 'Success' ) return ;
217+ expect ( decoded . value . rootAccountId ) . toEqual ( new Uint8Array ( 32 ) . fill ( 0xa2 ) ) ;
218+ expect ( decoded . value . ssoEncPubKey ) . toEqual ( fixedSsoEncPubKey ) ;
219+ expect ( decoded . value . deviceEncPubKey ) . toEqual ( new Uint8Array ( 65 ) . fill ( 0x04 ) ) ;
220+ expect ( decoded . value . rootEntropySource ) . toEqual ( fixedRootEntropySource ) ;
221+ } ) ;
222+
223+ it ( 'decodes a 226-byte v0.2.2 Success body with ssoEncPubKey and surfaces rootEntropySource as null' , ( ) => {
224+ const body = HandshakeSuccessV2_v022 . enc ( {
225+ identityAccountId : new Uint8Array ( 32 ) . fill ( 0xa1 ) ,
226+ rootAccountId : new Uint8Array ( 32 ) . fill ( 0xa2 ) ,
227+ identityChatPrivateKey : fixedChatPrivateKey ,
228+ ssoEncPubKey : fixedSsoEncPubKey ,
229+ deviceEncPubKey : new Uint8Array ( 65 ) . fill ( 0x04 ) ,
180230 } ) ;
181231 const bytes = new Uint8Array ( 1 + body . length ) ;
182232 bytes [ 0 ] = 0x01 ;
@@ -187,6 +237,7 @@ describe('decodeEncryptedHandshakeResponseV2 (length-dispatched plaintext decode
187237 expect ( decoded . value . rootAccountId ) . toEqual ( new Uint8Array ( 32 ) . fill ( 0xa2 ) ) ;
188238 expect ( decoded . value . ssoEncPubKey ) . toEqual ( fixedSsoEncPubKey ) ;
189239 expect ( decoded . value . deviceEncPubKey ) . toEqual ( new Uint8Array ( 65 ) . fill ( 0x04 ) ) ;
240+ expect ( decoded . value . rootEntropySource ) . toBeNull ( ) ;
190241 } ) ;
191242
192243 it ( 'decodes a 161-byte v0.2.1 Success body with rootAccountId and surfaces ssoEncPubKey as null' , ( ) => {
@@ -205,6 +256,7 @@ describe('decodeEncryptedHandshakeResponseV2 (length-dispatched plaintext decode
205256 expect ( decoded . value . rootAccountId ) . toEqual ( new Uint8Array ( 32 ) . fill ( 0xa2 ) ) ;
206257 expect ( decoded . value . identityChatPrivateKey ) . toEqual ( fixedChatPrivateKey ) ;
207258 expect ( decoded . value . ssoEncPubKey ) . toBeNull ( ) ;
259+ expect ( decoded . value . rootEntropySource ) . toBeNull ( ) ;
208260 } ) ;
209261
210262 it ( 'decodes a 129-byte v0.2 Success body and surfaces rootAccountId as null' , ( ) => {
@@ -221,13 +273,14 @@ describe('decodeEncryptedHandshakeResponseV2 (length-dispatched plaintext decode
221273 if ( decoded . tag !== 'Success' ) return ;
222274 expect ( decoded . value . rootAccountId ) . toBeNull ( ) ;
223275 expect ( decoded . value . ssoEncPubKey ) . toBeNull ( ) ;
276+ expect ( decoded . value . rootEntropySource ) . toBeNull ( ) ;
224277 expect ( decoded . value . identityAccountId ) . toEqual ( new Uint8Array ( 32 ) . fill ( 0xa1 ) ) ;
225278 } ) ;
226279
227280 it ( 'rejects a Success body of unknown length' , ( ) => {
228281 const bytes = new Uint8Array ( 50 ) ;
229282 bytes [ 0 ] = 0x01 ;
230- expect ( ( ) => decodeEncryptedHandshakeResponseV2 ( bytes ) ) . toThrow ( / n o t i n \{ 1 2 9 , 1 6 1 , 2 2 6 \} / ) ;
283+ expect ( ( ) => decodeEncryptedHandshakeResponseV2 ( bytes ) ) . toThrow ( / n o t i n \{ 1 2 9 , 1 6 1 , 2 2 6 , 2 5 8 \} / ) ;
231284 } ) ;
232285
233286 it ( 'decodes Failed with a UTF-8 reason string' , ( ) => {
@@ -257,7 +310,7 @@ describe('EncryptedHandshakeResponseV2 (native scale-ts Enum, used for encode)',
257310 expect ( encoded ) . toEqual ( new Uint8Array ( [ 0x00 , 0x00 ] ) ) ;
258311 } ) ;
259312
260- it ( 'round-trips Success on the v0.2.2 wire format ' , ( ) => {
313+ it ( 'round-trips Success with rootEntropySource ' , ( ) => {
261314 const success = {
262315 tag : 'Success' as const ,
263316 value : {
@@ -266,10 +319,11 @@ describe('EncryptedHandshakeResponseV2 (native scale-ts Enum, used for encode)',
266319 identityChatPrivateKey : fixedChatPrivateKey ,
267320 ssoEncPubKey : fixedSsoEncPubKey ,
268321 deviceEncPubKey : new Uint8Array ( 65 ) . fill ( 0x04 ) ,
322+ rootEntropySource : fixedRootEntropySource ,
269323 } ,
270324 } ;
271325 const encoded = EncryptedHandshakeResponseV2 . enc ( success ) ;
272- expect ( encoded . length ) . toBe ( 1 + 226 ) ;
326+ expect ( encoded . length ) . toBe ( 1 + 258 ) ;
273327 expect ( encoded [ 0 ] ) . toBe ( 0x01 ) ;
274328 expect ( EncryptedHandshakeResponseV2 . dec ( encoded ) ) . toEqual ( success ) ;
275329 } ) ;
0 commit comments