From 0bbd8d74562a5582893a0c7f9339882bae94c46d Mon Sep 17 00:00:00 2001 From: Colin Roberts Date: Thu, 29 Aug 2024 14:10:14 -0600 Subject: [PATCH 1/4] slight refactor and basic test --- circuits/http/interpreter.circom | 34 +++++++++++++++++++ .../language.circom | 0 .../{parser_request => parser}/machine.circom | 0 .../{parser_request => parser}/parser.circom | 0 circuits/test/http/interpreter.test.ts | 25 ++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 circuits/http/interpreter.circom rename circuits/http/{parser_request => parser}/language.circom (100%) rename circuits/http/{parser_request => parser}/machine.circom (100%) rename circuits/http/{parser_request => parser}/parser.circom (100%) create mode 100644 circuits/test/http/interpreter.test.ts diff --git a/circuits/http/interpreter.circom b/circuits/http/interpreter.circom new file mode 100644 index 0000000..2f0a55f --- /dev/null +++ b/circuits/http/interpreter.circom @@ -0,0 +1,34 @@ +pragma circom 2.1.9; + +include "parser/language.circom"; +include "../utils/array.circom"; + +/* TODO: +Notes -- +- This is a pretty efficient way to simply check what the method used in a request is by checking +the first `DATA_LENGTH` number of bytes. +- Certainly this could be more modular. +*/ +template YieldMethod(DATA_LENGTH) { + signal input bytes[DATA_LENGTH]; + signal output MethodTag; + + component RequestMethod = RequestMethod(); + component RequestMethodTag = RequestMethodTag(); + + component IsGet = IsEqualArray(3); + for(var byte_idx = 0; byte_idx < 3; byte_idx++) { + IsGet.in[0][byte_idx] <== bytes[byte_idx]; + IsGet.in[1][byte_idx] <== RequestMethod.GET[byte_idx]; + } + signal TagGet <== IsGet.out * RequestMethodTag.GET; + + component IsPost = IsEqualArray(4); + for(var byte_idx = 0; byte_idx < 4; byte_idx++) { + IsPost.in[0][byte_idx] <== bytes[byte_idx]; + IsPost.in[1][byte_idx] <== RequestMethod.POST[byte_idx]; + } + signal TagPost <== IsPost.out * RequestMethodTag.POST; + + MethodTag <== TagGet + TagPost; +} \ No newline at end of file diff --git a/circuits/http/parser_request/language.circom b/circuits/http/parser/language.circom similarity index 100% rename from circuits/http/parser_request/language.circom rename to circuits/http/parser/language.circom diff --git a/circuits/http/parser_request/machine.circom b/circuits/http/parser/machine.circom similarity index 100% rename from circuits/http/parser_request/machine.circom rename to circuits/http/parser/machine.circom diff --git a/circuits/http/parser_request/parser.circom b/circuits/http/parser/parser.circom similarity index 100% rename from circuits/http/parser_request/parser.circom rename to circuits/http/parser/parser.circom diff --git a/circuits/test/http/interpreter.test.ts b/circuits/test/http/interpreter.test.ts new file mode 100644 index 0000000..10cc80c --- /dev/null +++ b/circuits/test/http/interpreter.test.ts @@ -0,0 +1,25 @@ +import { circomkit, WitnessTester, generateDescription } from "../common"; + +describe("HTTP :: Interpreter", async () => { + describe("YieldMethod", async () => { + let circuit: WitnessTester<["bytes"], ["MethodTag"]>; + + function generatePassCase(input: any, expected: any, depth: number, desc: string) { + const description = generateDescription(input); + + it(`(valid) witness: ${description} ${desc}`, async () => { + circuit = await circomkit.WitnessTester(`YieldMethod`, { + file: "circuits/http/interpreter", + template: "YieldMethod", + params: [4], + }); + console.log("#constraints:", await circuit.getConstraintCount()); + + await circuit.expectPass(input, expected); + }); + } + + // The string `"GET "` + generatePassCase({ bytes: [71, 69, 84, 32] }, { MethodTag: 1 }, 0, ""); + }); +}); \ No newline at end of file From f01c685e344f2e68a51a02dc1408fb0c9fb2976a Mon Sep 17 00:00:00 2001 From: Colin Roberts Date: Thu, 29 Aug 2024 15:19:36 -0600 Subject: [PATCH 2/4] decent progress on request parse --- circuits.json | 4 +- circuits/http/interpreter.circom | 5 +- circuits/http/parser/language.circom | 2 +- circuits/http/parser/machine.circom | 71 ++++++++++++++++++---------- circuits/http/parser/parser.circom | 40 ++++++++++++++-- examples/http/get_request.http | 6 +-- src/bin/witness.rs | 15 ++++-- 7 files changed, 102 insertions(+), 41 deletions(-) diff --git a/circuits.json b/circuits.json index bd295ac..f1d7ee1 100644 --- a/circuits.json +++ b/circuits.json @@ -72,8 +72,8 @@ ] }, "get_request": { - "file": "parser_http_request/parser", + "file": "http/parser/parser", "template": "Parser", - "params": [158] + "params": [60] } } \ No newline at end of file diff --git a/circuits/http/interpreter.circom b/circuits/http/interpreter.circom index 2f0a55f..68e4a1d 100644 --- a/circuits/http/interpreter.circom +++ b/circuits/http/interpreter.circom @@ -6,8 +6,9 @@ include "../utils/array.circom"; /* TODO: Notes -- - This is a pretty efficient way to simply check what the method used in a request is by checking -the first `DATA_LENGTH` number of bytes. -- Certainly this could be more modular. + the first `DATA_LENGTH` number of bytes. +- Could probably change this to a template that checks if it is one of the given methods + so we don't check them all in one */ template YieldMethod(DATA_LENGTH) { signal input bytes[DATA_LENGTH]; diff --git a/circuits/http/parser/language.circom b/circuits/http/parser/language.circom index a001d86..b6fce6c 100644 --- a/circuits/http/parser/language.circom +++ b/circuits/http/parser/language.circom @@ -14,7 +14,7 @@ template Syntax() { signal output QUOTE <== 34; //-White_space--------------------------------------------------------------------------------// // - ASCII pair: `\r\n` - signal output CLRF <== [13, 10]; // https://www.rfc-editor.org/rfc/rfc2616#section-2.2 + signal output CLRF[2] <== [13, 10]; // https://www.rfc-editor.org/rfc/rfc2616#section-2.2 // https://www.rfc-editor.org/rfc/rfc7230#section-3.5 // - ASCII char: ` ` signal output SPACE <== 32; diff --git a/circuits/http/parser/machine.circom b/circuits/http/parser/machine.circom index ee0cff1..18dc21e 100644 --- a/circuits/http/parser/machine.circom +++ b/circuits/http/parser/machine.circom @@ -1,28 +1,51 @@ pragma circom 2.1.9; include "language.circom"; -include "../utils/array.circom"; - -template ParseMethod() { - signal input bytes[7]; - signal output MethodTag; - - component RequestMethod = RequestMethod(); - component RequestMethodTag = RequestMethodTag(); - - component IsGet = IsEqualArray(3); - for(var byte_idx = 0; byte_idx < 3; byte_idx++) { - IsGet.in[0][byte_idx] <== bytes[byte_idx]; - IsGet.in[1][byte_idx] <== RequestMethod.GET[byte_idx]; - } - signal TagGet <== IsGet.out * RequestMethodTag.GET; - - component IsPost = IsEqualArray(4); - for(var byte_idx = 0; byte_idx < 4; byte_idx++) { - IsPost.in[0][byte_idx] <== bytes[byte_idx]; - IsPost.in[1][byte_idx] <== RequestMethod.POST[byte_idx]; - } - signal TagPost <== IsPost.out * RequestMethodTag.POST; - - MethodTag <== TagGet + TagPost; +include "../../utils/array.circom"; + +template StateUpdate() { + signal input parsing_start; // Bool flag for if we are in the start line + signal input parsing_header; // Flag + Counter for what header line we are in + signal input parsing_body; + signal input read_clrf; // Bool flag to say whether we just read a CLRF + signal input byte_pair[2]; + + signal output next_parsing_start; + signal output next_parsing_header; + signal output next_parsing_body; + signal output next_read_clrf; + + signal state[3] <== [parsing_start, parsing_header, parsing_body]; + component stateToMask = StateToMask(); + stateToMask.state <== state; + + component Syntax = Syntax(); + + component pairIsCLRF = IsEqualArray(2); + pairIsCLRF.in <== [byte_pair, Syntax.CLRF]; + log("pairIsCLRF: ", pairIsCLRF.out); + + component stateChange = ScalarArrayMul(3); + stateChange.array <== stateToMask.mask; + stateChange.scalar <== pairIsCLRF.out; + log("stateChange[0]: ", stateChange.out[0]); + log("stateChange[1]: ", stateChange.out[1]); + log("stateChange[2]: ", stateChange.out[2]); + + component nextState = ArrayAdd(3); + nextState.lhs <== state; + nextState.rhs <== stateChange.out; + + next_parsing_start <== nextState.out[0]; + next_parsing_header <== nextState.out[1]; + next_parsing_body <== nextState.out[2]; + next_read_clrf <== pairIsCLRF.out; + +} + +template StateToMask() { + signal input state[3]; + signal output mask[3]; + + mask <== [- state[0], state[0] - state[1], state[2]]; } \ No newline at end of file diff --git a/circuits/http/parser/parser.circom b/circuits/http/parser/parser.circom index 9fd9524..7262a35 100644 --- a/circuits/http/parser/parser.circom +++ b/circuits/http/parser/parser.circom @@ -1,6 +1,6 @@ pragma circom 2.1.9; -include "../utils/bytes.circom"; +include "../../utils/bytes.circom"; include "machine.circom"; @@ -16,9 +16,39 @@ template Parser(DATA_BYTES) { dataASCII.in <== data; //--------------------------------------------------------------------------------------------// - component ParseMethod = ParseMethod(); - for(var byte_idx = 0; byte_idx < 7; byte_idx++) { - ParseMethod.bytes[byte_idx] <== data[byte_idx]; + // Initialze the parser + component State[DATA_BYTES]; + State[0] = StateUpdate(); + State[0].byte_pair <== [data[0], data[1]]; + State[0].parsing_start <== 1; + State[0].parsing_header <== 0; + State[0].parsing_body <== 0; + State[0].read_clrf <== 0; + + for(var data_idx = 1; data_idx < DATA_BYTES - 1; data_idx++) { + State[data_idx] = StateUpdate(); + State[data_idx].byte_pair <== [data[data_idx], data[data_idx + 1]]; + State[data_idx].parsing_start <== State[data_idx - 1].next_parsing_start; + State[data_idx].parsing_header <== State[data_idx - 1].next_parsing_header; + State[data_idx].parsing_body <== State[data_idx - 1].next_parsing_body; + State[data_idx].read_clrf <== State[data_idx - 1].next_read_clrf; + + // Debugging + log("State[", data_idx, "].parsing_start ", "= ", State[data_idx].parsing_start); + log("State[", data_idx, "].parsing_header", "= ", State[data_idx].parsing_header); + log("State[", data_idx, "].parsing_body ", "= ", State[data_idx].parsing_body); + log("State[", data_idx, "].read_clrf ", "= ", State[data_idx].read_clrf); + log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); } - log("MethodTag: ", ParseMethod.MethodTag); + + // Constrain to have valid JSON (TODO: more is needed) + // State[DATA_BYTES - 1].next_tree_depth === 0; + + // // Debugging + // log("State[", DATA_BYTES, "].parsing_start ", "= ", State[DATA_BYTES-1].next_parsing_start); + // log("State[", DATA_BYTES, "].parsing_header", "= ", State[DATA_BYTES-1].next_parsing_header); + // log("State[", DATA_BYTES, "].parsing_body ", "= ", State[DATA_BYTES-1].next_parsing_body); + // log("State[", DATA_BYTES, "].read_clrf ", "= ", State[DATA_BYTES-1].next_read_clrf); + // log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + } \ No newline at end of file diff --git a/examples/http/get_request.http b/examples/http/get_request.http index 88eb48d..89257e9 100644 --- a/examples/http/get_request.http +++ b/examples/http/get_request.http @@ -1,5 +1,3 @@ -GET /objectserver/restapi/alerts/status HTTP/1.1 +GET /api HTTP/1.1 Accept: application/json -Authorization: Basic dGVzdHVzZXIwMTpuZXRjb29s -Host: localhost -Connection: keep-alive \ No newline at end of file +Host: localhost \ No newline at end of file diff --git a/src/bin/witness.rs b/src/bin/witness.rs index d3c324f..bacabe0 100644 --- a/src/bin/witness.rs +++ b/src/bin/witness.rs @@ -10,11 +10,11 @@ struct Args { command: Command, /// Output directory (will be created if it doesn't exist) - #[arg(global = true, short, long, default_value = ".")] + #[arg(global = true, long, default_value = ".")] output_dir: PathBuf, /// Output filename (will be created if it doesn't exist) - #[arg(global = true, short, long, default_value = "output.json")] + #[arg(global = true, long, default_value = "output.json")] output_filename: String, } @@ -64,7 +64,16 @@ pub fn main() -> Result<(), Box> { (data, keys_map) } Command::Http { input_file } => { - let data = std::fs::read(input_file)?; + let mut data = std::fs::read(input_file)?; + let mut i = 0; + while i < data.len() { + if data[i] == 10 && (i == 0 || data[i - 1] != 13) { + data.insert(i, 13); + i += 2; + } else { + i += 1; + } + } let keys_map = serde_json::Map::new(); (data, keys_map) } From 0f4d3e8e3a47380b13d70f2e5a86e5a17d2a95c3 Mon Sep 17 00:00:00 2001 From: Colin Roberts Date: Thu, 29 Aug 2024 16:08:37 -0600 Subject: [PATCH 3/4] feat: very basic HTTP parsing --- circuits.json | 5 ++ circuits/http/parser/language.circom | 9 ++-- circuits/http/parser/machine.circom | 71 +++++++++++++++++++--------- circuits/http/parser/parser.circom | 27 +++++------ 4 files changed, 72 insertions(+), 40 deletions(-) diff --git a/circuits.json b/circuits.json index f1d7ee1..d254c67 100644 --- a/circuits.json +++ b/circuits.json @@ -75,5 +75,10 @@ "file": "http/parser/parser", "template": "Parser", "params": [60] + }, + "get_response": { + "file": "http/parser/parser", + "template": "Parser", + "params": [89] } } \ No newline at end of file diff --git a/circuits/http/parser/language.circom b/circuits/http/parser/language.circom index b6fce6c..b8e3fa6 100644 --- a/circuits/http/parser/language.circom +++ b/circuits/http/parser/language.circom @@ -13,9 +13,12 @@ template Syntax() { // - ASCII char `"` signal output QUOTE <== 34; //-White_space--------------------------------------------------------------------------------// - // - ASCII pair: `\r\n` - signal output CLRF[2] <== [13, 10]; // https://www.rfc-editor.org/rfc/rfc2616#section-2.2 - // https://www.rfc-editor.org/rfc/rfc7230#section-3.5 + // https://www.rfc-editor.org/rfc/rfc2616#section-2.2 + // https://www.rfc-editor.org/rfc/rfc7230#section-3.5 + // - ASCII char `\r` + signal output CL <== 13; + // - ASCII char `\n` + signal output RF <== 10; // - ASCII char: ` ` signal output SPACE <== 32; //-Escape-------------------------------------------------------------------------------------// diff --git a/circuits/http/parser/machine.circom b/circuits/http/parser/machine.circom index 18dc21e..16540a9 100644 --- a/circuits/http/parser/machine.circom +++ b/circuits/http/parser/machine.circom @@ -7,45 +7,72 @@ template StateUpdate() { signal input parsing_start; // Bool flag for if we are in the start line signal input parsing_header; // Flag + Counter for what header line we are in signal input parsing_body; - signal input read_clrf; // Bool flag to say whether we just read a CLRF - signal input byte_pair[2]; + signal input line_status; // Flag that counts up to 4 to read a double CLRF + signal input byte; signal output next_parsing_start; signal output next_parsing_header; signal output next_parsing_body; - signal output next_read_clrf; - - signal state[3] <== [parsing_start, parsing_header, parsing_body]; - component stateToMask = StateToMask(); - stateToMask.state <== state; + signal output next_line_status; component Syntax = Syntax(); - component pairIsCLRF = IsEqualArray(2); - pairIsCLRF.in <== [byte_pair, Syntax.CLRF]; - log("pairIsCLRF: ", pairIsCLRF.out); + //---------------------------------------------------------------------------------// + // Check if what we just read is a CL / RF + component readCL = IsEqual(); + readCL.in <== [byte, Syntax.CL]; + component readRF = IsEqual(); + readRF.in <== [byte, Syntax.RF]; + + signal notCLAndRF <== (1 - readCL.out) * (1 - readRF.out); + //---------------------------------------------------------------------------------// + + //---------------------------------------------------------------------------------// + // Check if we had read previously CL / RF or multiple + component prevReadCL = IsEqual(); + prevReadCL.in <== [line_status, 1]; + log("prevReadCL: ", prevReadCL.out); + component prevReadCLRF = IsEqual(); + prevReadCLRF.in <== [line_status, 2]; + log("prevReadCLRF: ", prevReadCLRF.out); + component prevReadCLRFCL = IsEqual(); + prevReadCLRFCL.in <== [line_status, 3]; + log("prevReadCLRFCL: ", prevReadCLRFCL.out); - component stateChange = ScalarArrayMul(3); - stateChange.array <== stateToMask.mask; - stateChange.scalar <== pairIsCLRF.out; - log("stateChange[0]: ", stateChange.out[0]); - log("stateChange[1]: ", stateChange.out[1]); - log("stateChange[2]: ", stateChange.out[2]); + signal readCLRF <== prevReadCL.out * readRF.out; + log("readCLRF: ", readCLRF); + signal readCLRFCLRF <== prevReadCLRFCL.out * readRF.out; + log("readCLRFCLRF: ", readCLRFCLRF); + //---------------------------------------------------------------------------------// + + //---------------------------------------------------------------------------------// + // Take current state and CLRF info to update state + signal state[3] <== [parsing_start, parsing_header, parsing_body]; + component stateChange = StateChange(); + stateChange.readCLRF <== readCLRF; + stateChange.readCLRFCLRF <== readCLRFCLRF; + stateChange.state <== state; component nextState = ArrayAdd(3); nextState.lhs <== state; nextState.rhs <== stateChange.out; + //---------------------------------------------------------------------------------// - next_parsing_start <== nextState.out[0]; + next_parsing_start <== nextState.out[0]; next_parsing_header <== nextState.out[1]; - next_parsing_body <== nextState.out[2]; - next_read_clrf <== pairIsCLRF.out; + next_parsing_body <== nextState.out[2]; + next_line_status <== line_status + readCL.out + readCLRF + readCLRFCLRF - line_status * notCLAndRF; } -template StateToMask() { +template StateChange() { + signal input readCLRF; + signal input readCLRFCLRF; signal input state[3]; - signal output mask[3]; + signal output out[3]; + + signal disableParsingStart <== readCLRF * state[0]; + signal disableParsingHeader <== readCLRFCLRF * state[1]; - mask <== [- state[0], state[0] - state[1], state[2]]; + out <== [-disableParsingStart, disableParsingStart - disableParsingHeader, disableParsingHeader]; } \ No newline at end of file diff --git a/circuits/http/parser/parser.circom b/circuits/http/parser/parser.circom index 7262a35..487fb63 100644 --- a/circuits/http/parser/parser.circom +++ b/circuits/http/parser/parser.circom @@ -19,36 +19,33 @@ template Parser(DATA_BYTES) { // Initialze the parser component State[DATA_BYTES]; State[0] = StateUpdate(); - State[0].byte_pair <== [data[0], data[1]]; + State[0].byte <== data[0]; State[0].parsing_start <== 1; State[0].parsing_header <== 0; State[0].parsing_body <== 0; - State[0].read_clrf <== 0; + State[0].line_status <== 0; - for(var data_idx = 1; data_idx < DATA_BYTES - 1; data_idx++) { + for(var data_idx = 1; data_idx < DATA_BYTES; data_idx++) { State[data_idx] = StateUpdate(); - State[data_idx].byte_pair <== [data[data_idx], data[data_idx + 1]]; + State[data_idx].byte <== data[data_idx]; State[data_idx].parsing_start <== State[data_idx - 1].next_parsing_start; State[data_idx].parsing_header <== State[data_idx - 1].next_parsing_header; State[data_idx].parsing_body <== State[data_idx - 1].next_parsing_body; - State[data_idx].read_clrf <== State[data_idx - 1].next_read_clrf; + State[data_idx].line_status <== State[data_idx - 1].next_line_status; // Debugging log("State[", data_idx, "].parsing_start ", "= ", State[data_idx].parsing_start); log("State[", data_idx, "].parsing_header", "= ", State[data_idx].parsing_header); log("State[", data_idx, "].parsing_body ", "= ", State[data_idx].parsing_body); - log("State[", data_idx, "].read_clrf ", "= ", State[data_idx].read_clrf); + log("State[", data_idx, "].line_status ", "= ", State[data_idx].line_status); log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); } - // Constrain to have valid JSON (TODO: more is needed) - // State[DATA_BYTES - 1].next_tree_depth === 0; - - // // Debugging - // log("State[", DATA_BYTES, "].parsing_start ", "= ", State[DATA_BYTES-1].next_parsing_start); - // log("State[", DATA_BYTES, "].parsing_header", "= ", State[DATA_BYTES-1].next_parsing_header); - // log("State[", DATA_BYTES, "].parsing_body ", "= ", State[DATA_BYTES-1].next_parsing_body); - // log("State[", DATA_BYTES, "].read_clrf ", "= ", State[DATA_BYTES-1].next_read_clrf); - // log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + // Debugging + log("State[", DATA_BYTES, "].parsing_start ", "= ", State[DATA_BYTES-1].next_parsing_start); + log("State[", DATA_BYTES, "].parsing_header", "= ", State[DATA_BYTES-1].next_parsing_header); + log("State[", DATA_BYTES, "].parsing_body ", "= ", State[DATA_BYTES-1].next_parsing_body); + log("State[", DATA_BYTES, "].line_status ", "= ", State[DATA_BYTES-1].next_line_status); + log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); } \ No newline at end of file From d35f17b35e88aa90626429cb11457a7f17e32e78 Mon Sep 17 00:00:00 2001 From: Colin Roberts Date: Fri, 30 Aug 2024 11:39:47 -0600 Subject: [PATCH 4/4] fix typos, remove logs --- circuits/http/parser/language.circom | 8 ++--- circuits/http/parser/machine.circom | 51 +++++++++++++--------------- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/circuits/http/parser/language.circom b/circuits/http/parser/language.circom index b8e3fa6..faf958b 100644 --- a/circuits/http/parser/language.circom +++ b/circuits/http/parser/language.circom @@ -15,10 +15,10 @@ template Syntax() { //-White_space--------------------------------------------------------------------------------// // https://www.rfc-editor.org/rfc/rfc2616#section-2.2 // https://www.rfc-editor.org/rfc/rfc7230#section-3.5 - // - ASCII char `\r` - signal output CL <== 13; - // - ASCII char `\n` - signal output RF <== 10; + // - ASCII char `\r` (carriage return) + signal output CR <== 13; + // - ASCII char `\n` (line feed) + signal output LF <== 10; // - ASCII char: ` ` signal output SPACE <== 32; //-Escape-------------------------------------------------------------------------------------// diff --git a/circuits/http/parser/machine.circom b/circuits/http/parser/machine.circom index 16540a9..da51e4f 100644 --- a/circuits/http/parser/machine.circom +++ b/circuits/http/parser/machine.circom @@ -18,39 +18,34 @@ template StateUpdate() { component Syntax = Syntax(); //---------------------------------------------------------------------------------// - // Check if what we just read is a CL / RF - component readCL = IsEqual(); - readCL.in <== [byte, Syntax.CL]; - component readRF = IsEqual(); - readRF.in <== [byte, Syntax.RF]; + // Check if what we just read is a CR / LF + component readCR = IsEqual(); + readCR.in <== [byte, Syntax.CR]; + component readLF = IsEqual(); + readLF.in <== [byte, Syntax.LF]; - signal notCLAndRF <== (1 - readCL.out) * (1 - readRF.out); + signal notCRAndLF <== (1 - readCR.out) * (1 - readLF.out); //---------------------------------------------------------------------------------// //---------------------------------------------------------------------------------// - // Check if we had read previously CL / RF or multiple - component prevReadCL = IsEqual(); - prevReadCL.in <== [line_status, 1]; - log("prevReadCL: ", prevReadCL.out); - component prevReadCLRF = IsEqual(); - prevReadCLRF.in <== [line_status, 2]; - log("prevReadCLRF: ", prevReadCLRF.out); - component prevReadCLRFCL = IsEqual(); - prevReadCLRFCL.in <== [line_status, 3]; - log("prevReadCLRFCL: ", prevReadCLRFCL.out); + // Check if we had read previously CR / LF or multiple + component prevReadCR = IsEqual(); + prevReadCR.in <== [line_status, 1]; + component prevReadCRLF = IsEqual(); + prevReadCRLF.in <== [line_status, 2]; + component prevReadCRLFCR = IsEqual(); + prevReadCRLFCR.in <== [line_status, 3]; - signal readCLRF <== prevReadCL.out * readRF.out; - log("readCLRF: ", readCLRF); - signal readCLRFCLRF <== prevReadCLRFCL.out * readRF.out; - log("readCLRFCLRF: ", readCLRFCLRF); + signal readCRLF <== prevReadCR.out * readLF.out; + signal readCRLFCRLF <== prevReadCRLFCR.out * readLF.out; //---------------------------------------------------------------------------------// //---------------------------------------------------------------------------------// - // Take current state and CLRF info to update state + // Take current state and CRLF info to update state signal state[3] <== [parsing_start, parsing_header, parsing_body]; component stateChange = StateChange(); - stateChange.readCLRF <== readCLRF; - stateChange.readCLRFCLRF <== readCLRFCLRF; + stateChange.readCRLF <== readCRLF; + stateChange.readCRLFCRLF <== readCRLFCRLF; stateChange.state <== state; component nextState = ArrayAdd(3); @@ -61,18 +56,18 @@ template StateUpdate() { next_parsing_start <== nextState.out[0]; next_parsing_header <== nextState.out[1]; next_parsing_body <== nextState.out[2]; - next_line_status <== line_status + readCL.out + readCLRF + readCLRFCLRF - line_status * notCLAndRF; + next_line_status <== line_status + readCR.out + readCRLF + readCRLFCRLF - line_status * notCRAndLF; } template StateChange() { - signal input readCLRF; - signal input readCLRFCLRF; + signal input readCRLF; + signal input readCRLFCRLF; signal input state[3]; signal output out[3]; - signal disableParsingStart <== readCLRF * state[0]; - signal disableParsingHeader <== readCLRFCLRF * state[1]; + signal disableParsingStart <== readCRLF * state[0]; + signal disableParsingHeader <== readCRLFCRLF * state[1]; out <== [-disableParsingStart, disableParsingStart - disableParsingHeader, disableParsingHeader]; } \ No newline at end of file