├── NOIR ├── README.md ├── miniCTF │ ├── Prover.toml │ ├── itworked.png │ ├── Nargo.toml │ ├── Verifier.toml │ ├── src │ │ └── main.nr │ └── README.MD └── security_checklist.md ├── tutorial ├── HALO2 │ ├── pics │ │ ├── README.md │ │ ├── coulmtypes.png │ │ ├── table_layout1.png │ │ ├── table_layout2.png │ │ ├── first_constraint.png │ │ └── layout_privateColumns.png │ ├── General_Rust_Fuzzing.md │ └── Part1.md ├── README.md ├── merkle.md ├── picus.md ├── Siderophile_install_Ubuntu.md └── zokrates.md ├── miniCTF ├── itworked.png ├── change_input.png ├── generate_call.png ├── generate_input.png ├── prover │ ├── circuit.wasm │ ├── circuit_0001.zkey │ ├── input.json │ ├── README.md │ ├── CTFVerifier.sol │ ├── generate_witness.js │ ├── Verifier.sol │ └── witness_calculator.js ├── solution.md └── README.md ├── quizzes ├── README.md ├── quizz1 │ ├── Answers.md │ └── Questions.md ├── quizz3 │ ├── Answers.md │ └── Questions.md └── quizz2 │ ├── Answers.md │ └── Questions.md ├── README.md ├── Halo2 └── Highlighter │ ├── templates │ ├── unwrapCheck.json │ ├── todoCheck.json │ ├── createFieldElementCheck.json │ └── endiancheck.json │ ├── highlighter.py │ ├── report │ └── HighLighterReport.md │ └── readme.md ├── circom ├── over_underflow_template.circom └── circom_auditchecklist.md ├── forensic └── readelf.md └── riscv └── general.md /NOIR/README.md: -------------------------------------------------------------------------------- 1 | ## NOIR Related content 2 | -------------------------------------------------------------------------------- /tutorial/HALO2/pics/README.md: -------------------------------------------------------------------------------- 1 | pictures used in text 2 | -------------------------------------------------------------------------------- /NOIR/miniCTF/Prover.toml: -------------------------------------------------------------------------------- 1 | inputNum = INPUT_NUMBER 2 | inputValue = "INPUT_TWITTER_HANDLE" 3 | -------------------------------------------------------------------------------- /miniCTF/itworked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/miniCTF/itworked.png -------------------------------------------------------------------------------- /quizzes/README.md: -------------------------------------------------------------------------------- 1 | 1. [Quiz 1](./quizz1) 2 | 2. [Quiz 2](./quizz2) 3 | 3. [Quiz 3](./quizz3) 4 | -------------------------------------------------------------------------------- /NOIR/miniCTF/itworked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/NOIR/miniCTF/itworked.png -------------------------------------------------------------------------------- /miniCTF/change_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/miniCTF/change_input.png -------------------------------------------------------------------------------- /miniCTF/generate_call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/miniCTF/generate_call.png -------------------------------------------------------------------------------- /miniCTF/generate_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/miniCTF/generate_input.png -------------------------------------------------------------------------------- /NOIR/miniCTF/Nargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = [""] 3 | compiler_version = "0.5.1" 4 | 5 | [dependencies] -------------------------------------------------------------------------------- /miniCTF/prover/circuit.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/miniCTF/prover/circuit.wasm -------------------------------------------------------------------------------- /NOIR/miniCTF/Verifier.toml: -------------------------------------------------------------------------------- 1 | inputNum = "0x0000000000000000000000000000000000000000000000000000000000000001" 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repository will hold information,tutorials, tooling and quizzes I set up while learning ZK 2 | -------------------------------------------------------------------------------- /miniCTF/prover/circuit_0001.zkey: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/miniCTF/prover/circuit_0001.zkey -------------------------------------------------------------------------------- /tutorial/HALO2/pics/coulmtypes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/tutorial/HALO2/pics/coulmtypes.png -------------------------------------------------------------------------------- /tutorial/HALO2/pics/table_layout1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/tutorial/HALO2/pics/table_layout1.png -------------------------------------------------------------------------------- /tutorial/HALO2/pics/table_layout2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/tutorial/HALO2/pics/table_layout2.png -------------------------------------------------------------------------------- /miniCTF/prover/input.json: -------------------------------------------------------------------------------- 1 | {"inWebAddress" : "000000000000000000000000000000000000000000000000000000000000","ctf_version": "1"} 2 | -------------------------------------------------------------------------------- /tutorial/HALO2/pics/first_constraint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/tutorial/HALO2/pics/first_constraint.png -------------------------------------------------------------------------------- /tutorial/HALO2/pics/layout_privateColumns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbresearcher/ZK/HEAD/tutorial/HALO2/pics/layout_privateColumns.png -------------------------------------------------------------------------------- /tutorial/README.md: -------------------------------------------------------------------------------- 1 | # ZK-tutorials 2 | 1. [Creating and testing proofs with Zokrates](./zokrates.md) 3 | 2. [Using Veridise Picus](./picus.md) 4 | -------------------------------------------------------------------------------- /NOIR/miniCTF/src/main.nr: -------------------------------------------------------------------------------- 1 | fn main(inputNum: pub Field, inputValue : str<9>) { 2 | assert(inputValue == "@NoirLang"); 3 | assert(inputNum == 1); 4 | } 5 | -------------------------------------------------------------------------------- /Halo2/Highlighter/templates/unwrapCheck.json: -------------------------------------------------------------------------------- 1 | { "name":"unwrapCheck", 2 | "match": [".unwrap() "], 3 | "description":"Found unwrap without ? after make sure errors are handled correctly" 4 | } 5 | -------------------------------------------------------------------------------- /Halo2/Highlighter/templates/todoCheck.json: -------------------------------------------------------------------------------- 1 | { "name":"todoCheck", 2 | "match": ["TODO"], 3 | "description":"Found comment with the text TODO, check that code is complete and correctly implemented, or remove if not needed" 4 | } 5 | -------------------------------------------------------------------------------- /Halo2/Highlighter/templates/createFieldElementCheck.json: -------------------------------------------------------------------------------- 1 | { "name":"createFieldElementCheck", 2 | "match": ["Fp::from"], 3 | "description":"Found code creating a field element from another value, check for endianness and overflows" 4 | } 5 | -------------------------------------------------------------------------------- /quizzes/quizz1/Answers.md: -------------------------------------------------------------------------------- 1 | # Quiz 1 Answers 2 | 1. B 3 | 2. D 4 | 3. A,C,D 5 | 4. A,C 6 | 5. A,C 7 | 8 | 9 | Further reading can be found on [https://ethereum.org/en/zero-knowledge-proofs/](https://ethereum.org/en/zero-knowledge-proofs/) 10 | -------------------------------------------------------------------------------- /Halo2/Highlighter/templates/endiancheck.json: -------------------------------------------------------------------------------- 1 | { "name":"endianCheck", 2 | "match": ["from_little_endian","from_big_endian"], 3 | "description":"Found code using specific endian calls, Always check that the endian values used are consistent and valid" 4 | } 5 | -------------------------------------------------------------------------------- /quizzes/quizz3/Answers.md: -------------------------------------------------------------------------------- 1 | # Quiz 3 Answers 2 | 1. A,B,D 3 | 2. A,B,C,D 4 | 3. C 5 | 4. D 6 | 5. A 7 | 6. A 8 | 7. D 9 | 10 | You can read more on this at [https://www.alchemy.com/overviews/snarks-vs-starks](https://www.alchemy.com/overviews/snarks-vs-starks) 11 | -------------------------------------------------------------------------------- /miniCTF/prover/README.md: -------------------------------------------------------------------------------- 1 | # The files needed for the Mini CTF 2 | ## USE input.json to add the int value you generated and generate the proof. 3 | ## DISCLAIMER: THESE FILES ARE PROVIDED AS THEY WERE GENERATED ON MY COMPUTER, I CANNOT GAURANTEE THEY WILL WORK. MAKE SURE TO VIRUS SCAN THEM, AND CHECK FOR MALWARE. 4 | 5 | -------------------------------------------------------------------------------- /quizzes/quizz2/Answers.md: -------------------------------------------------------------------------------- 1 | # Quiz 2 Answers 2 | 1. B 3 | 2. D 4 | 3. C 5 | 4. A 6 | 5. TRUE 7 | 6. B 8 | 7. C,A,B 9 | 10 | For extra reading (as the questions as based on the content of the site) you can go to [https://www.alchemy.com/overviews/snarks-vs-starks](https://www.alchemy.com/overviews/snarks-vs-starks) 11 | -------------------------------------------------------------------------------- /circom/over_underflow_template.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.1.4; 2 | template SignalValues () { 3 | var staticMaxNumber = 21888242871839275222246405745257275088548364400416034343698204186575808495616; 4 | 5 | assert((0 - 1 ) == staticMaxNumber); 6 | assert(staticMaxNumber + 1 == 0); 7 | 8 | } 9 | 10 | component main = SignalValues(); 11 | -------------------------------------------------------------------------------- /miniCTF/prover/CTFVerifier.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.7.0 <0.9.0; 2 | 3 | import "./Verifier.sol"; 4 | contract CTFVerifier { 5 | Groth16Verifier _verifier; 6 | 7 | constructor(){ 8 | _verifier = Groth16Verifier(0x5958d140A16587e117affE9c2dF3A79A3bABb133); 9 | } 10 | 11 | function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[1] calldata _pubSignals) public view returns (bool) { 12 | return _verifier.verifyProof(_pA,_pB,_pC,_pubSignals); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /NOIR/security_checklist.md: -------------------------------------------------------------------------------- 1 | ## NOIR Security best practice checklist 2 | - [ ] Check any imported libraries for known vulnerabilites 3 | - [ ] Check variable assignment 4 | - [ ] Check variable types used 5 | - [ ] Check public and private variables are correctly indicated 6 | - [ ] Check any functions for logic errors 7 | 8 | ## Code best practices 9 | - [ ] Tuples cannot be inputs currently (if you want to generate a proof) 10 | - [ ] TO BE ADDED AS I GET TO KNOW OF THEM 11 | 12 | ## Besides manual testing and Hardhat/Foundry are there any other testing frameworks? 13 | - [ ] Run any tests provided 14 | - [ ] Write tests 15 | 16 | ## Are there any static analyzers/Fuzzers/verifiers? 17 | - [ ] Static analyzers? 18 | -------------------------------------------------------------------------------- /miniCTF/prover/generate_witness.js: -------------------------------------------------------------------------------- 1 | const wc = require("./witness_calculator.js"); 2 | const { readFileSync, writeFile } = require("fs"); 3 | 4 | if (process.argv.length != 5) { 5 | console.log("Usage: node generate_witness.js "); 6 | } else { 7 | const input = JSON.parse(readFileSync(process.argv[3], "utf8")); 8 | 9 | const buffer = readFileSync(process.argv[2]); 10 | wc(buffer).then(async witnessCalculator => { 11 | // const w= await witnessCalculator.calculateWitness(input,0); 12 | // for (let i=0; i< w.length; i++){ 13 | // console.log(w[i]); 14 | // } 15 | const buff= await witnessCalculator.calculateWTNSBin(input,0); 16 | writeFile(process.argv[4], buff, function(err) { 17 | if (err) throw err; 18 | }); 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /quizzes/quizz1/Questions.md: -------------------------------------------------------------------------------- 1 | # Quiz 1 Questions 2 | 1. A zero-knowledge proof allows you to prove the truth of a statement without sharing the statement’s
3 | a. Signature
4 | b. Content
5 | c. Keccak hash
6 | d. Message sender

7 | 2. Which one of these is not a criteria that must be satisfied
8 | a. Completeness
9 | b. Soundness
10 | c. Zero-knowledge
11 | d. Privacy

12 | 3. In basic form, a zero-knowledge proof is made up of three elements
13 | a. witness
14 | b. validation
15 | c. challenge
16 | d. response

17 | 4. What two basic classes proofs are there:
18 | a. Interactive
19 | b. Witnessed
20 | c. Non-interactive
21 | d. Verified

22 | 5. Proofs can further be divied into:
23 | a. ZK-SNARKS
24 | b. ZK-SHARDS
25 | c. ZK-STARKS
26 | d. ZK-TRUSTPROOFS
27 | -------------------------------------------------------------------------------- /tutorial/merkle.md: -------------------------------------------------------------------------------- 1 | # Merkle Trees, Merkle Sum Trees and "Broken" Merkle Sum Trees 2 | 3 | # What are Merkle Trees 4 | Merkle trees are a logical way of storing data in an organised structure. In specidic a tree-like structure is used, where the bottom most layers contain actual data eg. Account balances. 5 | 6 | As we traverse the tree structure from the bottom to the top of the tree, each leaf is hashed with it's sibling to generate a hash value representing the data held by the two sibling nodes. 7 | 8 | An example of this would be a below: 9 | | | | | | | | | | | 10 | | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | 11 | | | | | | Root Hash is the hash value of HASH(Level1 LHS,Level1 RHS) | | | | | 12 | | | | | Level1 Lefthand side Hash is the hash value of HASH(Level2 Value1,Level1 Value2)| | Level1 Righthand Hash side is the hash value of HASH(Level2 Value3,Level2 Value4)| | | | 13 | | |Level2 Value1 | | Level2 Value2 | | Level2 Value3 | | Level2 value4 | | 14 | 15 | -------------------------------------------------------------------------------- /tutorial/picus.md: -------------------------------------------------------------------------------- 1 | ## Picus 2 | [https://github.com/Veridise/Picus](https://github.com/Veridise/Picus) 3 | 4 | Picus is used to run verification tasks on r1cs files. 5 | 6 | ## Follow the instructions on the github link above to clone the repo, build the docker file and run the docker container. 7 | 8 | ## Copy files into the container 9 | 1. To run the docker container ```docker run -it --rm picus:v0 bash``` 10 | 2. Once the docker container is running you will be presented with a commandline prompt in the docker container. 11 | 3. On the host pc get the docker container id: ```sudo docker container ls``` 12 | 4. Inside the Docker container create a directory in the container for your test files eg. ```mkdir tester``` and then ```mkdir r1cs``` 13 | 5. From your host pc copy the r1cs files into the docker container ```sudo docker cp myr1csfile.r1cs CONTAINERID:/Picus/tester/r1cs/myr1csfile.r1cs``` 14 | 6. in the docker container you can now run any of the verification ```.rkt``` scripts against your r1cs file to verify it. eg. ```racket ./test-v1-uniqueness.rkt --r1cs ./tester/r1cs/myr1csfile.r1cs``` 15 | -------------------------------------------------------------------------------- /circom/circom_auditchecklist.md: -------------------------------------------------------------------------------- 1 | ## Circom Audit Checklist 2 | 3 | ## Language checks 4 | - [ ] Check for over/underflows (21888242871839275222246405745257275088548364400416034343698204186575808495616 MAX value) 5 | - [ ] Check <-- type assignments without constraints 6 | - [ ] Check constraint assignment 7 | - [ ] Check variables being added/multiplied etc. that they are the correct ones for the formula 8 | - [ ] Check public signals that are not used that might be optimized out by compiler 9 | - [ ] Check for public input malleability 10 | - [ ] Check basic logic flow 11 | - [ ] Do a web search to check any imported libraries for reported vulnerabilites 12 | 13 | ## Tooling 14 | - [ ] Run circompect 15 | - [ ] Run Veridise Picus 16 | - [ ] Run Veridise Coda 17 | - [ ] Run Ecne 18 | - [ ] Run tests if provided 19 | - [ ] Write tests 20 | 21 | ## Resources to check 22 | [https://github.com/trailofbits/circomspect/blob/main/doc/analysis_passes.md](https://github.com/trailofbits/circomspect/blob/main/doc/analysis_passes.md) 23 | 24 | [https://github.com/0xPARC/zk-bug-tracker](https://github.com/0xPARC/zk-bug-tracker) 25 | -------------------------------------------------------------------------------- /miniCTF/solution.md: -------------------------------------------------------------------------------- 1 | # Solution to the Mini CTF. 2 | 3 | ## The steps to resolve the CTF are: 4 | 1. Make sure to have the circom and snarkjs installed as mentioned in the links to the circom documentation. 5 | 2. Download the files or clone the repo and move into the **prover** directory. 6 | 3. Open a terminal and start chisel : `chisel` 7 | 4. Get the input value needed in the input.json file : ```uint256 inputVal = uint256(keccak256("https://yacademy.dev/"));```
![Input value](generate_input.png)
8 | 5. Enter the resulting int value into the input.json
![Edit file](change_input.png)
9 | 6. Run the node command to generate a witness ```node generate_witness.js circuit.wasm input.json witness.wtns``` 10 | 7. This will create a file called `witness.wtns` 11 | 8. Run the snarkjs command to create the proof.json and public.json files: ```snarkjs groth16 prove circuit_0001.zkey witness.wtns proof.json public.json``` 12 | 9. Run the snarkjs command to generate the call data to send in the call from REMIX: ```snarkjs generatecall```
![Generate call](generate_call.png)
13 | 10. Open REMIX and interact with the CTFVerifier contract at address 0x37dEA441346447b271c372Bd21dEc2347aB6d0f4 14 | 11. Enter the value that was generated by the snarkjs command and it should return true
![It Worked](itworked.png)
15 | -------------------------------------------------------------------------------- /NOIR/miniCTF/README.MD: -------------------------------------------------------------------------------- 1 | # MINI CTF 2 | ## There is no prize it's just to learn. 3 | ## LEVEL : EASY 4 | The files needed are in a the main directory of this miniCTF folder.
5 | I have created a mini CTF on the `Sepolia` network.
6 | [https://sepolia.etherscan.io/address/0x54ea97c4b15bb81744fdd82d7fd3466d4b151d17](https://sepolia.etherscan.io/address/0x54ea97c4b15bb81744fdd82d7fd3466d4b151d17)
7 | The aim of the CTF is to generate and submit a proof, that you know the `inputValue` of the NoirLang twitter handle [https://twitter.com/NoirLang](https://twitter.com/NoirLang), as a string (including "") and the `inputNum` of 1.
8 | ## AIM 9 | To generate and submit a proof to the contract and get a response as `true` 10 | ## Helpful links: 11 | [https://noir-lang.org/getting_started/breakdown](https://noir-lang.org/getting_started/breakdown)
12 | [https://github.com/noir-lang/noir-starter](https://github.com/noir-lang/noir-starter) 13 | 14 | You can use REMIX to interact with `plonk_vk.sol` supplied in the `contract` directory of this miniCTF, the contract is on the `Sepolia` test net at the address **0x54ea97c4b15Bb81744fDD82d7FD3466D4b151D17**

15 | If the proof submitted is correct it will return ***true*** on the call to the function `verify`.
16 | ![It Worked](itworked.png)

17 | ## DISCLAIMER: Do not use any of this code in production it's just an example. always verify software. 18 | -------------------------------------------------------------------------------- /quizzes/quizz3/Questions.md: -------------------------------------------------------------------------------- 1 | # Quiz 3 Questions 2 | Based on [https://www.alchemy.com/overviews/snarks-vs-starks](https://www.alchemy.com/overviews/snarks-vs-starks)

3 | 1. What benefits do ZK-SNARKs give us
4 | a. High throughput
5 | b. Small proof sizes
6 | c. Synchronous proofs
7 | d. Security

8 | 2. What benefits do ZK-STARKs give us
9 | a. No need for a trusted setup
10 | b. Scalable properties
11 | c. High Throughput
12 | d. High Security gaurantees

13 | 3. Which type of SNARK can verify other SNARKs
14 | a. a synchrous SNARK
15 | b. a interactive SNARK
16 | c. a recursive SNARK
17 | d. a multi-proof SNARK

18 | 4. What mechanism is used for Polygon ZK Rollups
19 | a. ZK-STARKs
20 | b. L2 Prover
21 | c. ZK-POLY
22 | d. PLONKY2

23 | 5. Which mechanism allows for muliple transactions to be included into a single proof
24 | a. a recursive SNARK
25 | b. MULTI-SNARK
26 | c. StarkNet
27 | d. MULTI-PROOFING

28 | 6. ZK-STARKs Produce:
29 | a. larger proofs than ZK-SNARKs
30 | b. smaller proofs than ZK-SNARKs
31 | c. identical proofs to ZK-SNARKs
32 | d. Cheaper proofs than ZK-SNARKs

33 | 7. ZK-SNARKs are succinct which means
34 | a. They are an exact representation of the content they are signing
35 | b. They are less accurate
36 | c. They are smaller than 32 bytes
37 | d. They are small enough to be verified in a short timeframe

38 | -------------------------------------------------------------------------------- /miniCTF/README.md: -------------------------------------------------------------------------------- 1 | [LINK TO SOLUTION WALKTHROUGH](./solution.md) 2 | # MINI CTF 3 | ## There is no prize it's just to learn. 4 | The files needed are in a folder called **prover** in this repo.
5 | I have created a mini CTF on the sepolia network.
6 | [https://sepolia.etherscan.io/address/0x37dEA441346447b271c372Bd21dEc2347aB6d0f4](https://sepolia.etherscan.io/address/0x37dEA441346447b271c372Bd21dEc2347aB6d0f4)
7 | The aim of the CTF is to generate and submit a proof, that you know the keccak256 hash of the yAcademy website **https://yacademy.dev/** URL, which you then casted into a uint256.
8 | ## HINT: The number starts with 1113 and ends with 929. 9 | ## Helpful links: 10 | [https://docs.circom.io/getting-started/computing-the-witness/](https://docs.circom.io/getting-started/computing-the-witness/)
11 | [https://docs.circom.io/getting-started/proving-circuits/](https://docs.circom.io/getting-started/proving-circuits/)

12 | You need to use snarkjs to genearate a witness and proof file, and then submit this to the verifier.
13 | You can use REMIX to interact with `CTFVerifier.sol` supplied in the **prover** directory of this repo at the address **0x37dEA441346447b271c372Bd21dEc2347aB6d0f4**

14 | If the proof submitted is correct it will return ***true*** on the call to the function `verifyProof`.
15 | ![It Worked](itworked.png)

16 | ## DISCLAIMER: Do not use any of this code in production it's just an example. always verify software, DO NOT just install software you think you may need without double checking, so if you install anything based on this CTF it is at your own risk. 17 | -------------------------------------------------------------------------------- /quizzes/quizz2/Questions.md: -------------------------------------------------------------------------------- 1 | # Quiz 2 Questions 2 | 1. What does ZK-SNARK stand for
3 | a. Zero-Knowledge Secret Non-Interactive Argument of Knowledge
4 | b. Zero-Knowledge Succinct Non-Interactive Argument of Knowledge
5 | c. Zero-Knowledge Synchronous Non-Interactive Argument of Knowledge
6 | d. Zero-Knowledge Supported Non-Interactive Argument of Knowledge

7 | 2. What does ZK-STARK stand for
8 | a. Zero-Knowledge Scalable Transport Argument of Knowledge
9 | b. Zero-Knowledge Secret Transparent Argument of Knowledge
10 | c. Zero-Knowledge Scalable Transparent Augmentation of Knowledge
11 | d. Zero-Knowledge Scalable Transparent Argument of Knowledge

12 | 3. ZK-STARKs produce proofs that are
13 | a. smaller than ZK-SNARKs
14 | b. less comlex than ZK-SNARKs
15 | c. larger than ZK-SNARKs
16 | d. the same as ZK-SNARKs

17 | 4. ZK-STARK and ZK-SNARK allow for the message to be veirifed:
18 | a. without replaying the transaction
19 | b. without the transaction being signed
20 | c. without the transaction being verified
21 | d. without needing the shared key

22 | 5. ZK-SNARKs can prove the correctness of off-chain computations
23 | a. TRUE
24 | b. FALSE

25 | 6. ZK-ROLLUPs are:
26 | a. A solution to batch signature
27 | b. A Layer 2 scaling solution
28 | c. A solution to synchronize Layer 2 transactions
29 | d. A soltion to make transactions smaller

30 | 7. PUT THE BELOW IN ORDER-> ZK-ROLLUPs that use ZK-SNARKS follow this structure:
31 | a. Validators compress transactions into a block and generate a proof
32 | b. A smart contract on L1 validates the proof, and if it's valid posts to the main chain
33 | c. L2 Users sign transaction

34 | -------------------------------------------------------------------------------- /tutorial/HALO2/General_Rust_Fuzzing.md: -------------------------------------------------------------------------------- 1 | # This is a quick step-by-step walkthrough to set up fuzzing using libfuzzer and cargo-fuzz 2 | 3 | # Installation (official documentation at: https://rust-fuzz.github.io/book/cargo-fuzz/setup.html) 4 | 1. First make sure you have the nightly compiler installed, it will only work with the nightly compiler 5 | 2. To install the nightly compiler run `rustup install nightly` (you can set it to be the default by issuing the `rustup default nightly` command) 6 | 3. Now install cargo-fuzz : `cargo install cargo-fuzz` or upgrade `cargo install --force cargo-fuzz` 7 | 8 | # Start fuzzing a project 9 | 1. If you dont have the project on the computer you are going to use to fuzz get a copy of the project locally on the computer 10 | 2. `cd` into the root directory of the project 11 | 3. Initialize the cargo-fuzz framework : `cargo fuzz init` 12 | 13 | You project will now have a `fuzz` directory in the directory structure. 14 | Inside of this directory will be a second directory called `fuzz_targets`, this is the directory all the fuzzing tests will be in. 15 | There will also by default be your first fuzzing tagert called `fuzz_target_1.rs`. You can check this by running `cargo +nightly fuzz list` which will output all your fuzz tragets. 16 | 17 | # Writing the test 18 | 1. Decide on a method/function that you would like to run a fuzz test against 19 | 2. Get the input needed for method/function you will fuzz (more information at: https://rust-fuzz.github.io/book/cargo-fuzz/tutorial.html) 20 | 3. Open the file called `fuzz_target_1.rs`. 21 | 4. You will see code that looks as below 22 | ```rust 23 | #![no_main] 24 | 25 | use libfuzzer_sys::fuzz_target; 26 | 27 | fuzz_target!(|data: &[u8]| { 28 | // fuzzed code goes here 29 | }); 30 | ``` 31 | The fuzz function takes input in the form of a u8 vector which needs to be converted to a string or other data structure (if you need something more complex than a string take a look at the official documentation : https://rust-fuzz.github.io/book/cargo-fuzz/structure-aware-fuzzing.html) 32 | 33 | To convert to string and invoke your intended fuzz target you can add the code: 34 | ```rust 35 | fuzz_target!(|data: &[u8]| { 36 | // fuzzed code goes here 37 | if let Ok(s) = std::str::from_utf8(data){ 38 | let _ = THE_METHOD_I_AM_FUZZING_WHICH_TAKES_A_STRING_INPUT(s); 39 | }; 40 | 41 | }); 42 | ``` 43 | That is all that is needed, you can now run the fuzz test with `cargo +nightly fuzz run fuzz_target_1` and watch the fuzz test output to the console. 44 | ``` 45 | -------------------------------------------------------------------------------- /forensic/readelf.md: -------------------------------------------------------------------------------- 1 | # Dump from Claude AI 2 | 3 | I'll explain how to use readelf to analyze ELF files and memory allocation in Linux. 4 | 5 | readelf is a powerful tool for analyzing ELF (Executable and Linkable Format) files, which are the standard binary format for executables, object code, and shared libraries in Linux. 6 | 7 | Here are the key readelf commands for memory and allocation analysis: 8 | 9 | 1. View Program Headers (segments): 10 | ```bash 11 | readelf -l executable 12 | ``` 13 | This shows segment information including: 14 | - Memory permissions (read/write/execute) 15 | - Virtual addresses 16 | - Segment sizes and alignment 17 | - Segment types (LOAD, DYNAMIC, etc.) 18 | 19 | 2. View Section Headers: 20 | ```bash 21 | readelf -S executable 22 | ``` 23 | This displays: 24 | - Section names and types 25 | - Memory addresses 26 | - Section sizes 27 | - Section flags (allocatable, writable, executable) 28 | 29 | 3. Analyze dynamic section and dependencies: 30 | ```bash 31 | readelf -d executable 32 | ``` 33 | Shows: 34 | - Shared library dependencies 35 | - Runtime path information 36 | - Symbol versioning 37 | - Other dynamic linking information 38 | 39 | 4. View symbol tables: 40 | ```bash 41 | readelf -s executable 42 | ``` 43 | Displays: 44 | - Global and local symbols 45 | - Symbol sizes and types 46 | - Symbol bindings (local/global/weak) 47 | - Symbol visibility 48 | 49 | For investigating ELF files in detail: 50 | 51 | 1. View file header information: 52 | ```bash 53 | readelf -h executable 54 | ``` 55 | Shows: 56 | - ELF class (32/64-bit) 57 | - Entry point address 58 | - Machine architecture 59 | - File type 60 | 61 | 2. View relocation entries: 62 | ```bash 63 | readelf -r executable 64 | ``` 65 | Shows how the dynamic linker needs to modify the program for loading. 66 | 67 | 3. Examine notes section: 68 | ```bash 69 | readelf -n executable 70 | ``` 71 | Displays additional metadata about the binary. 72 | 73 | 4. View all headers at once: 74 | ```bash 75 | readelf -a executable 76 | ``` 77 | Comprehensive view of all ELF file information. 78 | 79 | Practical examples for memory analysis: 80 | 81 | 1. Find the program's entry point: 82 | ```bash 83 | readelf -h executable | grep "Entry" 84 | ``` 85 | 86 | 2. Check for writable and executable segments (potential security issues): 87 | ```bash 88 | readelf -l executable | grep "RWE" 89 | ``` 90 | 91 | 3. Analyze memory layout: 92 | ```bash 93 | readelf -l executable | grep -A 5 "Program Headers" 94 | ``` 95 | 96 | 4. Find loaded shared libraries: 97 | ```bash 98 | readelf -d executable | grep "NEEDED" 99 | ``` 100 | 101 | Tips for memory allocation investigation: 102 | 103 | 1. Look for segments with RW (Read-Write) permissions to identify data sections: 104 | ```bash 105 | readelf -l executable | grep -A 1 "RW" 106 | ``` 107 | 108 | 2. Check section sizes to understand memory footprint: 109 | ```bash 110 | readelf -S executable | grep "Size" 111 | ``` 112 | 113 | 3. Analyze stack and heap-related segments: 114 | ```bash 115 | readelf -l executable | grep -A 3 "GNU_STACK" 116 | ``` 117 | 118 | 4. Examine dynamic memory allocations: 119 | ```bash 120 | readelf -d executable | grep "PLTRELSZ\|RELSZ" 121 | ``` 122 | 123 | Common use cases: 124 | 125 | 1. Security analysis: 126 | - Check for executable stack segments 127 | - Identify writable and executable sections 128 | - Analyze security-related flags 129 | 130 | 2. Debugging: 131 | - Find symbol addresses 132 | - Analyze relocation entries 133 | - Examine section permissions 134 | 135 | 3. Memory optimization: 136 | - Analyze section sizes 137 | - Check alignment requirements 138 | - Identify unused sections 139 | 140 | 4. Dependency analysis: 141 | - Check required shared libraries 142 | - Analyze dynamic linking information 143 | - Verify symbol resolution 144 | 145 | Remember to combine readelf with other tools like objdump, nm, and ldd for comprehensive binary analysis. The information from readelf can help you understand memory layout, identify security issues, and optimize memory usage in your programs. 146 | -------------------------------------------------------------------------------- /tutorial/HALO2/Part1.md: -------------------------------------------------------------------------------- 1 | # Halo2 101 2 | 3 | ## Introduction 4 | This is the first in a series of very high level tutorials on Halo2. The purpose of tutorials is to introduce Halo2 concepts in order to break them down into small understandable concepts, to guide the reader that is starting out on the journey of learning zero knowledge and Halo2. 5 | 6 | Halo2 was developed by Electric Coin Company, and has been used in Zcash and many other zero kenowledge protocols. 7 | 8 | Halo2 is an API implemented in Rust. It is used to create zero knowledge circuits used to prove and verify zero knowledge claims. Halo2 makes use of PLONKish arithmetic as the basis for computations. In order to understand how to develop Halo2 circuits it would be beneficial to first understand the table structure used by Halo2 and PLONKish arithmetic. 9 | 10 | ## Analogy 11 | Let me start off by using an abstract example, I think this will make understanding the concept slightly easier. 12 | Imagine a database table or an excel spreadsheet. Each column has a type of data it will hold, in a typical database the first column might be used for an auto-incrementing integer which will become the row index. The next column will hold a different type of data which the application will use internally for some function. Each row will be filled with values that correspond to the column data types. 13 | 14 | This is a long winded way to say each column has a function and each row is filled with data according to the column's data type. 15 | 16 | ## Scenario 17 | The scenario we will use in our example is a list where sales are recorded. 18 | There are two sales people and each day a tally of sales is recorded. 19 | The spreadsheet consists of three columns, column A is sales done by the first sales person, column B is the number of sales per day by the second sales person and column C is used to capture a running total of sales. 20 | 21 | In the example, the spreadsheet layout will be as set out in the image below. 22 | 23 | ![Table](pics/table_layout1.png) 24 | 25 | Now we can build further on our spreadsheet application. Imagine we wanted to write a macro that would check each row and ensure that the value of 26 | 27 | `ROW[CURRENT_ROW].COLUMN[A] + ROW[CURRENT_ROW].COLUMN[B] + ROW[PREVIOUS_ROW].COLUMN[C] = ROW[CURRENT_ROW].COLUMN[C]` 28 | 29 | as in the image below. 30 | 31 | ![Table](pics/first_constraint.png) 32 | 33 | Our first row does not have a previous row that the Column C can be checked against. To overcome this we decide to add an extra column that will only contain a 0 or a 1. If Column D has a value of 1 then it means we must run the check against this row to be sure our spreadsheet totals are correct. the new table layout will be as in the image below. 34 | 35 | ![Table](pics/table_layout2.png) 36 | 37 | Our new spreadsheet is coming along well, but lets imagine we wanted to keep track of the commision earned by each Sales person. The commision scale for each sales person may be different, and we certainly would want to keep this information private. We could add columns to our spreadsheet that are hidden, and can only be shown if the user knows the password. The values could be seen a private inputs into the spreadsheet. (We will use a background color of light red to show these columns in our pictures going forward, but for all intents and purposes they would not be visible to a normal user in the final spreadsheet.) 38 | 39 | ![Table](pics/layout_privateColumns.png) 40 | 41 | We will build on this example in a later tutorial where we deal with writing custom gates. For now we can progress to describing the types of columns used in Halo2 circuits. They have a similar structure and function. 42 | 43 | Each column type is used differently in Halo2 and the rows in turn will hold the values. The values may be present as the circuit is instantiated or the values be be calculated during the execution of the code of the circuit. 44 | There are fixed columns that can be used as lookup tables. The concept is very similar to lookup tables in spreadsheets. 45 | 46 | The table below lists these columns and the columns in our spreadsheet as reference. 47 | 48 | ![Table](pics/coulmtypes.png) 49 | 50 | In the tutorial where we look into "Custom Gates", I will start going into the code, and show how each of these columns is declared and and instantiated in Rust code. 51 | 52 | ## Conclusion 53 | In the next tutorial I will be looking into the structure of Halo2 projects. We will get an insight into the concepts of "Chips", "Circuits", "Layouter" , "Floorplanner". 54 | 55 | This was a very high level look at the table structure used in HALO2, if you would like to get a more in-depth view to build on this example I can recommend reading the HALO2 book at [https://zcash.github.io/halo2/concepts/arithmetization.html](https://zcash.github.io/halo2/concepts/arithmetization.html) 56 | 57 | -------------------------------------------------------------------------------- /riscv/general.md: -------------------------------------------------------------------------------- 1 | ## General Information I want to keep about RISC-V 2 | 3 | ### Instructions: 4 | ``` 5 | In RISC-V (and many other RISC architectures), these are load instructions that read data from memory into a register. Here’s what each means: 6 | 7 | LB: Load Byte 8 | Loads a signed 8-bit value from memory and sign-extends it to 32 bits. 9 | 10 | LH: Load Halfword 11 | Loads a signed 16-bit value from memory and sign-extends it to 32 bits. Requires the address to be 2-byte aligned. 12 | 13 | LW: Load Word 14 | Loads a 32-bit value from memory. Requires the address to be 4-byte aligned. 15 | 16 | LBU: Load Byte Unsigned 17 | Loads an unsigned 8-bit value from memory and zero-extends it to 32 bits. 18 | 19 | LHU: Load Halfword Unsigned 20 | Loads an unsigned 16-bit value from memory and zero-extends it to 32 bits. Requires the address to be 2-byte aligned. 21 | 22 | Summary Table: 23 | 24 | Instruction Size Loaded Signed/Unsigned Alignment Requirement 25 | LB 8 bits Signed None 26 | LH 16 bits Signed 2 bytes 27 | LW 32 bits Signed 4 bytes 28 | LBU 8 bits Unsigned None 29 | LHU 16 bits Unsigned 2 bytes 30 | ``` 31 | 32 | --- 33 | 34 | ## Arithmetic Instructions 35 | 36 | | Opcode | Description | 37 | |-------------|-----------------------------------------------| 38 | | ADD | Add two registers | 39 | | SUB | Subtract one register from another | 40 | | XOR | Bitwise XOR of two registers | 41 | | OR | Bitwise OR of two registers | 42 | | AND | Bitwise AND of two registers | 43 | | SLL | Shift left logical | 44 | | SRL | Shift right logical | 45 | | SRA | Shift right arithmetic | 46 | | SLT | Set if less than (signed) | 47 | | SLTU | Set if less than (unsigned) | 48 | 49 | --- 50 | 51 | ## Load Instructions 52 | 53 | | Opcode | Description | 54 | |-------------|-----------------------------------------------| 55 | | LB | Load byte (signed) | 56 | | LH | Load halfword (16 bits, signed) | 57 | | LW | Load word (32 bits, signed) | 58 | | LBU | Load byte (unsigned) | 59 | | LHU | Load halfword (16 bits, unsigned) | 60 | 61 | --- 62 | 63 | ## Store Instructions 64 | 65 | | Opcode | Description | 66 | |-------------|-----------------------------------------------| 67 | | SB | Store byte | 68 | | SH | Store halfword (16 bits) | 69 | | SW | Store word (32 bits) | 70 | 71 | --- 72 | 73 | ## Branch Instructions 74 | 75 | | Opcode | Description | 76 | |-------------|-----------------------------------------------| 77 | | BEQ | Branch if equal | 78 | | BNE | Branch if not equal | 79 | | BLT | Branch if less than (signed) | 80 | | BGE | Branch if greater or equal (signed) | 81 | | BLTU | Branch if less than (unsigned) | 82 | | BGEU | Branch if greater or equal (unsigned) | 83 | 84 | --- 85 | 86 | ## Jump Instructions 87 | 88 | | Opcode | Description | 89 | |-------------|-----------------------------------------------| 90 | | JAL | Jump and link (stores return address) | 91 | | JALR | Jump and link register | 92 | 93 | --- 94 | 95 | ## Upper Immediate Instruction 96 | 97 | | Opcode | Description | 98 | |-------------|-----------------------------------------------| 99 | | AUIPC | Add upper immediate to PC | 100 | 101 | --- 102 | 103 | ## System Instructions 104 | 105 | | Opcode | Description | 106 | |-------------|-----------------------------------------------| 107 | | ECALL | Environment call (system call) | 108 | | EBREAK | Breakpoint (used for debugging) | 109 | 110 | --- 111 | 112 | ## Multiply/Divide Instructions 113 | 114 | | Opcode | Description | 115 | |-------------|-----------------------------------------------| 116 | | MUL | Multiply (lower 32 bits) | 117 | | MULH | Multiply high (signed) | 118 | | MULHU | Multiply high (unsigned) | 119 | | MULHSU | Multiply high (signed/unsigned) | 120 | | DIV | Divide (signed) | 121 | | DIVU | Divide (unsigned) | 122 | | REM | Remainder (signed) | 123 | | REMU | Remainder (unsigned) | 124 | 125 | --- 126 | 127 | ## Other/Unimplemented 128 | 129 | | Opcode | Description | 130 | |-------------|-----------------------------------------------| 131 | | UNIMP | Unimplemented instruction | 132 | 133 | --- 134 | -------------------------------------------------------------------------------- /Halo2/Highlighter/highlighter.py: -------------------------------------------------------------------------------- 1 | #I DO NOT WARRANTY THIS CODE TO BE BUG FREE OR TO BE FIT FOR PURPOSE, RUNNING HIGHLIGHTER AGAINST A PROJECT DOES NOT GUARANTEE THAT THE PROJECT IS SECURE AND/OR BUG FREE 2 | from subprocess import PIPE,Popen 3 | import random 4 | import os 5 | import glob 6 | import json 7 | 8 | def runHighlight(project_dir,rules_dir): 9 | # Used for progress output 10 | print("---START--------------------------------------------------------------------\n") 11 | # Used for report output 12 | MarkdownString = "# HighLighter Report\n" 13 | print("[+] Running Highlighter against directory: ",project_dir) 14 | MarkdownString = MarkdownString + "- Running Highlighter against directory: " + project_dir + "\n" 15 | print("\n") 16 | print("[+] Rules templates directory set as : ",rules_dir) 17 | MarkdownString = MarkdownString + "- Rules templates directory set as : " + rules_dir + "\n" 18 | print("\n") 19 | try: 20 | # First import all templates to minimise IO 21 | # Rules are stored in the rules array 22 | rules = [] 23 | rulecheckfinds = "" 24 | for jsonfile in os.listdir(rules_dir): 25 | with open(rules_dir + "/" + jsonfile, 'r', encoding="utf-8") as rulefile: 26 | ruleEntry = rulefile.read() 27 | rule = json.loads(ruleEntry) 28 | rules.append(rule) 29 | 30 | # Now check for files that implement the Circuit trait 31 | circuitlist = "## Circuit files found:\n" 32 | # Walk all directories and subdirectories from the main folder which was set in project_dir 33 | for root,dirs, files in os.walk(project_dir): 34 | for file in files: 35 | # Only read files ending in ".rs" 36 | if file.endswith(".rs"): 37 | with open(os.path.join(root,file), 'r', encoding="utf-8") as rustfile: 38 | rustcode = rustfile.read() 39 | # For now just check for text as below which should find "> Circuit for " 40 | if rustcode.find("> Circuit<") > 0: 41 | circuitlist = circuitlist + " [^] " + file + "\n" 42 | # Now loop through the rules array and check the "match" value against the code 43 | # retrieved from reading the source file 44 | for rule in rules: 45 | intfound = 0 46 | for strmatch in rule["match"]: 47 | if rustcode.find(strmatch) > 0: 48 | # The counter makes sure it only lists the file once 49 | # and not for each match in a file 50 | if intfound == 0: 51 | intfound = 1 52 | rulecheckfinds = rulecheckfinds + "### File: " + os.path.join(root,file) + "\n #: Match found on : " + strmatch + "\n #: " + rule["description"] + "\n\n" 53 | # setup the file path 54 | filepath = os.path.join(root,file) 55 | # Use Popen to open grep the "match" value in the file 56 | # and capture the output 57 | with Popen("grep -n -C 1 '" + strmatch + "' " + filepath + " -rIs",shell=True,stdout=PIPE) as proc: 58 | try: 59 | out, errs = proc.communicate(timeout=15) 60 | except TimeoutExpired: 61 | proc.kill() 62 | out, errs = proc.communicate() 63 | bashOutput = out.decode() 64 | # String to concatenate all match finds 65 | rulecheckfinds = rulecheckfinds + "```\n" + bashOutput + "\n```\n" 66 | 67 | 68 | print(circuitlist) 69 | print("## Rule checks returned the list of code to check below:\n") 70 | rulecheckfinds = "## Rule checks returned the list of code to check below:\n" + rulecheckfinds 71 | print(rulecheckfinds) 72 | print("---END----------------------------------------------------------------------") 73 | # Setup final string to write out to report 74 | MarkdownString = MarkdownString + circuitlist + rulecheckfinds 75 | 76 | #Write out the markdown into the report file 77 | f = open("HighLighterReport.md", "w") 78 | f.write(MarkdownString) 79 | f.close() 80 | except Exception as e: 81 | print("[#### ] Highlighter ran into an exception : ",e) 82 | 83 | def main(): 84 | #Setup python argument parsing 85 | import argparse 86 | parser = argparse.ArgumentParser() 87 | # 2 arguments used 88 | # project_dir ---> is the fully qualified path to the HALO2 project folder 89 | # rules_dir ---> is the fully qualified path to the templates directory in 90 | # most cases will be one level down for here 91 | parser.add_argument("project_dir", help="The project directory") 92 | parser.add_argument("rules_dir", help="The directory which has the JSON rules templates to check against") 93 | args = parser.parse_args() 94 | # Parse the arguments and call the runHighlight function 95 | runHighlight(args.project_dir, args.rules_dir) 96 | 97 | main() 98 | -------------------------------------------------------------------------------- /tutorial/Siderophile_install_Ubuntu.md: -------------------------------------------------------------------------------- 1 | # THIS IS JUST AN EXAMLE AND NOT A COMPLETE GUIDE 2 | # PLEASE MAKE SURE YOU UNDERSTAND ALL COMMANDS THAT YOU RUN 3 | 4 | # Installing Siderophile on a fresh installation of Ubuntu 5 | This page documents the installation process of Siderophile on a fresh installation of Ubuntu. 6 | There are two methods to install (crates.io or Github) and both are documented below. 7 | ## Installing using crates.io 8 | 1. Install Siderophile using the command : `cargo install siderophile` 9 | 2. You may get an error while compiling openssl-sys : `error: failed to run custom build command for openssl-sys v0.9.102` 10 | 3. You can fix the above error by installing the libssl-dev package : `sudo apt install pkg-config libssl-dev` 11 | 4. Reload the profile : `. ~/.profile` 12 | 5. Re-issue the cargo install command: `cargo install siderophile` 13 | 6. You may get an error as below: 14 | ``` 15 | error: No suitable version of LLVM was found system-wide or pointed 16 | to by LLVM_SYS_140_PREFIX. 17 | ``` 18 | 7. To fix this you can install the missing version, the version is the number in the error text above eg. 140 or perhaps 170. In the above instance it will be: `sudo apt install llvm-14` 19 | 8. You may get an error about missing library `Polly` as below 20 | ``` 21 | error: could not find native static library `Polly`, perhaps an -L flag is missing? 22 | ``` 23 | 9. To fix this error you can install the missing package(once agian taking into account the correct version): `sudo apt install libpolly-14-dev` 24 | 10. Once the installation is finished running the help command will confirm the installation has completed successfully 25 | ``` 26 | siderophile --help 27 | siderophile 0.2.1 28 | 29 | USAGE: 30 | siderophile [FLAGS] [OPTIONS] 31 | 32 | FLAGS: 33 | --include-tests Count unsafe usage in tests 34 | --no-mark-closures Do not mark closures 35 | -h, --help Prints help information 36 | -V, --version Prints version information 37 | 38 | OPTIONS: 39 | --crate-name Crate name (deprecated) 40 | -p, --package Package to be used as the root of the tree 41 | --mark Mark bad functions with TEXT 42 | --threshold Minimum badness required to mark a function [default: 0] 43 | ``` 44 | 45 | 46 | 47 | ## Installing by building from github 48 | 1. Before cloning the siderophile repository we will need to install the git command using: `sudo apt install git` 49 | 2. Check the installation by issuing the command : `git --version` it should return a value similar to below: 50 | ``` 51 | git version 2.43.0 52 | ``` 53 | 3. Create a new directory and change the working directory for the project eg. `mkdir siderophile_build && cd ./siderophile_build` 54 | 4. Clone the repo and cd into the siderophile driectory : `git clone https://github.com/trailofbits/siderophile && cd ./siderophile` 55 | 5. Use the cargo build command to build the project : `cargo build` 56 | 6. You may get the following error while compiling openssl-sys : `error: failed to run custom build command for openssl-sys v0.9.99` 57 | 7. You can fix the above error by installing the libssl-dev package : `sudo apt install pkg-config libssl-dev` 58 | 8. Reload the profile : `. ~/.proofile` 59 | 9. You may get an error as below: 60 | ``` 61 | error: No suitable version of LLVM was found system-wide or pointed 62 | to by LLVM_SYS_170_PREFIX. 63 | ``` 64 | 10. There are two possible fixes, and you may need to action one or both 65 | - The first way to fix this is to install the missing version, the version is the number in the error text above eg. 140 or perhaps 170. In the above instance it will be: `sudo apt install llvm-17` 66 | - Or you may need to set the library in the cargo build command by issuing the command: `LLVM_SYS_170_PREFIX=/usr/lib/llvm-17 cargo build` 67 | 11. You may get an error about a missing library `Polly` as below 68 | ``` 69 | error: could not find native static library `Polly`, perhaps an -L flag is missing? 70 | ``` 71 | 12. To fix this error you can install the missing package (once again taking into account the correct version): `sudo apt install libpolly-17-dev` 72 | 13. Reload the profile: `. ~/.profile` 73 | 14 You may get an error about a missing linking library `cc` and the description lower down in the error text about `libzstd` missing as below 74 | ``` 75 | error: linking with `cc` failed: exit status: 1 76 | .... 77 | .... 78 | /usr/bin/ld: cannot find -lzstd: No such file or directory 79 | ``` 80 | 15. To fix this error you can install the missing package: `sudo apt install libzstd-dev` 81 | 16. The compiler may show errors but it will compile 82 | 17. Siderophile can then be installed using the command: `cargo install --path .` 83 | 18. Running the help command will confirm the installation has completed successfully 84 | ``` 85 | siderophile --help 86 | siderophile 0.2.1 87 | 88 | USAGE: 89 | siderophile [FLAGS] [OPTIONS] 90 | 91 | FLAGS: 92 | --include-tests Count unsafe usage in tests 93 | --no-mark-closures Do not mark closures 94 | -h, --help Prints help information 95 | -V, --version Prints version information 96 | 97 | OPTIONS: 98 | --crate-name Crate name (deprecated) 99 | -p, --package Package to be used as the root of the tree 100 | --mark Mark bad functions with TEXT 101 | --threshold Minimum badness required to mark a function [default: 0] 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /tutorial/zokrates.md: -------------------------------------------------------------------------------- 1 | # Creating proofs with Zokrates. 2 | ## Prerequisites 3 | - Foundry [https://book.getfoundry.sh/getting-started/installation](https://book.getfoundry.sh/getting-started/installation) 4 | - Zokrates [https://zokrates.github.io/gettingstarted.html](https://zokrates.github.io/gettingstarted.html) 5 | - VS code 6 | 7 | ## Create proving code in Zokrates 8 | Zokrates allows us to create a proving function to assert that the proof provided is true. 9 | This tutorial is a really basic introduction to ZK-Proofs.
10 | In our example project, we will create a zokrates function to verify the proof and also write a `Foundry` test in order to test the resulting proof. 11 | ## First create the off-chain verfying code 12 | In our very basic example we will create two inputs, the first one must be exactly double the second one.

13 | **Steps to follow along**
14 | 1. Create a directory **mkdir zk_demo**. 15 | 2. **forge init --no-git** to initialize the `Foundry` structure. 16 | 3. Create a second folder to mimic the folder of someone wishing to send a proof. **mkdir prover**. 17 | 4. In the base directory of the **zk_demo** folder create a file called **isdouble.zok**. 18 | 5. Paste the code below into the **isdouble.zok** and save it. The code takes two inputs, the first value is expected to be double the second value. 19 | ``` 20 | 21 | def main(public field doulbedVal, public field inputVal) { 22 | assert(doulbedVal == inputVal * 2); 23 | } 24 | ``` 25 | 6. Compile **isdouble.zok**. Do this by typing the terminal command **zokrates compile -i isdouble.zok -o isdouble** 26 | 7. Create the needed key files to share with any prover **zokrates setup -i isdouble**, this will result in two files called **verification.key** and **proving.key** 27 | 8. Copy the **proving.key** and **isdouble.zok** to the **prover** folder. 28 | 29 | ## Create the Solidity file to test our verification on chain. 30 | We can use `Zokrates'` built in function to export our verification code as a soldity contract. 31 | 1. In the base directory **zk_demo** type the command **zokrates export-verifier**, this will result in a file called **verifier.sol**. 32 | 2. Move **verfier.sol** to the **src** directory of the `Foundry structure`. 33 | 34 | We are now ready to move on to how a `Prover` would supply a proof. 35 | 36 | ## Generate a proof using Zokrates. 37 | A prover would need to generate a `proof` to send to the verifier. We will use Zokrates to generate this proof.

38 | **Steps to follow**
39 | 1. Move into the **prover** directory, which should contain the files **isdouble.zok** and **proving.key**. 40 | 2. Compile the **.zok** file, **zokrates compile -i isdouble.zok -o isdouble** 41 | 3. Create a witness (you can read more about this on the `Zokrates` book website using the link on top). **zokrates compute-witness --verbose -i isdouble -a 4 2**, The -a is the values that need to be sent into the `isdouble` code , so the first number needs to be double the second number, ie 4 2 , or 16 8. 42 | 4. **We can finally generate our proof**, type the command **zokrates generate-proof -i isdouble**, this will output a file called **proof.json**. 43 | 44 | ## Verifying our proof before we try it on-chain 45 | We can copy the resulting **proof.json**, back into the root folder **zk_demo** which should contain our file called **verification.key**. 46 | 47 | If we type the command **zokrates verify** we should get the output 48 | ```text 49 | Performing verification... 50 | PASSED 51 | ``` 52 | # Testing our code on-chain 53 | To test our code on-chain we will use `Foundry` so that there is no need to deploy to testnets in order to keep the tutorial as simple as possible. 54 | 55 | ## Foundry test file 56 | In the `Foundry` folder structure there should be a directory called `test`, and inside the `test` directory a file called `Counter.t.sol`, this is placed there by the `forge init` command and can be deleted.

57 | **Steps to follow**

58 | 1. Create a file called `Verifier.t.sol` 59 | 2. Paste the code below into the file and save. 60 | 3. **We will discuss what needs to be changed in the file, below the code block** 61 | 62 | ```solidity 63 | // SPDX-License-Identifier: UNLICENSED 64 | pragma solidity ^0.8.13; 65 | 66 | import "forge-std/Test.sol"; 67 | import {Verifier,Pairing} from "../src/verifier.sol"; 68 | import "../src/verifier.sol"; 69 | 70 | contract VerifierTest is Test { 71 | Verifier public verifier; 72 | 73 | function setUp() public { 74 | verifier = new Verifier(); 75 | } 76 | 77 | function testProof() public { 78 | Verifier.Proof memory proof; 79 | Pairing.G1Point memory a = Pairing.G1Point(uint256(0x0..ADD VALUES HERE{1}),uint256(0x0..ADD VALUES HERE{2})); 80 | Pairing.G2Point memory b = Pairing.G2Point([uint256(0x0..ADD VALUES HERE{3}),uint256(0x0..ADD VALUES HERE{4})],[uint256(0x0..ADD VALUES HERE{5}),uint256(0x0..ADD VALUES HERE{6})]); 81 | Pairing.G1Point memory c = Pairing.G1Point(uint256(0x0..ADD VALUES HERE{7}),uint256(0x0..ADD VALUES HERE{8})); 82 | proof.a = a; 83 | proof.b = b; 84 | proof.c = c; 85 | //IF YOU CHANGE THE NUMBERS YOU WILL NEED TO REGENERATE THE PROOF, SO ONLY ENTER THE NUMBER YOU USED TO CREATE THE WITNESS 86 | uint256 doubledVal = 4; 87 | uint256 inputVal = 2; 88 | uint256[2] memory invals = [doubledVal,inputVal]; 89 | bool resp = verifier.verifyTx(proof,invals); 90 | assertTrue(resp); 91 | } 92 | 93 | } 94 | ``` 95 | 4. In the **proof.json** file that was created we need to copy and paste the values into the **Pairing.G1Point** and **Pairing.G2Point** areas in the code marked **ADD VALUES HERE{NUM}**. 96 | 5. I have marked an example proof file below to show which values need to go into which parts of the `Foundry` test contract. 97 | 98 | ```text 99 | { 100 | "scheme": "g16", 101 | "curve": "bn128", 102 | "proof": { 103 | "a": [ 104 | "0x0..COPY VALUES HERE{1}", 105 | "0x0..COPY VALUES HERE{2}" 106 | ], 107 | "b": [ 108 | [ 109 | "0x0..COPY VALUES HERE{3}", 110 | "0x0..COPY VALUES HERE{4}" 111 | ], 112 | [ 113 | "0x0..COPY VALUES HERE{5}", 114 | "0x0..COPY VALUES HERE{6}" 115 | ] 116 | ], 117 | "c": [ 118 | "0x0..COPY VALUES HERE{7}", 119 | "0x0..COPY VALUES HERE{8}" 120 | ] 121 | }, 122 | "inputs": [ 123 | "0x0000000000000000000000000000000000000000000000000000000000000004", 124 | "0x0000000000000000000000000000000000000000000000000000000000000002" 125 | ] 126 | } 127 | ``` 128 | 129 | 6. Run the test **forge test -vv** 130 | 131 | If all goes well you should see the output below 132 | ``` 133 | [⠊] Compiling... 134 | [⠘] Compiling 1 files with 0.8.20 135 | [⠊] Solc 0.8.20 finished in 1.66s 136 | Compiler run successful! 137 | 138 | Running 1 test for test/Verifier.t.sol:VerifierTest 139 | [PASS] testProof() (gas: 221270) 140 | Test result: ok. 1 passed; 0 failed; finished in 60.43ms 141 | ``` 142 | 143 | ## IF YOU FOLLOWED ALONG THIS FAR -- THANK YOU -- 144 | -------------------------------------------------------------------------------- /miniCTF/prover/Verifier.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | /* 3 | Copyright 2021 0KIMS association. 4 | 5 | This file is generated with [snarkJS](https://github.com/iden3/snarkjs). 6 | 7 | snarkJS is a free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | snarkJS is distributed in the hope that it will be useful, but WITHOUT 13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 | License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with snarkJS. If not, see . 19 | */ 20 | 21 | pragma solidity >=0.7.0 <0.9.0; 22 | 23 | contract Groth16Verifier { 24 | // Scalar field size 25 | uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; 26 | // Base field size 27 | uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; 28 | 29 | // Verification Key data 30 | uint256 constant alphax = 5950945174348139734055759710246113371423487308491079264502913208085949346012; 31 | uint256 constant alphay = 2321014420112674038023182193279456085221380797073564961898363443296395417959; 32 | uint256 constant betax1 = 1703666028135268134180779407944996190815923170132398744853849395643552517484; 33 | uint256 constant betax2 = 3745698475542127820377559940118675285605340883595488127158952659810213027188; 34 | uint256 constant betay1 = 21116590208003926361374080993703232519040810060927882751925367473881042096646; 35 | uint256 constant betay2 = 14374828611094349727477485962333298886220926811390669485192500526137334454104; 36 | uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; 37 | uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; 38 | uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; 39 | uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; 40 | uint256 constant deltax1 = 18646145670205833392427865020969626538265685389126334138317604059994330521135; 41 | uint256 constant deltax2 = 12600366264214675126434403073919140712214520845215185347918083569579513330137; 42 | uint256 constant deltay1 = 5692073407747632532340739940411475958471506363352221197476484002820305503541; 43 | uint256 constant deltay2 = 10476938640909476222059543791082059693810791803210245035574815431780370355021; 44 | 45 | 46 | uint256 constant IC0x = 10340021064291701766987613085572438663213805436954277123102300102991239519787; 47 | uint256 constant IC0y = 166801648585048323002901093764474257102675845389961735737160825050254186244; 48 | 49 | uint256 constant IC1x = 4331289330633392945190716263663463011225701887156915020853325784698999090133; 50 | uint256 constant IC1y = 2749232861195759038633265256677712257913736913359856453711058304330238386633; 51 | 52 | 53 | // Memory data 54 | uint16 constant pVk = 0; 55 | uint16 constant pPairing = 128; 56 | 57 | uint16 constant pLastMem = 896; 58 | 59 | function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[1] calldata _pubSignals) public view returns (bool) { 60 | assembly { 61 | function checkField(v) { 62 | if iszero(lt(v, q)) { 63 | mstore(0, 0) 64 | return(0, 0x20) 65 | } 66 | } 67 | 68 | // G1 function to multiply a G1 value(x,y) to value in an address 69 | function g1_mulAccC(pR, x, y, s) { 70 | let success 71 | let mIn := mload(0x40) 72 | mstore(mIn, x) 73 | mstore(add(mIn, 32), y) 74 | mstore(add(mIn, 64), s) 75 | 76 | success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) 77 | 78 | if iszero(success) { 79 | mstore(0, 0) 80 | return(0, 0x20) 81 | } 82 | 83 | mstore(add(mIn, 64), mload(pR)) 84 | mstore(add(mIn, 96), mload(add(pR, 32))) 85 | 86 | success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) 87 | 88 | if iszero(success) { 89 | mstore(0, 0) 90 | return(0, 0x20) 91 | } 92 | } 93 | 94 | function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { 95 | let _pPairing := add(pMem, pPairing) 96 | let _pVk := add(pMem, pVk) 97 | 98 | mstore(_pVk, IC0x) 99 | mstore(add(_pVk, 32), IC0y) 100 | 101 | // Compute the linear combination vk_x 102 | 103 | g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) 104 | 105 | 106 | // -A 107 | mstore(_pPairing, calldataload(pA)) 108 | mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) 109 | 110 | // B 111 | mstore(add(_pPairing, 64), calldataload(pB)) 112 | mstore(add(_pPairing, 96), calldataload(add(pB, 32))) 113 | mstore(add(_pPairing, 128), calldataload(add(pB, 64))) 114 | mstore(add(_pPairing, 160), calldataload(add(pB, 96))) 115 | 116 | // alpha1 117 | mstore(add(_pPairing, 192), alphax) 118 | mstore(add(_pPairing, 224), alphay) 119 | 120 | // beta2 121 | mstore(add(_pPairing, 256), betax1) 122 | mstore(add(_pPairing, 288), betax2) 123 | mstore(add(_pPairing, 320), betay1) 124 | mstore(add(_pPairing, 352), betay2) 125 | 126 | // vk_x 127 | mstore(add(_pPairing, 384), mload(add(pMem, pVk))) 128 | mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) 129 | 130 | 131 | // gamma2 132 | mstore(add(_pPairing, 448), gammax1) 133 | mstore(add(_pPairing, 480), gammax2) 134 | mstore(add(_pPairing, 512), gammay1) 135 | mstore(add(_pPairing, 544), gammay2) 136 | 137 | // C 138 | mstore(add(_pPairing, 576), calldataload(pC)) 139 | mstore(add(_pPairing, 608), calldataload(add(pC, 32))) 140 | 141 | // delta2 142 | mstore(add(_pPairing, 640), deltax1) 143 | mstore(add(_pPairing, 672), deltax2) 144 | mstore(add(_pPairing, 704), deltay1) 145 | mstore(add(_pPairing, 736), deltay2) 146 | 147 | 148 | let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) 149 | 150 | isOk := and(success, mload(_pPairing)) 151 | } 152 | 153 | let pMem := mload(0x40) 154 | mstore(0x40, add(pMem, pLastMem)) 155 | 156 | // Validate that all evaluations ∈ F 157 | 158 | checkField(calldataload(add(_pubSignals, 0))) 159 | 160 | checkField(calldataload(add(_pubSignals, 32))) 161 | 162 | 163 | // Validate all evaluations 164 | let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) 165 | 166 | mstore(0, isValid) 167 | return(0, 0x20) 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Halo2/Highlighter/report/HighLighterReport.md: -------------------------------------------------------------------------------- 1 | # HighLighter Report 2 | - Running Highlighter against directory: /home/halo2/project 3 | - Rules templates directory set as : /home/Highlighter/templates/ 4 | ## Circuit files found: 5 | [^] Circuit.rs 6 | ## Rule checks returned the list of code to check below: 7 | ### File: /home/aaaa.rs 8 | #: Match found on : .unwrap() 9 | #: Found unwrap without ? after make sure errors are handled correctly 10 | 11 | ``` 12 | 102- #[cfg(test)] 13 | 103: if let Some(command) = &*RUN_COMMAND_MOCK.lock().unwrap() { 14 | 104- return command(name, path, arguments); 15 | 16 | ``` 17 | ### File: /home/bbb.rs 18 | #: Match found on : Fp::from 19 | #: Found code creating a field element from another value, check for endianness and overflows 20 | 21 | ``` 22 | 140- i, 23 | 141: || Value::known(Fp::from(i as u64)), 24 | 142- )?; 25 | 26 | ``` 27 | ### File: /home/ccc.rs 28 | #: Match found on : Fp::from 29 | #: Found code creating a field element from another value, check for endianness and overflows 30 | 31 | ``` 32 | 357- .iter() 33 | 358: .map(|eval| fp_to_big_uint(*eval * Fp::from(polynomial_length))) 34 | 359- .collect(), 35 | 36 | ``` 37 | ### File: /home/ddd.rs 38 | #: Match found on : from_little_endian 39 | #: Found code using specific endian calls, Always check that the endian values used are consistent and valid 40 | 41 | ``` 42 | 558- let bytes = field_element.to_repr(); 43 | 559: let u = U256::from_little_endian(bytes.as_slice()); 44 | 560- u 45 | 46 | ``` 47 | ### File: /home/eee.rs 48 | #: Match found on : Fp::from 49 | #: Found code creating a field element from another value, check for endianness and overflows 50 | 51 | ``` 52 | 205- // The inversion represents the division by the polynomial length (grand total is equal to the constant coefficient times the number of points) 53 | 206: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 54 | 207- .collect::>() 55 | -- 56 | 398- .iter() 57 | 399: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 58 | 400- .collect::>() 59 | 60 | ``` 61 | ### File: /home/fff.rs 62 | #: Match found on : Fp::from 63 | #: Found code creating a field element from another value, check for endianness and overflows 64 | 65 | ``` 66 | 83- // Scale the result by the size of the vector (part of the iFFT) 67 | 84: let n_inv = Fp::from(2 * d as u64).invert().unwrap(); 68 | 85- h.par_iter_mut().map(|h| *h *= n_inv).collect::>(); 69 | 70 | ``` 71 | ### File: /home/ggg.rs 72 | #: Match found on : Fp::from 73 | #: Found code creating a field element from another value, check for endianness and overflows 74 | 75 | ``` 76 | 10-pub fn big_uint_to_fp(big_uint: &BigUint) -> Fp { 77 | 11: Fp::from_str_vartime(&big_uint.to_str_radix(10)[..]).unwrap() 78 | 12-} 79 | 80 | ``` 81 | ### File: /home/hhh.rs 82 | #: Match found on : Fp::from 83 | #: Found code creating a field element from another value, check for endianness and overflows 84 | 85 | ``` 86 | 101- 87 | 102: let diff = element - zero_truncation * Expression::Constant(Fp::from(1 << 16)); 88 | 103- 89 | -- 90 | 118- 91 | 119: let diff = i_truncation - i_plus_one_truncation * Expression::Constant(Fp::from(1 << 16)); 92 | 120- 93 | -- 94 | 146- // Calculate 1 / 2^16 95 | 147: let two_pow_sixteen_inv = Value::known(Fp::from(1 << 16).invert().unwrap()); 96 | 148- 97 | -- 98 | 151- let zs_next = { 99 | 152: let k = k.map(|byte| Fp::from(u64::from(byte))); 100 | 153- let zs_next_val = (z.value().copied() - k) * two_pow_sixteen_inv; 101 | 102 | ``` 103 | ### File: /home/iii.rs 104 | #: Match found on : Fp::from 105 | #: Found code creating a field element from another value, check for endianness and overflows 106 | 107 | ``` 108 | 82- fn test_fp_to_big_uint() { 109 | 83: let f = Fp::from(5); 110 | 84- let big_uint = fp_to_big_uint(f); 111 | -- 112 | 90- fn test_decompose_fp_to_bytes_no_padding() { 113 | 91: let f = Fp::from(0x1f2f3f4f); 114 | 92- let bytes = decompose_fp_to_bytes(f, 4); 115 | -- 116 | 98- fn test_decompose_fp_byte_pairs_no_padding() { 117 | 99: let f = Fp::from(0x1f2f3f4f); 118 | 100- let bytes = decompose_fp_to_byte_pairs(f, 2); 119 | -- 120 | 106- fn test_decompose_fp_to_bytes_padding() { 121 | 107: let f = Fp::from(0x1f2f3f4f); 122 | 108- let bytes = decompose_fp_to_bytes(f, 6); 123 | -- 124 | 114- fn test_decompose_fp_to_byte_pairs_padding() { 125 | 115: let f = Fp::from(0x1f2f3f4f); 126 | 116- let bytes = decompose_fp_to_byte_pairs(f, 3); 127 | -- 128 | 122- fn test_decompose_fp_to_bytes_overflow() { 129 | 123: let f = Fp::from(0x1f2f3f4f); 130 | 124- let bytes = decompose_fp_to_bytes(f, 2); 131 | -- 132 | 130- fn test_decompose_fp_to_byte_pairs_overflow() { 133 | 131: let f = Fp::from(0x1f2f3f4f); 134 | 132- let bytes = decompose_fp_to_byte_pairs(f, 1); 135 | -- 136 | 138- fn test_decompose_fp_to_bytes_overflow_2() { 137 | 139: let f = Fp::from(0xf1f2f3f); 138 | 140- let bytes = decompose_fp_to_bytes(f, 2); 139 | -- 140 | 146- let pow = pow_of_two(8); 141 | 147: assert_eq!(pow, Fp::from(0x100)); 142 | 148- let pow = pow_of_two(72); 143 | 144 | ``` 145 | ### File: /home/jjj.rs 146 | #: Match found on : Fp::from 147 | #: Found code creating a field element from another value, check for endianness and overflows 148 | 149 | ``` 150 | 169- i, 151 | 170: || Value::known(Fp::from(i as u64)), 152 | 171- )?; 153 | -- 154 | 219- let a = big_uint_to_fp(&a); 155 | 220: let b = Fp::from(1); 156 | 221- 157 | -- 158 | 237- let a = big_uint_to_fp(&a); 159 | 238: let b = Fp::from(2); 160 | 239- 161 | -- 162 | 272- let circuit = TestCircuit { 163 | 273: a: Fp::from(0x1f2f3f4f), 164 | 274: b: Fp::from(1), 165 | 275- }; 166 | 167 | ``` 168 | ### File: /home/zzz.rs 169 | #: Match found on : Fp::from 170 | #: Found code creating a field element from another value, check for endianness and overflows 171 | 172 | ``` 173 | 94- .iter() 174 | 95: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 175 | 96- .collect::>() 176 | -- 177 | 114- .iter() 178 | 115: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 179 | 116- .collect::>() 180 | -- 181 | 191- .iter() 182 | 192: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 183 | 193- .collect::>() 184 | 185 | ``` 186 | ### File: /home/lll.rs 187 | #: Match found on : Fp::from 188 | #: Found code creating a field element from another value, check for endianness and overflows 189 | 190 | ``` 191 | 163- let eval = 192 | 164: big_uint_to_fp(&(csv_total[BALANCES_INDEX - 1])) * Fp::from(poly_length).invert().unwrap(); 193 | 165- let kzg_proof = create_naive_kzg_proof::>( 194 | 195 | ``` 196 | ### File: /home/mmm.rs 197 | #: Match found on : Fp::from 198 | #: Found code creating a field element from another value, check for endianness and overflows 199 | 200 | ``` 201 | 106- .iter() 202 | 107: .map(|x| big_uint_to_fp(x) * Fp::from(poly_length).invert().unwrap()) 203 | 108- .collect::>(); 204 | 205 | ``` 206 | ### File: /home/nnnn.rs 207 | #: Match found on : from_little_endian 208 | #: Found code using specific endian calls, Always check that the endian values used are consistent and valid 209 | 210 | ``` 211 | 147- .iter() 212 | 148: .map(|x| U256::from_little_endian(big_uint_to_fp(x).to_bytes().as_slice())) 213 | 149- .collect::>(), 214 | -- 215 | 217- .iter() 216 | 218: .map(|x| U256::from_little_endian(x.to_bytes().as_slice())) 217 | 219- .collect::>(); 218 | -- 219 | 225- let challenges = vec![ 220 | 226: U256::from_little_endian(s_g2_affine.x.c1.to_bytes().as_slice()), 221 | 227: U256::from_little_endian(s_g2_affine.x.c0.to_bytes().as_slice()), 222 | 228: U256::from_little_endian(s_g2_affine.y.c1.to_bytes().as_slice()), 223 | 229: U256::from_little_endian(s_g2_affine.y.c0.to_bytes().as_slice()), 224 | 230- ]; 225 | 226 | ``` 227 | -------------------------------------------------------------------------------- /Halo2/Highlighter/readme.md: -------------------------------------------------------------------------------- 1 | # Highlighter 2 | Highlighter (the name was chosen as its not quite a bug finder but can highlight code that may need a bit of extra attention) 3 | is a python script which runs against a HALO2 (or Rust) project and will highlight any code that may need to be checked a bit closer 4 | 5 | The analysis is configured in `templates` which can take an array of similar types of text to scan for. 6 | 7 | ## Run Highlighter 8 | `python3 highlighter.py FULLY_QUALIFIED_PROJECT_PATH FULLY_QUALIFIED_TEMPLATES_PATH` 9 | 10 | I DO NOT WARRANTY THIS CODE TO BE BUG FREE OR TO BE FIT FOR PURPOSE, RUNNING HIGHLIGHTER AGAINST A PROJECT DOES NOT GUARANTEE THAT THE PROJECT IS SECURE AND/OR BUG FREE 11 | 12 | 13 | # Below is an example report: 14 | 15 | # HighLighter Report 16 | - Running Highlighter against directory: /home/halo2/project 17 | - Rules templates directory set as : /home/Highlighter/templates/ 18 | ## Circuit files found: 19 | [^] circuit.rs 20 | ## Rule checks returned the list of code to check below: 21 | ### File: /home/aaaa.rs 22 | #: Match found on : .unwrap() 23 | #: Found unwrap without ? after make sure errors are handled correctly 24 | 25 | ``` 26 | 102- #[cfg(test)] 27 | 103: if let Some(command) = &*RUN_COMMAND_MOCK.lock().unwrap() { 28 | 104- return command(name, path, arguments); 29 | 30 | ``` 31 | ### File: /home/bbb.rs 32 | #: Match found on : Fp::from 33 | #: Found code creating a field element from another value, check for endianness and overflows 34 | 35 | ``` 36 | 140- i, 37 | 141: || Value::known(Fp::from(i as u64)), 38 | 142- )?; 39 | 40 | ``` 41 | ### File: /home/ccc.rs 42 | #: Match found on : Fp::from 43 | #: Found code creating a field element from another value, check for endianness and overflows 44 | 45 | ``` 46 | 357- .iter() 47 | 358: .map(|eval| fp_to_big_uint(*eval * Fp::from(polynomial_length))) 48 | 359- .collect(), 49 | 50 | ``` 51 | ### File: /home/ddd.rs 52 | #: Match found on : from_little_endian 53 | #: Found code using specific endian calls, Always check that the endian values used are consistent and valid 54 | 55 | ``` 56 | 558- let bytes = field_element.to_repr(); 57 | 559: let u = U256::from_little_endian(bytes.as_slice()); 58 | 560- u 59 | 60 | ``` 61 | ### File: /home/eee.rs 62 | #: Match found on : Fp::from 63 | #: Found code creating a field element from another value, check for endianness and overflows 64 | 65 | ``` 66 | 205- // The inversion represents the division by the polynomial length (grand total is equal to the constant coefficient times the number of points) 67 | 206: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 68 | 207- .collect::>() 69 | -- 70 | 398- .iter() 71 | 399: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 72 | 400- .collect::>() 73 | 74 | ``` 75 | ### File: /home/fff.rs 76 | #: Match found on : Fp::from 77 | #: Found code creating a field element from another value, check for endianness and overflows 78 | 79 | ``` 80 | 83- // Scale the result by the size of the vector (part of the iFFT) 81 | 84: let n_inv = Fp::from(2 * d as u64).invert().unwrap(); 82 | 85- h.par_iter_mut().map(|h| *h *= n_inv).collect::>(); 83 | 84 | ``` 85 | ### File: /home/ggg.rs 86 | #: Match found on : Fp::from 87 | #: Found code creating a field element from another value, check for endianness and overflows 88 | 89 | ``` 90 | 10-pub fn big_uint_to_fp(big_uint: &BigUint) -> Fp { 91 | 11: Fp::from_str_vartime(&big_uint.to_str_radix(10)[..]).unwrap() 92 | 12-} 93 | 94 | ``` 95 | ### File: /home/hhh.rs 96 | #: Match found on : Fp::from 97 | #: Found code creating a field element from another value, check for endianness and overflows 98 | 99 | ``` 100 | 101- 101 | 102: let diff = element - zero_truncation * Expression::Constant(Fp::from(1 << 16)); 102 | 103- 103 | -- 104 | 118- 105 | 119: let diff = i_truncation - i_plus_one_truncation * Expression::Constant(Fp::from(1 << 16)); 106 | 120- 107 | -- 108 | 146- // Calculate 1 / 2^16 109 | 147: let two_pow_sixteen_inv = Value::known(Fp::from(1 << 16).invert().unwrap()); 110 | 148- 111 | -- 112 | 151- let zs_next = { 113 | 152: let k = k.map(|byte| Fp::from(u64::from(byte))); 114 | 153- let zs_next_val = (z.value().copied() - k) * two_pow_sixteen_inv; 115 | 116 | ``` 117 | ### File: /home/iii.rs 118 | #: Match found on : Fp::from 119 | #: Found code creating a field element from another value, check for endianness and overflows 120 | 121 | ``` 122 | 82- fn test_fp_to_big_uint() { 123 | 83: let f = Fp::from(5); 124 | 84- let big_uint = fp_to_big_uint(f); 125 | -- 126 | 90- fn test_decompose_fp_to_bytes_no_padding() { 127 | 91: let f = Fp::from(0x1f2f3f4f); 128 | 92- let bytes = decompose_fp_to_bytes(f, 4); 129 | -- 130 | 98- fn test_decompose_fp_byte_pairs_no_padding() { 131 | 99: let f = Fp::from(0x1f2f3f4f); 132 | 100- let bytes = decompose_fp_to_byte_pairs(f, 2); 133 | -- 134 | 106- fn test_decompose_fp_to_bytes_padding() { 135 | 107: let f = Fp::from(0x1f2f3f4f); 136 | 108- let bytes = decompose_fp_to_bytes(f, 6); 137 | -- 138 | 114- fn test_decompose_fp_to_byte_pairs_padding() { 139 | 115: let f = Fp::from(0x1f2f3f4f); 140 | 116- let bytes = decompose_fp_to_byte_pairs(f, 3); 141 | -- 142 | 122- fn test_decompose_fp_to_bytes_overflow() { 143 | 123: let f = Fp::from(0x1f2f3f4f); 144 | 124- let bytes = decompose_fp_to_bytes(f, 2); 145 | -- 146 | 130- fn test_decompose_fp_to_byte_pairs_overflow() { 147 | 131: let f = Fp::from(0x1f2f3f4f); 148 | 132- let bytes = decompose_fp_to_byte_pairs(f, 1); 149 | -- 150 | 138- fn test_decompose_fp_to_bytes_overflow_2() { 151 | 139: let f = Fp::from(0xf1f2f3f); 152 | 140- let bytes = decompose_fp_to_bytes(f, 2); 153 | -- 154 | 146- let pow = pow_of_two(8); 155 | 147: assert_eq!(pow, Fp::from(0x100)); 156 | 148- let pow = pow_of_two(72); 157 | 158 | ``` 159 | ### File: /home/jjj.rs 160 | #: Match found on : Fp::from 161 | #: Found code creating a field element from another value, check for endianness and overflows 162 | 163 | ``` 164 | 169- i, 165 | 170: || Value::known(Fp::from(i as u64)), 166 | 171- )?; 167 | -- 168 | 219- let a = big_uint_to_fp(&a); 169 | 220: let b = Fp::from(1); 170 | 221- 171 | -- 172 | 237- let a = big_uint_to_fp(&a); 173 | 238: let b = Fp::from(2); 174 | 239- 175 | -- 176 | 272- let circuit = TestCircuit { 177 | 273: a: Fp::from(0x1f2f3f4f), 178 | 274: b: Fp::from(1), 179 | 275- }; 180 | 181 | ``` 182 | ### File: /home/zzz.rs 183 | #: Match found on : Fp::from 184 | #: Found code creating a field element from another value, check for endianness and overflows 185 | 186 | ``` 187 | 94- .iter() 188 | 95: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 189 | 96- .collect::>() 190 | -- 191 | 114- .iter() 192 | 115: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 193 | 116- .collect::>() 194 | -- 195 | 191- .iter() 196 | 192: .map(|x| big_uint_to_fp(&(x)) * Fp::from(poly_length).invert().unwrap()) 197 | 193- .collect::>() 198 | 199 | ``` 200 | ### File: /home/lll.rs 201 | #: Match found on : Fp::from 202 | #: Found code creating a field element from another value, check for endianness and overflows 203 | 204 | ``` 205 | 163- let eval = 206 | 164: big_uint_to_fp(&(csv_total[BALANCES_INDEX - 1])) * Fp::from(poly_length).invert().unwrap(); 207 | 165- let kzg_proof = create_naive_kzg_proof::>( 208 | 209 | ``` 210 | ### File: /home/mmm.rs 211 | #: Match found on : Fp::from 212 | #: Found code creating a field element from another value, check for endianness and overflows 213 | 214 | ``` 215 | 106- .iter() 216 | 107: .map(|x| big_uint_to_fp(x) * Fp::from(poly_length).invert().unwrap()) 217 | 108- .collect::>(); 218 | 219 | ``` 220 | ### File: /home/nnnn.rs 221 | #: Match found on : from_little_endian 222 | #: Found code using specific endian calls, Always check that the endian values used are consistent and valid 223 | 224 | ``` 225 | 147- .iter() 226 | 148: .map(|x| U256::from_little_endian(big_uint_to_fp(x).to_bytes().as_slice())) 227 | 149- .collect::>(), 228 | -- 229 | 217- .iter() 230 | 218: .map(|x| U256::from_little_endian(x.to_bytes().as_slice())) 231 | 219- .collect::>(); 232 | -- 233 | 225- let challenges = vec![ 234 | 226: U256::from_little_endian(s_g2_affine.x.c1.to_bytes().as_slice()), 235 | 227: U256::from_little_endian(s_g2_affine.x.c0.to_bytes().as_slice()), 236 | 228: U256::from_little_endian(s_g2_affine.y.c1.to_bytes().as_slice()), 237 | 229: U256::from_little_endian(s_g2_affine.y.c0.to_bytes().as_slice()), 238 | 230- ]; 239 | 240 | ``` 241 | 242 | -------------------------------------------------------------------------------- /miniCTF/prover/witness_calculator.js: -------------------------------------------------------------------------------- 1 | module.exports = async function builder(code, options) { 2 | 3 | options = options || {}; 4 | 5 | let wasmModule; 6 | try { 7 | wasmModule = await WebAssembly.compile(code); 8 | } catch (err) { 9 | console.log(err); 10 | console.log("\nTry to run circom --c in order to generate c++ code instead\n"); 11 | throw new Error(err); 12 | } 13 | 14 | let wc; 15 | 16 | let errStr = ""; 17 | let msgStr = ""; 18 | 19 | const instance = await WebAssembly.instantiate(wasmModule, { 20 | runtime: { 21 | exceptionHandler : function(code) { 22 | let err; 23 | if (code == 1) { 24 | err = "Signal not found.\n"; 25 | } else if (code == 2) { 26 | err = "Too many signals set.\n"; 27 | } else if (code == 3) { 28 | err = "Signal already set.\n"; 29 | } else if (code == 4) { 30 | err = "Assert Failed.\n"; 31 | } else if (code == 5) { 32 | err = "Not enough memory.\n"; 33 | } else if (code == 6) { 34 | err = "Input signal array access exceeds the size.\n"; 35 | } else { 36 | err = "Unknown error.\n"; 37 | } 38 | throw new Error(err + errStr); 39 | }, 40 | printErrorMessage : function() { 41 | errStr += getMessage() + "\n"; 42 | // console.error(getMessage()); 43 | }, 44 | writeBufferMessage : function() { 45 | const msg = getMessage(); 46 | // Any calls to `log()` will always end with a `\n`, so that's when we print and reset 47 | if (msg === "\n") { 48 | console.log(msgStr); 49 | msgStr = ""; 50 | } else { 51 | // If we've buffered other content, put a space in between the items 52 | if (msgStr !== "") { 53 | msgStr += " " 54 | } 55 | // Then append the message to the message we are creating 56 | msgStr += msg; 57 | } 58 | }, 59 | showSharedRWMemory : function() { 60 | printSharedRWMemory (); 61 | } 62 | 63 | } 64 | }); 65 | 66 | const sanityCheck = 67 | options 68 | // options && 69 | // ( 70 | // options.sanityCheck || 71 | // options.logGetSignal || 72 | // options.logSetSignal || 73 | // options.logStartComponent || 74 | // options.logFinishComponent 75 | // ); 76 | 77 | 78 | wc = new WitnessCalculator(instance, sanityCheck); 79 | return wc; 80 | 81 | function getMessage() { 82 | var message = ""; 83 | var c = instance.exports.getMessageChar(); 84 | while ( c != 0 ) { 85 | message += String.fromCharCode(c); 86 | c = instance.exports.getMessageChar(); 87 | } 88 | return message; 89 | } 90 | 91 | function printSharedRWMemory () { 92 | const shared_rw_memory_size = instance.exports.getFieldNumLen32(); 93 | const arr = new Uint32Array(shared_rw_memory_size); 94 | for (let j=0; j { 137 | const h = fnvHash(k); 138 | const hMSB = parseInt(h.slice(0,8), 16); 139 | const hLSB = parseInt(h.slice(8,16), 16); 140 | const fArr = flatArray(input[k]); 141 | let signalSize = this.instance.exports.getInputSignalSize(hMSB, hLSB); 142 | if (signalSize < 0){ 143 | throw new Error(`Signal ${k} not found\n`); 144 | } 145 | if (fArr.length < signalSize) { 146 | throw new Error(`Not enough values for input signal ${k}\n`); 147 | } 148 | if (fArr.length > signalSize) { 149 | throw new Error(`Too many values for input signal ${k}\n`); 150 | } 151 | for (let i=0; i0) { 287 | res.unshift(0); 288 | i--; 289 | } 290 | } 291 | return res; 292 | } 293 | 294 | function fromArray32(arr) { //returns a BigInt 295 | var res = BigInt(0); 296 | const radix = BigInt(0x100000000); 297 | for (let i = 0; i