Method and system for verifying correctness of function of Circom compiler

By pre-verification and formal specification generation of the Circcom compiler's assembly function library, combined with the SMT solver for equivalence verification of constraints and computational models, the zero-knowledge proof compiler's theoretical shortcomings in reliability verification are solved, and multiple consistency verification of compiled products and source code is achieved, which improves the security and reliability of the basic blockchain software.

CN120045457AActive Publication Date: 2025-05-27TONGJI UNIV
View PDF 7 Cites 0 Cited by

Patent Information

Application Number
CN202510118352.5
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-01-24
Publication Date
2025-05-27
Estimated Expiration
2045-01-24

AI Technical Summary

Technical Problem

The existing zero-knowledge proof compilers are imperfect in reliability verification theory and lack formal verification, which may pose potential security hazards and data breach risks.

Method used

A method for verification of functional correctness for Circcom compiler is proposed. By pre-verifying assembly functions in the assembly function library, formal regulations are generated, and combined with SMT solver CVC5, the equivalence verification of the constraints and calculation models is ensured to ensure the correctness of the compilation products and source code in terms of constraints and calculation consistency.

Benefits of technology

Effectively detect potential errors in the compilation process, ensure the multiple consistency between the compiled products and the source code, improve the security and reliability of the basic blockchain software, and reduce the risk of error propagation.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120045457A_ABST
    Figure CN120045457A_ABST
Patent Text Reader

Abstract

The invention provides a method and a system for verifying correctness of functions of a Circom compiler, which are used for guaranteeing correctness of a compilation product of the compiler based on a Circom source code and a source file in constraint consistency and calculation consistency, and the method comprises the following steps: S1, verifying an assembly function called by the Circom compiler; s2, compiling the Circom source code; s3, extracting an abstract syntax tree of the Circom source code; s4, analyzing the abstract syntax tree, and extracting a constraint model and a calculation model; s5, analyzing the R1CS file, and extracting a constraint model of a compiled product; s6, extracting a calculation model of a compiled product; s7, carrying out equivalent verification on the constraint model of the source code and the constraint model of the R1CS file; s8, carrying out equivalence verification on the calculation model of the source code and the CPP file; and S9, proving that the Circom compiler can correctly compile the Circom source file.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the technical field of software development, and in particular, to a method and system for verifying the functional correctness of a Circom compiler. Background Art

[0002] With the continuous expansion of the application scenarios of blockchain technology, the application of zero-knowledge proof technology has also been deepened to meet the increasing requirements of users in terms of privacy, security, and verifiability. Currently, in addition to manually generating zero-knowledge proof algorithms, developers can also use zero-knowledge proof compilers to automatically translate the zero-knowledge proof process or target described in a high-level language into a general intermediate language, thereby simplifying the complexity of zero-knowledge proofs.

[0003] The zero-knowledge proof compiler is a key tool for constructing and verifying zero-knowledge proof systems. Ensuring the credibility and security of the compiler is a crucial task. However, although many zero-knowledge proof compilers such as Circom, zk-SNARK, and zk-STARK have been developed in the field, the theory of reliability verification is still not perfect, and only a few compilers, such as ZoKrates, have undergone formal verification. Almeida et al. designed a zero-knowledge proof compiler based on the Σ protocol, which allows the automatic conversion of the abstract description of the target to be proven into an executable implementation and automatically outputs the formal proof of the compiled protocol, but it does not formally verify the correctness of the compiler code implementation. Cairo is the first Turing-complete language for creating provable programs for general computing, and its compiler is often used in zero-knowledge proofs. However, developers only use testing means to conduct necessary tests on the correctness of the compiler and do not give formal security guarantees. RISC Zero is a general-purpose zero-knowledge verification computing platform based on zk-STARK and the RISC-V microarchitecture, but formal verification techniques are not used in its design and development process, and there may be potential vulnerabilities leading to risks such as security hazards and data leakage.

[0004] Currently, in other fields, there have been many progresses in the formal verification of high-level language compilers. Bochmann et al. proposed a formal verification scheme for the design correctness of Java bytecode compilers, which covers all object-oriented related features. Leroy et al. designed and developed a trusted compiler CompCert using formal verification methods, and the correctness of this compiler from design to operation has been formally verified, effectively ensuring its functional reliability.

[0005] As shown by the formal verification precedents of the above high-level language compilers, the feasibility of formal verification of zero-knowledge proof compilers is demonstrated. However, compared with the former, the verification work of zero-knowledge proof compilers is more complex. On the one hand, it needs to have basic functions such as syntax analysis and syntactic analysis. On the other hand, it also needs to be specifically designed for aspects such as security and privacy guarantees, involving professional knowledge in fields such as cryptographic algorithms and protocol design. This greatly increases the complexity of the design of zero-knowledge proof compilers, making its verification process very vulnerable to the problem of state space explosion. In response to the state space explosion problem, scholars at home and abroad have carried out many studies in different fields. Berendsen et al. used the time-step simulation theory to manually establish an abstraction of some components of the Zeroconf protocol, achieving the correctness verification for any number of terminals. The combined verification framework proposed by Lin et al. uses the model learning algorithm to automatically construct abstractions, achieving the efficient verification of the event recording automaton model. Hanyue Chen et al. overcame the combination problem of the time automaton model learning algorithm and the combined verification framework, achieving an efficient verification algorithm for time systems. The above solutions can also be applied to the verification process of zero-knowledge proof compilers.

[0006] Therefore, the technical problem to be urgently solved is: how to use combined verification techniques such as time-step simulation and assumption learning to propose an efficient formal verification algorithm for zero-knowledge proof compilers at the design level, expand the reliability verification theory of zero-knowledge proof compilers, and provide technical support for the formal proof work of both. Summary of the Invention

[0007] The present invention is made to solve the above problems, and its purpose is to provide a method and system for verifying the functional correctness of the Circom compiler.

[0008] The present invention provides a method for verifying the functional correctness of the Circom compiler, which has the following characteristics, including: Step S1, verify each assembly function in the assembly function library called by the Circom compiler in advance, verify the functional correctness, and form corresponding formal specifications, denoted as the formal specifications of the assembly function functions; Step S2, use the Circom compiler to compile the Circom source code. If it can pass, save the R1CS files and CPP files in the.sym,.dat, and json formats obtained by the compilation; Step S3, extract the abstract syntax tree from the Circom source code and store it in the json file format; Step S4, parse the abstract syntax tree of the Circom source code, and based on the syntax and semantics of the Circom language, extract the constraint model and calculation model corresponding to the Circom source code, denoted as the constraint model corresponding to the source code and the calculation model corresponding to the source code; Step S5, parse the R1CS file obtained by the compilation based on the.sym file, and extract the constraint model corresponding to the compilation product, denoted as the constraint model corresponding to the R1CS file; Step S6, parse the.dat and CPP files based on the formal specifications of the assembly function functions and the.sym file, and extract the calculation model corresponding to the compilation product, denoted as the calculation model corresponding to the.dat file and the calculation model corresponding to the CPP file, as well as element_dict used to store the mapping relationship of signals in the CPP file; Step S7, connect the constraint model corresponding to the source code and the constraint model corresponding to the R1CS file using the equivalence relationship, take the negation and use the CVC5 solver to solve. If there is no solution, it indicates that the Circom compiler can ensure the constraint consistency between the compilation product and the source file. If there is a solution, that is, there is a counterexample, it indicates that the Circom compiler has an error; Step S8, based on element_dict, combine the SMT solver to verify the equivalence of the calculation model corresponding to the source code and the calculation model corresponding to the CPP file to form the target property, and use the CVC5 solver to solve. If there is no solution, it indicates that the Circom compiler can ensure the calculation consistency between the compilation product and the source file. If there is a solution, that is, there is a counterexample, it indicates that the Circom compiler has an error; Step S9, if the solution results of S7 and S8 are both no solution, it indicates that the Circom compiler can correctly compile the Circom source file.

[0009] In the method for verifying the functional correctness of the Circom compiler provided by the present invention, it may also have the following features: Among them, step S1 includes the following sub-steps: Step S1-1, for each function in fr.asm, write a corresponding verification script.ini file, and the script content mainly includes constraints such as verifying whether the function function is correct and whether the register overflows; Step S1-2, start the symbolic execution process of Binsec, and the execution result will return whether there is an error in the currently verified function. If there is an error, a counterexample will be returned. If it is correct, the number of execution paths and the execution time will be returned. Finally, the correctly executed script content will be summarized into a more concise specification for subsequent use.

[0010] In the method for verifying the functional correctness of the Circom compiler provided by the present invention, it may also have the following features: Among them, step S3 includes the following sub-steps: Step S3-1, analyze the file where the main module declaration of the Circom source code is located, parse each syntax node, convert the syntax structure into an abstract syntax tree, and temporarily store it in memory in json format, and annotate in detail information such as signal declarations, variable declarations, module declarations, expression types, branch structures, loop structures, and main module declaration parameters; Step S3-2, store the abstract syntax tree in a specified location on the hard disk in the form of a json file.

[0011] In the method for verifying the functional correctness of the Circom compiler provided by the present invention, it may also have the following features: Among them, in step S3, the following sub-steps are further included between step S3-1 and step S3-2: According to the include import relationship, recursively parse the call relationship between Circom source codes, and convert all involved code files into abstract syntax trees correspondingly; Extract the template and function nodes in the abstract syntax tree and add them to the definitions list of the abstract syntax tree in turn to achieve the merger of the abstract syntax trees.

[0012] In the method for verifying the functional correctness of the Circom compiler provided by the present invention, the following features may also be included: Among them, step S4 includes the following sub-steps: Step S4-1, read the json file from a specified location on the hard disk and load the abstract syntax tree information into memory; Step S4-2, analyze the main_component node in the abstract syntax tree, and extract the id of the template corresponding to the main module and the parameter assignment list; Step S4-3, parse the parameter assignment list, calculate the values of the expressions therein, and store each parameter assignment in the form of an array in the original order, denoted as the parameter assignment array; Step S4-4, find the corresponding template in the definitions list according to the module id, then parse it, generate corresponding variables based on the parameter list described by the args node therein, and assign values according to the parameter assignment array; Step S4-5, parse each node in the stmt list of the parsed template. Based on the Declaration node therein, generate corresponding var variables, signal variables, and component variables. Based on the ConstraintEquality node therein, form an equality expression and store it in the constraint expression set. Based on the Substitution node therein, assign a value to the specified variable. If the left value type is var, parse the value of the right value expression to update the var variable. If the left value type is signal, model the right value expression as an expression over a finite field, form an equality with the signal variable, and store the generated expression in the calculation expression set. If the assignment operator is AssignConstraintSignal, the generated expression also needs to be stored in the constraint expression set. If the left value type is Component, it indicates that the right side is a template call statement. Extract the corresponding id and parameter assignment list, then return to step S4-3 and recursively parse. Based on the While node therein, first calculate the truth value of the cond node therein. If it is true, parse each node in the loop body, and then check the truth value of the cond node again until it is false. Based on the IfThenElse node therein, first calculate the truth value of the cond node therein. If it is true, parse the if_case sub-node therein. If it is false and the else_case sub-node exists, parse the else_case; Step S4-6, connect the elements in the constraint expression set with a conjunction relationship to form the constraint model corresponding to the source code, and connect the elements in the calculation expression set with a conjunction relationship to form the calculation model corresponding to the source code.

[0013] In the method for verifying the functional correctness of the Circom compiler provided by the present invention, it may also have the following features: Among them, step S5 includes the following sub-steps: Step S5-1, read the.sym file line by line from a specified position on the hard disk, and each line stores the index information of a certain signal; Step S5-2, use the English comma as the delimiter to divide each line into 4 parts. The first part represents the order of appearance of the signal in the Circom source code, denoted as id s , the second part represents the order of appearance of the signal in the witness file, id w , the third part represents the number of the component to which the signal belongs, id c , the fourth part represents the name of the signal in the source code, denoted as name. Based on this, construct the two-way mapping relationship table between id w and name; Step S5-3, read the R1CS file stored in json format line by line from a specified position on the hard disk, and parse each element in the list stored in the Constraints node one by one. Each element contains three sub-elements, denoted as A, B, C respectively, and each sub-element contains several id w and coefficient pairs. Based on the two-way mapping relationship table, obtain the corresponding variable name according to id w . Based on this, convert A, B, and C into the corresponding linear expressions respectively, denoted as a, b, c, and form a constraint in the form of a*b = c; Step S5-4, connect the constraints of a*b = c using the conjunction relationship to form the constraint model corresponding to the R1CS file.

[0014] In the method for verifying the functional correctness of the Circom compiler provided by the present invention, it may also have the following features: Among them, step S6 includes the following sub-steps: Step S6-1, in the.dat file, taking 40 bytes as a group from back to front, map binary constants to the FrElement required in the.cpp file; Step S6-2, parse the text line by line in the.sym file, and map signals to the FrElement required in the.cpp file; Step S6-3, use CVC5 to formalize the specification of the assembly function's functionality, generate verification conditions for operations on a certain finite field, and use them to ensure that the operation results input later conform to the given verification logic; Step S6-4, use the method of string matching to parse the.cpp file line by line, convert the operation operations involved in the file into verification conditions for operations on a finite field. The specific supported operations include: creation and reference of templates, control flow code containing for, if, while, support for the four arithmetic operations of addition, subtraction, multiplication, and division, support for finding the inverse element in finite field operations, support for comparison operations such as 'Fr_eq', 'Fr_neq', 'Fr_gt', 'Fr_lt', 'Fr_geq', 'Fr_leq', and support for assignment and exponentiation operations. Finally, store the generated series of constraint conditions in a list in the SMT format.

[0015] In the method for verifying the functional correctness of the Circom compiler provided by the present invention, it may also have the following features: Among them, step S8 includes the following sub-steps: Step S8-1, traverse the signal mapping relationship table, convert each key-value pair in it into an equality constraint, and store the equality constraint in the input equality constraint set or the result equality constraint set according to whether the signal involved is an input signal; Step S8-2, use the conjunction relationship to connect the elements in the input equality constraint set to form an input constraint, and use the conjunction relationship to connect the elements in the result equality constraint set to form a result constraint; Step S8-3, take the negation of the result constraint, and then use the conjunction relationship to connect it with the input constraint, the calculation model corresponding to the source code, and the calculation model corresponding to the CPP file to form a target property; Step S8-4, use the CVC5 solver to solve the target property. If there is no solution, it indicates that the Circom compiler can ensure the computational consistency between the compiled product and the source file. If there is a solution, that is, there is a counterexample, it indicates that there is an error in the Circom compiler.

[0016] The present invention also discloses a method and system for verifying the functional correctness of the Circom compiler, which has the following features: an AST generation tool for extracting the abstract syntax tree from the Circom source code to be compiled and storing it in the form of a json file; an AST parsing tool for parsing the abstract syntax tree and extracting the constraint model and calculation model corresponding to the source code based on the syntax and semantics of the Circom language; a CPP parsing tool for extracting the calculation model corresponding to the compilation product and an element_dict for storing the mapping relationship of signals in the CPP file, and finally parsing the.cpp file line by line using the string matching method to convert the arithmetic operations involved in the file into SMT-formatted arithmetic verification conditions; an R1CS parsing tool for reading the R1CS file stored in json format from a specified location on the hard disk and parsing each element in the list stored in the Constraints node therein; a Circom and R1CS equivalence verification tool for checking the equivalence of the SMT formulas formed by the Circom code before compilation and the R1CS after compilation through CVC5 to verify the equivalence of the Circom code and the R1CS file; a Circom and CPP equivalence verification tool for checking the equivalence of the SMT formulas formed by the Circom code before compilation and the CPP code after compilation through CVC5 to verify the equivalence of the Circom code and the CPP file.

[0017] Functions and effects of the invention

[0018] According to the method and system for verifying the functional correctness of the Circom compiler involved in the present invention, it is possible to ensure the correctness of the compilation product and the Circom source code in terms of constraint consistency and calculation consistency in the absence of support from existing formal verification tools. The present invention pre-verifies the assembly function and generates formal specifications, and combines the SMT solver CVC5 to verify the equivalence of the constraint and calculation models. This method can effectively detect potential errors in the compilation process of the Circom compiler. Moreover, on the premise of ensuring the verification accuracy, this method can automate the verification process, reduce manual intervention, and improve the verification efficiency. At the same time, by combining the multiple consistency verifications of the compilation product and the source file, the security and reliability of the blockchain basic software are greatly improved, and the risk of error propagation is reduced, thus providing higher guarantee for the functional correctness of the compiler for blockchain applications. Description of the drawings

[0019] Figure 1 It is the structural block diagram of the system for verifying the functional correctness of the Circom compiler in the embodiment of the present invention;

[0020] Figure 2It is a schematic flowchart of the method for verifying the functional correctness of the Circom compiler in the embodiments of the present invention. Detailed implementation manners

[0021] In order to make the technical means, creative features, achieved purposes and functions of the present invention easy to understand, the following embodiments will specifically describe the method and system for verifying the functional correctness of the Circom compiler of the present invention in conjunction with the accompanying drawings.

[0022] Figure 1 It is a structural block diagram of the system for verifying the functional correctness of the Circom compiler in the embodiments of the present invention.

[0023] As Figure 1 shown, the system 10 for verifying the functional correctness of the Circom compiler in this example includes an AST generation tool 11, an AST parsing tool 12, a CPP parsing tool 13, an R1CS parsing tool 14, a Circom-CPP equivalence verification tool 15, and a Circom-R1CS equivalence verification tool 16.

[0024] The AST generation tool 11 is used to extract the abstract syntax tree (AST) from the Circom source code and store it in the form of a JSON file, laying a foundation for subsequent syntax parsing and model extraction.

[0025] The AST parsing tool 12 is used to parse the abstract syntax tree (AST), and based on the syntax and semantics of the Circom language, extract the corresponding constraint model and calculation model from the source code to facilitate the verification of the logical structure of the source code.

[0026] The CPP parsing tool 13 is used to analyze the compiled CPP file, extract the calculation model in the compilation product, and generate an element_dict to store the mapping relationship of signals in the CPP file. The tool parses the CPP file line by line through string matching, and converts the arithmetic operations therein into verifiable SMT-formatted arithmetic conditions.

[0027] The R1CS parsing tool 14 is used to read the R1CS file stored in JSON format from a specified location, parse the element list in the Constraints node one by one, and extract the constraint information to help build the constraint model of the compilation product.

[0028] The Circom-R1CS equivalence verification tool 15 uses the CVC5 solver to perform an equivalence check on the SMT formula formed by the Circom source code and the R1CS file, verify the consistency of the constraint model before and after compilation, and ensure the correct mapping between the Circom code and the R1CS file.

[0029] The Circom and CPP equivalence verification tool 16 uses the CVC5 solver to verify the equivalence of the SMT formulas formed by the Circom source code and the generated CPP code, ensuring the consistency of the computational logic between the source code and the compiled CPP file, thereby confirming the functional correctness of the compiler.

[0030] Figure 2 It is a schematic flowchart of the method for verifying the functional correctness of the Circom compiler in the embodiments of the present invention.

[0031] As Figure 2 shown, the method for verifying the functional correctness of the Circom compiler in this embodiment is used to ensure the correctness of the compiled product and the Circom source code in terms of constraint consistency and computational consistency, and includes the following steps:

[0032] In this embodiment, the content of the FrElement defined in Circom includes: the first 32 bits store the short - type data of the data, denoted as shortVal; the middle 32 bits store the type of the data, denoted as type; the last 256 bits store the long - type data of the data, denoted as longVal.

[0033] Step S1, pre - verify each assembly function in the assembly function library called by the Circom compiler, verify the functional correctness, and form corresponding formal specifications, denoted as the formal specifications of the assembly function functions.

[0034] Step S1 - 1, for each function in fr.asm, write a corresponding verification script.ini file, and the script content mainly includes verifying whether the function function is correct and constraints such as whether the register overflows.

[0035] Step S1 - 2, start the symbolic execution process of Binsec. The execution result will return whether there is an error in the currently verified function. If there is an error, it will return a counter - example. If it is correct, it will return the number of execution paths and the execution time. Finally, summarize the correctly executed script content into a more concise specification for subsequent use.

[0036] In this embodiment, taking the verification of the following circom code Num2Bits(n) as an example:

[0037]

[0038] The assembly functions involved in this Circom code are x86-64 assembly codes under Linux, including assembly functions such as Fr_copy and Fr_add. Script files such as Fr_copy.ini and Fr_add.ini are written for them respectively. The files contain the constraints that each function must satisfy, and are handed over to the Binsec tool for verification. After obtaining the correct verification results, each assembly function is abstracted into the following specifications (taking Fr_add as an example):

[0039]

[0040] Step S2: Use the Circom compiler to compile the Circom source code. If it passes, save the R1CS files and CPP files in.sym,.dat, and json formats obtained from the compilation.

[0041] The compilation instructions are as follows:

[0042]

[0043] The meanings of the parameters are shown in the following table:

[0044] Parameter Meaning compiler_path Path where the Circom compiler is located --OX Automated simplification level, X can take 0, 1, 2, where O0 means no optimization is performed raw_path Storage path of the file where maincomponent is located in the Circom source code --primeprime_name Specify the large prime number to be used. prime_name usually takes bn128 --r1cs Specify to output the R1CS file --sym Specify to output the sym file --c Specify to output the compiled executable file in C++ form --json Specify to output the R1CS file in json format -ocase_temp_path Specify the output path of the compilation product as case_temp_path

[0045] In this embodiment, the instructions are specifically:

[0046]

[0047] If the compilation fails, it means there is a problem with the writing of the Circom source code, and it must be corrected according to the compiler's prompt. If the compilation passes, save the R1CS files and CPP files in.sym,.dat, and json formats obtained from the compilation, and proceed to step S3.

[0048] Step S3: Extract the abstract syntax tree from the Circom source code and store it in the form of a json file.

[0049] This step is implemented by calling the Astbuilder tool. The instruction format is as follows:

[0050]

[0051] The meanings of the parameters are shown in the following table:

[0052] Parameter Meaning astbuilder_path Path where Astbuilder is located raw_path Storage path of the file where maincomponent is located in the Circom source code json_path Abstract syntax tree output path

[0053] In this embodiment, the instructions are specifically:

[0054]

[0055] Step S3-1: Analyze the file where the main module declaration of the Circom source code is located, parse each syntax node, parse the Num2Bits.circom file, convert the syntax structure into an abstract syntax tree, and temporarily store it in memory in json format, with detailed annotation of information such as signal declarations, variable declarations, module declarations, expression types, branch structures, loop structures, and main module declaration parameters.

[0056] Step S3-2: Store the abstract syntax tree in a specified location on the hard disk in the form of a json file.

[0057] Step S4: Parse the abstract syntax tree of the Circom source code obtained in Step S3, and based on the syntax and semantics of the Circom language, extract the constraint model and calculation model corresponding to the Circom source code, denoted as the constraint model corresponding to the source code and the calculation model corresponding to the source code.

[0058] Step S4-1: Read the json file from the specified location on the hard disk and load the abstract syntax tree information into memory.

[0059] Read the. / temp_file / Num2Bits / ast.json file and load the abstract syntax tree information it stores into memory. Traverse each template in the definitions list, use its name as an index, and store the information of each template in the dictionary structure of template_dic. After this sub-step, the information stored in template_dic is: ["Num2Bits": "..."].

[0060] Step S4-2: Analyze the main_component node in the abstract syntax tree and extract the id and parameter assignment list of the template corresponding to the main module.

[0061] Locate the main_component node in the abstract syntax tree. The main content is as follows. The id information is "Num2Bits", and the main information of the parameter assignment list is:

[0062]

[0063] Step S4-3: Parse the parameter assignment list, calculate the values of the expressions in it, and store each parameter assignment in an array in the original order, denoted as the parameter assignment array.

[0064] Step S4-4: Search for the corresponding template in the definitions list according to the module id, then parse it, generate corresponding variables based on the parameter list described in the args node therein, and assign values according to the parameter assignment array.

[0065] In this embodiment, extract the corresponding information from the template_dic according to the template id corresponding to the main module, i.e., Num2Bits. The information stored in the args node is: ["n"], generate var Num2Bits[0].n, and assign it an initial value of 4 according to the parameter assignment list.

[0066] Step S4-5: Parse each node in the stmt list of the parsed template. Based on the Declaration node therein, generate corresponding var variables, signal variables, and component variables. Based on the ConstraintEquality node, form an equation expression and store it in the constraint expression set. Based on the Substitution node, assign a value to the specified variable. If the left value type is var, parse the value of the right value expression to update the var variable; if the left value type is signal, model the right value expression as an expression over a finite field, form an equation with the signal variable, and store the generated expression in the calculation expression set. If the assignment operator is AssignConstraintSignal, also store the generated expression in the constraint expression set; if the left value type is Component, it indicates that the right side is a template call statement, extract the corresponding id and parameter assignment list, then return to Step S4-3 for recursive parsing. Based on the While node, first calculate the truth value of the cond node therein. If it is true, parse each node in the loop body, and then check the truth value of the cond node again until it is false. Based on the IfThenElse node, first calculate the truth value of the cond node therein. If it is true, parse the if_case sub-node therein. If it is false and the else_case sub-node exists, parse the else_case.

[0067] In this embodiment, parse each node in the stmt list of the parsed template to generate the following parameters:

[0068]

[0069] And form the following constraint expression set:

[0070]

[0071]

[0072] and form a set of computational expressions as shown below:

[0073]

[0074] Step S4-6, connect each element in the set of constraint expressions with a conjunction relationship to form a constraint model corresponding to the source code.

[0075] In this embodiment, the constraint model is specifically as follows:

[0076]

[0077]

[0078] Connect each element in the set of computational expressions with a conjunction relationship to form a computational model corresponding to the source code.

[0079] In this embodiment, the computational model is specifically as follows:

[0080]

[0081] Step S5, based on the.sym file, parse the compiled R1CS file to extract the constraint model corresponding to the compilation product, denoted as the constraint model corresponding to the R1CS file.

[0082] In this embodiment, parse the compiled Num2Bits_constraints.json based on the Num2Bits.sym file.

[0083] Step S5-1, read the.sym file from the specified location on the hard disk line by line, and each line stores the index information of a certain signal.

[0084] In this embodiment, read the Num2Bits.sym file into memory from the location. / temp_file / Num2Bits / Num2Bits.sym on the hard disk, and the content is as follows:

[0085]

[0086] Step S5-2, using the English comma as the delimiter, divide each line into 4 parts. The first part represents the order of appearance of the signal in the Circom source code, denoted as id s , the second part represents the order of appearance of the signal in the witness file, id w, the third part represents the component ID number to which the signal belongs c , the fourth part represents the name of the signal in the source code, denoted as name. Based on this, an ID is constructed w A two-way mapping relationship table between ID and name.

[0087] In this embodiment, based on the above four parts, a SymDataDic object is generated, which contains the following five attributes, and the contents are as follows:

[0088]

[0089] Step S5-3, read the R1CS file stored in json format row by row from a specified location on the hard disk.

[0090] In this embodiment, the content of Num2Bits_constraints.json is read from the location. / temp_file / Num2Bits / Num2Bits_constraints.json on the hard disk, and the information is as follows:

[0091]

[0092] Parse each element in the list stored in the Constraints node one by one. Each element contains three sub-elements, denoted as A, B, and C respectively, and each sub-element contains several IDs w And coefficient pairs. Based on the two-way mapping relationship table, according to the ID w Obtain the corresponding variable name. Based on this, convert A, B, and C into corresponding linear expressions respectively, denoted as a, b, and c, and form a constraint in the form of a*b = c.

[0093] In this embodiment, the three sub-elements are:

[0094]

[0095] For the first sub - element, based on __w_dic_r in SymDataDic, "0" is #f1m21888242871839275222246405745257275088548364400416034343698204186575808495617, which is the identity element in the finite field defined by bn128 large prime numbers. The "1" on the left side of the colon is'main.out[0]'. Further, according to __signal_dic in SymDataDic,'main.out[0]' can be further mapped to Output signal Num2Bits[0].out[0]. "21888242871839275222246405745257275088548364400416034343698204186575808495616" is its coefficient, equivalent to - 1 in the finite field, and the "1" on the left side of the colon is 1 in the finite field. Thus, the expression 1 * - 1+Num2Bits[0].out[0] * 1 is formed.

[0096] Similarly, for the second sub - element, the expression 1 * 1 can be parsed and formed. The third sub - element contains nothing, so the expression 0 is formed. Based on the expressions formed by parsing the three sub - elements, the constraint is formed: (1 * - 1+Num2Bits[0].out[0] * 1)+1 = 0.

[0097] Similarly, the remaining elements in constraints are parsed in turn to form a set of constraints. Their storage situation in memory is as follows:

[0098]

[0099]

[0100] Step S5 - 4, connect the constraints obtained in step 5 - 3 using the conjunction relationship to form the constraint model corresponding to the R1CS file.

[0101] Step S6, based on the formal specification of the assembly function's function and the.sym file, parse the.dat and CPP files, extract the calculation models corresponding to the compilation products, denoted as the calculation model corresponding to the.dat file and the calculation model corresponding to the CPP file, and element_dict used to store the mapping relationship of signals in the CPP file.

[0102] Step S6-1, starting from the end of the Num2Bits.dat file, group 40 bytes at a time and map the binary constants to the required FrElement in the.cpp file. In this embodiment, taking the constant 1 as an example, it is stored in binary form in the Num2Bits.dat file:

[0103]

[0104] The first 32 bits store the short-type data of the data, the middle 32 bits store the type of the data, and the last 256 bits store the long-type data of the data. Extract them in sequence and save them as FrElement format data.

[0105] Step S6-2, parse the text line by line in the.sym file and map the signal to the required FrElement in the.cpp file;

[0106] In this embodiment, store the signal names and their corresponding numbers involved in the Num2Bits.sym file in the FrElement format, and the content is as follows:

[0107]

[0108] Step S6-3, use CVC5 to generate the formal specification formed by the Fr_add prepared in S1-2 to generate the operation verification conditions on a certain finite field, which are used to ensure that the input operation results conform to the given verification logic subsequently, as follows:

[0109]

[0110]

[0111] Step S6-4, use the method of string matching to parse the Num2Bits.cpp file line by line, and convert the operation operations involved in the file into the operation verification conditions on the finite field prepared in Step S6-3.

[0112] Specifically supported operations include: creation and reference of templates, control flow code including for, if, while, support for the four arithmetic operations of addition, subtraction, multiplication, and division, support for finding the inverse element in finite field operations, support for comparison operations such as 'Fr_eq', 'Fr_neq', 'Fr_gt', 'Fr_lt', 'Fr_geq', 'Fr_leq', and support for assignment and exponentiation operations. Finally, store the generated series of constraint conditions in the list in the SMT format.

[0113] In this embodiment, Num2Bits.circom involves for-loop operations. Therefore, when parsing the cpp file, the corresponding loop needs to be unrolled. In this embodiment, when an operation such as Fr_add(&expaux[0],&lvar[1],&expaux[2]); is encountered, the operation verification conditions on the finite field prepared in S6-3 are automatically inserted (the same logic is adopted for other operations). Finally, all the prepared operation verification conditions are stored in a list in SMT format, which is the calculation model corresponding to the cpp file.

[0114] Step S7: Connect the constraint model corresponding to the source code in Step S4 and the constraint model corresponding to the R1CS file in Step S5 using an equivalence relationship, take the negation, and then use the CVC5 solver to solve. If there is no solution, it indicates that the Circom compiler can ensure the constraint consistency between the compiled product and the source file. If there is a solution, that is, there is a counterexample, it indicates that there is an error in the Circom compiler.

[0115] Step S8: Based on element_dict, verify the equivalence of the calculation model corresponding to the source code and the calculation model corresponding to the CPP file in combination with the SMT solver to form a target property, and use the CVC5 solver to solve. If there is no solution, it indicates that the Circom compiler can ensure the calculation consistency between the compiled product and the source file. If there is a solution, that is, there is a counterexample, it indicates that there is an error in the Circom compiler.

[0116] Step S8-1: Traverse the signal mapping relationship table, convert each key-value pair into an equality constraint, and store the equality constraint in the input equality constraint set or the result equality constraint set according to whether the involved signal is an input signal.

[0117] The obtained input equality constraint set is as follows:

[0118]

[0119] The obtained result equality constraint set is as follows:

[0120]

[0121] Step S8-2: Connect the elements in the input equality constraint set using a conjunction relationship to form an input constraint, and connect the elements in the result equality constraint set using a conjunction relationship to form a result constraint.

[0122] Step S8-3: Take the negation of the result constraint, and then use a conjunction relationship to connect it with the input constraint, the calculation model corresponding to the source code in Step S4, and the calculation model corresponding to the CPP file in Step S6 to form a target property.

[0123] Step S8-4: Use the CVC5 solver to solve the target property. If there is no solution, it indicates that the Circom compiler can ensure the computational consistency between the compiled product and the source file. If there is a solution, that is, there is a counterexample, it indicates that there is an error in the Circom compiler.

[0124] Step S9: If both the constraint consistency in Step S7 and the computational consistency in Step S8 are ensured, it indicates that the Circom compiler can correctly compile the Circom source file and output "equivalent".

[0125] Embodiment 2

[0126] In this embodiment, the sub-steps in Step S3 are replaced with:

[0127] Step S3-1: Analyze the file where the main module declaration of the Circom source code is located, parse each syntax node, convert the syntax structure into an abstract syntax tree, and temporarily store it in memory in json format, with detailed annotation of information such as signal declarations, variable declarations, module declarations, expression types, branch structures, loop structures, and main module declaration parameters.

[0128] Step S3-2: According to the include import relationship, recursively parse the call relationships between Circom source codes, and convert all involved code files into abstract syntax trees correspondingly.

[0129] Step S3-3: Extract the template and function nodes in the abstract syntax tree and add them to the definitions list of the abstract syntax tree in sequence, so as to achieve the merging of the abstract syntax tree.

[0130] Step S3-4: Store the abstract syntax tree in a specified location on the hard disk in the form of a json file.

[0131] For the sake of easy expression, in this embodiment, the same structures as those in Embodiment 1 are given the same symbols, and the same descriptions are omitted.

[0132] Those skilled in the art of this industry should understand that the present invention is not limited by the above embodiments. The above embodiments and the descriptions in the specification only illustrate the principles of the present invention. Without departing from the spirit and scope of the present invention, the present invention will have various changes and improvements, and these changes and improvements all fall within the scope of the present invention claimed. The scope of the present invention claimed is defined by the appended claims and their equivalents.

Claims

1. A method for verifying the functional correctness of the Circom compiler, characterized in that: include: Step S1, pre-verify each assembly function in the assembly function library called by the Circom compiler to verify the functional correctness, and form a corresponding formal specification, which is recorded as the assembly function formal specification; Step S2, using the Circom compiler to compile the Circom source code, if it passes, save the compiled R1CS file and CPP file in .sym, .dat, json format; Step S3, extracting an abstract syntax tree from the Circom source code and storing it in a json file format; Step S4, parsing the abstract syntax tree of the Circom source code, and extracting the constraint model and the computation model corresponding to the Circom source code based on the grammatical semantics of the Circom language, which are recorded as the constraint model corresponding to the source code and the computation model corresponding to the source code; Step S5, parsing the compiled R1CS file based on the .sym file, extracting the constraint model corresponding to the compiled product, and recording it as the constraint model corresponding to the R1CS file; Step S6, parsing the .dat and CPP files based on the formalized specification of the assembly function and the .sym file, extracting the computational model corresponding to the compiled product, recording it as the computational model corresponding to the .dat file and the computational model corresponding to the CPP file, and element_dict is used to store the mapping relationship of signal in the CPP file; Step S7, connecting the constraint model corresponding to the source code and the constraint model corresponding to the R1CS file using an equivalence relationship, inverting them and solving them using the CVC5 solver. If there is no solution, it indicates that the Circom compiler can ensure the constraint consistency between the compiled product and the source file. If there is a solution, that is, there is a counterexample, it indicates that there is an error in the Circom compiler. Step S8, based on the element_dict, in combination with the SMT solver, verify the equivalence of the computational model corresponding to the source code and the computational model corresponding to the CPP file to form a target property, and use the CVC5 solver to solve. If there is no solution, it indicates that the Circom compiler can ensure the computational consistency between the compiled product and the source file. If there is a solution, that is, there is a counterexample, it indicates that there is an error in the Circom compiler; Step S9: If the solution results of S7 and S8 are both no solution, it means that the Circom compiler can correctly compile the Circom source file.

2. The method for verifying the functional correctness of the Circom compiler according to claim 1, Features: Wherein, the step S1 includes the following sub-steps: Step S1-1, for each function in fr.asm, write a corresponding verification script .ini file for it, the script content mainly includes constraints such as whether the verification function is correct and whether the register overflows; Step S1-2, start Binsec's symbolic execution process. The execution result will return whether the currently verified function has an error. If an error occurs, a counterexample will be returned. If correct, the number of execution paths and the execution time will be returned. Finally, the correctly executed script content will be summarized into a more concise specification for subsequent use.

3. The method for verifying the functional correctness of the Circom compiler according to claim 1, Features: Wherein, the step S3 includes the following sub-steps: Step S3-1, analyzing the file where the main module declaration of the Circom source code is located, parsing each syntax node, converting the syntax structure into an abstract syntax tree, and temporarily storing it in the memory in JSON format, with detailed annotations on signal declaration, variable declaration, module declaration, expression type, branch structure, loop structure, main module declaration parameters and other information; Step S3-2, storing the abstract syntax tree in a specified location on the hard disk in the form of a json file.

4. The method for verifying the functional correctness of the Circom compiler according to claim 3, Features: Wherein, in the step S3, the following sub-steps are also included between step S3-1 and step S3-2: According to the include import relationship, recursively parse the calling relationship between the Circom source codes, and convert all the code files involved into abstract syntax trees accordingly; The template and function nodes in the abstract syntax tree are extracted and added to the definitions list of the abstract syntax tree in sequence, thereby realizing the merging of the abstract syntax trees.

5. The method for verifying the functional correctness of the Circom compiler according to claim 1, Features: Wherein, the step S4 includes the following sub-steps: Step S4-1, reading the json file from a specified location on the hard disk and loading the abstract syntax tree information into the memory; Step S4-2, analyzing the main_component node in the abstract syntax tree, extracting the id and parameter assignment list of the template corresponding to the main module; Step S4-3, parsing the parameter assignment list, calculating the value of the expression therein, and storing each parameter assignment in an array form according to the original order, recorded as a parameter assignment array; Step S4-4, searching for the corresponding template in the definitions list according to the module id, parsing it, generating corresponding variables based on the parameter list described by the args node, and assigning values ​​according to the parameter assignment array; Step S4-5, parse each node in the stmt list of the parsed template, generate the corresponding var variable, signal variable and component variable based on the Declaration node, form an equality expression based on the ConstraintEquality node, and store it in the constraint expression set, assign a value to the specified variable based on the Substitution node, if the left value type is var, parse the right value expression to get the value, and update the var variable; if the left value type is signal, model the right value expression as an expression on a finite field, form an equation with the signal variable, and store the generated expression in the calculation expression set, if the assignment operator is AssignCon straintSignal, the generated expression needs to be stored in the constraint expression set; if the left value type is Component, it indicates that the right side is a template call statement, extract the corresponding id and parameter assignment list, and then return to step S4-3, recursively parse, based on the While node, first calculate the truth value of the cond node, if it is true, parse each node in the loop body, and then check the truth value of the cond node again until it is false, based on the IfThenElse node, first calculate the truth value of the cond node, if it is true, parse the if_case child node, if it is false and the else_case child node exists, parse the else_case; Step S4-6, connecting each element in the constraint expression set with a conjunction relationship to form a constraint model corresponding to the source code, and connecting each element in the calculation expression set with a conjunction relationship to form a calculation model corresponding to the source code.

6. The method for verifying the functional correctness of the Circom compiler according to claim 1, Features: Wherein, the step S5 includes the following sub-steps: Step S5-1, read the .sym file from the specified position of the hard disk line by line, each line stores the index information of a certain signal; Step S5-2, using English commas as separators, divide each line into four parts, where the first part represents the order in which the signal appears in the Circom source code, recorded as id s The second part represents the order id of the signal in the witness file. w The third part represents the ID of the component to which the signal belongs. c The fourth part represents the name of the signal in the source code, recorded as name, based on which, construct id w A bidirectional mapping relationship table with name; Step S5-3, read the R1CS file stored in json format from the specified location on the hard disk line by line, and parse the elements in the list stored in the Constraints node one by one, where each element contains three sub-elements, denoted as A, B, and C, and each sub-element contains several ids w With coefficient pairs, based on the bidirectional mapping relationship table, according to the id w Get the corresponding variable names, and based on them, convert A, B, and C into corresponding primary expressions, recorded as a, b, and c, respectively, and form constraints such as a*b=c; Step S5-4, connecting the constraints of a*b=c using a conjunction relationship to form a constraint model corresponding to the R1CS file.

7. The method for verifying the functional correctness of the Circom compiler according to claim 1, characterized in that: in, The step S6 comprises the following sub-steps: Step S6-1, in the .dat file, map the binary constants to the FrElements required in the .cpp file in groups of 40 bytes from the back to the front; Step S6-2, parse the text line by line in the .sym file and map the signal to the FrElement required in the .cpp file; Step S6-3, using CVC5 to formalize the assembly function and generate a certain operation verification condition on a finite field, which is used to ensure that the input operation result conforms to the given verification logic; Step S6-4, use the string matching method to parse the .cpp file line by line, and convert the calculation operations involved in the file into calculation verification conditions on the finite field. The specific supported operations are: template creation and reference, control flow code including for, if, while, support for addition, subtraction, multiplication and division operations, support for inverse elements in finite field operations, support for comparison operations such as 'Fr_eq', 'Fr_neq', 'Fr_gt', 'Fr_lt', 'Fr_geq', 'Fr_leq', and support for assignment and exponentiation operations. Finally, the generated series of constraints are stored in a list in SMT format.

8. The method for verifying the functional correctness of the Circom compiler according to claim 1, Features: Wherein, the step S8 includes the following sub-steps: Step S8-1, traverse the signal mapping relationship table, convert each key-value pair therein into an equality constraint, and store the equality constraint into an input equality constraint set or a result equality constraint set according to whether the signal involved is an input signal; Step S8-2, using a conjunction relation to connect the elements in the input equality constraint set to form an input constraint, and using a conjunction relation to connect the elements in the result equality constraint set to form a result constraint; Step S8-3, negate the result constraint, and then connect it with the input constraint, the calculation model corresponding to the source code, and the calculation model corresponding to the CPP file using a conjunction relationship to form a target property; Step S8-4, use the CVC5 solver to solve the target property. If there is no solution, it means that the Circom compiler can ensure the computational consistency between the compiled product and the source file. If there is a solution, that is, there is a counterexample, it means that there is an error in the Circom compiler.

9. A method system for verifying the functional correctness of the Circom compiler, characterized in that: include: AST generation tool, used to extract the abstract syntax tree from the Circom source code to be compiled and store it in json file format; An AST parsing tool is used to parse the abstract syntax tree and extract the constraint model and computation model corresponding to the source code based on the syntax semantics of the Circom language; CPP parsing tool, used to extract the computational model corresponding to the compiled product, and element_dict is used to store the mapping relationship of signal in the CPP file. Finally, the .cpp file is parsed line by line using the string matching method, and the operation operations involved in the file are converted into operation verification conditions in SMT format. R1CS parsing tool, used to read the R1CS file stored in json format from the specified location on the hard disk, and parse the elements in the list stored in the Constraints node one by one; Circom and R1CS equivalence verification tool, used to check the equivalence of the SMT formulas formed by the pre-compiled Circom code and the compiled R1CS through CVC5, so as to verify the equivalence of the Circom code and the R1CS file; The Circom and CPP equivalence verification tool is used to perform equivalence checks on the SMT formulas formed by the Circom code before compilation and the CPP code after compilation through CVC5, so as to verify the equivalence of the Circom code and the CPP file.

Citation Information

Patent Citations

  • Formal verification method of intelligent contract, electronic device and storage medium

    CN110532176A

  • Automatic form verification method and device based on constraint solver

    CN115268853A

  • Digital identity verification method and system based on block chain smart contract

    CN115622812A

  • Off-line verification method for consistency of source code and binary version

    CN117573197A

  • Automatic correctness and performance measurement of binary transformation systems

    EP3991075A1