-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: http parse max lengths #106
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,7 +138,7 @@ describe("HTTP :: Codegen :: Response", async () => { | |
|
||
const headers = getHeaders(lockData); | ||
|
||
const params = [input.length, parseInt(http.headers["Content-Length".toLowerCase()]), lockData.version.length, lockData.status.length, lockData.message.length]; | ||
const params = [input.length, parseInt(http.headers["Content-Length"]), lockData.version.length, lockData.status.length, lockData.message.length]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh good, we dropped this case requirement here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it can be a debatable decision. IDK why I added this in the first place, so my reasoning to remove this is to perform an exact match on headers, because previously it was lower case.
So, we have to add support for it down the line. created an issue: #107 |
||
headers.forEach(header => { | ||
params.push(header[0].length); | ||
params.push(header[1].length); | ||
|
@@ -184,7 +184,7 @@ describe("HTTP :: Codegen :: Response", async () => { | |
|
||
const headers = getHeaders(lockData); | ||
|
||
const params = [input.length, parseInt(http.headers["Content-Length".toLowerCase()]), lockData.version.length, lockData.status.length, lockData.message.length]; | ||
const params = [input.length, parseInt(http.headers["Content-Length"]), lockData.version.length, lockData.status.length, lockData.message.length]; | ||
headers.forEach(header => { | ||
params.push(header[0].length); | ||
params.push(header[1].length); | ||
|
lonerapier marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { circomkit, WitnessTester, toByte } from "../../common"; | ||
import { readHTTPInputFile } from "../../common/http"; | ||
|
||
describe("HTTPLockHeader", async () => { | ||
let httpParseAndLockStartLineCircuit: WitnessTester<["step_in", "beginning", "beginning_length", "middle", "middle_length", "final", "final_length"], ["step_out"]>; | ||
let lockHeaderCircuit: WitnessTester<["step_in", "header", "headerNameLength", "value", "headerValueLength"], ["step_out"]>; | ||
|
||
const DATA_BYTES = 320; | ||
const MAX_STACK_HEIGHT = 5; | ||
const PER_ITERATION_DATA_LENGTH = MAX_STACK_HEIGHT * 2 + 2; | ||
const TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * (PER_ITERATION_DATA_LENGTH + 1) + 1; | ||
|
||
const MAX_BEGINNING_LENGTH = 10; | ||
const MAX_MIDDLE_LENGTH = 50; | ||
const MAX_FINAL_LENGTH = 10; | ||
const MAX_HEADER_NAME_LENGTH = 20; | ||
const MAX_HEADER_VALUE_LENGTH = 35; | ||
|
||
before(async () => { | ||
httpParseAndLockStartLineCircuit = await circomkit.WitnessTester(`ParseAndLockStartLine`, { | ||
file: "http/nivc/parse_and_lock_start_line", | ||
template: "ParseAndLockStartLine", | ||
params: [DATA_BYTES, MAX_STACK_HEIGHT, MAX_BEGINNING_LENGTH, MAX_MIDDLE_LENGTH, MAX_FINAL_LENGTH], | ||
}); | ||
console.log("#constraints:", await httpParseAndLockStartLineCircuit.getConstraintCount()); | ||
|
||
lockHeaderCircuit = await circomkit.WitnessTester(`LockHeader`, { | ||
file: "http/nivc/lock_header", | ||
template: "LockHeader", | ||
params: [DATA_BYTES, MAX_STACK_HEIGHT, MAX_HEADER_NAME_LENGTH, MAX_HEADER_VALUE_LENGTH], | ||
}); | ||
console.log("#constraints:", await lockHeaderCircuit.getConstraintCount()); | ||
}); | ||
|
||
function generatePassCase(input: number[], beginning: number[], middle: number[], final: number[], headerName: number[], headerValue: number[], desc: string) { | ||
it(`should pass: \"${headerName}: ${headerValue}\", ${desc}`, async () => { | ||
let extendedInput = input.concat(Array(Math.max(0, TOTAL_BYTES_ACROSS_NIVC - input.length)).fill(0)); | ||
|
||
let beginningPadded = beginning.concat(Array(MAX_BEGINNING_LENGTH - beginning.length).fill(0)); | ||
let middlePadded = middle.concat(Array(MAX_MIDDLE_LENGTH - middle.length).fill(0)); | ||
let finalPadded = final.concat(Array(MAX_FINAL_LENGTH - final.length).fill(0)); | ||
|
||
let headerNamePadded = headerName.concat(Array(MAX_HEADER_NAME_LENGTH - headerName.length).fill(0)); | ||
let headerValuePadded = headerValue.concat(Array(MAX_HEADER_VALUE_LENGTH - headerValue.length).fill(0)); | ||
|
||
let parseAndLockStartLine = await httpParseAndLockStartLineCircuit.compute({ step_in: extendedInput, beginning: beginningPadded, beginning_length: beginning.length, middle: middlePadded, middle_length: middle.length, final: finalPadded, final_length: final.length }, ["step_out"]); | ||
|
||
await lockHeaderCircuit.expectPass({ step_in: parseAndLockStartLine.step_out, header: headerNamePadded, headerNameLength: headerName.length, value: headerValuePadded, headerValueLength: headerValue.length }); | ||
}); | ||
} | ||
|
||
function generateFailCase(input: number[], beginning: number[], middle: number[], final: number[], headerName: number[], headerValue: number[], desc: string) { | ||
it(`should fail: ${desc}`, async () => { | ||
let extendedInput = input.concat(Array(Math.max(0, TOTAL_BYTES_ACROSS_NIVC - input.length)).fill(0)); | ||
|
||
let beginningPadded = beginning.concat(Array(MAX_BEGINNING_LENGTH - beginning.length).fill(0)); | ||
let middlePadded = middle.concat(Array(MAX_MIDDLE_LENGTH - middle.length).fill(0)); | ||
let finalPadded = final.concat(Array(MAX_FINAL_LENGTH - final.length).fill(0)); | ||
|
||
let headerNamePadded = headerName.concat(Array(MAX_HEADER_NAME_LENGTH - headerName.length).fill(0)); | ||
let headerValuePadded = headerValue.concat(Array(MAX_HEADER_VALUE_LENGTH - headerValue.length).fill(0)); | ||
|
||
let parseAndLockStartLine = await httpParseAndLockStartLineCircuit.compute({ step_in: extendedInput, beginning: beginningPadded, beginning_length: beginning.length, middle: middlePadded, middle_length: middle.length, final: finalPadded, final_length: final.length }, ["step_out"]); | ||
|
||
await lockHeaderCircuit.expectFail({ step_in: parseAndLockStartLine.step_out, header: headerNamePadded, headerNameLength: headerName.length, value: headerValuePadded, headerValueLength: headerValue.length }); | ||
}); | ||
} | ||
|
||
describe("request", async () => { | ||
let { input, headers } = readHTTPInputFile("post_request.http"); | ||
|
||
let beginning = toByte("POST"); | ||
let middle = toByte("/contact_form.php"); | ||
let final = toByte("HTTP/1.1"); | ||
|
||
let headerName = toByte("Host"); | ||
let headerValue = toByte("developer.mozilla.org"); | ||
|
||
for (const [key, value] of Object.entries(headers)) { | ||
generatePassCase(input, beginning, middle, final, toByte(key), toByte(value), "request"); | ||
} | ||
let incorrectHeaderValue = toByte("application/json"); | ||
generateFailCase(input, beginning, middle, final, headerName, incorrectHeaderValue, "incorrect header value"); | ||
}); | ||
|
||
describe("response", async () => { | ||
let { input, headers } = readHTTPInputFile("spotify_top_artists_response.http"); | ||
let beginning = toByte("HTTP/1.1"); | ||
let middle = toByte("200"); | ||
let final = toByte("OK"); | ||
|
||
for (const [key, value] of Object.entries(headers)) { | ||
generatePassCase(input, beginning, middle, final, toByte(key), toByte(value), "response"); | ||
} | ||
|
||
let headerName = toByte("content-encoding"); | ||
let invalidHeaderValue = toByte("chunked"); | ||
generateFailCase(input, beginning, middle, final, headerName, invalidHeaderValue, "should fail: invalid header value"); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Big upper bound for sure, but if someone does pick something larger than this, what happens with the
GreaterThan(10)
template? Does it fail to prove? Or do we get some incorrect value out?Just want to make sure this is properly constrained. If not, it's okay for now, but we should make an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it fails to run, there's an assert in
LessThan
template that checksinput - 2^10
is 10 bit valid number