https://github.com/noway/sha256-var-circom
Variable length sha256 hash function in Circom
https://github.com/noway/sha256-var-circom
circom circuit sha256 variable-length zk-snarks
Last synced: about 2 months ago
JSON representation
Variable length sha256 hash function in Circom
- Host: GitHub
- URL: https://github.com/noway/sha256-var-circom
- Owner: noway
- License: mit
- Created: 2022-02-13T11:23:22.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2023-12-08T12:20:29.000Z (over 2 years ago)
- Last Synced: 2025-03-15T03:28:07.252Z (about 1 year ago)
- Topics: circom, circuit, sha256, variable-length, zk-snarks
- Language: JavaScript
- Homepage:
- Size: 90.8 KB
- Stars: 6
- Watchers: 2
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Sha256Var.circom
Variable length sha256 hash function in [Circom](https://docs.circom.io/).
## Problem
- [Sha256](https://github.com/iden3/circomlib/tree/master/circuits/sha256) function from [circomlib](https://github.com/iden3/circomlib) requires length of the input to be known at compile time.
- [Sha256](https://github.com/TheFrozenFire/snark-jwt-verify/blob/master/circuits/sha256.circom) function from [TheFrozenFire/snark-jwt-verify](https://github.com/TheFrozenFire/snark-jwt-verify) requires the input to be crafted in a special format by an out-of-circuit function.
## Solution
Building on [TheFrozenFire/snark-jwt-verify](https://github.com/TheFrozenFire/snark-jwt-verify), this circuit implements variable length sha256 hash function in Circom.
## Usage
Given `input` (in bits) of length `input_len` (in bits), the following code returns the hash of `input`:
```circom
var BLOCK_LEN = 512;
var MAX_BLOCKS = 2;
var SHA256_LEN = 256;
// See bellow for explanation
var BlockSpace = 1;
component sha256 = Sha256Var(BlockSpace);
// Set input
sha256.len <== input_len;
for (var i = 0; i < BLOCK_LEN * MAX_BLOCKS; i++) {
sha256.in[i] <== input[i];
}
// Export the sha256 hash
for (var i = 0; i < SHA256_LEN; i++) {
hash[i] <== sha256.out[i];
}
```
For more usage, see [test/sha256var.js](test/sha256var.js).
## Block space cheat sheet
- 1 block space = max 2 blocks = max 960 bits = 0-119 characters
- 2 block space = max 4 blocks = max 1984 bits = 0-247 characters
- 3 block space = max 8 blocks = max 4032 bits = 0-503 characters
- 4 block space = max 16 blocks = max 8128 bits = 0-1015 characters
## How it works
We take the avaialble block space and prepare `2^BlockSpace` blocks. We put the data into the blocks. Each block is prepared using the `Sha256InputBlock` component which expects the block to either be the last block or not. If it is the last block, `L` is added in the last 64 bits. If it's not, block is copied over normally. The `1` bit is also set at the end of the input length.
## Limitations
The bigger the block space, the bigger the circuit. While 1 and 2 block spaces are ok, the 3 block space is slow and the 4 is slower.
## Performance
Measured on a Mac
| | compile time (s) | run time (s) | constraints (lines in .sym file) |
|--------------|------------------|--------------|----------------------------------|
| BlockSpace=1 | 6.221 | 27.303 | 435332 |
| BlockSpace=2 | 12.055 | 96.13 | 869606 |
| BlockSpace=3 | 24.241 | 350.22 | 1738150 |
| BlockSpace=4 | 51.843 | 1356.917 | 3475234 |
## Tests
- Run `make test`