Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/generic_batched_token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class BatchedTokenRequest {

static deserialize(bytes: Uint8Array): BatchedTokenRequest {
let offset = 0;
const input = new DataView(bytes.buffer);
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);

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

while (offset < bytes.length) {
const tokenTypeEntry = tokenRequestToTokenTypeEntry(bytes);
const tokenTypeEntry = tokenRequestToTokenTypeEntry(bytes.subarray(offset));
const len = tokenEntryToSerializedLength(tokenTypeEntry);
const b = new Uint8Array(input.buffer.slice(offset, offset + len));
const b = bytes.subarray(offset, offset + len);
offset += len;

batchedTokenRequests.push(TokenRequest.deserialize(b));
Expand All @@ -111,7 +111,12 @@ export class BatchedTokenRequest {
let length = 0;
for (const tokenRequest of this.tokenRequests) {
const tokenRequestSerialized = tokenRequest.serialize();
output.push(tokenRequestSerialized.buffer);
output.push(
(tokenRequestSerialized.buffer as ArrayBuffer).slice(
tokenRequestSerialized.byteOffset,
tokenRequestSerialized.byteOffset + tokenRequestSerialized.byteLength,
),
);
length += tokenRequestSerialized.length;
}

Expand Down Expand Up @@ -217,7 +222,7 @@ export class GenericBatchTokenResponse {

static deserialize(bytes: Uint8Array): GenericBatchTokenResponse {
let offset = 0;
const input = new DataView(bytes.buffer);
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);

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

while (offset < bytes.length) {
const otr = OptionalTokenResponse.deserialize(bytes.slice(offset));
const otr = OptionalTokenResponse.deserialize(bytes.subarray(offset));
offset += otr.length();
batchedTokenResponses.push(otr);
}
Expand All @@ -244,7 +249,12 @@ export class GenericBatchTokenResponse {
for (const tokenResponse of this.tokenResponses) {
const tokenResponseSerialized = tokenResponse.serialize();

output.push(tokenResponseSerialized);
output.push(
(tokenResponseSerialized.buffer as ArrayBuffer).slice(
tokenResponseSerialized.byteOffset,
tokenResponseSerialized.byteOffset + tokenResponseSerialized.byteLength,
),
);
length += tokenResponseSerialized.length;
}

Expand Down
10 changes: 6 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,23 @@ export async function header_to_token(header: string): Promise<string | null> {
}

export function tokenEntryToSerializedLength(tokenType: TokenTypeEntry): number {
// TokenRequest structure: 2-byte token_type + 1-byte truncated_token_key_id + blinded_msg
const headerLen = 3; // token_type (2) + truncated_token_key_id (1)
switch (tokenType.value) {
case TOKEN_TYPES.VOPRF.value:
return VOPRF.Ne + 2 * VOPRF.Nk;
return headerLen + VOPRF.Ne;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the blinded_msg size is Ne

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. For VOPRF the blinded_msg is Ne bytes per Section 5.1 of the spec (v16). The fix adds the 3 byte header (token_type + truncated_token_key_id) that was missing from the original calculation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add this test in this line:
https://github.com/cloudflare/privacypass-ts/blob/main/test/generic_batched_token.test.ts#L134

        // check BatchedTokenRequest deserialization.
        const token_request_bytes = hexToUint8(v.token_request);
        const tokReqGot = BatchedTokenRequest.deserialize(token_request_bytes);
        expect(tokReq.tokenRequests.length).toBe(tokReqGot.tokenRequests.length);
        for (let i = 0; i < tokReq.tokenRequests.length; i += 1) {
            expect(tokReq.tokenRequests[i].tokenType).toBe(tokReqGot.tokenRequests[i].tokenType);
            expect(tokReq.tokenRequests[i].truncatedTokenKeyId).toBe(
                tokReqGot.tokenRequests[i].truncatedTokenKeyId,
            );
            expect(tokReq.tokenRequests[i].blindMsg).toStrictEqual(
                tokReqGot.tokenRequests[i].blindMsg,
            );
        }

case TOKEN_TYPES.BLIND_RSA.value:
return BLIND_RSA.Nk;
return headerLen + BLIND_RSA.Nk;
case TOKEN_TYPES.PARTIALLY_BLIND_RSA.value:
return PARTIALLY_BLIND_RSA.Nk;
return headerLen + PARTIALLY_BLIND_RSA.Nk;
default:
throw new Error(`unrecognized or non-supported token type: ${tokenType.value}`);
}
}

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

const type = input.getUint16(0);
const tokenType = Object.values(TOKEN_TYPES).find((t) => t.value === type);
Expand Down
22 changes: 18 additions & 4 deletions src/priv_verif_token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export class TokenRequest {

static deserialize(bytes: Uint8Array): TokenRequest {
let offset = 0;
const input = new DataView(bytes.buffer);
const input = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);

const type = input.getUint16(offset);
offset += 2;
Expand All @@ -106,7 +106,7 @@ export class TokenRequest {
offset += 1;

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

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

b = this.blindedMsg.buffer;
b = (this.blindedMsg.buffer as ArrayBuffer).slice(
this.blindedMsg.byteOffset,
this.blindedMsg.byteOffset + this.blindedMsg.byteLength,
);
output.push(b);

return new Uint8Array(joinAll(output));
Expand Down Expand Up @@ -161,7 +164,18 @@ export class TokenResponse {
}

serialize(): Uint8Array {
return new Uint8Array(joinAll([this.evaluateMsg, this.evaluateProof]));
return new Uint8Array(
joinAll([
(this.evaluateMsg.buffer as ArrayBuffer).slice(
this.evaluateMsg.byteOffset,
this.evaluateMsg.byteOffset + this.evaluateMsg.byteLength,
),
(this.evaluateProof.buffer as ArrayBuffer).slice(
this.evaluateProof.byteOffset,
this.evaluateProof.byteOffset + this.evaluateProof.byteLength,
),
]),
);
}

length(): number {
Expand Down
23 changes: 18 additions & 5 deletions src/pub_verif_token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class TokenRequest {

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

const type = input.getUint16(offset);
offset += 2;
Expand All @@ -139,7 +139,7 @@ export class TokenRequest {
offset += 1;

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

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

b = this.blindedMsg.buffer;
b = (this.blindedMsg.buffer as ArrayBuffer).slice(
this.blindedMsg.byteOffset,
this.blindedMsg.byteOffset + this.blindedMsg.byteLength,
);
output.push(b);

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

const request = this.request.serialize();
output.push(request.buffer);
output.push(
(request.buffer as ArrayBuffer).slice(
request.byteOffset,
request.byteOffset + request.byteLength,
),
);

const extensions = this.extensions.serialize();
output.push(extensions.buffer);
output.push(
(extensions.buffer as ArrayBuffer).slice(
extensions.byteOffset,
extensions.byteOffset + extensions.byteLength,
),
);

return new Uint8Array(joinAll(output));
}
Expand Down