Skip to content

Commit ed2342e

Browse files
Merge pull request #62 from lbaquerofierro/fix/byte-offset-bugs-0.8.1
Fix byte offset bugs when working with Uint8Array subarrays
2 parents 8d3bd94 + f00a7fc commit ed2342e

4 files changed

Lines changed: 59 additions & 20 deletions

File tree

src/generic_batched_token.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export class BatchedTokenRequest {
8282

8383
static deserialize(bytes: Uint8Array): BatchedTokenRequest {
8484
let offset = 0;
85-
const input = new DataView(bytes.buffer);
85+
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
8686

8787
const { value: length, usize } = varint.read(input, offset);
8888
offset += usize;
@@ -94,9 +94,9 @@ export class BatchedTokenRequest {
9494
const batchedTokenRequests: TokenRequest[] = [];
9595

9696
while (offset < bytes.length) {
97-
const tokenTypeEntry = tokenRequestToTokenTypeEntry(bytes);
97+
const tokenTypeEntry = tokenRequestToTokenTypeEntry(bytes.subarray(offset));
9898
const len = tokenEntryToSerializedLength(tokenTypeEntry);
99-
const b = new Uint8Array(input.buffer.slice(offset, offset + len));
99+
const b = bytes.subarray(offset, offset + len);
100100
offset += len;
101101

102102
batchedTokenRequests.push(TokenRequest.deserialize(b));
@@ -111,7 +111,12 @@ export class BatchedTokenRequest {
111111
let length = 0;
112112
for (const tokenRequest of this.tokenRequests) {
113113
const tokenRequestSerialized = tokenRequest.serialize();
114-
output.push(tokenRequestSerialized.buffer);
114+
output.push(
115+
(tokenRequestSerialized.buffer as ArrayBuffer).slice(
116+
tokenRequestSerialized.byteOffset,
117+
tokenRequestSerialized.byteOffset + tokenRequestSerialized.byteLength,
118+
),
119+
);
115120
length += tokenRequestSerialized.length;
116121
}
117122

@@ -217,7 +222,7 @@ export class GenericBatchTokenResponse {
217222

218223
static deserialize(bytes: Uint8Array): GenericBatchTokenResponse {
219224
let offset = 0;
220-
const input = new DataView(bytes.buffer);
225+
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
221226

222227
const { value: length, usize } = varint.read(input, offset);
223228
offset += usize;
@@ -229,7 +234,7 @@ export class GenericBatchTokenResponse {
229234
const batchedTokenResponses: OptionalTokenResponse[] = [];
230235

231236
while (offset < bytes.length) {
232-
const otr = OptionalTokenResponse.deserialize(bytes.slice(offset));
237+
const otr = OptionalTokenResponse.deserialize(bytes.subarray(offset));
233238
offset += otr.length();
234239
batchedTokenResponses.push(otr);
235240
}
@@ -244,7 +249,12 @@ export class GenericBatchTokenResponse {
244249
for (const tokenResponse of this.tokenResponses) {
245250
const tokenResponseSerialized = tokenResponse.serialize();
246251

247-
output.push(tokenResponseSerialized);
252+
output.push(
253+
(tokenResponseSerialized.buffer as ArrayBuffer).slice(
254+
tokenResponseSerialized.byteOffset,
255+
tokenResponseSerialized.byteOffset + tokenResponseSerialized.byteLength,
256+
),
257+
);
248258
length += tokenResponseSerialized.length;
249259
}
250260

src/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,23 @@ export async function header_to_token(header: string): Promise<string | null> {
8585
}
8686

8787
export function tokenEntryToSerializedLength(tokenType: TokenTypeEntry): number {
88+
// TokenRequest structure: 2-byte token_type + 1-byte truncated_token_key_id + blinded_msg
89+
const headerLen = 3; // token_type (2) + truncated_token_key_id (1)
8890
switch (tokenType.value) {
8991
case TOKEN_TYPES.VOPRF.value:
90-
return VOPRF.Ne + 2 * VOPRF.Nk;
92+
return headerLen + VOPRF.Ne;
9193
case TOKEN_TYPES.BLIND_RSA.value:
92-
return BLIND_RSA.Nk;
94+
return headerLen + BLIND_RSA.Nk;
9395
case TOKEN_TYPES.PARTIALLY_BLIND_RSA.value:
94-
return PARTIALLY_BLIND_RSA.Nk;
96+
return headerLen + PARTIALLY_BLIND_RSA.Nk;
9597
default:
9698
throw new Error(`unrecognized or non-supported token type: ${tokenType.value}`);
9799
}
98100
}
99101

100102
export function tokenRequestToTokenTypeEntry(bytes: Uint8Array): TokenTypeEntry {
101103
// All token requests have a 2-byte value at the beginning of the token describing TokenTypeEntry.
102-
const input = new DataView(bytes.buffer);
104+
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
103105

104106
const type = input.getUint16(0);
105107
const tokenType = Object.values(TOKEN_TYPES).find((t) => t.value === type);

src/priv_verif_token.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class TokenRequest {
9393

9494
static deserialize(bytes: Uint8Array): TokenRequest {
9595
let offset = 0;
96-
const input = new DataView(bytes.buffer);
96+
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
9797

9898
const type = input.getUint16(offset);
9999
offset += 2;
@@ -106,7 +106,7 @@ export class TokenRequest {
106106
offset += 1;
107107

108108
const len = VOPRF.Ne;
109-
const blindedMsg = new Uint8Array(input.buffer.slice(offset, offset + len));
109+
const blindedMsg = bytes.subarray(offset, offset + len);
110110
offset += len;
111111

112112
return new TokenRequest(truncatedTokenKeyId, blindedMsg);
@@ -123,7 +123,10 @@ export class TokenRequest {
123123
new DataView(b).setUint8(0, this.truncatedTokenKeyId);
124124
output.push(b);
125125

126-
b = this.blindedMsg.buffer;
126+
b = (this.blindedMsg.buffer as ArrayBuffer).slice(
127+
this.blindedMsg.byteOffset,
128+
this.blindedMsg.byteOffset + this.blindedMsg.byteLength,
129+
);
127130
output.push(b);
128131

129132
return new Uint8Array(joinAll(output));
@@ -161,7 +164,18 @@ export class TokenResponse {
161164
}
162165

163166
serialize(): Uint8Array {
164-
return new Uint8Array(joinAll([this.evaluateMsg, this.evaluateProof]));
167+
return new Uint8Array(
168+
joinAll([
169+
(this.evaluateMsg.buffer as ArrayBuffer).slice(
170+
this.evaluateMsg.byteOffset,
171+
this.evaluateMsg.byteOffset + this.evaluateMsg.byteLength,
172+
),
173+
(this.evaluateProof.buffer as ArrayBuffer).slice(
174+
this.evaluateProof.byteOffset,
175+
this.evaluateProof.byteOffset + this.evaluateProof.byteLength,
176+
),
177+
]),
178+
);
165179
}
166180

167181
length(): number {

src/pub_verif_token.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export class TokenRequest {
126126

127127
static deserialize(tokenType: TokenTypeEntry, bytes: Uint8Array): TokenRequest {
128128
let offset = 0;
129-
const input = new DataView(bytes.buffer);
129+
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
130130

131131
const type = input.getUint16(offset);
132132
offset += 2;
@@ -139,7 +139,7 @@ export class TokenRequest {
139139
offset += 1;
140140

141141
const len = tokenType.Nk;
142-
const blindedMsg = new Uint8Array(input.buffer.slice(offset, offset + len));
142+
const blindedMsg = bytes.subarray(offset, offset + len);
143143
offset += len;
144144

145145
return new TokenRequest(tokenKeyId, blindedMsg, tokenType);
@@ -156,7 +156,10 @@ export class TokenRequest {
156156
new DataView(b).setUint8(0, this.truncatedTokenKeyId);
157157
output.push(b);
158158

159-
b = this.blindedMsg.buffer;
159+
b = (this.blindedMsg.buffer as ArrayBuffer).slice(
160+
this.blindedMsg.byteOffset,
161+
this.blindedMsg.byteOffset + this.blindedMsg.byteLength,
162+
);
160163
output.push(b);
161164

162165
return new Uint8Array(joinAll(output));
@@ -184,10 +187,20 @@ export class ExtendedTokenRequest {
184187
const output = new Array<ArrayBuffer>();
185188

186189
const request = this.request.serialize();
187-
output.push(request.buffer);
190+
output.push(
191+
(request.buffer as ArrayBuffer).slice(
192+
request.byteOffset,
193+
request.byteOffset + request.byteLength,
194+
),
195+
);
188196

189197
const extensions = this.extensions.serialize();
190-
output.push(extensions.buffer);
198+
output.push(
199+
(extensions.buffer as ArrayBuffer).slice(
200+
extensions.byteOffset,
201+
extensions.byteOffset + extensions.byteLength,
202+
),
203+
);
191204

192205
return new Uint8Array(joinAll(output));
193206
}

0 commit comments

Comments
 (0)