mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-08 03:36:49 +01:00
Compare commits
2 Commits
feature/up
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de34085109 | ||
|
|
e9b5da742a |
@@ -1,4 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
|
"plugins": [
|
||||||
|
"mocha"
|
||||||
|
],
|
||||||
"env": {
|
"env": {
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"node": true,
|
"node": true,
|
||||||
@@ -24,6 +27,7 @@ module.exports = {
|
|||||||
"semi": [
|
"semi": [
|
||||||
"error",
|
"error",
|
||||||
"always"
|
"always"
|
||||||
]
|
],
|
||||||
|
"mocha/no-exclusive-tests": "error"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -1,18 +1,4 @@
|
|||||||
# CircomLib
|
# cirpedersen
|
||||||
|
|
||||||
## Description
|
Pedersen Hash and Exponentiation circuits using Baby Jub Curve in circom language
|
||||||
|
|
||||||
- This repository contains a library of circuit templates.
|
|
||||||
- All files are copyrighted under 2018 0KIMS association and part of the free software [circom](https://github.com/iden3/circom) (Zero Knowledge Circuit Compiler).
|
|
||||||
- You can read more about the circom language in [the circom documentation webpage](https://docs.circom.io/).
|
|
||||||
|
|
||||||
## Organisation
|
|
||||||
|
|
||||||
This respository contains 5 folders:
|
|
||||||
- `circuits`: it contains the implementation of different cryptographic primitives in circom language.
|
|
||||||
- `calcpedersenbases`: set of functions in JavaScript used to find a set of points in [Baby Jubjub](https://github.com/barryWhiteHat/baby_jubjub) elliptic curve that serve as basis for the [Pedersen Hash](https://github.com/zcash/zcash/issues/2234).
|
|
||||||
- `doc`: it contains some circuit schemes in ASCII (must be opened with Monodraw, an ASCII art editor for Mac).
|
|
||||||
- `src`: it contains similar implementation of circuits in JavaScript.
|
|
||||||
- `test`: tests.
|
|
||||||
|
|
||||||
A description of the specific circuit templates for the `circuit` folder will be soon updated.
|
|
||||||
|
|||||||
@@ -1,19 +1,3 @@
|
|||||||
# CircomLib/Circuits
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
- This folder contains circuit templates for standard operations and many cryptographic primitives.
|
|
||||||
- Below you can find specifications of each function. In the representation of elements, there are three tyes:
|
|
||||||
- Binary
|
|
||||||
- String
|
|
||||||
- Field element (the field is specified in each case. We consider 2 possible fields: Fp and Fr, where p... and r... .)
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
[TOC]
|
|
||||||
|
|
||||||
## Jordi
|
|
||||||
|
|
||||||
* compconstant - Returns 1 if `in` (expanded to binary array) > `ct`
|
* compconstant - Returns 1 if `in` (expanded to binary array) > `ct`
|
||||||
* aliascheck - check if `in` (expanded to binary array) oveflowed its 254 bits (<= -1)
|
* aliascheck - check if `in` (expanded to binary array) oveflowed its 254 bits (<= -1)
|
||||||
* babyjub - twisted Edwards curve 168700.x^2 + y^2 = 1 + 168696.x^2.y^2
|
* babyjub - twisted Edwards curve 168700.x^2 + y^2 = 1 + 168696.x^2.y^2
|
||||||
@@ -28,803 +12,3 @@
|
|||||||
* smt - Sparse Merkle Tree
|
* smt - Sparse Merkle Tree
|
||||||
* https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751
|
* https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751
|
||||||
* montgomery https://en.wikipedia.org/wiki/Montgomery_curve
|
* montgomery https://en.wikipedia.org/wiki/Montgomery_curve
|
||||||
|
|
||||||
## Circuits
|
|
||||||
|
|
||||||
### sha256
|
|
||||||
|
|
||||||
Folder containing the implementation of sha256 hash circuit.
|
|
||||||
|
|
||||||
### smt
|
|
||||||
|
|
||||||
Folder containing the circuit implementation of Sparse Merkle Trees.
|
|
||||||
|
|
||||||
### aliascheck
|
|
||||||
|
|
||||||
- `AliasCheck()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### babyjub
|
|
||||||
|
|
||||||
Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?)
|
|
||||||
|
|
||||||
|
|
||||||
- `BabyAdd()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
|
|
||||||
It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that
|
|
||||||
|
|
||||||
(`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`)
|
|
||||||
= ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`))
|
|
||||||
|
|
||||||
- SCHEMA
|
|
||||||
```
|
|
||||||
var a var d
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
______v_________v_______
|
|
||||||
input x1 ----> | |
|
|
||||||
input y1 ----> | BabyAdd() | ----> output xout
|
|
||||||
input x2 ----> | | ----> output yout
|
|
||||||
input y2 ----> |________________________|
|
|
||||||
```
|
|
||||||
|
|
||||||
- INPUTS
|
|
||||||
|
|
||||||
| Input | Representation | Description | |
|
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
|
||||||
| `x1` | Bigint | Field element of Fp | First coordinate of a point (x1, y1) on E. |
|
|
||||||
| `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. |
|
|
||||||
| `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. |
|
|
||||||
| `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. |
|
|
||||||
|
|
||||||
Requirement: at least `x1`!=`x2` or `y1`!=`y2`.
|
|
||||||
|
|
||||||
- OUTPUT
|
|
||||||
|
|
||||||
| Input | Representation | Description | |
|
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
|
||||||
| `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
|
||||||
| `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
|
||||||
|
|
||||||
- BENCHMARKS (constraints)
|
|
||||||
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `BabyDbl()`
|
|
||||||
- DESCRIPTION : doubles a point (`xout`,`yout`) = 2*(`x`,`y`).
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `BabyCheck()`
|
|
||||||
|
|
||||||
- DESCRIPTION : checks if a given point is in the curve.
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `BabyPbk()`
|
|
||||||
|
|
||||||
- DESCRIPTION: : given a private key, it returns the associated public key.
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
|
|
||||||
### binsub
|
|
||||||
|
|
||||||
- `BinSub(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION: binary substraction.
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### binsum
|
|
||||||
|
|
||||||
- `nbits(a)`
|
|
||||||
|
|
||||||
- DESCRIPTION : binary sum.
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `BinSum(n, ops)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### bitify
|
|
||||||
|
|
||||||
- `Num2Bits()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Num2Bits_strict()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Bits2Num()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Bits2Num_strict()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Num2BitsNeg()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### comparators
|
|
||||||
|
|
||||||
- `IsZero() `
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `IsEqual()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `ForceEqualIfEnabled()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `LessThan()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `GreaterThan()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `GreaterEqThan()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### compconstant
|
|
||||||
|
|
||||||
- `CompConstant(ct)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### eddsa
|
|
||||||
|
|
||||||
Edwards Digital Signature Algorithm in Baby Jubjbub (link a eddsa)
|
|
||||||
|
|
||||||
- `EdDSAVerifier(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### eddsamimc
|
|
||||||
|
|
||||||
- `EdDSAMiMCVerifier()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### eddsamimcsponge
|
|
||||||
|
|
||||||
- `EdDSAMiMCSpongeVerifier()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### eddsaposeidon
|
|
||||||
|
|
||||||
- `EdDSAPoseidonVerifier()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### escalarmul
|
|
||||||
|
|
||||||
- `EscalarMulWindow(base, k)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `EscalarMul(n, base)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### escalarmulany
|
|
||||||
|
|
||||||
- `Multiplexor2()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `BitElementMulAny()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `SegmentMulAny(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `EscalarMulAny(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### escalarmulfix
|
|
||||||
|
|
||||||
- `WindowMulFix()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `SegmentMulFix(nWindows)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `EscalarMulFix(n, BASE)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### escalarmulw4table
|
|
||||||
|
|
||||||
- `pointAdd`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `EscalarMulW4Table`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### gates
|
|
||||||
|
|
||||||
- `XOR`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `AND`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `OR`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `NOT`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `NAND`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `NOR`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `MultiAND`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### mimc
|
|
||||||
|
|
||||||
Implementation of MiMC-7 hash in Fp being... (link to description of the hash)
|
|
||||||
|
|
||||||
- `MiMC7(nrounds)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `MultiMiMC7(nInputs, nRounds)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### mimcsponge
|
|
||||||
|
|
||||||
- `MiMCSponge(nInputs, nRounds, nOutputs)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `MiMCFeistel(nrounds)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### montgomery
|
|
||||||
|
|
||||||
- `Edwards2Montgomery()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Montgomery2Edwards()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `MontgomeryAdd()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `MontgomeryDouble()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### multiplexer
|
|
||||||
|
|
||||||
- `log2(a)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `EscalarProduct(w)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Decoder(w)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Multiplexer(wIn, nIn)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### mux1
|
|
||||||
|
|
||||||
- `MultiMux1(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Mux1()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### mux2
|
|
||||||
|
|
||||||
- `MultiMux2(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Mux2()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### mux3
|
|
||||||
|
|
||||||
- `MultiMux3(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Mux3()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### mux4
|
|
||||||
|
|
||||||
- `MultiMux4(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Mux4()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### pedersen_old
|
|
||||||
|
|
||||||
Old version of the Pedersen hash (do not use any
|
|
||||||
more?).
|
|
||||||
|
|
||||||
### pedersen
|
|
||||||
|
|
||||||
- `Window4()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Segment(nWindows)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Pedersen(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### pointbits
|
|
||||||
|
|
||||||
- `sqrt(n)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Bits2Point()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Bits2Point_Strict()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Point2Bits`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Point2Bits_Strict`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### poseidon
|
|
||||||
|
|
||||||
Implementation of Poseidon hash function (LINK)
|
|
||||||
|
|
||||||
- `Sigma()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Ark(t, C, r)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Mix(t, M)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
- `Poseidon(nInputs)`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### sign
|
|
||||||
|
|
||||||
- `Sign()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|
||||||
### switcher
|
|
||||||
|
|
||||||
- `Switcher()`
|
|
||||||
|
|
||||||
- DESCRIPTION
|
|
||||||
- SCHEMA
|
|
||||||
- INPUT
|
|
||||||
- OUTPUT
|
|
||||||
- BENCHMARKS
|
|
||||||
- EXAMPLE
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ template BabyPbk() {
|
|||||||
signal output Ax;
|
signal output Ax;
|
||||||
signal output Ay;
|
signal output Ay;
|
||||||
|
|
||||||
var BASE8[2] = [
|
var BASE8 = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -48,14 +48,12 @@ template BinSub(n) {
|
|||||||
var lin = 2**n;
|
var lin = 2**n;
|
||||||
var lout = 0;
|
var lout = 0;
|
||||||
|
|
||||||
var i;
|
for (var i=0; i<n; i++) {
|
||||||
|
|
||||||
for (i=0; i<n; i++) {
|
|
||||||
lin = lin + in[0][i]*(2**i);
|
lin = lin + in[0][i]*(2**i);
|
||||||
lin = lin - in[1][i]*(2**i);
|
lin = lin - in[1][i]*(2**i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<n; i++) {
|
for (var i=0; i<n; i++) {
|
||||||
out[i] <-- (lin >> i) & 1;
|
out[i] <-- (lin >> i) & 1;
|
||||||
|
|
||||||
// Ensure out is binary
|
// Ensure out is binary
|
||||||
|
|||||||
@@ -72,26 +72,19 @@ template BinSum(n, ops) {
|
|||||||
var k;
|
var k;
|
||||||
var j;
|
var j;
|
||||||
|
|
||||||
var e2;
|
|
||||||
|
|
||||||
e2 = 1;
|
|
||||||
for (k=0; k<n; k++) {
|
for (k=0; k<n; k++) {
|
||||||
for (j=0; j<ops; j++) {
|
for (j=0; j<ops; j++) {
|
||||||
lin += in[j][k] * e2;
|
lin += in[j][k] * 2**k;
|
||||||
}
|
}
|
||||||
e2 = e2 + e2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e2 = 1;
|
|
||||||
for (k=0; k<nout; k++) {
|
for (k=0; k<nout; k++) {
|
||||||
out[k] <-- (lin >> k) & 1;
|
out[k] <-- (lin >> k) & 1;
|
||||||
|
|
||||||
// Ensure out is binary
|
// Ensure out is binary
|
||||||
out[k] * (out[k] - 1) === 0;
|
out[k] * (out[k] - 1) === 0;
|
||||||
|
|
||||||
lout += out[k] * e2;
|
lout += out[k] * 2**k;
|
||||||
|
|
||||||
e2 = e2+e2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the sum;
|
// Ensure the sum;
|
||||||
|
|||||||
@@ -26,12 +26,10 @@ template Num2Bits(n) {
|
|||||||
signal output out[n];
|
signal output out[n];
|
||||||
var lc1=0;
|
var lc1=0;
|
||||||
|
|
||||||
var e2=1;
|
|
||||||
for (var i = 0; i<n; i++) {
|
for (var i = 0; i<n; i++) {
|
||||||
out[i] <-- (in >> i) & 1;
|
out[i] <-- (in >> i) & 1;
|
||||||
out[i] * (out[i] -1 ) === 0;
|
out[i] * (out[i] -1 ) === 0;
|
||||||
lc1 += out[i] * e2;
|
lc1 += out[i] * 2**i;
|
||||||
e2 = e2+e2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lc1 === in;
|
lc1 === in;
|
||||||
@@ -56,10 +54,8 @@ template Bits2Num(n) {
|
|||||||
signal output out;
|
signal output out;
|
||||||
var lc1=0;
|
var lc1=0;
|
||||||
|
|
||||||
var e2 = 1;
|
|
||||||
for (var i = 0; i<n; i++) {
|
for (var i = 0; i<n; i++) {
|
||||||
lc1 += in[i] * e2;
|
lc1 += in[i] * 2**i;
|
||||||
e2 = e2 + e2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lc1 ==> out;
|
lc1 ==> out;
|
||||||
|
|||||||
@@ -86,11 +86,10 @@ template LessThan(n) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
template LessThan(n) {
|
template LessThan(n) {
|
||||||
assert(n <= 252);
|
|
||||||
signal input in[2];
|
signal input in[2];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component n2b = Num2Bits(n+1);
|
component n2b = Num2Bits(n*2+1);
|
||||||
|
|
||||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,12 @@ template CompConstant(ct) {
|
|||||||
slsb = in[i*2];
|
slsb = in[i*2];
|
||||||
smsb = in[i*2+1];
|
smsb = in[i*2+1];
|
||||||
|
|
||||||
if ((cmsb==0)&&(clsb==0)) {
|
|
||||||
|
if ((cmsb==0)&(clsb==0)) {
|
||||||
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb;
|
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb;
|
||||||
} else if ((cmsb==0)&&(clsb==1)) {
|
} else if ((cmsb==0)&(clsb==1)) {
|
||||||
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a;
|
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a;
|
||||||
} else if ((cmsb==1)&&(clsb==0)) {
|
} else if ((cmsb==1)&(clsb==0)) {
|
||||||
parts[i] <== b*smsb*slsb - a*smsb + a;
|
parts[i] <== b*smsb*slsb - a*smsb + a;
|
||||||
} else {
|
} else {
|
||||||
parts[i] <== -a*smsb*slsb + a;
|
parts[i] <== -a*smsb*slsb + a;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ template EdDSAVerifier(n) {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8[2] = [
|
var BASE8 = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ template EdDSAMiMCVerifier() {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8[2] = [
|
var BASE8 = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ template EdDSAMiMCSpongeVerifier() {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8[2] = [
|
var BASE8 = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -47,11 +47,11 @@ template EdDSAPoseidonVerifier() {
|
|||||||
snum2bits.out[i] ==> compConstant.in[i];
|
snum2bits.out[i] ==> compConstant.in[i];
|
||||||
}
|
}
|
||||||
compConstant.in[253] <== 0;
|
compConstant.in[253] <== 0;
|
||||||
compConstant.out*enabled === 0;
|
compConstant.out === 0;
|
||||||
|
|
||||||
// Calculate the h = H(R,A, msg)
|
// Calculate the h = H(R,A, msg)
|
||||||
|
|
||||||
component hash = Poseidon(5);
|
component hash = Poseidon(5, 6, 8, 57);
|
||||||
|
|
||||||
hash.inputs[0] <== R8x;
|
hash.inputs[0] <== R8x;
|
||||||
hash.inputs[1] <== R8y;
|
hash.inputs[1] <== R8y;
|
||||||
@@ -79,7 +79,7 @@ template EdDSAPoseidonVerifier() {
|
|||||||
// We check that A is not zero.
|
// We check that A is not zero.
|
||||||
component isZero = IsZero();
|
component isZero = IsZero();
|
||||||
isZero.in <== dbl3.x;
|
isZero.in <== dbl3.x;
|
||||||
isZero.out*enabled === 0;
|
isZero.out === 0;
|
||||||
|
|
||||||
component mulAny = EscalarMulAny(254);
|
component mulAny = EscalarMulAny(254);
|
||||||
for (i=0; i<254; i++) {
|
for (i=0; i<254; i++) {
|
||||||
@@ -99,7 +99,7 @@ template EdDSAPoseidonVerifier() {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8[2] = [
|
var BASE8 = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ template EscalarMulWindow(base, k) {
|
|||||||
signal input sel[4];
|
signal input sel[4];
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var table[16][2];
|
component table;
|
||||||
component mux;
|
component mux;
|
||||||
component adder;
|
component adder;
|
||||||
|
|
||||||
@@ -86,8 +86,8 @@ template EscalarMulWindow(base, k) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<16; i++) {
|
for (i=0; i<16; i++) {
|
||||||
mux.c[0][i] <== table[i][0];
|
table.out[i][0] ==> mux.c[0][i];
|
||||||
mux.c[1][i] <== table[i][1];
|
table.out[i][1] ==> mux.c[1][i];
|
||||||
}
|
}
|
||||||
|
|
||||||
in[0] ==> adder.x1;
|
in[0] ==> adder.x1;
|
||||||
|
|||||||
@@ -176,9 +176,6 @@ template SegmentMulFix(nWindows) {
|
|||||||
cadders[i].in1[0] <== cadders[i-1].out[0];
|
cadders[i].in1[0] <== cadders[i-1].out[0];
|
||||||
cadders[i].in1[1] <== cadders[i-1].out[1];
|
cadders[i].in1[1] <== cadders[i-1].out[1];
|
||||||
}
|
}
|
||||||
for (j=0; j<3; j++) {
|
|
||||||
windows[i].in[j] <== e[3*i+j];
|
|
||||||
}
|
|
||||||
if (i<nWindows-1) {
|
if (i<nWindows-1) {
|
||||||
cadders[i].in2[0] <== windows[i].out8[0];
|
cadders[i].in2[0] <== windows[i].out8[0];
|
||||||
cadders[i].in2[1] <== windows[i].out8[1];
|
cadders[i].in2[1] <== windows[i].out8[1];
|
||||||
@@ -188,6 +185,9 @@ template SegmentMulFix(nWindows) {
|
|||||||
cadders[i].in2[0] <== dblLast.out[0];
|
cadders[i].in2[0] <== dblLast.out[0];
|
||||||
cadders[i].in2[1] <== dblLast.out[1];
|
cadders[i].in2[1] <== dblLast.out[1];
|
||||||
}
|
}
|
||||||
|
for (j=0; j<3; j++) {
|
||||||
|
windows[i].in[j] <== e[3*i+j];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<nWindows; i++) {
|
for (i=0; i<nWindows; i++) {
|
||||||
|
|||||||
@@ -27,25 +27,23 @@ function pointAdd(x1,y1,x2,y2) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function EscalarMulW4Table(base, k) {
|
template EscalarMulW4Table(base, k) {
|
||||||
var out[16][2];
|
signal output out[16][2];
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
var p[2];
|
var p[2];
|
||||||
|
|
||||||
var dbl[2] = base;
|
var dbl = base;
|
||||||
|
|
||||||
for (i=0; i<k*4; i++) {
|
for (i=0; i<k*4; i++) {
|
||||||
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
out[0][0] = 0;
|
out[0][0] <== 0;
|
||||||
out[0][1] = 1;
|
out[0][1] <== 1;
|
||||||
for (i=1; i<16; i++) {
|
for (i=1; i<16; i++) {
|
||||||
p = pointAdd(out[i-1][0], out[i-1][1], dbl[0], dbl[1]);
|
p = pointAdd(out[i-1][0], out[i-1][1], dbl[0], dbl[1]);
|
||||||
out[i][0] = p[0];
|
out[i][0] <== p[0];
|
||||||
out[i][1] = p[1];
|
out[i][1] <== p[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ template NOR() {
|
|||||||
template MultiAND(n) {
|
template MultiAND(n) {
|
||||||
signal input in[n];
|
signal input in[n];
|
||||||
signal output out;
|
signal output out;
|
||||||
var i;
|
|
||||||
if (n==1) {
|
if (n==1) {
|
||||||
out <== in[0];
|
out <== in[0];
|
||||||
} else if (n==2) {
|
} else if (n==2) {
|
||||||
@@ -82,8 +81,8 @@ template MultiAND(n) {
|
|||||||
var n2 = n-n\2;
|
var n2 = n-n\2;
|
||||||
ands[0] = MultiAND(n1);
|
ands[0] = MultiAND(n1);
|
||||||
ands[1] = MultiAND(n2);
|
ands[1] = MultiAND(n2);
|
||||||
for (i=0; i<n1; i++) ands[0].in[i] <== in[i];
|
for (var i=0; i<n1; i++) ands[0].in[i] <== in[i];
|
||||||
for (i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
|
for (var i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
|
||||||
and2.a <== ands[0].out;
|
and2.a <== ands[0].out;
|
||||||
and2.b <== ands[1].out;
|
and2.b <== ands[1].out;
|
||||||
out <== and2.out;
|
out <== and2.out;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ template MiMC7(nrounds) {
|
|||||||
signal input k;
|
signal input k;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
var c[91] = [
|
var c = [
|
||||||
0,
|
0,
|
||||||
20888961410941983456478427210666206549300505294776164667214940546594746570981,
|
20888961410941983456478427210666206549300505294776164667214940546594746570981,
|
||||||
15265126113435022738560151911929040668591755459209400716467504685752745317193,
|
15265126113435022738560151911929040668591755459209400716467504685752745317193,
|
||||||
|
|||||||
@@ -6,12 +6,10 @@ template MiMCSponge(nInputs, nRounds, nOutputs) {
|
|||||||
signal input k;
|
signal input k;
|
||||||
signal output outs[nOutputs];
|
signal output outs[nOutputs];
|
||||||
|
|
||||||
var i;
|
|
||||||
|
|
||||||
// S = R||C
|
// S = R||C
|
||||||
component S[nInputs + nOutputs - 1];
|
component S[nInputs + nOutputs - 1];
|
||||||
|
|
||||||
for (i = 0; i < nInputs; i++) {
|
for (var i = 0; i < nInputs; i++) {
|
||||||
S[i] = MiMCFeistel(nRounds);
|
S[i] = MiMCFeistel(nRounds);
|
||||||
S[i].k <== k;
|
S[i].k <== k;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -23,9 +21,9 @@ template MiMCSponge(nInputs, nRounds, nOutputs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outs[0] <== S[nInputs - 1].xL_out;
|
outs[0] = S[nInputs - 1].xL_out;
|
||||||
|
|
||||||
for (i = 0; i < nOutputs - 1; i++) {
|
for (var i = 0; i < nOutputs - 1; i++) {
|
||||||
S[nInputs + i] = MiMCFeistel(nRounds);
|
S[nInputs + i] = MiMCFeistel(nRounds);
|
||||||
S[nInputs + i].k <== k;
|
S[nInputs + i].k <== k;
|
||||||
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out;
|
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out;
|
||||||
@@ -41,8 +39,8 @@ template MiMCFeistel(nrounds) {
|
|||||||
signal output xL_out;
|
signal output xL_out;
|
||||||
signal output xR_out;
|
signal output xR_out;
|
||||||
|
|
||||||
// doesn't contain the first and last round constants, which are always zero
|
var c = [
|
||||||
var c_partial[218] = [
|
0,
|
||||||
7120861356467848435263064379192047478074060781135320967663101236819528304084,
|
7120861356467848435263064379192047478074060781135320967663101236819528304084,
|
||||||
5024705281721889198577876690145313457398658950011302225525409148828000436681,
|
5024705281721889198577876690145313457398658950011302225525409148828000436681,
|
||||||
17980351014018068290387269214713820287804403312720763401943303895585469787384,
|
17980351014018068290387269214713820287804403312720763401943303895585469787384,
|
||||||
@@ -260,7 +258,8 @@ template MiMCFeistel(nrounds) {
|
|||||||
18224457394066545825553407391290108485121649197258948320896164404518684305122,
|
18224457394066545825553407391290108485121649197258948320896164404518684305122,
|
||||||
274945154732293792784580363548970818611304339008964723447672490026510689427,
|
274945154732293792784580363548970818611304339008964723447672490026510689427,
|
||||||
11050822248291117548220126630860474473945266276626263036056336623671308219529,
|
11050822248291117548220126630860474473945266276626263036056336623671308219529,
|
||||||
2119542016932434047340813757208803962484943912710204325088879681995922344971
|
2119542016932434047340813757208803962484943912710204325088879681995922344971,
|
||||||
|
0
|
||||||
];
|
];
|
||||||
|
|
||||||
var t;
|
var t;
|
||||||
@@ -269,19 +268,13 @@ template MiMCFeistel(nrounds) {
|
|||||||
signal xL[nrounds-1];
|
signal xL[nrounds-1];
|
||||||
signal xR[nrounds-1];
|
signal xR[nrounds-1];
|
||||||
|
|
||||||
var c;
|
|
||||||
for (var i=0; i<nrounds; i++) {
|
for (var i=0; i<nrounds; i++) {
|
||||||
if ((i == 0) || (i == nrounds - 1)) {
|
t = (i==0) ? k+xL_in : k + xL[i-1] + c[i];
|
||||||
c = 0;
|
|
||||||
} else {
|
|
||||||
c = c_partial[i - 1];
|
|
||||||
}
|
|
||||||
t = (i==0) ? k+xL_in : k + xL[i-1] + c;
|
|
||||||
t2[i] <== t*t;
|
t2[i] <== t*t;
|
||||||
t4[i] <== t2[i]*t2[i];
|
t4[i] <== t2[i]*t2[i];
|
||||||
if (i<nrounds-1) {
|
if (i<nrounds-1) {
|
||||||
xL[i] <== ((i==0) ? xR_in : xR[i-1]) + t4[i]*t;
|
xL[i] <== ((i==0) ? xR_in : xR[i-1]) + t4[i]*t;
|
||||||
xR[i] <== (i==0) ? xL_in : xL[i-1];
|
xR[i] = (i==0) ? xL_in : xL[i-1];
|
||||||
} else {
|
} else {
|
||||||
xR_out <== xR[i-1] + t4[i]*t;
|
xR_out <== xR[i-1] + t4[i]*t;
|
||||||
xL_out <== xL[i-1];
|
xL_out <== xL[i-1];
|
||||||
|
|||||||
@@ -128,9 +128,6 @@ template Segment(nWindows) {
|
|||||||
component adders[nWindows-1];
|
component adders[nWindows-1];
|
||||||
for (i=0; i<nWindows; i++) {
|
for (i=0; i<nWindows; i++) {
|
||||||
windows[i] = Window4();
|
windows[i] = Window4();
|
||||||
for (j=0; j<4; j++) {
|
|
||||||
windows[i].in[j] <== in[4*i+j];
|
|
||||||
}
|
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
windows[i].base[0] <== e2m.out[0];
|
windows[i].base[0] <== e2m.out[0];
|
||||||
windows[i].base[1] <== e2m.out[1];
|
windows[i].base[1] <== e2m.out[1];
|
||||||
@@ -156,6 +153,9 @@ template Segment(nWindows) {
|
|||||||
adders[i-1].in2[0] <== windows[i].out[0];
|
adders[i-1].in2[0] <== windows[i].out[0];
|
||||||
adders[i-1].in2[1] <== windows[i].out[1];
|
adders[i-1].in2[1] <== windows[i].out[1];
|
||||||
}
|
}
|
||||||
|
for (j=0; j<4; j++) {
|
||||||
|
windows[i].in[j] <== in[4*i+j];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component m2e = Montgomery2Edwards();
|
component m2e = Montgomery2Edwards();
|
||||||
@@ -176,7 +176,7 @@ template Pedersen(n) {
|
|||||||
signal input in[n];
|
signal input in[n];
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var BASE[10][2] = [
|
var BASE = [
|
||||||
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
||||||
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
||||||
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
||||||
@@ -187,8 +187,7 @@ template Pedersen(n) {
|
|||||||
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
||||||
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
||||||
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
||||||
|
]
|
||||||
];
|
|
||||||
|
|
||||||
var nSegments = ((n-1)\200)+1;
|
var nSegments = ((n-1)\200)+1;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ template Pedersen(n) {
|
|||||||
|
|
||||||
component escalarMuls[nexps];
|
component escalarMuls[nexps];
|
||||||
|
|
||||||
var PBASE[10][2] = [
|
var PBASE = [
|
||||||
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
||||||
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
||||||
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
||||||
@@ -39,7 +39,6 @@ template Pedersen(n) {
|
|||||||
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
||||||
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
||||||
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ function sqrt(n) {
|
|||||||
r = r*b;
|
r = r*b;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0 ) {
|
if (r > ((-1) >> 1)) {
|
||||||
r = -r;
|
r = -r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
include "./poseidon_constants.circom";
|
|
||||||
|
|
||||||
template Sigma() {
|
template Sigma() {
|
||||||
signal input in;
|
signal input in;
|
||||||
@@ -13,52 +12,163 @@ template Sigma() {
|
|||||||
out <== in4*in;
|
out <== in4*in;
|
||||||
}
|
}
|
||||||
|
|
||||||
template Ark(t, C, r) {
|
template Ark(t, C) {
|
||||||
signal input in[t];
|
signal input in[t];
|
||||||
signal output out[t];
|
signal output out[t];
|
||||||
|
|
||||||
for (var i=0; i<t; i++) {
|
for (var i=0; i<t; i++) {
|
||||||
out[i] <== in[i] + C[i + r];
|
out[i] <== in[i] + C;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template Mix(t, M) {
|
template Mix(t, M) {
|
||||||
signal input in[t];
|
signal input in[t];
|
||||||
signal output out[t];
|
signal output out[t];
|
||||||
|
|
||||||
var lc;
|
var lc;
|
||||||
|
|
||||||
for (var i=0; i<t; i++) {
|
for (var i=0; i<t; i++) {
|
||||||
lc = 0;
|
lc = 0;
|
||||||
for (var j=0; j<t; j++) {
|
for (var j=0; j<t; j++) {
|
||||||
lc += M[i][j]*in[j];
|
lc = lc + M[i][j]*in[j];
|
||||||
}
|
}
|
||||||
out[i] <== lc;
|
out[i] <== lc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template Poseidon(nInputs) {
|
// var nRoundsF = 8;
|
||||||
|
// var nRoundsP = 57;
|
||||||
|
// var t = 6;
|
||||||
|
|
||||||
|
template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
|
||||||
|
|
||||||
|
var C = [
|
||||||
|
14397397413755236225575615486459253198602422701513067526754101844196324375522,
|
||||||
|
10405129301473404666785234951972711717481302463898292859783056520670200613128,
|
||||||
|
5179144822360023508491245509308555580251733042407187134628755730783052214509,
|
||||||
|
9132640374240188374542843306219594180154739721841249568925550236430986592615,
|
||||||
|
20360807315276763881209958738450444293273549928693737723235350358403012458514,
|
||||||
|
17933600965499023212689924809448543050840131883187652471064418452962948061619,
|
||||||
|
3636213416533737411392076250708419981662897009810345015164671602334517041153,
|
||||||
|
2008540005368330234524962342006691994500273283000229509835662097352946198608,
|
||||||
|
16018407964853379535338740313053768402596521780991140819786560130595652651567,
|
||||||
|
20653139667070586705378398435856186172195806027708437373983929336015162186471,
|
||||||
|
17887713874711369695406927657694993484804203950786446055999405564652412116765,
|
||||||
|
4852706232225925756777361208698488277369799648067343227630786518486608711772,
|
||||||
|
8969172011633935669771678412400911310465619639756845342775631896478908389850,
|
||||||
|
20570199545627577691240476121888846460936245025392381957866134167601058684375,
|
||||||
|
16442329894745639881165035015179028112772410105963688121820543219662832524136,
|
||||||
|
20060625627350485876280451423010593928172611031611836167979515653463693899374,
|
||||||
|
16637282689940520290130302519163090147511023430395200895953984829546679599107,
|
||||||
|
15599196921909732993082127725908821049411366914683565306060493533569088698214,
|
||||||
|
16894591341213863947423904025624185991098788054337051624251730868231322135455,
|
||||||
|
1197934381747032348421303489683932612752526046745577259575778515005162320212,
|
||||||
|
6172482022646932735745595886795230725225293469762393889050804649558459236626,
|
||||||
|
21004037394166516054140386756510609698837211370585899203851827276330669555417,
|
||||||
|
15262034989144652068456967541137853724140836132717012646544737680069032573006,
|
||||||
|
15017690682054366744270630371095785995296470601172793770224691982518041139766,
|
||||||
|
15159744167842240513848638419303545693472533086570469712794583342699782519832,
|
||||||
|
11178069035565459212220861899558526502477231302924961773582350246646450941231,
|
||||||
|
21154888769130549957415912997229564077486639529994598560737238811887296922114,
|
||||||
|
20162517328110570500010831422938033120419484532231241180224283481905744633719,
|
||||||
|
2777362604871784250419758188173029886707024739806641263170345377816177052018,
|
||||||
|
15732290486829619144634131656503993123618032247178179298922551820261215487562,
|
||||||
|
6024433414579583476444635447152826813568595303270846875177844482142230009826,
|
||||||
|
17677827682004946431939402157761289497221048154630238117709539216286149983245,
|
||||||
|
10716307389353583413755237303156291454109852751296156900963208377067748518748,
|
||||||
|
14925386988604173087143546225719076187055229908444910452781922028996524347508,
|
||||||
|
8940878636401797005293482068100797531020505636124892198091491586778667442523,
|
||||||
|
18911747154199663060505302806894425160044925686870165583944475880789706164410,
|
||||||
|
8821532432394939099312235292271438180996556457308429936910969094255825456935,
|
||||||
|
20632576502437623790366878538516326728436616723089049415538037018093616927643,
|
||||||
|
71447649211767888770311304010816315780740050029903404046389165015534756512,
|
||||||
|
2781996465394730190470582631099299305677291329609718650018200531245670229393,
|
||||||
|
12441376330954323535872906380510501637773629931719508864016287320488688345525,
|
||||||
|
2558302139544901035700544058046419714227464650146159803703499681139469546006,
|
||||||
|
10087036781939179132584550273563255199577525914374285705149349445480649057058,
|
||||||
|
4267692623754666261749551533667592242661271409704769363166965280715887854739,
|
||||||
|
4945579503584457514844595640661884835097077318604083061152997449742124905548,
|
||||||
|
17742335354489274412669987990603079185096280484072783973732137326144230832311,
|
||||||
|
6266270088302506215402996795500854910256503071464802875821837403486057988208,
|
||||||
|
2716062168542520412498610856550519519760063668165561277991771577403400784706,
|
||||||
|
19118392018538203167410421493487769944462015419023083813301166096764262134232,
|
||||||
|
9386595745626044000666050847309903206827901310677406022353307960932745699524,
|
||||||
|
9121640807890366356465620448383131419933298563527245687958865317869840082266,
|
||||||
|
3078975275808111706229899605611544294904276390490742680006005661017864583210,
|
||||||
|
7157404299437167354719786626667769956233708887934477609633504801472827442743,
|
||||||
|
14056248655941725362944552761799461694550787028230120190862133165195793034373,
|
||||||
|
14124396743304355958915937804966111851843703158171757752158388556919187839849,
|
||||||
|
11851254356749068692552943732920045260402277343008629727465773766468466181076,
|
||||||
|
9799099446406796696742256539758943483211846559715874347178722060519817626047,
|
||||||
|
10156146186214948683880719664738535455146137901666656566575307300522957959544,
|
||||||
|
19908645952733301583346063785055921934459499091029406575311417879963332475861,
|
||||||
|
11766105336238068471342414351862472329437473380853789942065610694000443387471,
|
||||||
|
11002137593249972174092192767251572171769044073555430468487809799220351297047,
|
||||||
|
284136377911685911941431040940403846843630064858778505937392780738953624163,
|
||||||
|
19448733709802908339787967270452055364068697565906862913410983275341804035680,
|
||||||
|
14423660424692802524250720264041003098290275890428483723270346403986712981505,
|
||||||
|
10635360132728137321700090133109897687122647659471659996419791842933639708516
|
||||||
|
];
|
||||||
|
|
||||||
|
var M = [
|
||||||
|
[
|
||||||
|
19167410339349846567561662441069598364702008768579734801591448511131028229281,
|
||||||
|
14183033936038168803360723133013092560869148726790180682363054735190196956789,
|
||||||
|
9067734253445064890734144122526450279189023719890032859456830213166173619761,
|
||||||
|
16378664841697311562845443097199265623838619398287411428110917414833007677155,
|
||||||
|
12968540216479938138647596899147650021419273189336843725176422194136033835172,
|
||||||
|
3636162562566338420490575570584278737093584021456168183289112789616069756675
|
||||||
|
],[
|
||||||
|
17034139127218860091985397764514160131253018178110701196935786874261236172431,
|
||||||
|
2799255644797227968811798608332314218966179365168250111693473252876996230317,
|
||||||
|
2482058150180648511543788012634934806465808146786082148795902594096349483974,
|
||||||
|
16563522740626180338295201738437974404892092704059676533096069531044355099628,
|
||||||
|
10468644849657689537028565510142839489302836569811003546969773105463051947124,
|
||||||
|
3328913364598498171733622353010907641674136720305714432354138807013088636408
|
||||||
|
],[
|
||||||
|
18985203040268814769637347880759846911264240088034262814847924884273017355969,
|
||||||
|
8652975463545710606098548415650457376967119951977109072274595329619335974180,
|
||||||
|
970943815872417895015626519859542525373809485973005165410533315057253476903,
|
||||||
|
19406667490568134101658669326517700199745817783746545889094238643063688871948,
|
||||||
|
17049854690034965250221386317058877242629221002521630573756355118745574274967,
|
||||||
|
4964394613021008685803675656098849539153699842663541444414978877928878266244
|
||||||
|
],[
|
||||||
|
19025623051770008118343718096455821045904242602531062247152770448380880817517,
|
||||||
|
9077319817220936628089890431129759976815127354480867310384708941479362824016,
|
||||||
|
4770370314098695913091200576539533727214143013236894216582648993741910829490,
|
||||||
|
4298564056297802123194408918029088169104276109138370115401819933600955259473,
|
||||||
|
6905514380186323693285869145872115273350947784558995755916362330070690839131,
|
||||||
|
4783343257810358393326889022942241108539824540285247795235499223017138301952
|
||||||
|
],[
|
||||||
|
16205238342129310687768799056463408647672389183328001070715567975181364448609,
|
||||||
|
8303849270045876854140023508764676765932043944545416856530551331270859502246,
|
||||||
|
20218246699596954048529384569730026273241102596326201163062133863539137060414,
|
||||||
|
1712845821388089905746651754894206522004527237615042226559791118162382909269,
|
||||||
|
13001155522144542028910638547179410124467185319212645031214919884423841839406,
|
||||||
|
16037892369576300958623292723740289861626299352695838577330319504984091062115
|
||||||
|
],[
|
||||||
|
15162889384227198851506890526431746552868519326873025085114621698588781611738,
|
||||||
|
13272957914179340594010910867091459756043436017766464331915862093201960540910,
|
||||||
|
9416416589114508529880440146952102328470363729880726115521103179442988482948,
|
||||||
|
8035240799672199706102747147502951589635001418759394863664434079699838251138,
|
||||||
|
21642389080762222565487157652540372010968704000567605990102641816691459811717,
|
||||||
|
20261355950827657195644012399234591122288573679402601053407151083849785332516
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
signal input inputs[nInputs];
|
signal input inputs[nInputs];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
|
component ark[nRoundsF + nRoundsP];
|
||||||
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
|
component sigmaF[nRoundsF][t];
|
||||||
// And rounded up to nearest integer that divides by t
|
|
||||||
var N_ROUNDS_P[8] = [56, 57, 56, 60, 60, 63, 64, 63];
|
|
||||||
var t = nInputs + 1;
|
|
||||||
var nRoundsF = 8;
|
|
||||||
var nRoundsP = N_ROUNDS_P[t - 2];
|
|
||||||
var C[t*(nRoundsF + nRoundsP)] = POSEIDON_C(t);
|
|
||||||
var M[t][t] = POSEIDON_M(t);
|
|
||||||
|
|
||||||
component ark[nRoundsF + nRoundsP - 1];
|
|
||||||
component sigmaF[nRoundsF - 1][t];
|
|
||||||
component sigmaP[nRoundsP];
|
component sigmaP[nRoundsP];
|
||||||
component mix[nRoundsF + nRoundsP - 1];
|
component mix[nRoundsF + nRoundsP];
|
||||||
|
|
||||||
var k;
|
var k;
|
||||||
|
|
||||||
for (var i=0; i<nRoundsF + nRoundsP - 1; i++) {
|
for (var i=0; i<(nRoundsF + nRoundsP); i++) {
|
||||||
ark[i] = Ark(t, C, t*i);
|
ark[i] = Ark(t, C[i]);
|
||||||
|
mix[i] = Mix(t, M);
|
||||||
|
|
||||||
for (var j=0; j<t; j++) {
|
for (var j=0; j<t; j++) {
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
if (j<nInputs) {
|
if (j<nInputs) {
|
||||||
@@ -71,9 +181,8 @@ template Poseidon(nInputs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) {
|
if ((i<(nRoundsF/2)) || (i>= (nRoundsP + nRoundsF/2))) {
|
||||||
k = i < nRoundsF/2 ? i : i - nRoundsP;
|
k= i<nRoundsF/2 ? i : (i-nRoundsP);
|
||||||
mix[i] = Mix(t, M);
|
|
||||||
for (var j=0; j<t; j++) {
|
for (var j=0; j<t; j++) {
|
||||||
sigmaF[k][j] = Sigma();
|
sigmaF[k][j] = Sigma();
|
||||||
sigmaF[k][j].in <== ark[i].out[j];
|
sigmaF[k][j].in <== ark[i].out[j];
|
||||||
@@ -81,7 +190,6 @@ template Poseidon(nInputs) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
k= i-nRoundsF/2;
|
k= i-nRoundsF/2;
|
||||||
mix[i] = Mix(t, M);
|
|
||||||
sigmaP[k] = Sigma();
|
sigmaP[k] = Sigma();
|
||||||
sigmaP[k].in <== ark[i].out[0];
|
sigmaP[k].in <== ark[i].out[0];
|
||||||
mix[i].in[0] <== sigmaP[k].out;
|
mix[i].in[0] <== sigmaP[k].out;
|
||||||
@@ -91,8 +199,5 @@ template Poseidon(nInputs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// last round is done only for the first word, so we do it manually to save constraints
|
out <== mix[nRoundsF + nRoundsP -1].out[0];
|
||||||
component lastSigmaF = Sigma();
|
|
||||||
lastSigmaF.in <== mix[nRoundsF + nRoundsP - 2].out[0] + C[t*(nRoundsF + nRoundsP - 1)];
|
|
||||||
out <== lastSigmaF.out;
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
template H(x) {
|
template H(x) {
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var c[8] = [0x6a09e667,
|
var c = [0x6a09e667,
|
||||||
0xbb67ae85,
|
0xbb67ae85,
|
||||||
0x3c6ef372,
|
0x3c6ef372,
|
||||||
0xa54ff53a,
|
0xa54ff53a,
|
||||||
@@ -35,7 +35,7 @@ template H(x) {
|
|||||||
|
|
||||||
template K(x) {
|
template K(x) {
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var c[64] = [
|
var c = [
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ include "t1.circom";
|
|||||||
include "t2.circom";
|
include "t2.circom";
|
||||||
include "../binsum.circom";
|
include "../binsum.circom";
|
||||||
include "sigmaplus.circom";
|
include "sigmaplus.circom";
|
||||||
include "sha256compression_function.circom";
|
|
||||||
|
|
||||||
|
|
||||||
template Sha256compression() {
|
template Sha256compression() {
|
||||||
signal input hin[256];
|
signal input hin[256];
|
||||||
@@ -39,11 +37,7 @@ template Sha256compression() {
|
|||||||
signal h[65][32];
|
signal h[65][32];
|
||||||
signal w[64][32];
|
signal w[64][32];
|
||||||
|
|
||||||
|
|
||||||
var outCalc[256] = sha256compression(hin, inp);
|
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
for (i=0; i<256; i++) out[i] <-- outCalc[i];
|
|
||||||
|
|
||||||
component sigmaPlus[48];
|
component sigmaPlus[48];
|
||||||
for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus();
|
for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus();
|
||||||
@@ -80,9 +74,6 @@ template Sha256compression() {
|
|||||||
sigmaPlus[t-16].in7[k] <== w[t-7][k];
|
sigmaPlus[t-16].in7[k] <== w[t-7][k];
|
||||||
sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
||||||
sigmaPlus[t-16].in16[k] <== w[t-16][k];
|
sigmaPlus[t-16].in16[k] <== w[t-16][k];
|
||||||
}
|
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
w[t][k] <== sigmaPlus[t-16].out[k];
|
w[t][k] <== sigmaPlus[t-16].out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,13 +144,13 @@ template Sha256compression() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
for (k=0; k<32; k++) {
|
||||||
out[31-k] === fsum[0].out[k];
|
out[31-k] <== fsum[0].out[k];
|
||||||
out[32+31-k] === fsum[1].out[k];
|
out[32+31-k] <== fsum[1].out[k];
|
||||||
out[64+31-k] === fsum[2].out[k];
|
out[64+31-k] <== fsum[2].out[k];
|
||||||
out[96+31-k] === fsum[3].out[k];
|
out[96+31-k] <== fsum[3].out[k];
|
||||||
out[128+31-k] === fsum[4].out[k];
|
out[128+31-k] <== fsum[4].out[k];
|
||||||
out[160+31-k] === fsum[5].out[k];
|
out[160+31-k] <== fsum[5].out[k];
|
||||||
out[192+31-k] === fsum[6].out[k];
|
out[192+31-k] <== fsum[6].out[k];
|
||||||
out[224+31-k] === fsum[7].out[k];
|
out[224+31-k] <== fsum[7].out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
// signal input hin[256];
|
|
||||||
// signal input inp[512];
|
|
||||||
// signal output out[256];
|
|
||||||
|
|
||||||
|
|
||||||
function rrot(x, n) {
|
|
||||||
return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
function bsigma0(x) {
|
|
||||||
return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22);
|
|
||||||
}
|
|
||||||
|
|
||||||
function bsigma1(x) {
|
|
||||||
return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ssigma0(x) {
|
|
||||||
return rrot(x,7) ^ rrot(x,18) ^ (x >> 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ssigma1(x) {
|
|
||||||
return rrot(x,17) ^ rrot(x,19) ^ (x >> 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Maj(x, y, z) {
|
|
||||||
return (x&y) ^ (x&z) ^ (y&z);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Ch(x, y, z) {
|
|
||||||
return (x & y) ^ ((0xFFFFFFFF ^x) & z);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sha256K(i) {
|
|
||||||
var k[64] = [
|
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
||||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
||||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
||||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
||||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
||||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
||||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
||||||
];
|
|
||||||
return k[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
function sha256compression(hin, inp) {
|
|
||||||
var H[8];
|
|
||||||
var a;
|
|
||||||
var b;
|
|
||||||
var c;
|
|
||||||
var d;
|
|
||||||
var e;
|
|
||||||
var f;
|
|
||||||
var g;
|
|
||||||
var h;
|
|
||||||
var out[256];
|
|
||||||
for (var i=0; i<8; i++) {
|
|
||||||
H[i] = 0;
|
|
||||||
for (var j=0; j<32; j++) {
|
|
||||||
H[i] += hin[i*32+j] << j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a=H[0];
|
|
||||||
b=H[1];
|
|
||||||
c=H[2];
|
|
||||||
d=H[3];
|
|
||||||
e=H[4];
|
|
||||||
f=H[5];
|
|
||||||
g=H[6];
|
|
||||||
h=H[7];
|
|
||||||
var w[64];
|
|
||||||
var T1;
|
|
||||||
var T2;
|
|
||||||
for (var i=0; i<64; i++) {
|
|
||||||
if (i<16) {
|
|
||||||
w[i]=0;
|
|
||||||
for (var j=0; j<32; j++) {
|
|
||||||
w[i] += inp[i*32+31-j]<<j;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w[i] = (ssigma1(w[i-2]) + w[i-7] + ssigma0(w[i-15]) + w[i-16]) & 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
T1 = (h + bsigma1(e) + Ch(e,f,g) + sha256K(i) + w[i]) & 0xFFFFFFFF;
|
|
||||||
T2 = (bsigma0(a) + Maj(a,b,c)) & 0xFFFFFFFF;
|
|
||||||
|
|
||||||
h=g;
|
|
||||||
g=f;
|
|
||||||
f=e;
|
|
||||||
e=(d+T1) & 0xFFFFFFFF;
|
|
||||||
d=c;
|
|
||||||
c=b;
|
|
||||||
b=a;
|
|
||||||
a=(T1+T2) & 0xFFFFFFFF;
|
|
||||||
|
|
||||||
}
|
|
||||||
H[0] = H[0] + a;
|
|
||||||
H[1] = H[1] + b;
|
|
||||||
H[2] = H[2] + c;
|
|
||||||
H[3] = H[3] + d;
|
|
||||||
H[4] = H[4] + e;
|
|
||||||
H[5] = H[5] + f;
|
|
||||||
H[6] = H[6] + g;
|
|
||||||
H[7] = H[7] + h;
|
|
||||||
for (var i=0; i<8; i++) {
|
|
||||||
for (var j=0; j<32; j++) {
|
|
||||||
out[i*32+31-j] = (H[i] >> j) & 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
@@ -24,26 +24,22 @@ include "shift.circom";
|
|||||||
template SmallSigma(ra, rb, rc) {
|
template SmallSigma(ra, rb, rc) {
|
||||||
signal input in[32];
|
signal input in[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var k;
|
|
||||||
|
component xor3 = Xor3(32);
|
||||||
|
|
||||||
component rota = RotR(32, ra);
|
component rota = RotR(32, ra);
|
||||||
component rotb = RotR(32, rb);
|
component rotb = RotR(32, rb);
|
||||||
component shrc = ShR(32, rc);
|
component shrc = ShR(32, rc);
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
for (var k=0; k<32; k++) {
|
||||||
rota.in[k] <== in[k];
|
rota.in[k] <== in[k];
|
||||||
rotb.in[k] <== in[k];
|
rotb.in[k] <== in[k];
|
||||||
shrc.in[k] <== in[k];
|
shrc.in[k] <== in[k];
|
||||||
}
|
|
||||||
|
|
||||||
component xor3 = Xor3(32);
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
xor3.a[k] <== rota.out[k];
|
xor3.a[k] <== rota.out[k];
|
||||||
xor3.b[k] <== rotb.out[k];
|
xor3.b[k] <== rotb.out[k];
|
||||||
xor3.c[k] <== shrc.out[k];
|
xor3.c[k] <== shrc.out[k];
|
||||||
}
|
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
out[k] <== xor3.out[k];
|
out[k] <== xor3.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,26 +47,22 @@ template SmallSigma(ra, rb, rc) {
|
|||||||
template BigSigma(ra, rb, rc) {
|
template BigSigma(ra, rb, rc) {
|
||||||
signal input in[32];
|
signal input in[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var k;
|
|
||||||
|
component xor3 = Xor3(32);
|
||||||
|
|
||||||
component rota = RotR(32, ra);
|
component rota = RotR(32, ra);
|
||||||
component rotb = RotR(32, rb);
|
component rotb = RotR(32, rb);
|
||||||
component rotc = RotR(32, rc);
|
component rotc = RotR(32, rc);
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
|
for (var k=0; k<32; k++) {
|
||||||
rota.in[k] <== in[k];
|
rota.in[k] <== in[k];
|
||||||
rotb.in[k] <== in[k];
|
rotb.in[k] <== in[k];
|
||||||
rotc.in[k] <== in[k];
|
rotc.in[k] <== in[k];
|
||||||
}
|
|
||||||
|
|
||||||
component xor3 = Xor3(32);
|
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
xor3.a[k] <== rota.out[k];
|
xor3.a[k] <== rota.out[k];
|
||||||
xor3.b[k] <== rotb.out[k];
|
xor3.b[k] <== rotb.out[k];
|
||||||
xor3.c[k] <== rotc.out[k];
|
xor3.c[k] <== rotc.out[k];
|
||||||
}
|
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
out[k] <== xor3.out[k];
|
out[k] <== xor3.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,24 +26,20 @@ template SigmaPlus() {
|
|||||||
signal input in15[32];
|
signal input in15[32];
|
||||||
signal input in16[32];
|
signal input in16[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var k;
|
|
||||||
|
|
||||||
component sigma1 = SmallSigma(17,19,10);
|
|
||||||
component sigma0 = SmallSigma(7, 18, 3);
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
sigma1.in[k] <== in2[k];
|
|
||||||
sigma0.in[k] <== in15[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
component sum = BinSum(32, 4);
|
component sum = BinSum(32, 4);
|
||||||
for (k=0; k<32; k++) {
|
component sigma1 = SmallSigma(17,19,10);
|
||||||
|
component sigma0 = SmallSigma(7, 18, 3);
|
||||||
|
|
||||||
|
for (var k=0; k<32; k++) {
|
||||||
|
sigma1.in[k] <== in2[k];
|
||||||
|
sigma0.in[k] <== in15[k];
|
||||||
|
|
||||||
sum.in[0][k] <== sigma1.out[k];
|
sum.in[0][k] <== sigma1.out[k];
|
||||||
sum.in[1][k] <== in7[k];
|
sum.in[1][k] <== in7[k];
|
||||||
sum.in[2][k] <== sigma0.out[k];
|
sum.in[2][k] <== sigma0.out[k];
|
||||||
sum.in[3][k] <== in16[k];
|
sum.in[3][k] <== in16[k];
|
||||||
}
|
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
out[k] <== sum.out[k];
|
out[k] <== sum.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,28 +30,23 @@ template T1() {
|
|||||||
signal input w[32];
|
signal input w[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
|
|
||||||
var ki;
|
component sum = BinSum(32, 5);
|
||||||
|
|
||||||
component ch = Ch(32);
|
component ch = Ch(32);
|
||||||
|
|
||||||
component bigsigma1 = BigSigma(6, 11, 25);
|
component bigsigma1 = BigSigma(6, 11, 25);
|
||||||
|
|
||||||
for (ki=0; ki<32; ki++) {
|
for (var ki=0; ki<32; ki++) {
|
||||||
bigsigma1.in[ki] <== e[ki];
|
bigsigma1.in[ki] <== e[ki];
|
||||||
ch.a[ki] <== e[ki];
|
ch.a[ki] <== e[ki];
|
||||||
ch.b[ki] <== f[ki];
|
ch.b[ki] <== f[ki];
|
||||||
ch.c[ki] <== g[ki];
|
ch.c[ki] <== g[ki]
|
||||||
}
|
|
||||||
|
|
||||||
component sum = BinSum(32, 5);
|
|
||||||
for (ki=0; ki<32; ki++) {
|
|
||||||
sum.in[0][ki] <== h[ki];
|
sum.in[0][ki] <== h[ki];
|
||||||
sum.in[1][ki] <== bigsigma1.out[ki];
|
sum.in[1][ki] <== bigsigma1.out[ki];
|
||||||
sum.in[2][ki] <== ch.out[ki];
|
sum.in[2][ki] <== ch.out[ki];
|
||||||
sum.in[3][ki] <== k[ki];
|
sum.in[3][ki] <== k[ki];
|
||||||
sum.in[4][ki] <== w[ki];
|
sum.in[4][ki] <== w[ki];
|
||||||
}
|
|
||||||
|
|
||||||
for (ki=0; ki<32; ki++) {
|
|
||||||
out[ki] <== sum.out[ki];
|
out[ki] <== sum.out[ki];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,25 +26,22 @@ template T2() {
|
|||||||
signal input b[32];
|
signal input b[32];
|
||||||
signal input c[32];
|
signal input c[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var k;
|
|
||||||
|
component sum = BinSum(32, 2);
|
||||||
|
|
||||||
component bigsigma0 = BigSigma(2, 13, 22);
|
component bigsigma0 = BigSigma(2, 13, 22);
|
||||||
component maj = Maj(32);
|
component maj = Maj(32);
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
|
for (var k=0; k<32; k++) {
|
||||||
|
|
||||||
bigsigma0.in[k] <== a[k];
|
bigsigma0.in[k] <== a[k];
|
||||||
maj.a[k] <== a[k];
|
maj.a[k] <== a[k];
|
||||||
maj.b[k] <== b[k];
|
maj.b[k] <== b[k];
|
||||||
maj.c[k] <== c[k];
|
maj.c[k] <== c[k];
|
||||||
}
|
|
||||||
|
|
||||||
component sum = BinSum(32, 2);
|
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
sum.in[0][k] <== bigsigma0.out[k];
|
sum.in[0][k] <== bigsigma0.out[k];
|
||||||
sum.in[1][k] <== maj.out[k];
|
sum.in[1][k] <== maj.out[k];
|
||||||
}
|
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
|
||||||
out[k] <== sum.out[k];
|
out[k] <== sum.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ template SMTHash1() {
|
|||||||
signal input value;
|
signal input value;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = Poseidon(3); // Constant
|
component h = Poseidon(3, 6, 8, 57); // Constant
|
||||||
h.inputs[0] <== key;
|
h.inputs[0] <== key;
|
||||||
h.inputs[1] <== value;
|
h.inputs[1] <== value;
|
||||||
h.inputs[2] <== 1;
|
h.inputs[2] <== 1;
|
||||||
@@ -48,7 +48,7 @@ template SMTHash2() {
|
|||||||
signal input R;
|
signal input R;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = Poseidon(2); // Constant
|
component h = Poseidon(2, 6, 8, 57); // Constant
|
||||||
h.inputs[0] <== L;
|
h.inputs[0] <== L;
|
||||||
h.inputs[1] <== R;
|
h.inputs[1] <== R;
|
||||||
|
|
||||||
|
|||||||
@@ -79,11 +79,9 @@ template SMTLevIns(nLevels) {
|
|||||||
signal output levIns[nLevels];
|
signal output levIns[nLevels];
|
||||||
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
|
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
|
||||||
|
|
||||||
var i;
|
|
||||||
|
|
||||||
component isZero[nLevels];
|
component isZero[nLevels];
|
||||||
|
|
||||||
for (i=0; i<nLevels; i++) {
|
for (var i=0; i<nLevels; i++) {
|
||||||
isZero[i] = IsZero();
|
isZero[i] = IsZero();
|
||||||
isZero[i].in <== siblings[i];
|
isZero[i].in <== siblings[i];
|
||||||
}
|
}
|
||||||
@@ -93,7 +91,7 @@ template SMTLevIns(nLevels) {
|
|||||||
|
|
||||||
levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
|
levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
|
||||||
done[nLevels-2] <== levIns[nLevels-1];
|
done[nLevels-2] <== levIns[nLevels-1];
|
||||||
for (i=nLevels-2; i>0; i--) {
|
for (var i=nLevels-2; i>0; i--) {
|
||||||
levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
|
levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
|
||||||
done[i-1] <== levIns[i] + done[i];
|
done[i-1] <== levIns[i] + done[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,8 +150,6 @@ template SMTProcessor(nLevels) {
|
|||||||
|
|
||||||
signal enabled;
|
signal enabled;
|
||||||
|
|
||||||
var i;
|
|
||||||
|
|
||||||
enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]
|
enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]
|
||||||
|
|
||||||
component hash1Old = SMTHash1();
|
component hash1Old = SMTHash1();
|
||||||
@@ -169,18 +167,18 @@ template SMTProcessor(nLevels) {
|
|||||||
n2bNew.in <== newKey;
|
n2bNew.in <== newKey;
|
||||||
|
|
||||||
component smtLevIns = SMTLevIns(nLevels);
|
component smtLevIns = SMTLevIns(nLevels);
|
||||||
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
||||||
smtLevIns.enabled <== enabled;
|
smtLevIns.enabled <== enabled;
|
||||||
|
|
||||||
component xors[nLevels];
|
component xors[nLevels];
|
||||||
for (i=0; i<nLevels; i++) {
|
for (var i=0; i<nLevels; i++) {
|
||||||
xors[i] = XOR();
|
xors[i] = XOR();
|
||||||
xors[i].a <== n2bOld.out[i];
|
xors[i].a <== n2bOld.out[i];
|
||||||
xors[i].b <== n2bNew.out[i];
|
xors[i].b <== n2bNew.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
component sm[nLevels];
|
component sm[nLevels];
|
||||||
for (i=0; i<nLevels; i++) {
|
for (var i=0; i<nLevels; i++) {
|
||||||
sm[i] = SMTProcessorSM();
|
sm[i] = SMTProcessorSM();
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
sm[i].prev_top <== enabled;
|
sm[i].prev_top <== enabled;
|
||||||
@@ -206,7 +204,7 @@ template SMTProcessor(nLevels) {
|
|||||||
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
|
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
|
||||||
|
|
||||||
component levels[nLevels];
|
component levels[nLevels];
|
||||||
for (i=nLevels-1; i != -1; i--) {
|
for (var i=nLevels-1; i != -1; i--) {
|
||||||
levels[i] = SMTProcessorLevel();
|
levels[i] = SMTProcessorLevel();
|
||||||
|
|
||||||
levels[i].st_top <== sm[i].st_top;
|
levels[i].st_top <== sm[i].st_top;
|
||||||
|
|||||||
@@ -48,8 +48,6 @@ template SMTVerifier(nLevels) {
|
|||||||
signal input value;
|
signal input value;
|
||||||
signal input fnc;
|
signal input fnc;
|
||||||
|
|
||||||
var i;
|
|
||||||
|
|
||||||
component hash1Old = SMTHash1();
|
component hash1Old = SMTHash1();
|
||||||
hash1Old.key <== oldKey;
|
hash1Old.key <== oldKey;
|
||||||
hash1Old.value <== oldValue;
|
hash1Old.value <== oldValue;
|
||||||
@@ -65,11 +63,11 @@ template SMTVerifier(nLevels) {
|
|||||||
n2bNew.in <== key;
|
n2bNew.in <== key;
|
||||||
|
|
||||||
component smtLevIns = SMTLevIns(nLevels);
|
component smtLevIns = SMTLevIns(nLevels);
|
||||||
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
||||||
smtLevIns.enabled <== enabled;
|
smtLevIns.enabled <== enabled;
|
||||||
|
|
||||||
component sm[nLevels];
|
component sm[nLevels];
|
||||||
for (i=0; i<nLevels; i++) {
|
for (var i=0; i<nLevels; i++) {
|
||||||
sm[i] = SMTVerifierSM();
|
sm[i] = SMTVerifierSM();
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
sm[i].prev_top <== enabled;
|
sm[i].prev_top <== enabled;
|
||||||
@@ -91,7 +89,7 @@ template SMTVerifier(nLevels) {
|
|||||||
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
|
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
|
||||||
|
|
||||||
component levels[nLevels];
|
component levels[nLevels];
|
||||||
for (i=nLevels-1; i != -1; i--) {
|
for (var i=nLevels-1; i != -1; i--) {
|
||||||
levels[i] = SMTVerifierLevel();
|
levels[i] = SMTVerifierLevel();
|
||||||
|
|
||||||
levels[i].st_top <== sm[i].st_top;
|
levels[i].st_top <== sm[i].st_top;
|
||||||
|
|||||||
6
index.js
6
index.js
@@ -4,9 +4,3 @@ exports.mimc7 = require("./src/mimc7");
|
|||||||
exports.mimcsponge = require("./src/mimcsponge");
|
exports.mimcsponge = require("./src/mimcsponge");
|
||||||
exports.babyJub = require("./src/babyjub");
|
exports.babyJub = require("./src/babyjub");
|
||||||
exports.pedersenHash = require("./src/pedersenHash");
|
exports.pedersenHash = require("./src/pedersenHash");
|
||||||
exports.SMT = require("./src/smt").SMT;
|
|
||||||
exports.SMTMemDB = require("./src/smt_memdb");
|
|
||||||
exports.poseidon = require("./src/poseidon");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
8254
package-lock.json
generated
8254
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circomlib",
|
"name": "circomlib",
|
||||||
"version": "0.3.0",
|
"version": "0.0.15",
|
||||||
"description": "Basic circuits library for Circom",
|
"description": "Basic circuits library for Circom",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -26,13 +26,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"blake-hash": "^1.1.0",
|
"blake-hash": "^1.1.0",
|
||||||
"blake2b": "^2.1.3",
|
"blake2b": "^2.1.3",
|
||||||
"circom": "0.5.33",
|
"snarkjs": "^0.1.19",
|
||||||
"ffjavascript": "0.1.0"
|
"typedarray-to-buffer": "^3.1.5",
|
||||||
|
"web3": "^1.0.0-beta.55"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^6.8.0",
|
"circom": "0.0.28",
|
||||||
"ganache-cli": "^6.12.1",
|
"eslint-plugin-mocha": "^5.2.0",
|
||||||
"mocha": "^7.1.1",
|
"ganache-cli": "^6.4.4",
|
||||||
"web3": "^1.3.0"
|
"mocha": "^5.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
const F1Field = require("ffjavascript").F1Field;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const utils = require("ffjavascript").utils;
|
|
||||||
|
|
||||||
exports.addPoint = addPoint;
|
exports.addPoint = addPoint;
|
||||||
exports.mulPointEscalar = mulPointEscalar;
|
exports.mulPointEscalar = mulPointEscalar;
|
||||||
@@ -8,27 +7,23 @@ exports.inCurve = inCurve;
|
|||||||
exports.inSubgroup = inSubgroup;
|
exports.inSubgroup = inSubgroup;
|
||||||
exports.packPoint = packPoint;
|
exports.packPoint = packPoint;
|
||||||
exports.unpackPoint = unpackPoint;
|
exports.unpackPoint = unpackPoint;
|
||||||
|
|
||||||
|
|
||||||
exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
const F = new F1Field(exports.p);
|
|
||||||
exports.F = F;
|
|
||||||
|
|
||||||
exports.Generator = [
|
exports.Generator = [
|
||||||
F.e("995203441582195749578291179787384436505546430278305826713579947235728471134"),
|
bigInt("995203441582195749578291179787384436505546430278305826713579947235728471134"),
|
||||||
F.e("5472060717959818805561601436314318772137091100104008585924551046643952123905")
|
bigInt("5472060717959818805561601436314318772137091100104008585924551046643952123905")
|
||||||
];
|
];
|
||||||
exports.Base8 = [
|
exports.Base8 = [
|
||||||
F.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
F.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
exports.order = Scalar.fromString("21888242871839275222246405745257275088614511777268538073601725287587578984328");
|
exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328");
|
||||||
exports.subOrder = Scalar.shiftRight(exports.order, 3);
|
exports.subOrder = exports.order.shr(3);
|
||||||
exports.A = F.e("168700");
|
exports.p = bn128.r;
|
||||||
exports.D = F.e("168696");
|
exports.A = bigInt("168700");
|
||||||
|
exports.D = bigInt("168696");
|
||||||
|
|
||||||
|
|
||||||
function addPoint(a,b) {
|
function addPoint(a,b) {
|
||||||
|
const q = bn128.r;
|
||||||
|
|
||||||
const res = [];
|
const res = [];
|
||||||
|
|
||||||
@@ -36,40 +31,23 @@ function addPoint(a,b) {
|
|||||||
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
*/
|
*/
|
||||||
|
res[0] = bigInt((bigInt(a[0]).mul(b[1]).add(bigInt(b[0]).mul(a[1]))).mul(bigInt(bigInt("1").add(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
|
||||||
const beta = F.mul(a[0],b[1]);
|
res[1] = bigInt((bigInt(a[1]).mul(b[1]).sub(exports.A.mul(a[0]).mul(b[0]))).mul(bigInt(bigInt("1").sub(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
|
||||||
const gamma = F.mul(a[1],b[0]);
|
|
||||||
const delta = F.mul(
|
|
||||||
F.sub(a[1], F.mul(exports.A, a[0])),
|
|
||||||
F.add(b[0], b[1])
|
|
||||||
);
|
|
||||||
const tau = F.mul(beta, gamma);
|
|
||||||
const dtau = F.mul(exports.D, tau);
|
|
||||||
|
|
||||||
res[0] = F.div(
|
|
||||||
F.add(beta, gamma),
|
|
||||||
F.add(F.one, dtau)
|
|
||||||
);
|
|
||||||
|
|
||||||
res[1] = F.div(
|
|
||||||
F.add(delta, F.sub(F.mul(exports.A,beta), gamma)),
|
|
||||||
F.sub(F.one, dtau)
|
|
||||||
);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mulPointEscalar(base, e) {
|
function mulPointEscalar(base, e) {
|
||||||
let res = [F.e("0"),F.e("1")];
|
let res = [bigInt("0"),bigInt("1")];
|
||||||
let rem = e;
|
let rem = bigInt(e);
|
||||||
let exp = base;
|
let exp = base;
|
||||||
|
|
||||||
while (! Scalar.isZero(rem)) {
|
while (! rem.isZero()) {
|
||||||
if (Scalar.isOdd(rem)) {
|
if (rem.isOdd()) {
|
||||||
res = addPoint(res, exp);
|
res = addPoint(res, exp);
|
||||||
}
|
}
|
||||||
exp = addPoint(exp, exp);
|
exp = addPoint(exp, exp);
|
||||||
rem = Scalar.shiftRight(rem, 1);
|
rem = rem.shr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -78,15 +56,16 @@ function mulPointEscalar(base, e) {
|
|||||||
function inSubgroup(P) {
|
function inSubgroup(P) {
|
||||||
if (!inCurve(P)) return false;
|
if (!inCurve(P)) return false;
|
||||||
const res= mulPointEscalar(P, exports.subOrder);
|
const res= mulPointEscalar(P, exports.subOrder);
|
||||||
return (F.isZero(res[0]) && F.eq(res[1], F.one));
|
return (res[0].equals(bigInt(0))) && (res[1].equals(bigInt(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function inCurve(P) {
|
function inCurve(P) {
|
||||||
|
const F = bn128.Fr;
|
||||||
|
|
||||||
const x2 = F.square(P[0]);
|
const x2 = F.square(P[0]);
|
||||||
const y2 = F.square(P[1]);
|
const y2 = F.square(P[1]);
|
||||||
|
|
||||||
if (!F.eq(
|
if (!F.equals(
|
||||||
F.add(F.mul(exports.A, x2), y2),
|
F.add(F.mul(exports.A, x2), y2),
|
||||||
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
|
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
|
||||||
|
|
||||||
@@ -94,14 +73,16 @@ function inCurve(P) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function packPoint(P) {
|
function packPoint(P) {
|
||||||
const buff = utils.leInt2Buff(P[1], 32);
|
const buff = bigInt.leInt2Buff(P[1], 32);
|
||||||
if (F.lt(P[0], F.zero)) {
|
if (P[0].greater(exports.p.shr(1))) {
|
||||||
buff[31] = buff[31] | 0x80;
|
buff[31] = buff[31] | 0x80;
|
||||||
}
|
}
|
||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpackPoint(_buff) {
|
function unpackPoint(_buff) {
|
||||||
|
const F = bn128.Fr;
|
||||||
|
|
||||||
const buff = Buffer.from(_buff);
|
const buff = Buffer.from(_buff);
|
||||||
let sign = false;
|
let sign = false;
|
||||||
const P = new Array(2);
|
const P = new Array(2);
|
||||||
@@ -109,8 +90,8 @@ function unpackPoint(_buff) {
|
|||||||
sign = true;
|
sign = true;
|
||||||
buff[31] = buff[31] & 0x7F;
|
buff[31] = buff[31] & 0x7F;
|
||||||
}
|
}
|
||||||
P[1] = utils.leBuff2int(buff);
|
P[1] = bigInt.leBuff2int(buff);
|
||||||
if (Scalar.gt(P[1], exports.p)) return null;
|
if (P[1].greaterOrEquals(exports.p)) return null;
|
||||||
|
|
||||||
const y2 = F.square(P[1]);
|
const y2 = F.square(P[1]);
|
||||||
|
|
||||||
@@ -122,7 +103,7 @@ function unpackPoint(_buff) {
|
|||||||
|
|
||||||
if (sign) x = F.neg(x);
|
if (sign) x = F.neg(x);
|
||||||
|
|
||||||
P[0] = x;
|
P[0] = F.affine(x);
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
|||||||
97
src/eddsa.js
97
src/eddsa.js
@@ -1,14 +1,11 @@
|
|||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const F1Field = require("ffjavascript").F1Field;
|
|
||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
const utils = require("ffjavascript").utils;
|
|
||||||
const pedersenHash = require("./pedersenHash").hash;
|
const pedersenHash = require("./pedersenHash").hash;
|
||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
const poseidon = require("./poseidon.js");
|
const poseidon = require("./poseidon.js");
|
||||||
const mimcsponge = require("./mimcsponge");
|
const mimcsponge = require("./mimcsponge");
|
||||||
|
|
||||||
|
|
||||||
exports.prv2pub= prv2pub;
|
exports.prv2pub= prv2pub;
|
||||||
exports.sign = sign;
|
exports.sign = sign;
|
||||||
exports.signMiMC = signMiMC;
|
exports.signMiMC = signMiMC;
|
||||||
@@ -33,27 +30,26 @@ function pruneBuffer(_buff) {
|
|||||||
|
|
||||||
function prv2pub(prv) {
|
function prv2pub(prv) {
|
||||||
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
|
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
|
||||||
let s = utils.leBuff2int(sBuff);
|
let s = bigInt.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s,3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||||
return A;
|
return A;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sign(prv, msg) {
|
function sign(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0,32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = utils.leBuff2int(sBuff);
|
const s = bigInt.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||||
|
|
||||||
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
|
||||||
let r = utils.leBuff2int(rBuff);
|
let r = bigInt.leBuff2int(rBuff);
|
||||||
const Fr = new F1Field(babyJub.subOrder);
|
r = r.mod(babyJub.subOrder);
|
||||||
r = Fr.e(r);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const R8p = babyJub.packPoint(R8);
|
const R8p = babyJub.packPoint(R8);
|
||||||
const Ap = babyJub.packPoint(A);
|
const Ap = babyJub.packPoint(A);
|
||||||
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
||||||
const hm = utils.leBuff2int(hmBuff);
|
const hm = bigInt.leBuff2int(hmBuff);
|
||||||
const S = Fr.add(r , Fr.mul(hm, s));
|
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S
|
S: S
|
||||||
@@ -63,17 +59,16 @@ function sign(prv, msg) {
|
|||||||
function signMiMC(prv, msg) {
|
function signMiMC(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0,32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = utils.leBuff2int(sBuff);
|
const s = bigInt.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||||
|
|
||||||
const msgBuff = utils.leInt2Buff(msg, 32);
|
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
||||||
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
let r = utils.leBuff2int(rBuff);
|
let r = bigInt.leBuff2int(rBuff);
|
||||||
const Fr = new F1Field(babyJub.subOrder);
|
r = r.mod(babyJub.subOrder);
|
||||||
r = Fr.e(r);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
const S = Fr.add(r , Fr.mul(hm, s));
|
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S
|
S: S
|
||||||
@@ -83,17 +78,16 @@ function signMiMC(prv, msg) {
|
|||||||
function signMiMCSponge(prv, msg) {
|
function signMiMCSponge(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0,32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = utils.leBuff2int(sBuff);
|
const s = bigInt.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||||
|
|
||||||
const msgBuff = utils.leInt2Buff(msg, 32);
|
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
||||||
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
let r = utils.leBuff2int(rBuff);
|
let r = bigInt.leBuff2int(rBuff);
|
||||||
const Fr = new F1Field(babyJub.subOrder);
|
r = r.mod(babyJub.subOrder);
|
||||||
r = Fr.e(r);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
const S = Fr.add(r , Fr.mul(hm, s));
|
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S
|
S: S
|
||||||
@@ -103,17 +97,17 @@ function signMiMCSponge(prv, msg) {
|
|||||||
function signPoseidon(prv, msg) {
|
function signPoseidon(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0,32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = utils.leBuff2int(sBuff);
|
const s = bigInt.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||||
|
|
||||||
const msgBuff = utils.leInt2Buff(msg, 32);
|
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
||||||
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
let r = utils.leBuff2int(rBuff);
|
let r = bigInt.leBuff2int(rBuff);
|
||||||
const Fr = new F1Field(babyJub.subOrder);
|
r = r.mod(babyJub.subOrder);
|
||||||
r = Fr.e(r);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hm = poseidon([R8[0], R8[1], A[0], A[1], msg]);
|
const hash = poseidon.createHash(6, 8, 57);
|
||||||
const S = Fr.add(r , Fr.mul(hm, s));
|
const hm = hash([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
|
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S
|
S: S
|
||||||
@@ -134,14 +128,14 @@ function verify(msg, sig, A) {
|
|||||||
const R8p = babyJub.packPoint(sig.R8);
|
const R8p = babyJub.packPoint(sig.R8);
|
||||||
const Ap = babyJub.packPoint(A);
|
const Ap = babyJub.packPoint(A);
|
||||||
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
||||||
const hm = utils.leBuff2int(hmBuff);
|
const hm = bigInt.leBuff2int(hmBuff);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm,8));
|
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
if (!Pleft[0].equals(Pright[0])) return false;
|
||||||
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
if (!Pleft[1].equals(Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,11 +153,11 @@ function verifyMiMC(msg, sig, A) {
|
|||||||
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
|
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
if (!Pleft[0].equals(Pright[0])) return false;
|
||||||
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
if (!Pleft[1].equals(Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,14 +173,15 @@ function verifyPoseidon(msg, sig, A) {
|
|||||||
if (!babyJub.inCurve(A)) return false;
|
if (!babyJub.inCurve(A)) return false;
|
||||||
if (sig.S>= babyJub.subOrder) return false;
|
if (sig.S>= babyJub.subOrder) return false;
|
||||||
|
|
||||||
const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
const hash = poseidon.createHash(6, 8, 57);
|
||||||
|
const hm = hash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
|
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
if (!Pleft[0].equals(Pright[0])) return false;
|
||||||
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
if (!Pleft[1].equals(Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,24 +199,24 @@ function verifyMiMCSponge(msg, sig, A) {
|
|||||||
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
|
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
if (!Pleft[0].equals(Pright[0])) return false;
|
||||||
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
if (!Pleft[1].equals(Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function packSignature(sig) {
|
function packSignature(sig) {
|
||||||
const R8p = babyJub.packPoint(sig.R8);
|
const R8p = babyJub.packPoint(sig.R8);
|
||||||
const Sp = utils.leInt2Buff(sig.S, 32);
|
const Sp = bigInt.leInt2Buff(sig.S, 32);
|
||||||
return Buffer.concat([R8p, Sp]);
|
return Buffer.concat([R8p, Sp]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpackSignature(sigBuff) {
|
function unpackSignature(sigBuff) {
|
||||||
return {
|
return {
|
||||||
R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
|
R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
|
||||||
S: utils.leBuff2int(sigBuff.slice(32,64))
|
S: bigInt.leBuff2int(sigBuff.slice(32,64))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,17 +154,6 @@ class Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
push(data) {
|
push(data) {
|
||||||
if (typeof data === "number") {
|
|
||||||
let isNeg;
|
|
||||||
if (data<0) {
|
|
||||||
isNeg = true;
|
|
||||||
data = -data;
|
|
||||||
}
|
|
||||||
data = data.toString(16);
|
|
||||||
if (data.length % 2 == 1) data = "0" + data;
|
|
||||||
data = "0x" + data;
|
|
||||||
if (isNeg) data = "-"+data;
|
|
||||||
}
|
|
||||||
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
||||||
if (d.length == 0 || d.length > 32) {
|
if (d.length == 0 || d.length > 32) {
|
||||||
throw new Error("Assertion failed");
|
throw new Error("Assertion failed");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
const G2 = require("snarkjs").bn128.G2;
|
const G2 = require("snarkjs").bn128.G2;
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
|
|
||||||
function toHex256(a) {
|
function toHex256(a) {
|
||||||
@@ -538,7 +539,7 @@ function createCode(P, w) {
|
|||||||
function storeVals() {
|
function storeVals() {
|
||||||
C.push(VAR_POINTS); // p
|
C.push(VAR_POINTS); // p
|
||||||
for (let i=0; i<NPOINTS; i++) {
|
for (let i=0; i<NPOINTS; i++) {
|
||||||
const MP = G2.affine(G2.mulScalar(P, i));
|
const MP = G2.affine(G2.mulScalar(P, bigInt(i)));
|
||||||
for (let j=0; j<2; j++) {
|
for (let j=0; j<2; j++) {
|
||||||
for (let k=0; k<2; k++) {
|
for (let k=0; k<2; k++) {
|
||||||
C.push(toHex256(MP[j][k])); // MP[0][0] p
|
C.push(toHex256(MP[j][k])); // MP[0][0] p
|
||||||
|
|||||||
48
src/mimc7.js
48
src/mimc7.js
@@ -1,9 +1,7 @@
|
|||||||
const Scalar = require("ffjavascript").Scalar;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3Utils = require("web3-utils");
|
||||||
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
const F = bn128.Fr;
|
||||||
exports.F = F;
|
|
||||||
|
|
||||||
const SEED = "mimc";
|
const SEED = "mimc";
|
||||||
const NROUNDS = 91;
|
const NROUNDS = 91;
|
||||||
@@ -11,8 +9,8 @@ const NROUNDS = 91;
|
|||||||
exports.getIV = (seed) => {
|
exports.getIV = (seed) => {
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
const c = Web3Utils.keccak256(seed+"_iv");
|
const c = Web3Utils.keccak256(seed+"_iv");
|
||||||
const cn = Scalar.FromString(Web3Utils.toBN(c).toString());
|
const cn = bigInt(Web3Utils.toBN(c).toString());
|
||||||
const iv = cn.mod(F.p);
|
const iv = cn.mod(F.q);
|
||||||
return iv;
|
return iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -24,26 +22,26 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
for (let i=1; i<nRounds; i++) {
|
for (let i=1; i<nRounds; i++) {
|
||||||
c = Web3Utils.keccak256(c);
|
c = Web3Utils.keccak256(c);
|
||||||
|
|
||||||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
|
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
||||||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
||||||
cts[i] = Scalar.fromString(Web3Utils.toBN(c2).toString());
|
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
||||||
}
|
}
|
||||||
cts[0] = F.e(0);
|
cts[0] = bigInt(0);
|
||||||
return cts;
|
return cts;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cts = exports.getConstants(SEED, 91);
|
const cts = exports.getConstants(SEED, 91);
|
||||||
|
|
||||||
exports.hash = (_x_in, _k) =>{
|
exports.hash = (_x_in, _k) =>{
|
||||||
const x_in = F.e(_x_in);
|
const x_in = bigInt(_x_in);
|
||||||
const k = F.e(_k);
|
const k = bigInt(_k);
|
||||||
let r;
|
let r;
|
||||||
for (let i=0; i<NROUNDS; i++) {
|
for (let i=0; i<NROUNDS; i++) {
|
||||||
const c = cts[i];
|
const c = cts[i];
|
||||||
const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c);
|
const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c);
|
||||||
r = F.pow(t, 7);
|
r = F.exp(t, 7);
|
||||||
}
|
}
|
||||||
return F.add(r, k);
|
return F.affine(F.add(r, k));
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.multiHash = (arr, key) => {
|
exports.multiHash = (arr, key) => {
|
||||||
@@ -59,8 +57,26 @@ exports.multiHash = (arr, key) => {
|
|||||||
r,
|
r,
|
||||||
arr[i]
|
arr[i]
|
||||||
),
|
),
|
||||||
exports.hash(F.e(arr[i]), r)
|
exports.hash(bigInt(arr[i]), r)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return r;
|
return F.affine(r);
|
||||||
|
};
|
||||||
|
|
||||||
|
// hashBuffer performs the MiMC7 hash over a buffer array, splitting the bytes into 31 bytes bigints,
|
||||||
|
// and making chunks of two bigints to perform the MiMC7 hash
|
||||||
|
exports.hashBuffer = (msgBuff) => {
|
||||||
|
const n = 31;
|
||||||
|
const msgArray = [];
|
||||||
|
const fullParts = Math.floor(msgBuff.length / n);
|
||||||
|
for (let i = 0; i < fullParts; i++) {
|
||||||
|
const v = bigInt.leBuff2int(msgBuff.slice(n * i, n * (i + 1)));
|
||||||
|
msgArray.push(v);
|
||||||
|
}
|
||||||
|
if (msgBuff.length % n !== 0) {
|
||||||
|
const v = bigInt.leBuff2int(msgBuff.slice(fullParts * n));
|
||||||
|
msgArray.push(v);
|
||||||
|
}
|
||||||
|
return exports.multiHash(msgArray);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const Scalar = require("ffjavascript").Scalar
|
const bn128 = require("snarkjs").bn128;
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3Utils = require("web3-utils");
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const F = bn128.Fr;
|
||||||
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
|
||||||
|
|
||||||
const SEED = "mimcsponge";
|
const SEED = "mimcsponge";
|
||||||
const NROUNDS = 220;
|
const NROUNDS = 220;
|
||||||
@@ -9,8 +9,8 @@ const NROUNDS = 220;
|
|||||||
exports.getIV = (seed) => {
|
exports.getIV = (seed) => {
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
const c = Web3Utils.keccak256(seed+"_iv");
|
const c = Web3Utils.keccak256(seed+"_iv");
|
||||||
const cn = Scalar.fromString(Web3Utils.toBN(c).toString());
|
const cn = bigInt(Web3Utils.toBN(c).toString());
|
||||||
const iv = cn.mod(F.p);
|
const iv = cn.mod(F.q);
|
||||||
return iv;
|
return iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,35 +22,35 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
for (let i=1; i<nRounds; i++) {
|
for (let i=1; i<nRounds; i++) {
|
||||||
c = Web3Utils.keccak256(c);
|
c = Web3Utils.keccak256(c);
|
||||||
|
|
||||||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
|
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
||||||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
||||||
cts[i] = F.e(Web3Utils.toBN(c2).toString());
|
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
||||||
}
|
}
|
||||||
cts[0] = F.e(0);
|
cts[0] = bigInt(0);
|
||||||
cts[cts.length - 1] = F.e(0);
|
cts[cts.length - 1] = bigInt(0);
|
||||||
return cts;
|
return cts;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cts = exports.getConstants(SEED, NROUNDS);
|
const cts = exports.getConstants(SEED, NROUNDS);
|
||||||
|
|
||||||
exports.hash = (_xL_in, _xR_in, _k) =>{
|
exports.hash = (_xL_in, _xR_in, _k) =>{
|
||||||
let xL = F.e(_xL_in);
|
let xL = bigInt(_xL_in);
|
||||||
let xR = F.e(_xR_in);
|
let xR = bigInt(_xR_in);
|
||||||
const k = F.e(_k);
|
const k = bigInt(_k);
|
||||||
for (let i=0; i<NROUNDS; i++) {
|
for (let i=0; i<NROUNDS; i++) {
|
||||||
const c = cts[i];
|
const c = cts[i];
|
||||||
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c);
|
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c);
|
||||||
const xR_tmp = F.e(xR);
|
const xR_tmp = bigInt(xR);
|
||||||
if (i < (NROUNDS - 1)) {
|
if (i < (NROUNDS - 1)) {
|
||||||
xR = xL;
|
xR = xL;
|
||||||
xL = F.add(xR_tmp, F.pow(t, 5));
|
xL = F.add(xR_tmp, F.exp(t, 5));
|
||||||
} else {
|
} else {
|
||||||
xR = F.add(xR_tmp, F.pow(t, 5));
|
xR = F.add(xR_tmp, F.exp(t, 5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
xL: F.normalize(xL),
|
xL: F.affine(xL),
|
||||||
xR: F.normalize(xR),
|
xR: F.affine(xR),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ exports.multiHash = (arr, key, numOutputs) => {
|
|||||||
let C = F.zero;
|
let C = F.zero;
|
||||||
|
|
||||||
for (let i=0; i<arr.length; i++) {
|
for (let i=0; i<arr.length; i++) {
|
||||||
R = F.add(R, F.e(arr[i]));
|
R = F.add(R, bigInt(arr[i]));
|
||||||
const S = exports.hash(R, C, key);
|
const S = exports.hash(R, C, key);
|
||||||
R = S.xL;
|
R = S.xL;
|
||||||
C = S.xR;
|
C = S.xR;
|
||||||
@@ -79,8 +79,8 @@ exports.multiHash = (arr, key, numOutputs) => {
|
|||||||
outputs.push(R);
|
outputs.push(R);
|
||||||
}
|
}
|
||||||
if (numOutputs == 1) {
|
if (numOutputs == 1) {
|
||||||
return F.normalize(outputs[0]);
|
return F.affine(outputs[0]);
|
||||||
} else {
|
} else {
|
||||||
return outputs.map(x => F.normalize(x));
|
return outputs.map(x => F.affine(x));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
const bn128 = require("snarkjs").bn128;
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const blake2b = require("blake2b");
|
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
|
||||||
|
|
||||||
const GENPOINT_PREFIX = "PedersenGenerator";
|
const GENPOINT_PREFIX = "PedersenGenerator";
|
||||||
const windowSize = 4;
|
const windowSize = 4;
|
||||||
@@ -10,23 +10,13 @@ const nWindowsPerSegment = 50;
|
|||||||
exports.hash = pedersenHash;
|
exports.hash = pedersenHash;
|
||||||
exports.getBasePoint = getBasePoint;
|
exports.getBasePoint = getBasePoint;
|
||||||
|
|
||||||
function baseHash(type, S) {
|
function pedersenHash(msg) {
|
||||||
if (type == "blake") {
|
|
||||||
return createBlakeHash("blake256").update(S).digest();
|
|
||||||
} else if (type == "blake2b") {
|
|
||||||
return Buffer.from(blake2b(32).update(Buffer.from(S)).digest());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function pedersenHash(msg, options) {
|
|
||||||
options = options || {};
|
|
||||||
options.baseHash = options.baseHash || "blake";
|
|
||||||
const bitsPerSegment = windowSize*nWindowsPerSegment;
|
const bitsPerSegment = windowSize*nWindowsPerSegment;
|
||||||
const bits = buffer2bits(msg);
|
const bits = buffer2bits(msg);
|
||||||
|
|
||||||
const nSegments = Math.floor((bits.length - 1)/(windowSize*nWindowsPerSegment)) +1;
|
const nSegments = Math.floor((bits.length - 1)/(windowSize*nWindowsPerSegment)) +1;
|
||||||
|
|
||||||
let accP = [babyJub.F.zero,babyJub.F.one];
|
let accP = [bigInt.zero,bigInt.one];
|
||||||
|
|
||||||
for (let s=0; s<nSegments; s++) {
|
for (let s=0; s<nSegments; s++) {
|
||||||
let nWindows;
|
let nWindows;
|
||||||
@@ -35,32 +25,32 @@ function pedersenHash(msg, options) {
|
|||||||
} else {
|
} else {
|
||||||
nWindows = nWindowsPerSegment;
|
nWindows = nWindowsPerSegment;
|
||||||
}
|
}
|
||||||
let escalar = Scalar.e(0);
|
let escalar = bigInt.zero;
|
||||||
let exp = Scalar.e(1);
|
let exp = bigInt.one;
|
||||||
for (let w=0; w<nWindows; w++) {
|
for (let w=0; w<nWindows; w++) {
|
||||||
let o = s*bitsPerSegment + w*windowSize;
|
let o = s*bitsPerSegment + w*windowSize;
|
||||||
let acc = Scalar.e(1);
|
let acc = bigInt.one;
|
||||||
for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) {
|
for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) {
|
||||||
if (bits[o]) {
|
if (bits[o]) {
|
||||||
acc = Scalar.add(acc, Scalar.shl(Scalar.e(1), b) );
|
acc = acc.add( bigInt.one.shl(b) );
|
||||||
}
|
}
|
||||||
o++;
|
o++;
|
||||||
}
|
}
|
||||||
if (o<bits.length) {
|
if (o<bits.length) {
|
||||||
if (bits[o]) {
|
if (bits[o]) {
|
||||||
acc = Scalar.neg(acc);
|
acc = acc.neg();
|
||||||
}
|
}
|
||||||
o++;
|
o++;
|
||||||
}
|
}
|
||||||
escalar = Scalar.add(escalar, Scalar.mul(acc, exp));
|
escalar = escalar.add(acc.mul(exp));
|
||||||
exp = Scalar.shl(exp, windowSize+1);
|
exp = exp.shl(windowSize+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Scalar.lt(escalar, 0)) {
|
if (escalar.lesser(bigInt.zero)) {
|
||||||
escalar = Scalar.add( escalar, babyJub.subOrder);
|
escalar = babyJub.subOrder.add(escalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
accP = babyJub.addPoint(accP, babyJub.mulPointEscalar(getBasePoint(options.baseHash, s), escalar));
|
accP = babyJub.addPoint(accP, babyJub.mulPointEscalar(getBasePoint(s), escalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
return babyJub.packPoint(accP);
|
return babyJub.packPoint(accP);
|
||||||
@@ -68,13 +58,13 @@ function pedersenHash(msg, options) {
|
|||||||
|
|
||||||
let bases = [];
|
let bases = [];
|
||||||
|
|
||||||
function getBasePoint(baseHashType, pointIdx) {
|
function getBasePoint(pointIdx) {
|
||||||
if (pointIdx<bases.length) return bases[pointIdx];
|
if (pointIdx<bases.length) return bases[pointIdx];
|
||||||
let p= null;
|
let p= null;
|
||||||
let tryIdx = 0;
|
let tryIdx = 0;
|
||||||
while (p==null) {
|
while (p==null) {
|
||||||
const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32);
|
const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32);
|
||||||
const h = baseHash(baseHashType, S);
|
const h = createBlakeHash("blake256").update(S).digest();
|
||||||
h[31] = h[31] & 0xBF; // Set 255th bit to 0 (256th is the signal and 254th is the last possible bit to 1)
|
h[31] = h[31] & 0xBF; // Set 255th bit to 0 (256th is the signal and 254th is the last possible bit to 1)
|
||||||
p = babyJub.unpackPoint(h);
|
p = babyJub.unpackPoint(h);
|
||||||
tryIdx++;
|
tryIdx++;
|
||||||
|
|||||||
@@ -7,15 +7,7 @@ if (typeof process.argv[2] != "undefined") {
|
|||||||
nBases = 5;
|
nBases = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
let baseHash;
|
|
||||||
if (typeof process.argv[3] != "undefined") {
|
|
||||||
baseHash = process.argv[3];
|
|
||||||
} else {
|
|
||||||
baseHash = "blake";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (let i=0; i < nBases; i++) {
|
for (let i=0; i < nBases; i++) {
|
||||||
const p = pedersenHash.getBasePoint(baseHash, i);
|
const p = pedersenHash.getBasePoint(i);
|
||||||
console.log(`[${p[0]},${p[1]}]`);
|
console.log(`[${p[0]},${p[1]}]`);
|
||||||
}
|
}
|
||||||
|
|||||||
176
src/poseidon.js
176
src/poseidon.js
@@ -1,49 +1,157 @@
|
|||||||
|
const bn128 = require("snarkjs").bn128;
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
const blake2b = require('blake2b');
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const F = bn128.Fr;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
|
||||||
const { unstringifyBigInts } = require("ffjavascript").utils;
|
|
||||||
|
|
||||||
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
const SEED = "poseidon";
|
||||||
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
const NROUNDSF = 8;
|
||||||
|
const NROUNDSP = 57;
|
||||||
|
const T = 6;
|
||||||
|
|
||||||
// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
|
function getPseudoRandom(seed, n) {
|
||||||
// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
const res = [];
|
||||||
const { C, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
let input = Buffer.from(seed);
|
||||||
|
let h = blake2b(32).update(input).digest()
|
||||||
|
while (res.length<n) {
|
||||||
|
const n = F.affine(bigInt.leBuff2int(h));
|
||||||
|
res.push(n);
|
||||||
|
h = blake2b(32).update(h).digest()
|
||||||
|
}
|
||||||
|
|
||||||
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
|
return res;
|
||||||
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
|
}
|
||||||
// And rounded up to nearest integer that divides by t
|
|
||||||
const N_ROUNDS_F = 8;
|
|
||||||
const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63];
|
|
||||||
|
|
||||||
const pow5 = a => F.mul(a, F.square(F.square(a, a)));
|
function allDifferent(v) {
|
||||||
|
for (let i=0; i<v.length; i++) {
|
||||||
|
if (v[i].isZero()) return false;
|
||||||
|
for (let j=i+1; j<v.length; j++) {
|
||||||
|
if (v[i].equals(v[j])) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function poseidon(inputs) {
|
exports.getMatrix = (t, seed, nRounds) => {
|
||||||
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
|
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP;
|
||||||
|
if (typeof t === "undefined") t = T;
|
||||||
|
let nonce = "0000";
|
||||||
|
let cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2);
|
||||||
|
while (!allDifferent(cmatrix)) {
|
||||||
|
nonce = (Number(nonce)+1)+"";
|
||||||
|
while(nonce.length<4) nonce = "0"+nonce;
|
||||||
|
cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const M = new Array(t);
|
||||||
|
for (let i=0; i<t; i++) {
|
||||||
|
M[i] = new Array(t);
|
||||||
|
for (let j=0; j<t; j++) {
|
||||||
|
M[i][j] = F.affine(F.inverse(F.sub(cmatrix[i], cmatrix[t+j])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return M;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.getConstants = (t, seed, nRounds) => {
|
||||||
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
|
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP;
|
||||||
|
if (typeof t === "undefined") t = T;
|
||||||
|
const cts = getPseudoRandom(seed+"_constants", nRounds);
|
||||||
|
return cts;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ark(state, c) {
|
||||||
|
for (let j=0; j<state.length; j++ ) {
|
||||||
|
state[j] = F.add(state[j], c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sigma(a) {
|
||||||
|
return F.mul(a, F.square(F.square(a,a)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function mix(state, M) {
|
||||||
|
const newState = new Array(state.length);
|
||||||
|
for (let i=0; i<state.length; i++) {
|
||||||
|
newState[i] = F.zero;
|
||||||
|
for (let j=0; j<state.length; j++) {
|
||||||
|
newState[i] = F.add(newState[i], F.mul(M[i][j], state[j]) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i=0; i<state.length; i++) state[i] = newState[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.createHash = (t, nRoundsF, nRoundsP, seed) => {
|
||||||
|
|
||||||
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
|
if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF;
|
||||||
|
if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP;
|
||||||
|
if (typeof t === "undefined") t = T;
|
||||||
|
|
||||||
|
assert(nRoundsF % 2 == 0);
|
||||||
|
const C = exports.getConstants(t, seed, nRoundsF + nRoundsP);
|
||||||
|
const M = exports.getMatrix(t, seed, nRoundsF + nRoundsP);
|
||||||
|
return function(inputs) {
|
||||||
|
let state = [];
|
||||||
|
assert(inputs.length < t);
|
||||||
assert(inputs.length > 0);
|
assert(inputs.length > 0);
|
||||||
assert(inputs.length < N_ROUNDS_P.length - 1);
|
for (let i=0; i<inputs.length; i++) state[i] = bigInt(inputs[i]);
|
||||||
|
for (let i=inputs.length; i<t; i++) state[i] = F.zero;
|
||||||
|
|
||||||
const t = inputs.length + 1;
|
for (let i=0; i< nRoundsF + nRoundsP; i++) {
|
||||||
const nRoundsF = N_ROUNDS_F;
|
ark(state, C[i]);
|
||||||
const nRoundsP = N_ROUNDS_P[t - 2];
|
if ((i<nRoundsF/2) || (i >= nRoundsF/2 + nRoundsP)) {
|
||||||
|
for (let j=0; j<t; j++) state[j] = sigma(state[j]);
|
||||||
let state = [...inputs.map(a => F.e(a)), F.zero];
|
|
||||||
for (let r = 0; r < nRoundsF + nRoundsP; r++) {
|
|
||||||
state = state.map((a, i) => F.add(a, C[t - 2][r * t + i]));
|
|
||||||
|
|
||||||
if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) {
|
|
||||||
state = state.map(a => pow5(a));
|
|
||||||
} else {
|
} else {
|
||||||
state[0] = pow5(state[0]);
|
state[0] = sigma(state[0]);
|
||||||
|
}
|
||||||
|
mix(state, M);
|
||||||
|
}
|
||||||
|
return F.affine(state[0]);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// hash exposes the generic Poseidon hash function
|
||||||
|
// with nRoundsF:8, nRoundsP: 57, t: 6
|
||||||
|
exports.hash = (arr) => {
|
||||||
|
const poseidonHash = exports.createHash(6, 8, 57);
|
||||||
|
return poseidonHash(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no matrix multiplication in the last round
|
// multiHash splits the bigint array into chunks of five elements
|
||||||
if (r < nRoundsF + nRoundsP - 1) {
|
// and performs the Poseidon hash over the five elements chunks
|
||||||
state = state.map((_, i) =>
|
exports.multiHash = (arr) => {
|
||||||
state.reduce((acc, a, j) => F.add(acc, F.mul(M[t - 2][i][j], a)), F.zero)
|
let r = bigInt(0);
|
||||||
);
|
for (let i=0; i<arr.length; i = i+5) {
|
||||||
|
let fiveElems = [];
|
||||||
|
for (let j=0; j<5; j++) {
|
||||||
|
if (i+j < arr.length) {
|
||||||
|
fiveElems.push(arr[i+j]);
|
||||||
|
} else {
|
||||||
|
fiveElems.push(bigInt(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return F.normalize(state[0]);
|
const ph = exports.hash(fiveElems);
|
||||||
|
r = F.add(r, ph);
|
||||||
}
|
}
|
||||||
|
return F.affine(r);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = poseidon;
|
// hashBuffer performs the Poseidon hash over a buffer array, splitting the bytes into 31 bytes bigints,
|
||||||
|
// and making chunks of five bigints to perform the Poseidon hash
|
||||||
|
exports.hashBuffer = (msgBuff) => {
|
||||||
|
const n = 31;
|
||||||
|
const msgArray = [];
|
||||||
|
const fullParts = Math.floor(msgBuff.length / n);
|
||||||
|
for (let i = 0; i < fullParts; i++) {
|
||||||
|
const v = bigInt.leBuff2int(msgBuff.slice(n * i, n * (i + 1)));
|
||||||
|
msgArray.push(v);
|
||||||
|
}
|
||||||
|
if (msgBuff.length % n !== 0) {
|
||||||
|
const v = bigInt.leBuff2int(msgBuff.slice(fullParts * n));
|
||||||
|
msgArray.push(v);
|
||||||
|
}
|
||||||
|
return exports.multiHash(msgArray);
|
||||||
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,14 +2,14 @@
|
|||||||
// License: LGPL-3.0+
|
// License: LGPL-3.0+
|
||||||
//
|
//
|
||||||
|
|
||||||
|
const Poseidon = require("./poseidon.js");
|
||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
const { unstringifyBigInts } = require("ffjavascript").utils;
|
|
||||||
const Web3Utils = require("web3-utils");
|
|
||||||
|
|
||||||
const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
const SEED = "poseidon";
|
||||||
|
const NROUNDSF = 8;
|
||||||
const N_ROUNDS_F = 8;
|
const NROUNDSP = 57;
|
||||||
const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63];
|
const T = 6;
|
||||||
|
|
||||||
function toHex256(a) {
|
function toHex256(a) {
|
||||||
let S = a.toString(16);
|
let S = a.toString(16);
|
||||||
@@ -17,34 +17,38 @@ function toHex256(a) {
|
|||||||
return "0x" + S;
|
return "0x" + S;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createCode(nInputs) {
|
function createCode(t, nRoundsF, nRoundsP, seed) {
|
||||||
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
|
if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF;
|
||||||
|
if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP;
|
||||||
|
if (typeof t === "undefined") t = T;
|
||||||
|
|
||||||
if (( nInputs<1) || (nInputs>8)) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
|
const K = Poseidon.getConstants(t, seed, nRoundsP + nRoundsF);
|
||||||
const t = nInputs + 1;
|
const M = Poseidon.getMatrix(t, seed, nRoundsP + nRoundsF);
|
||||||
const nRoundsF = N_ROUNDS_F;
|
|
||||||
const nRoundsP = N_ROUNDS_P[t - 2];
|
|
||||||
|
|
||||||
const C = new Contract();
|
const C = new Contract();
|
||||||
|
|
||||||
function saveM() {
|
function saveM() {
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
for (let j=0; j<t; j++) {
|
for (let j=0; j<t; j++) {
|
||||||
C.push(toHex256(M[t-2][i][j]));
|
C.push(toHex256(M[i][j]));
|
||||||
C.push((1+i*t+j)*32);
|
C.push((1+i*t+j)*32);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ark(r) { // st, q
|
function ark(r) {
|
||||||
|
C.push(toHex256(K[r])); // K, st, q
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.dup(t); // q, st, q
|
C.dup(1+t); // q, K, st, q
|
||||||
C.push(toHex256(K[t-2][r*t+i])); // K, q, st, q
|
C.dup(1); // K, q, K, st, q
|
||||||
C.dup(2+i); // st[i], K, q, st, q
|
C.dup(3+i); // st[i], K, q, K, st, q
|
||||||
C.addmod(); // newSt[i], st, q
|
C.addmod(); // newSt[i], K, st, q
|
||||||
C.swap(1 + i); // xx, st, q
|
C.swap(2 + i); // xx, K, st, q
|
||||||
C.pop();
|
C.pop();
|
||||||
}
|
}
|
||||||
|
C.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sigma(p) {
|
function sigma(p) {
|
||||||
@@ -100,13 +104,8 @@ function createCode(nInputs) {
|
|||||||
C.push(0);
|
C.push(0);
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
C.div();
|
C.div();
|
||||||
C.dup(0);
|
C.push("0xc4420fb4"); // poseidon(uint256[])
|
||||||
C.push(Web3Utils.keccak256(`poseidon(uint256[${nInputs}])`).slice(0, 10)); // poseidon(uint256[n])
|
|
||||||
C.eq();
|
C.eq();
|
||||||
C.swap(1);
|
|
||||||
C.push(Web3Utils.keccak256(`poseidon(bytes32[${nInputs}])`).slice(0, 10)); // poseidon(bytes32[n])
|
|
||||||
C.eq();
|
|
||||||
C.or();
|
|
||||||
C.jmpi("start");
|
C.jmpi("start");
|
||||||
C.invalid();
|
C.invalid();
|
||||||
|
|
||||||
@@ -116,16 +115,17 @@ function createCode(nInputs) {
|
|||||||
|
|
||||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||||
|
|
||||||
// Load t values from the call data.
|
// Load 6 values from the call data.
|
||||||
// The function has a single array param param
|
// The function has a single array param param
|
||||||
// [Selector (4)] [item1 (32)] [item2 (32)] ....
|
// [Selector (4)] [Pointer (32)][Length (32)] [data1 (32)] ....
|
||||||
// Stack positions 0-nInputs.
|
// We ignore the pointer and the length and just load 6 values to the state
|
||||||
|
// (Stack positions 0-5) If the array is shorter, we just set zeros.
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.push(0x04+(0x20*(nInputs-i)));
|
C.push(0x44+(0x20*(5-i)));
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i=0; i<nRoundsF+nRoundsP-1; i++) {
|
for (let i=0; i<nRoundsF+nRoundsP; i++) {
|
||||||
ark(i);
|
ark(i);
|
||||||
if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) {
|
if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) {
|
||||||
for (let j=0; j<t; j++) {
|
for (let j=0; j<t; j++) {
|
||||||
@@ -142,13 +142,6 @@ function createCode(nInputs) {
|
|||||||
C.label(strLabel);
|
C.label(strLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
C.push(toHex256(K[t-2][(nRoundsF+nRoundsP-1)*t])); // K, st, q
|
|
||||||
C.dup(t+1); // q, K, st, q
|
|
||||||
C.swap(2); // st[0], K, q, st\st[0]
|
|
||||||
C.addmod(); // st q
|
|
||||||
|
|
||||||
sigma(0);
|
|
||||||
|
|
||||||
C.push("0x00");
|
C.push("0x00");
|
||||||
C.mstore(); // Save it to pos 0;
|
C.mstore(); // Save it to pos 0;
|
||||||
C.push("0x20");
|
C.push("0x20");
|
||||||
@@ -160,42 +153,18 @@ function createCode(nInputs) {
|
|||||||
return C.createTxData();
|
return C.createTxData();
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateABI(nInputs) {
|
module.exports.abi = [
|
||||||
return [
|
|
||||||
{
|
{
|
||||||
"constant": true,
|
"constant": true,
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
"internalType": `bytes32[${nInputs}]`,
|
|
||||||
"name": "input",
|
"name": "input",
|
||||||
"type": `bytes32[${nInputs}]`
|
"type": "uint256[]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "poseidon",
|
"name": "poseidon",
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "pure",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": `uint256[${nInputs}]`,
|
|
||||||
"name": "input",
|
|
||||||
"type": `uint256[${nInputs}]`
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "poseidon",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
"name": "",
|
||||||
"type": "uint256"
|
"type": "uint256"
|
||||||
}
|
}
|
||||||
@@ -205,9 +174,7 @@ function generateABI(nInputs) {
|
|||||||
"type": "function"
|
"type": "function"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.generateABI = generateABI;
|
|
||||||
module.exports.createCode = createCode;
|
module.exports.createCode = createCode;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
16
src/poseidon_printconstants.js
Normal file
16
src/poseidon_printconstants.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
const Poseidon = require("./poseidon.js");
|
||||||
|
|
||||||
|
const C = Poseidon.getConstants();
|
||||||
|
|
||||||
|
let S = "[\n";
|
||||||
|
|
||||||
|
for (let i=0; i<C.length; i++) {
|
||||||
|
S = S + " " + C[i].toString();
|
||||||
|
if (i<C.length-1) S = S + ",";
|
||||||
|
S = S + "\n";
|
||||||
|
}
|
||||||
|
S=S+ "]\n";
|
||||||
|
|
||||||
|
console.log(S);
|
||||||
@@ -1,13 +1,5 @@
|
|||||||
const poseidonGenContract = require("./poseidon_gencontract");
|
const poseidonGenContract = require("./poseidon_gencontract");
|
||||||
|
|
||||||
if (process.argv.length != 3) {
|
|
||||||
console.log("Usage: node poseidon_gencontract.js [numberOfInputs]");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nInputs = Number(process.argv[2]);
|
console.log(poseidonGenContract.createCode(6, 8, 57));
|
||||||
|
|
||||||
console.log(nInputs);
|
|
||||||
|
|
||||||
console.log(poseidonGenContract.createCode(nInputs));
|
|
||||||
|
|
||||||
|
|||||||
62
src/smt.js
62
src/smt.js
@@ -1,6 +1,7 @@
|
|||||||
const Scalar = require("ffjavascript").Scalar;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
const SMTMemDB = require("./smt_memdb");
|
const SMTMemDB = require("./smt_memdb");
|
||||||
const {hash0, hash1, F} = require("./smt_hashes_poseidon");
|
const {hash0, hash1} = require("./smt_hashes_poseidon");
|
||||||
|
|
||||||
class SMT {
|
class SMT {
|
||||||
|
|
||||||
@@ -10,7 +11,18 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_splitBits(_key) {
|
_splitBits(_key) {
|
||||||
const res = Scalar.bits(_key);
|
|
||||||
|
let k = bigInt(_key);
|
||||||
|
const res = [];
|
||||||
|
|
||||||
|
while (!k.isZero()) {
|
||||||
|
if (k.isOdd()) {
|
||||||
|
res.push(true);
|
||||||
|
} else {
|
||||||
|
res.push(false);
|
||||||
|
}
|
||||||
|
k = k.shr(1);
|
||||||
|
}
|
||||||
|
|
||||||
while (res.length<256) res.push(false);
|
while (res.length<256) res.push(false);
|
||||||
|
|
||||||
@@ -18,8 +30,8 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(_key, _newValue) {
|
async update(_key, _newValue) {
|
||||||
const key = Scalar.e(_key);
|
const key = bigInt(_key);
|
||||||
const newValue = F.e(_newValue);
|
const newValue = bigInt(_newValue);
|
||||||
|
|
||||||
|
|
||||||
const resFind = await this.find(key);
|
const resFind = await this.find(key);
|
||||||
@@ -58,16 +70,16 @@ class SMT {
|
|||||||
|
|
||||||
res.newRoot = rtNew;
|
res.newRoot = rtNew;
|
||||||
|
|
||||||
await this.db.multiDel(dels);
|
|
||||||
await this.db.multiIns(ins);
|
await this.db.multiIns(ins);
|
||||||
await this.db.setRoot(rtNew);
|
await this.db.setRoot(rtNew);
|
||||||
this.root = rtNew;
|
this.root = rtNew;
|
||||||
|
await this.db.multiDel(dels);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(_key) {
|
async delete(_key) {
|
||||||
const key = Scalar.e(_key);
|
const key = bigInt(_key);
|
||||||
|
|
||||||
const resFind = await this.find(key);
|
const resFind = await this.find(key);
|
||||||
if (!resFind.found) throw new Error("Key does not exists");
|
if (!resFind.found) throw new Error("Key does not exists");
|
||||||
@@ -87,7 +99,7 @@ class SMT {
|
|||||||
let mixed;
|
let mixed;
|
||||||
if (resFind.siblings.length > 0) {
|
if (resFind.siblings.length > 0) {
|
||||||
const record = await this.db.get(resFind.siblings[resFind.siblings.length - 1]);
|
const record = await this.db.get(resFind.siblings[resFind.siblings.length - 1]);
|
||||||
if ((record.length == 3)&&(F.eq(record[0], F.one))) {
|
if ((record.length == 3)&&(record[0].equals(bigInt.one))) {
|
||||||
mixed = false;
|
mixed = false;
|
||||||
res.oldKey = record[1];
|
res.oldKey = record[1];
|
||||||
res.oldValue = record[2];
|
res.oldValue = record[2];
|
||||||
@@ -96,16 +108,16 @@ class SMT {
|
|||||||
} else if (record.length == 2) {
|
} else if (record.length == 2) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
res.oldKey = key;
|
res.oldKey = key;
|
||||||
res.oldValue = F.zero;
|
res.oldValue = bigInt(0);
|
||||||
res.isOld0 = true;
|
res.isOld0 = true;
|
||||||
rtNew = F.zero;
|
rtNew = bigInt.zero;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Invalid node. Database corrupted");
|
throw new Error("Invalid node. Database corrupted");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rtNew = F.zero;
|
rtNew = bigInt.zero;
|
||||||
res.oldKey = key;
|
res.oldKey = key;
|
||||||
res.oldValue = F.zero;
|
res.oldValue = bigInt(0);
|
||||||
res.isOld0 = true;
|
res.isOld0 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +126,7 @@ class SMT {
|
|||||||
for (let level = resFind.siblings.length-1; level >=0; level--) {
|
for (let level = resFind.siblings.length-1; level >=0; level--) {
|
||||||
let newSibling = resFind.siblings[level];
|
let newSibling = resFind.siblings[level];
|
||||||
if ((level == resFind.siblings.length-1)&&(!res.isOld0)) {
|
if ((level == resFind.siblings.length-1)&&(!res.isOld0)) {
|
||||||
newSibling = F.zero;
|
newSibling = bigInt.zero;
|
||||||
}
|
}
|
||||||
const oldSibling = resFind.siblings[level];
|
const oldSibling = resFind.siblings[level];
|
||||||
if (keyBits[level]) {
|
if (keyBits[level]) {
|
||||||
@@ -123,7 +135,7 @@ class SMT {
|
|||||||
rtOld = hash0(rtOld, oldSibling);
|
rtOld = hash0(rtOld, oldSibling);
|
||||||
}
|
}
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
if (!F.isZero(newSibling)) {
|
if (!newSibling.isZero()) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,8 +164,8 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async insert(_key, _value) {
|
async insert(_key, _value) {
|
||||||
const key = Scalar.e(_key);
|
const key = bigInt(_key);
|
||||||
const value = F.e(_value);
|
const value = bigInt(_value);
|
||||||
let addedOne = false;
|
let addedOne = false;
|
||||||
const res = {};
|
const res = {};
|
||||||
res.oldRoot = this.root;
|
res.oldRoot = this.root;
|
||||||
@@ -171,7 +183,7 @@ class SMT {
|
|||||||
if (!resFind.isOld0) {
|
if (!resFind.isOld0) {
|
||||||
const oldKeyits = this._splitBits(resFind.notFoundKey);
|
const oldKeyits = this._splitBits(resFind.notFoundKey);
|
||||||
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
||||||
res.siblings.push(F.zero);
|
res.siblings.push(bigInt.zero);
|
||||||
}
|
}
|
||||||
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
|
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
|
||||||
res.siblings.push(rtOld);
|
res.siblings.push(rtOld);
|
||||||
@@ -179,7 +191,7 @@ class SMT {
|
|||||||
mixed = false;
|
mixed = false;
|
||||||
} else if (res.siblings.length >0) {
|
} else if (res.siblings.length >0) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
rtOld = F.zero;
|
rtOld = bigInt.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inserts = [];
|
const inserts = [];
|
||||||
@@ -189,7 +201,7 @@ class SMT {
|
|||||||
inserts.push([rt,[1, key, value]] );
|
inserts.push([rt,[1, key, value]] );
|
||||||
|
|
||||||
for (let i=res.siblings.length-1; i>=0; i--) {
|
for (let i=res.siblings.length-1; i>=0; i--) {
|
||||||
if ((i<res.siblings.length-1)&&(!F.isZero(res.siblings[i]))) {
|
if ((i<res.siblings.length-1)&&(!res.siblings[i].isZero())) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
}
|
}
|
||||||
if (mixed) {
|
if (mixed) {
|
||||||
@@ -215,7 +227,7 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (addedOne) res.siblings.pop();
|
if (addedOne) res.siblings.pop();
|
||||||
while ((res.siblings.length>0) && (F.isZero(res.siblings[res.siblings.length-1]))) {
|
while ((res.siblings.length>0) && (res.siblings[res.siblings.length-1].isZero())) {
|
||||||
res.siblings.pop();
|
res.siblings.pop();
|
||||||
}
|
}
|
||||||
res.oldKey = resFind.notFoundKey;
|
res.oldKey = resFind.notFoundKey;
|
||||||
@@ -241,12 +253,12 @@ class SMT {
|
|||||||
if (typeof root === "undefined") root = this.root;
|
if (typeof root === "undefined") root = this.root;
|
||||||
|
|
||||||
let res;
|
let res;
|
||||||
if (F.isZero(root)) {
|
if (root.isZero()) {
|
||||||
res = {
|
res = {
|
||||||
found: false,
|
found: false,
|
||||||
siblings: [],
|
siblings: [],
|
||||||
notFoundKey: key,
|
notFoundKey: key,
|
||||||
notFoundValue: F.zero,
|
notFoundValue: bigInt.zero,
|
||||||
isOld0: true
|
isOld0: true
|
||||||
};
|
};
|
||||||
return res;
|
return res;
|
||||||
@@ -254,8 +266,8 @@ class SMT {
|
|||||||
|
|
||||||
const record = await this.db.get(root);
|
const record = await this.db.get(root);
|
||||||
|
|
||||||
if ((record.length==3)&&(F.eq(record[0],F.one))) {
|
if ((record.length==3)&&(record[0].equals(bigInt.one))) {
|
||||||
if (F.eq(record[1],key)) {
|
if (record[1].equals(key)) {
|
||||||
res = {
|
res = {
|
||||||
found: true,
|
found: true,
|
||||||
siblings: [],
|
siblings: [],
|
||||||
@@ -297,5 +309,3 @@ async function newMemEmptyTrie() {
|
|||||||
|
|
||||||
module.exports.loadFromFile = loadFromFile;
|
module.exports.loadFromFile = loadFromFile;
|
||||||
module.exports.newMemEmptyTrie = newMemEmptyTrie;
|
module.exports.newMemEmptyTrie = newMemEmptyTrie;
|
||||||
module.exports.SMT = SMT;
|
|
||||||
module.exports.SMTMemDB = SMTMemDB;
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
const bigInt = require("big-integer");
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
exports.hash0 = function (left, right) {
|
exports.hash0 = function (left, right) {
|
||||||
return mimc7.multiHash(left, right);
|
return mimc7.multiHash(left, right);
|
||||||
@@ -8,5 +8,3 @@ exports.hash0 = function (left, right) {
|
|||||||
exports.hash1 = function(key, value) {
|
exports.hash1 = function(key, value) {
|
||||||
return mimc7.multiHash([key, value], bigInt.one);
|
return mimc7.multiHash([key, value], bigInt.one);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.F = mimc7.F;
|
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
|
const Poseidon = require("./poseidon");
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const hash = Poseidon.createHash(6, 8, 57);
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
|
||||||
|
|
||||||
const poseidon = require("./poseidon");
|
|
||||||
|
|
||||||
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
|
||||||
|
|
||||||
|
|
||||||
exports.hash0 = function (left, right) {
|
exports.hash0 = function (left, right) {
|
||||||
return poseidon([left, right]);
|
return hash([left, right]);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.hash1 = function(key, value) {
|
exports.hash1 = function(key, value) {
|
||||||
return poseidon([key, value, F.one]);
|
return hash([key, value, bigInt.one]);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.F = F;
|
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
|
||||||
|
|
||||||
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
|
||||||
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
|
||||||
|
|
||||||
class SMTMemDb {
|
class SMTMemDb {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.nodes = {};
|
this.nodes = {};
|
||||||
this.root = F.zero;
|
this.root = bigInt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRoot() {
|
async getRoot() {
|
||||||
@@ -17,13 +12,13 @@ class SMTMemDb {
|
|||||||
|
|
||||||
_key2str(k) {
|
_key2str(k) {
|
||||||
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
|
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
|
||||||
const keyS = k.toString();
|
const keyS = bigInt(k).toString();
|
||||||
return keyS;
|
return keyS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_normalize(n) {
|
_normalize(n) {
|
||||||
for (let i=0; i<n.length; i++) {
|
for (let i=0; i<n.length; i++) {
|
||||||
n[i] = F.e(n[i]);
|
n[i] = bigInt(n[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,14 +27,6 @@ class SMTMemDb {
|
|||||||
return this.nodes[keyS];
|
return this.nodes[keyS];
|
||||||
}
|
}
|
||||||
|
|
||||||
async multiGet(keys) {
|
|
||||||
const promises = [];
|
|
||||||
for (let i=0; i<keys.length; i++) {
|
|
||||||
promises.push(this.get(keys[i]));
|
|
||||||
}
|
|
||||||
return await Promise.all(promises);
|
|
||||||
}
|
|
||||||
|
|
||||||
async setRoot(rt) {
|
async setRoot(rt) {
|
||||||
this.root = rt;
|
this.root = rt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const bigInt = snarkjs.bigInt;
|
||||||
const F1Field = require("ffjavascript").F1Field;
|
|
||||||
const utils = require("ffjavascript").utils;
|
|
||||||
const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
const F = new F1Field(q);
|
|
||||||
|
|
||||||
const tester = require("circom").tester;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
@@ -18,59 +14,60 @@ function print(circuit, w, s) {
|
|||||||
function getBits(v, n) {
|
function getBits(v, n) {
|
||||||
const res = [];
|
const res = [];
|
||||||
for (let i=0; i<n; i++) {
|
for (let i=0; i<n; i++) {
|
||||||
if (Scalar.isOdd(Scalar.shr(v,i))) {
|
if (v.shr(i).isOdd()) {
|
||||||
res.push(F.one);
|
res.push(bigInt.one);
|
||||||
} else {
|
} else {
|
||||||
res.push(F.zero);
|
res.push(bigInt.zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
|
||||||
describe("Aliascheck test", function () {
|
describe("Aliascheck test", () => {
|
||||||
this.timeout(100000);
|
let circuit;
|
||||||
|
|
||||||
let cir;
|
|
||||||
before( async() => {
|
before( async() => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheck_test.circom"));
|
||||||
|
|
||||||
cir = await tester(path.join(__dirname, "circuits", "aliascheck_test.circom"));
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Satisfy the aliastest 0", async () => {
|
it("Satisfy the aliastest 0", async () => {
|
||||||
const inp = getBits(0, 254);
|
const inp = getBits(bigInt.zero, 254);
|
||||||
await cir.calculateWitness({in: inp}, true);
|
circuit.calculateWitness({in: inp});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Satisfy the aliastest 3", async () => {
|
it("Satisfy the aliastest 3", async () => {
|
||||||
const inp = getBits(3, 254);
|
const inp = getBits(bigInt(3), 254);
|
||||||
await cir.calculateWitness({in: inp}, true);
|
circuit.calculateWitness({in: inp});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Satisfy the aliastest q-1", async () => {
|
it("Satisfy the aliastest q-1", async () => {
|
||||||
const inp = getBits(F.minusone, 254);
|
const inp = getBits(q.sub(bigInt.one), 254);
|
||||||
// console.log(JSON.stringify(utils.stringifyBigInts(inp)));
|
circuit.calculateWitness({in: inp});
|
||||||
await cir.calculateWitness({in: inp}, true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not satisfy an input of q", async () => {
|
it("Nhot not satisfy an input of q", async () => {
|
||||||
const inp = getBits(q, 254);
|
const inp = getBits(q, 254);
|
||||||
try {
|
try {
|
||||||
await cir.calculateWitness({in: inp}, true);
|
circuit.calculateWitness({in: inp});
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not satisfy all ones", async () => {
|
it("Nhot not satisfy all ones", async () => {
|
||||||
|
|
||||||
const inp = getBits(Scalar.sub(Scalar.shl(1, 254) , 1) , 254);
|
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
|
||||||
try {
|
try {
|
||||||
await cir.calculateWitness({in: inp}, true);
|
circuit.calculateWitness({in: inp});
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
108
test/babyjub.js
108
test/babyjub.js
@@ -1,93 +1,106 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
const F = require("../src/babyjub.js").F;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const tester = require("circom").tester;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const utils = require("ffjavascript").utils;
|
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
|
||||||
|
|
||||||
describe("Baby Jub test", function () {
|
describe("Baby Jub test", function () {
|
||||||
let circuitAdd;
|
let circuitAdd;
|
||||||
let circuitTest;
|
let circuitTest;
|
||||||
let circuitPbk;
|
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async() => {
|
before( async() => {
|
||||||
circuitAdd = await tester(path.join(__dirname, "circuits", "babyadd_tester.circom"));
|
const cirDefAdd = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom"));
|
||||||
|
circuitAdd = new snarkjs.Circuit(cirDefAdd);
|
||||||
|
console.log("NConstrains BabyAdd: " + circuitAdd.nConstraints);
|
||||||
|
|
||||||
circuitTest = await tester(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
||||||
|
circuitTest = new snarkjs.Circuit(cirDefTest);
|
||||||
|
console.log("NConstrains BabyTest: " + circuitTest.nConstraints);
|
||||||
|
|
||||||
|
const cirDefPbk = await compiler(path.join(__dirname, "circuits", "babypbk_test.circom"));
|
||||||
|
circuitPbk = new snarkjs.Circuit(cirDefPbk);
|
||||||
|
console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints);
|
||||||
|
|
||||||
circuitPbk = await tester(path.join(__dirname, "circuits", "babypbk_test.circom"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add point (0,1) and (0,1)", async () => {
|
it("Should add point (0,1) and (0,1)", async () => {
|
||||||
|
|
||||||
const input={
|
const input={
|
||||||
x1: F.e(0),
|
x1: snarkjs.bigInt(0),
|
||||||
y1: F.e(1),
|
y1: snarkjs.bigInt(1),
|
||||||
x2: F.e(0),
|
x2: snarkjs.bigInt(0),
|
||||||
y2: F.e(1)
|
y2: snarkjs.bigInt(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = await circuitAdd.calculateWitness(input, true);
|
const w = circuitAdd.calculateWitness(input);
|
||||||
|
|
||||||
await circuitAdd.assertOut(w, {xout: F.e(0), yout: F.e(1)});
|
const xout = w[circuitAdd.getSignalIdx("main.xout")];
|
||||||
|
const yout = w[circuitAdd.getSignalIdx("main.yout")];
|
||||||
|
|
||||||
|
assert(xout.equals(0));
|
||||||
|
assert(yout.equals(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 same numbers", async () => {
|
it("Should add 2 same numbers", async () => {
|
||||||
|
|
||||||
const input={
|
const input={
|
||||||
x1: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
y1: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
x2: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
x2: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
y2: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475")
|
y2: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = await circuitAdd.calculateWitness(input, true);
|
const w = circuitAdd.calculateWitness(input);
|
||||||
|
|
||||||
await circuitAdd.assertOut(w, {
|
const xout = w[circuitAdd.getSignalIdx("main.xout")];
|
||||||
xout: F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
const yout = w[circuitAdd.getSignalIdx("main.yout")];
|
||||||
yout: F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889")
|
|
||||||
});
|
|
||||||
|
|
||||||
|
assert(xout.equals(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
|
||||||
|
assert(yout.equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 different numbers", async () => {
|
it("Should add 2 different numbers", async () => {
|
||||||
|
|
||||||
const input={
|
const input={
|
||||||
x1: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
y1: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
x2: F.e("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
x2: snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
||||||
y2: F.e("20819045374670962167435360035096875258406992893633759881276124905556507972311")
|
y2: snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311")
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = await circuitAdd.calculateWitness(input, true);
|
const w = circuitAdd.calculateWitness(input);
|
||||||
|
|
||||||
await circuitAdd.assertOut(w, {
|
const xout = w[circuitAdd.getSignalIdx("main.xout")];
|
||||||
xout: F.e("7916061937171219682591368294088513039687205273691143098332585753343424131937"),
|
const yout = w[circuitAdd.getSignalIdx("main.yout")];
|
||||||
yout: F.e("14035240266687799601661095864649209771790948434046947201833777492504781204499")
|
|
||||||
|
/*
|
||||||
|
console.log(xout.toString());
|
||||||
|
console.log(yout.toString());
|
||||||
|
*/
|
||||||
|
|
||||||
|
assert(xout.equals(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
|
||||||
|
assert(yout.equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should check 0 is a valid poiny", async() => {
|
||||||
|
const w = circuitTest.calculateWitness({x: 0, y:1});
|
||||||
|
assert(circuitTest.checkWitness(w));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check (0,1) is a valid point", async() => {
|
it("Should check 0 is an invalid poiny", async() => {
|
||||||
const w = await circuitTest.calculateWitness({x: 0, y:1}, true);
|
|
||||||
|
|
||||||
await circuitTest.checkConstraints(w);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should check (1,0) is an invalid point", async() => {
|
|
||||||
try {
|
try {
|
||||||
await circuitTest.calculateWitness({x: 1, y: 0}, true);
|
circuitTest.calculateWitness({x: 1, y: 0});
|
||||||
assert(false, "Should be a valid point");
|
assert(false, "Should be a valid point");
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message) );
|
assert.equal(err.message, "Constraint doesn't match: 168700 != 1");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -95,19 +108,18 @@ describe("Baby Jub test", function () {
|
|||||||
|
|
||||||
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
||||||
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
||||||
const S = Scalar.shr(utils.leBuff2int(pvk), 3);
|
const S = bigInt.leBuff2int(pvk).shr(3);
|
||||||
|
|
||||||
const A = eddsa.prv2pub(rawpvk);
|
const A = eddsa.prv2pub(rawpvk);
|
||||||
|
|
||||||
const input = {
|
const input = {
|
||||||
in : S
|
in : S,
|
||||||
};
|
Ax : A[0],
|
||||||
|
Ay : A[1]
|
||||||
|
}
|
||||||
|
|
||||||
const w = await circuitPbk.calculateWitness(input, true);
|
const w = circuitPbk.calculateWitness(input);
|
||||||
|
assert(circuitPbk.checkWitness(w));
|
||||||
await circuitPbk.assertOut(w, {Ax : A[0], Ay: A[1]});
|
|
||||||
|
|
||||||
await circuitPbk.checkConstraints(w);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
const babyjub = require("../src/babyjub.js");
|
const babyjub = require("../src/babyjub.js");
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
@@ -14,16 +16,16 @@ describe("Baby Jub js test", function () {
|
|||||||
it("Should add point (0,1) and (0,1)", () => {
|
it("Should add point (0,1) and (0,1)", () => {
|
||||||
|
|
||||||
const p1 = [
|
const p1 = [
|
||||||
babyjub.F.e(0),
|
snarkjs.bigInt(0),
|
||||||
babyjub.F.e(1)];
|
snarkjs.bigInt(1)];
|
||||||
const p2 = [
|
const p2 = [
|
||||||
babyjub.F.e(0),
|
snarkjs.bigInt(0),
|
||||||
babyjub.F.e(1)
|
snarkjs.bigInt(1)
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = babyjub.addPoint(p1, p2);
|
const out = babyjub.addPoint(p1, p2)
|
||||||
assert(babyjub.F.eq(out[0], babyjub.F.zero));
|
assert(out[0].equals(0));
|
||||||
assert(babyjub.F.eq(out[1], babyjub.F.one));
|
assert(out[1].equals(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should base be 8*generator", () => {
|
it("Should base be 8*generator", () => {
|
||||||
@@ -32,50 +34,50 @@ describe("Baby Jub js test", function () {
|
|||||||
res = babyjub.addPoint(res, res);
|
res = babyjub.addPoint(res, res);
|
||||||
res = babyjub.addPoint(res, res);
|
res = babyjub.addPoint(res, res);
|
||||||
|
|
||||||
assert(babyjub.F.eq(res[0], babyjub.Base8[0]));
|
assert(res[0].equals(babyjub.Base8[0]));
|
||||||
assert(babyjub.F.eq(res[1], babyjub.Base8[1]));
|
assert(res[1].equals(babyjub.Base8[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 same numbers", () => {
|
it("Should add 2 same numbers", () => {
|
||||||
|
|
||||||
const p1 = [
|
const p1 = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
const p2 = [
|
const p2 = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = babyjub.addPoint(p1, p2);
|
const out = babyjub.addPoint(p1, p2)
|
||||||
assert(babyjub.F.eq(out[0], babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
|
assert(out[0].equals(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
|
||||||
assert(babyjub.F.eq(out[1], babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
|
assert(out[1].equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 different numbers", () => {
|
it("Should add 2 different numbers", () => {
|
||||||
|
|
||||||
const p1 = [
|
const p1 = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
const p2 = [
|
const p2 = [
|
||||||
babyjub.F.e("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
||||||
babyjub.F.e("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
|
snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = babyjub.addPoint(p1, p2);
|
const out = babyjub.addPoint(p1, p2)
|
||||||
assert(babyjub.F.eq(out[0], babyjub.F.e("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
|
|
||||||
assert(babyjub.F.eq(out[1], babyjub.F.e("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
|
|
||||||
|
|
||||||
|
assert(out[0].equals(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
|
||||||
|
assert(out[1].equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should mulPointEscalar 0", () => {
|
it("should mulPointEscalar 0", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const r = babyjub.mulPointEscalar(p, 3);
|
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("3"));
|
||||||
let r2 = babyjub.addPoint(p, p);
|
let r2 = babyjub.addPoint(p, p);
|
||||||
r2 = babyjub.addPoint(r2, p);
|
r2 = babyjub.addPoint(r2, p);
|
||||||
assert.equal(r2[0].toString(), r[0].toString());
|
assert.equal(r2[0].toString(), r[0].toString());
|
||||||
@@ -86,65 +88,65 @@ describe("Baby Jub js test", function () {
|
|||||||
|
|
||||||
it("should mulPointEscalar 1", () => {
|
it("should mulPointEscalar 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const r = babyjub.mulPointEscalar(p, Scalar.fromString("14035240266687799601661095864649209771790948434046947201833777492504781204499"));
|
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"));
|
||||||
assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605");
|
assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605");
|
||||||
assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339");
|
assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should mulPointEscalar 2", () => {
|
it("should mulPointEscalar 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const r = babyjub.mulPointEscalar(p, Scalar.fromString("20819045374670962167435360035096875258406992893633759881276124905556507972311"));
|
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"));
|
||||||
assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983");
|
assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983");
|
||||||
assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662");
|
assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inCurve 1", () => {
|
it("should inCurve 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inCurve(p));
|
assert(babyjub.inCurve(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inCurve 2", () => {
|
it("should inCurve 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inCurve(p));
|
assert(babyjub.inCurve(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inSubgroup 1", () => {
|
it("should inSubgroup 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inSubgroup(p));
|
assert(babyjub.inSubgroup(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inSubgroup 2", () => {
|
it("should inSubgroup 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inSubgroup(p));
|
assert(babyjub.inSubgroup(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should packPoint - unpackPoint 1", () => {
|
it("should packPoint - unpackPoint 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
const buf = babyjub.packPoint(p);
|
const buf = babyjub.packPoint(p);
|
||||||
assert.equal(buf.toString("hex"), "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85");
|
assert.equal(buf.toString('hex'), '53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85');
|
||||||
const p2 = babyjub.unpackPoint(buf);
|
const p2 = babyjub.unpackPoint(buf);
|
||||||
assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268");
|
assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268");
|
||||||
assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475");
|
assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475");
|
||||||
@@ -152,11 +154,11 @@ describe("Baby Jub js test", function () {
|
|||||||
|
|
||||||
it("should packPoint - unpackPoint 2", () => {
|
it("should packPoint - unpackPoint 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
const buf = babyjub.packPoint(p);
|
const buf = babyjub.packPoint(p);
|
||||||
assert.equal(buf.toString("hex"), "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709");
|
assert.equal(buf.toString('hex'), 'e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709');
|
||||||
const p2 = babyjub.unpackPoint(buf);
|
const p2 = babyjub.unpackPoint(buf);
|
||||||
assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365");
|
assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365");
|
||||||
assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889");
|
assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889");
|
||||||
|
|||||||
@@ -1,52 +1,55 @@
|
|||||||
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const assert = chai.assert;
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
|
||||||
const tester = require("circom").tester;
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkSub(_a,_b, circuit) {
|
function checkSub(_a,_b, circuit) {
|
||||||
let a=Scalar.e(_a);
|
let a=bigInt(_a);
|
||||||
let b=Scalar.e(_b);
|
let b=bigInt(_b);
|
||||||
if (Scalar.lt(a, 0)) a = Scalar.add(a, Scalar.shl(1, 16));
|
if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shl(16));
|
||||||
if (Scalar.lt(b, 0)) b = Scalar.add(b, Scalar.shl(1, 16));
|
if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shl(16));
|
||||||
const w = await circuit.calculateWitness({a: a, b: b}, true);
|
const w = circuit.calculateWitness({a: a, b: b});
|
||||||
|
|
||||||
let res = Scalar.sub(a, b);
|
let res = a.sub(b);
|
||||||
if (Scalar.lt(res, 0)) res = Scalar.add(res, Scalar.shl(1, 16));
|
if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shl(16));
|
||||||
|
assert( w[circuit.getSignalIdx("main.out")].equals(bigInt(res)) );
|
||||||
await circuit.assertOut(w, {out: res});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("BinSub test", function () {
|
describe("BinSub test", () => {
|
||||||
|
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
let circuit;
|
let circuit;
|
||||||
before( async() => {
|
before( async() => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "binsub_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "binsub_test.circom"));
|
||||||
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains BinSub: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check variuos ege cases", async () => {
|
it("Should check variuos ege cases", async () => {
|
||||||
await checkSub(0,0, circuit);
|
checkSub(0,0, circuit);
|
||||||
await checkSub(1,0, circuit);
|
checkSub(1,0, circuit);
|
||||||
await checkSub(-1,0, circuit);
|
checkSub(-1,0, circuit);
|
||||||
await checkSub(2,1, circuit);
|
checkSub(2,1, circuit);
|
||||||
await checkSub(2,2, circuit);
|
checkSub(2,2, circuit);
|
||||||
await checkSub(2,3, circuit);
|
checkSub(2,3, circuit);
|
||||||
await checkSub(2,-1, circuit);
|
checkSub(2,-1, circuit);
|
||||||
await checkSub(2,-2, circuit);
|
checkSub(2,-2, circuit);
|
||||||
await checkSub(2,-3, circuit);
|
checkSub(2,-3, circuit);
|
||||||
await checkSub(-2,-3, circuit);
|
checkSub(-2,-3, circuit);
|
||||||
await checkSub(-2,-2, circuit);
|
checkSub(-2,-2, circuit);
|
||||||
await checkSub(-2,-1, circuit);
|
checkSub(-2,-1, circuit);
|
||||||
await checkSub(-2,0, circuit);
|
checkSub(-2,0, circuit);
|
||||||
await checkSub(-2,1, circuit);
|
checkSub(-2,1, circuit);
|
||||||
await checkSub(-2,2, circuit);
|
checkSub(-2,2, circuit);
|
||||||
await checkSub(-2,3, circuit);
|
checkSub(-2,3, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,35 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const crypto = require("crypto");
|
||||||
|
|
||||||
const tester = require("circom").tester;
|
const compiler = require("circom");
|
||||||
|
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("Binary sum test", function () {
|
describe("Sum test", () => {
|
||||||
|
|
||||||
this.timeout(100000000);
|
|
||||||
|
|
||||||
it("Should create a constant circuit", async () => {
|
it("Should create a constant circuit", async () => {
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "constants_test.circom"));
|
|
||||||
await circuit.loadConstraints();
|
|
||||||
|
|
||||||
assert.equal(circuit.nVars, 2);
|
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
|
||||||
assert.equal(circuit.constraints.length, 1);
|
assert.equal(cirDef.nVars, 2);
|
||||||
|
|
||||||
const witness = await circuit.calculateWitness({ "in": Fr.e("d807aa98", 16)}, true);
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
assert(Fr.eq(witness[0],Fr.e(1)));
|
const witness = circuit.calculateWitness({ "in": "0xd807aa98" });
|
||||||
assert(Fr.eq(witness[1],Fr.e("d807aa98", 16)));
|
|
||||||
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
|
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
|
||||||
});
|
});
|
||||||
it("Should create a sum circuit", async () => {
|
it("Should create a sum circuit", async () => {
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "sum_test.circom"));
|
|
||||||
await circuit.loadConstraints();
|
|
||||||
|
|
||||||
assert.equal(circuit.constraints.length, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
|
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
|
||||||
|
assert.equal(cirDef.nVars, 101);
|
||||||
|
|
||||||
const witness = await circuit.calculateWitness({ "a": "111", "b": "222" }, true);
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
assert(Fr.eq(witness[0],Fr.e(1)));
|
const witness = circuit.calculateWitness({ "a": "111", "b": "222" });
|
||||||
assert(Fr.eq(witness[1],Fr.e("333")));
|
|
||||||
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
|
assert(witness[1].equals(snarkjs.bigInt("333")));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ template A() {
|
|||||||
signal input b;
|
signal input b;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
var i;
|
|
||||||
|
|
||||||
component n2ba = Num2Bits(16);
|
component n2ba = Num2Bits(16);
|
||||||
component n2bb = Num2Bits(16);
|
component n2bb = Num2Bits(16);
|
||||||
component sub = BinSub(16);
|
component sub = BinSub(16);
|
||||||
@@ -16,12 +14,9 @@ template A() {
|
|||||||
n2ba.in <== a;
|
n2ba.in <== a;
|
||||||
n2bb.in <== b;
|
n2bb.in <== b;
|
||||||
|
|
||||||
for (i=0; i<16; i++) {
|
for (var i=0; i<16; i++) {
|
||||||
sub.in[0][i] <== n2ba.out[i];
|
sub.in[0][i] <== n2ba.out[i];
|
||||||
sub.in[1][i] <== n2bb.out[i];
|
sub.in[1][i] <== n2bb.out[i];
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<16; i++) {
|
|
||||||
b2n.in[i] <== sub.out[i];
|
b2n.in[i] <== sub.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ template Main() {
|
|||||||
var i;
|
var i;
|
||||||
|
|
||||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||||
|
|
||||||
component escalarMul = EscalarMul(256, base);
|
component escalarMul = EscalarMul(256, base);
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ template Main() {
|
|||||||
signal input in;
|
signal input in;
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||||
|
|
||||||
|
|
||||||
component n2b = Num2Bits(253);
|
component n2b = Num2Bits(253);
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ template Main() {
|
|||||||
|
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||||
|
|
||||||
component escalarMul = EscalarMul(256, base);
|
component escalarMul = EscalarMul(256, base);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ template Main() {
|
|||||||
signal input e;
|
signal input e;
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
include "../../circuits/escalarmulw4table.circom";
|
include "../../circuits/escalarmulw4table.circom";
|
||||||
|
|
||||||
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||||
|
|
||||||
component main = EscalarMulW4Table(base, 0);
|
component main = EscalarMulW4Table(base, 0);
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ include "../../circuits/escalarmulw4table.circom";
|
|||||||
template Main() {
|
template Main() {
|
||||||
signal input in;
|
signal input in;
|
||||||
signal output out[16][2];
|
signal output out[16][2];
|
||||||
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||||
|
|
||||||
var escalarMul[16][2] = EscalarMulW4Table(base, 0);
|
component escalarMul = EscalarMulW4Table(base, 0);
|
||||||
for (var i=0; i<16; i++) {
|
for (var i=0; i<16; i++) {
|
||||||
out[i][0] <== escalarMul[i][0]*in;
|
out[i][0] <== escalarMul.out[i][0]*in;
|
||||||
out[i][1] <== escalarMul[i][1]*in;
|
out[i][1] <== escalarMul.out[i][1]*in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ include "../../circuits/escalarmulw4table.circom";
|
|||||||
template Main() {
|
template Main() {
|
||||||
signal input in;
|
signal input in;
|
||||||
signal output out[16][2];
|
signal output out[16][2];
|
||||||
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||||
|
|
||||||
var escalarMul[16][2] = EscalarMulW4Table(base, 3);
|
component escalarMul = EscalarMulW4Table(base, 3);
|
||||||
for (var i=0; i<16; i++) {
|
for (var i=0; i<16; i++) {
|
||||||
out[i][0] <== escalarMul[i][0]*in;
|
out[i][0] <== escalarMul.out[i][0]*in;
|
||||||
out[i][1] <== escalarMul[i][1]*in;
|
out[i][1] <== escalarMul.out[i][1]*in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
include "../../circuits/poseidon.circom"
|
|
||||||
|
|
||||||
component main = Poseidon(2);
|
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
include "../../circuits/poseidon.circom"
|
include "../../circuits/poseidon.circom"
|
||||||
|
|
||||||
component main = Poseidon(5);
|
component main = Poseidon(2, 6, 8, 57);
|
||||||
@@ -6,8 +6,6 @@ template A() {
|
|||||||
signal input b;
|
signal input b;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
var i;
|
|
||||||
|
|
||||||
component n2ba = Num2Bits(32);
|
component n2ba = Num2Bits(32);
|
||||||
component n2bb = Num2Bits(32);
|
component n2bb = Num2Bits(32);
|
||||||
component sum = BinSum(32,2);
|
component sum = BinSum(32,2);
|
||||||
@@ -16,12 +14,9 @@ template A() {
|
|||||||
n2ba.in <== a;
|
n2ba.in <== a;
|
||||||
n2bb.in <== b;
|
n2bb.in <== b;
|
||||||
|
|
||||||
for (i=0; i<32; i++) {
|
for (var i=0; i<32; i++) {
|
||||||
sum.in[0][i] <== n2ba.out[i];
|
sum.in[0][i] <== n2ba.out[i];
|
||||||
sum.in[1][i] <== n2bb.out[i];
|
sum.in[1][i] <== n2bb.out[i];
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<32; i++) {
|
|
||||||
b2n.in[i] <== sum.out[i];
|
b2n.in[i] <== sum.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,185 +1,193 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const crypto = require("crypto");
|
||||||
|
|
||||||
const tester = require("circom").tester;
|
const compiler = require("circom");
|
||||||
|
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("Comparators test", function () {
|
describe("Sum test", () => {
|
||||||
|
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
it("Should create a iszero circuit", async() => {
|
it("Should create a iszero circuit", async() => {
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "iszero.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "iszero.circom"));
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = await circuit.calculateWitness({ "in": 111}, true);
|
witness = circuit.calculateWitness({ "in": 111});
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": 0 }, true);
|
witness = circuit.calculateWitness({ "in": 0 });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
});
|
});
|
||||||
it("Should create a isequal circuit", async() => {
|
it("Should create a isequal circuit", async() => {
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "isequal.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "isequal.circom"));
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = await circuit.calculateWitness({ "in": [111,222] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "111", "in[1]": "222" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
|
witness = circuit.calculateWitness({ "in[0]": "444", "in[1]": "444" });
|
||||||
witness = await circuit.calculateWitness({ "in": [444,444] }, true);
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
|
||||||
});
|
});
|
||||||
it("Should create a comparison lessthan", async() => {
|
it("Should create a comparison lessthan", async() => {
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "lessthan.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "lessthan.circom"));
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = await circuit.calculateWitness({ "in": [333,444] }), true;
|
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
});
|
});
|
||||||
it("Should create a comparison lesseqthan", async() => {
|
it("Should create a comparison lesseqthan", async() => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "lesseqthan.circom"));
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "lesseqthan.circom"));
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
});
|
});
|
||||||
it("Should create a comparison greaterthan", async() => {
|
it("Should create a comparison greaterthan", async() => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "greaterthan.circom"));
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "greaterthan.circom"));
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
});
|
});
|
||||||
it("Should create a comparison greatereqthan", async() => {
|
it("Should create a comparison greatereqthan", async() => {
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "greatereqthan.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "greatereqthan.circom"));
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstraints BalancesUpdater: " + circuit.nConstraints);
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(0)));
|
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
|
|
||||||
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
||||||
assert(Fr.eq(witness[0], Fr.e(1)));
|
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||||
assert(Fr.eq(witness[1], Fr.e(1)));
|
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
const tester = require("circom").tester;
|
const compiler = require("circom");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
// const crypto = require("crypto");
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
@@ -18,9 +20,9 @@ function buffer2bits(buff) {
|
|||||||
for (let i=0; i<buff.length; i++) {
|
for (let i=0; i<buff.length; i++) {
|
||||||
for (let j=0; j<8; j++) {
|
for (let j=0; j<8; j++) {
|
||||||
if ((buff[i]>>j)&1) {
|
if ((buff[i]>>j)&1) {
|
||||||
res.push(Fr.one);
|
res.push(bigInt.one);
|
||||||
} else {
|
} else {
|
||||||
res.push(Fr.zero);
|
res.push(bigInt.zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +36,11 @@ describe("EdDSA test", function () {
|
|||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "eddsa_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsa_test.circom"));
|
||||||
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains EdDSA: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign a single 10 bytes from 0 to 9", async () => {
|
it("Sign a single 10 bytes from 0 to 9", async () => {
|
||||||
@@ -60,8 +66,9 @@ describe("EdDSA test", function () {
|
|||||||
const sBits = buffer2bits(pSignature.slice(32, 64));
|
const sBits = buffer2bits(pSignature.slice(32, 64));
|
||||||
const aBits = buffer2bits(pPubKey);
|
const aBits = buffer2bits(pPubKey);
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits}, true);
|
const w = circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits});
|
||||||
|
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const utils = require("ffjavascript").utils;
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
describe("EdDSA js test", function () {
|
describe("EdDSA js test", function () {
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ describe("EdDSA js test", function () {
|
|||||||
|
|
||||||
it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => {
|
it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => {
|
||||||
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
||||||
const msg = utils.leBuff2int(msgBuf);
|
const msg = bigInt.leBuff2int(msgBuf);
|
||||||
|
|
||||||
// const prvKey = crypto.randomBytes(32);
|
// const prvKey = crypto.randomBytes(32);
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ describe("EdDSA js test", function () {
|
|||||||
|
|
||||||
it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => {
|
it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => {
|
||||||
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
||||||
const msg = utils.leBuff2int(msgBuf);
|
const msg = bigInt.leBuff2int(msgBuf);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@@ -67,12 +68,12 @@ describe("EdDSA js test", function () {
|
|||||||
assert.equal(signature.R8[1].toString(),
|
assert.equal(signature.R8[1].toString(),
|
||||||
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
||||||
assert.equal(signature.S.toString(),
|
assert.equal(signature.S.toString(),
|
||||||
"938949321795232811108166733391487122595698117244126885899082887611217406272");
|
"248298168863866362217836334079793350221620631973732197668910946177382043688");
|
||||||
|
|
||||||
const pSignature = eddsa.packSignature(signature);
|
const pSignature = eddsa.packSignature(signature);
|
||||||
assert.equal(pSignature.toString("hex"), ""+
|
assert.equal(pSignature.toString("hex"), ""+
|
||||||
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
||||||
"40e930f04ce3a13bdca883639e77d1a0cd52b5ed0666df8a201df1fe2d6d1302");
|
"28506bce274aa1b3f7e7c2fd7e4fe09bff8f9aa37a42def7994e98f322888c00");
|
||||||
|
|
||||||
const uSignature = eddsa.unpackSignature(pSignature);
|
const uSignature = eddsa.unpackSignature(pSignature);
|
||||||
assert(eddsa.verifyPoseidon(msg, uSignature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, uSignature, pubKey));
|
||||||
|
|||||||
@@ -1,25 +1,29 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
describe("EdDSA MiMC test", function () {
|
describe("EdDSA MiMC test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
|
||||||
|
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains EdDSA MiMC: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign a single number", async () => {
|
it("Sign a single number", async () => {
|
||||||
const msg = Fr.e(1234);
|
const msg = bigInt(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@@ -29,22 +33,20 @@ describe("EdDSA MiMC test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0],
|
R8x: signature.R8[0],
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg}, true);
|
M: msg});
|
||||||
|
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
|
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Detect Invalid signature", async () => {
|
it("Detect Invalid signature", async () => {
|
||||||
const msg = Fr.e(1234);
|
const msg = bigInt(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@@ -55,23 +57,23 @@ describe("EdDSA MiMC test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||||
try {
|
try {
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
R8x: signature.R8[0].add(bigInt(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg}, true);
|
M: msg});
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("Test a dissabled circuit with a bad signature", async () => {
|
it("Test a dissabled circuit with a bad signature", async () => {
|
||||||
const msg = Fr.e(1234);
|
const msg = bigInt(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@@ -82,16 +84,15 @@ describe("EdDSA MiMC test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
enabled: 0,
|
enabled: 0,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
R8x: signature.R8[0].add(bigInt(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg}, true);
|
M: msg});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
|
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,25 +1,29 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const compiler = require("circom");
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
describe("EdDSA Poseidon test", function () {
|
describe("EdDSA Poseidon test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsaposeidon_test.circom"));
|
||||||
|
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "eddsaposeidon_test.circom"));
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains EdDSA Poseidon: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign a single number", async () => {
|
it("Sign a single number", async () => {
|
||||||
const msg = Fr.e(1234);
|
const msg = bigInt(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@@ -29,25 +33,20 @@ describe("EdDSA Poseidon test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
||||||
|
|
||||||
const input = {
|
const w = circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0],
|
R8x: signature.R8[0],
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg
|
M: msg});
|
||||||
};
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(utils.stringifyBigInts(input)));
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness(input, true);
|
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Detect Invalid signature", async () => {
|
it("Detect Invalid signature", async () => {
|
||||||
const msg = Fr.e(1234);
|
const msg = bigInt(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@@ -58,23 +57,23 @@ describe("EdDSA Poseidon test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
||||||
try {
|
try {
|
||||||
await circuit.calculateWitness({
|
circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
R8x: signature.R8[0].add(bigInt(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg}, true);
|
M: msg});
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("Test a dissabled circuit with a bad signature", async () => {
|
it("Test a dissabled circuit with a bad signature", async () => {
|
||||||
const msg = Fr.e(1234);
|
const msg = bigInt(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@@ -85,15 +84,15 @@ describe("EdDSA Poseidon test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
enabled: 0,
|
enabled: 0,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
R8x: signature.R8[0].add(bigInt(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg}, true);
|
M: msg});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,115 +1,168 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const compiler = require("circom");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
|
||||||
|
const q=bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
function addPoint(a,b) {
|
||||||
|
const cta = bigInt("168700");
|
||||||
|
const d = bigInt("168696");
|
||||||
|
|
||||||
|
const res = [];
|
||||||
|
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt.one + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
|
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt.one - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("Exponentioation test", function () {
|
describe("Exponentioation test", () => {
|
||||||
|
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
it("Should generate the Exponentiation table in k=0", async () => {
|
it("Should generate the Exponentiation table in k=0", async () => {
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({in: 1});
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
// assert.equal(cirDef.nVars, 2);
|
||||||
|
|
||||||
let g = [
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
|
||||||
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
|
||||||
];
|
|
||||||
|
|
||||||
let dbl= [Fr.e("0"), Fr.e("1")];
|
console.log("NConstrains: " + circuit.nConstraints);
|
||||||
|
|
||||||
const expectedOut = [];
|
const w = circuit.calculateWitness({in: 1});
|
||||||
|
|
||||||
|
let g = [bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
|
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
|
||||||
|
|
||||||
|
dbl= [bigInt("0"), snarkjs.bigInt("1")];
|
||||||
|
|
||||||
for (let i=0; i<16; i++) {
|
for (let i=0; i<16; i++) {
|
||||||
|
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
||||||
|
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
||||||
|
/*
|
||||||
|
console.log(xout1.toString());
|
||||||
|
console.log(yout1.toString());
|
||||||
|
console.log(dbl[0]);
|
||||||
|
console.log(dbl[1]);
|
||||||
|
*/
|
||||||
|
assert(xout1.equals(dbl[0]));
|
||||||
|
assert(yout1.equals(dbl[1]));
|
||||||
|
|
||||||
expectedOut.push(dbl);
|
dbl = addPoint([xout1, yout1],g);
|
||||||
dbl = babyJub.addPoint(dbl,g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: expectedOut});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate the Exponentiation table in k=3", async () => {
|
it("Should generate the Exponentiation table in k=3", async () => {
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({in: 1});
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
// assert.equal(cirDef.nVars, 2);
|
||||||
|
|
||||||
let g = [
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
|
||||||
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
console.log("NConstrains: " + circuit.nConstraints);
|
||||||
];
|
|
||||||
|
const w = circuit.calculateWitness({in: 1});
|
||||||
|
|
||||||
|
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
|
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
|
||||||
|
|
||||||
for (let i=0; i<12;i++) {
|
for (let i=0; i<12;i++) {
|
||||||
g = babyJub.addPoint(g,g);
|
g = addPoint(g,g);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dbl= [Fr.e("0"), Fr.e("1")];
|
dbl= [snarkjs.bigInt("0"), snarkjs.bigInt("1")];
|
||||||
|
|
||||||
const expectedOut = [];
|
|
||||||
|
|
||||||
for (let i=0; i<16; i++) {
|
for (let i=0; i<16; i++) {
|
||||||
expectedOut.push(dbl);
|
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
||||||
|
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
||||||
|
|
||||||
dbl = babyJub.addPoint(dbl,g);
|
/*
|
||||||
|
console.log(xout1.toString());
|
||||||
|
console.log(yout1.toString());
|
||||||
|
console.log(dbl[0]);
|
||||||
|
console.log(dbl[1]);
|
||||||
|
*/
|
||||||
|
assert(xout1.equals(dbl[0]));
|
||||||
|
assert(yout1.equals(dbl[1]));
|
||||||
|
|
||||||
|
dbl = addPoint([xout1, yout1],g);
|
||||||
}
|
}
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: expectedOut});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should exponentiate g^31", async () => {
|
it("Should exponentiate g^31", async () => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test.circom"));
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "escalarmul_test.circom"));
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({"in": 31});
|
// assert.equal(cirDef.nVars, 2);
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
let g = [
|
console.log("NConstrains: " + circuit.nConstraints);
|
||||||
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
|
||||||
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
|
||||||
];
|
|
||||||
|
|
||||||
let c = [Fr.e(0), Fr.e(1)];
|
const w = circuit.calculateWitness({"in": 31});
|
||||||
|
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
|
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
|
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
|
||||||
|
|
||||||
|
let c = [0n, 1n];
|
||||||
|
|
||||||
for (let i=0; i<31;i++) {
|
for (let i=0; i<31;i++) {
|
||||||
c = babyJub.addPoint(c,g);
|
c = addPoint(c,g);
|
||||||
}
|
}
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: c});
|
const xout = w[circuit.getSignalIdx(`main.out[0]`)];
|
||||||
|
const yout = w[circuit.getSignalIdx(`main.out[1]`)];
|
||||||
|
|
||||||
const w2 = await circuit.calculateWitness({"in": Fr.add(Fr.shl(Fr.e(1), Fr.e(252)),Fr.one)});
|
/*
|
||||||
|
console.log(xout.toString());
|
||||||
|
console.log(yout.toString());
|
||||||
|
*/
|
||||||
|
assert(xout.equals(c[0]));
|
||||||
|
assert(yout.equals(c[1]));
|
||||||
|
|
||||||
|
console.log("-------")
|
||||||
|
const w2 = circuit.calculateWitness({"in": (1n<<252n)+1n});
|
||||||
|
|
||||||
|
const xout2 = w2[circuit.getSignalIdx(`main.out[0]`)];
|
||||||
|
const yout2 = w2[circuit.getSignalIdx(`main.out[1]`)];
|
||||||
|
|
||||||
c = [g[0], g[1]];
|
c = [g[0], g[1]];
|
||||||
for (let i=0; i<252;i++) {
|
for (let i=0; i<252;i++) {
|
||||||
c = babyJub.addPoint(c,c);
|
c = addPoint(c,c);
|
||||||
}
|
}
|
||||||
c = babyJub.addPoint(c,g);
|
c = addPoint(c,g);
|
||||||
|
/*
|
||||||
await circuit.assertOut(w2, {out: c});
|
console.log(xout2.toString());
|
||||||
|
console.log(yout2.toString());
|
||||||
|
console.log(c[0].toString());
|
||||||
|
console.log(c[1].toString());
|
||||||
|
*/
|
||||||
|
assert(xout2.equals(c[0]));
|
||||||
|
assert(yout2.equals(c[1]));
|
||||||
|
|
||||||
}).timeout(10000000);
|
}).timeout(10000000);
|
||||||
|
|
||||||
it("Number of constrains for 256 bits", async () => {
|
it("Number of constrains for 256 bits", async () => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test_min.circom"));
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "escalarmul_test_min.circom"));
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains: " + circuit.nConstraints);
|
||||||
}).timeout(10000000);
|
}).timeout(10000000);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const compiler = require("circom");
|
||||||
|
|
||||||
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
@@ -14,33 +18,41 @@ describe("Escalarmul test", function () {
|
|||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
let g = [
|
let g = [
|
||||||
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
before( async() => {
|
before( async() => {
|
||||||
circuitEMulAny = await tester(path.join(__dirname, "circuits", "escalarmulany_test.circom"));
|
const cirDefEMulAny = await compiler(path.join(__dirname, "circuits", "escalarmulany_test.circom"));
|
||||||
|
circuitEMulAny = new snarkjs.Circuit(cirDefEMulAny);
|
||||||
|
console.log("NConstrains Escalarmul any: " + circuitEMulAny.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate Same escalar mul", async () => {
|
it("Should generate Same escalar mul", async () => {
|
||||||
|
|
||||||
const w = await circuitEMulAny.calculateWitness({"e": 1, "p": g});
|
const w = circuitEMulAny.calculateWitness({"e": 1, "p": g});
|
||||||
|
|
||||||
await circuitEMulAny.checkConstraints(w);
|
assert(circuitEMulAny.checkWitness(w));
|
||||||
|
|
||||||
await circuitEMulAny.assertOut(w, {out: g}, true);
|
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
|
||||||
|
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals(g[0]));
|
||||||
|
assert(yout.equals(g[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("If multiply by order should return 0", async () => {
|
it("If multiply by order should return 0", async () => {
|
||||||
|
|
||||||
const r = Fr.e("2736030358979909402780800718157159386076813972158567259200215660948447373041");
|
const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041");
|
||||||
const w = await circuitEMulAny.calculateWitness({"e": r, "p": g});
|
const w = circuitEMulAny.calculateWitness({"e": r, "p": g});
|
||||||
|
|
||||||
await circuitEMulAny.checkConstraints(w);
|
assert(circuitEMulAny.checkWitness(w));
|
||||||
|
|
||||||
await circuitEMulAny.assertOut(w, {out: [0,1]}, true);
|
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
|
||||||
|
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals(bigInt.zero));
|
||||||
|
assert(yout.equals(bigInt.one));
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
const babyjub = require("../src/babyjub");
|
const babyjub = require("../src/babyjub");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
@@ -16,74 +19,93 @@ describe("Escalarmul test", function () {
|
|||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async() => {
|
before( async() => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "escalarmulfix_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulfix_test.circom"));
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
console.log("NConstrains Escalarmul fix: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate Same escalar mul", async () => {
|
it("Should generate Same escalar mul", async () => {
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({"e": 0});
|
const w = circuit.calculateWitness({"e": 0});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: [0,1]}, true);
|
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals(0));
|
||||||
|
assert(yout.equals(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate Same escalar mul", async () => {
|
it("Should generate Same escalar mul", async () => {
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({"e": 1}, true);
|
const w = circuit.calculateWitness({"e": 1});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: babyjub.Base8});
|
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals(babyjub.Base8[0]));
|
||||||
|
assert(yout.equals(babyjub.Base8[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate scalar mul of a specific constant", async () => {
|
it("Should generate scalar mul of a specific constant", async () => {
|
||||||
|
|
||||||
const s = Fr.e("2351960337287830298912035165133676222414898052661454064215017316447594616519");
|
const s = bigInt("2351960337287830298912035165133676222414898052661454064215017316447594616519");
|
||||||
const base8 = [
|
const base8 = [
|
||||||
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({"e": s}, true);
|
const w = circuit.calculateWitness({"e": s});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
|
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: expectedRes});
|
assert(xout.equals(expectedRes[0]));
|
||||||
|
assert(yout.equals(expectedRes[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate scalar mul of the firsts 50 elements", async () => {
|
it("Should generate scalar mul of the firsts 50 elements", async () => {
|
||||||
|
|
||||||
const base8 = [
|
const base8 = [
|
||||||
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<50; i++) {
|
for (let i=0; i<50; i++) {
|
||||||
const s = Fr.e(i);
|
const s = bigInt(i);
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({"e": s}, true);
|
const w = circuit.calculateWitness({"e": s});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
|
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: expectedRes});
|
assert(xout.equals(expectedRes[0]));
|
||||||
|
assert(yout.equals(expectedRes[1]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("If multiply by order should return 0", async () => {
|
it("If multiply by order should return 0", async () => {
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({"e": babyjub.subOrder }, true);
|
const w = circuit.calculateWitness({"e": babyjub.subOrder });
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: [0,1]});
|
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals(bigInt.zero));
|
||||||
|
assert(yout.equals(bigInt.one));
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
32
test/mimc7.js
Normal file
32
test/mimc7.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
const chai = require("chai");
|
||||||
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
const mimc7 = require("../src/mimc7.js");
|
||||||
|
|
||||||
|
describe('mimc7 primitives', () => {
|
||||||
|
it('hash two bigInt', () => {
|
||||||
|
const h = mimc7.hash(bigInt(12), bigInt(45));
|
||||||
|
assert.equal(h.toString(), '19746142529723647765530752502670948774458299263315590587358840390982005703908');
|
||||||
|
});
|
||||||
|
it('hash bigInt array (multiHash)', () => {
|
||||||
|
const h1 = mimc7.multiHash([bigInt(12)]);
|
||||||
|
assert.equal(h1.toString(), '16051049095595290701999129793867590386356047218708919933694064829788708231421');
|
||||||
|
|
||||||
|
const h2 = mimc7.multiHash([bigInt(78), bigInt(41)]);
|
||||||
|
assert.equal(h2.toString(), '2938611815373543102852102540059918590261345652613741345181300284995514063984');
|
||||||
|
|
||||||
|
const h4 = mimc7.multiHash([bigInt(12), bigInt(45)]);
|
||||||
|
assert.equal(h4.toString(), '9949998637984578981906561631883120271399801229641312099559043216173958006905');
|
||||||
|
|
||||||
|
const h5 = mimc7.multiHash([bigInt(12), bigInt(45), bigInt(78), bigInt(41)]);
|
||||||
|
assert.equal(h5.toString(), '18226366069841799622585958305961373004333097209608110160936134895615261821931');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('mimc7 hash buffer', () => {
|
||||||
|
const msg = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
|
||||||
|
const msgBuff = Buffer.from(msg, 'utf-8');
|
||||||
|
let h = mimc7.hashBuffer(msgBuff);
|
||||||
|
assert.equal(h.toString(), '16855787120419064316734350414336285711017110414939748784029922801367685456065');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,25 +1,35 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const mimcjs = require("../src/mimc7.js");
|
const mimcjs = require("../src/mimc7.js");
|
||||||
|
|
||||||
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("MiMC Circuit test", function () {
|
describe("MiMC Circuit test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "mimc_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom"));
|
||||||
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("MiMC constraints: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain", async () => {
|
it("Should check constrain", async () => {
|
||||||
const w = await circuit.calculateWitness({x_in: 1, k: 2}, true);
|
const w = circuit.calculateWitness({x_in: 1, k: 2});
|
||||||
|
|
||||||
|
const res = w[circuit.getSignalIdx("main.out")];
|
||||||
|
|
||||||
const res2 = mimcjs.hash(1,2,91);
|
const res2 = mimcjs.hash(1,2,91);
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: res2});
|
assert.equal(res.toString(), res2.toString());
|
||||||
|
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const mimcjs = require("../src/mimcsponge.js");
|
const mimcjs = require("../src/mimcsponge.js");
|
||||||
|
|
||||||
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("MiMC Sponge Circuit test", function () {
|
describe("MiMC Sponge Circuit test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
@@ -10,28 +13,46 @@ describe("MiMC Sponge Circuit test", function () {
|
|||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
it("Should check permutation", async () => {
|
it("Should check permutation", async () => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_test.circom"));
|
||||||
|
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "mimc_sponge_test.circom"));
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3});
|
console.log("MiMC Feistel constraints: " + circuit.nConstraints);
|
||||||
|
|
||||||
|
const w = circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3});
|
||||||
|
|
||||||
|
const xLout = w[circuit.getSignalIdx("main.xL_out")];
|
||||||
|
const xRout = w[circuit.getSignalIdx("main.xR_out")];
|
||||||
|
|
||||||
const out2 = mimcjs.hash(1,2,3);
|
const out2 = mimcjs.hash(1,2,3);
|
||||||
|
|
||||||
await circuit.assertOut(w, {xL_out: out2.xL, xR_out: out2.xR});
|
assert.equal(xLout.toString(), out2.xL.toString());
|
||||||
|
assert.equal(xRout.toString(), out2.xR.toString());
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check hash", async () => {
|
it("Should check hash", async () => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom"));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({ins: [1, 2], k: 0});
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("MiMC Sponge constraints: " + circuit.nConstraints);
|
||||||
|
|
||||||
|
const w = circuit.calculateWitness({ins: [1, 2], k: 0});
|
||||||
|
|
||||||
|
const o1 = w[circuit.getSignalIdx("main.outs[0]")];
|
||||||
|
const o2 = w[circuit.getSignalIdx("main.outs[1]")];
|
||||||
|
const o3 = w[circuit.getSignalIdx("main.outs[2]")];
|
||||||
|
|
||||||
const out2 = mimcjs.multiHash([1,2], 0, 3);
|
const out2 = mimcjs.multiHash([1,2], 0, 3);
|
||||||
|
|
||||||
await circuit.assertOut(w, {outs: out2});
|
assert.equal(o1.toString(), out2[0].toString());
|
||||||
|
assert.equal(o2.toString(), out2[1].toString());
|
||||||
|
assert.equal(o3.toString(), out2[2].toString());
|
||||||
|
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
describe("Montgomery test", function () {
|
describe("Montgomery test", function () {
|
||||||
let circuitE2M;
|
let circuitE2M;
|
||||||
let circuitM2E;
|
let circuitM2E;
|
||||||
@@ -13,80 +15,85 @@ describe("Montgomery test", function () {
|
|||||||
let circuitMDouble;
|
let circuitMDouble;
|
||||||
|
|
||||||
let g = [
|
let g = [
|
||||||
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")];
|
||||||
];
|
|
||||||
|
|
||||||
let mg, mg2, g2, g3, mg3;
|
let mg, mg2, g2, g3, mg3;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before( async() => {
|
before( async() => {
|
||||||
circuitE2M = await tester(path.join(__dirname, "circuits", "edwards2montgomery.circom"));
|
const cirDefE2M = await compiler(path.join(__dirname, "circuits", "edwards2montgomery.circom"));
|
||||||
await circuitE2M.loadSymbols();
|
circuitE2M = new snarkjs.Circuit(cirDefE2M);
|
||||||
circuitM2E = await tester(path.join(__dirname, "circuits", "montgomery2edwards.circom"));
|
console.log("NConstrains Edwards -> Montgomery: " + circuitE2M.nConstraints);
|
||||||
await circuitM2E.loadSymbols();
|
|
||||||
circuitMAdd = await tester(path.join(__dirname, "circuits", "montgomeryadd.circom"));
|
const cirDefM2E = await compiler(path.join(__dirname, "circuits", "montgomery2edwards.circom"));
|
||||||
await circuitMAdd.loadSymbols();
|
circuitM2E = new snarkjs.Circuit(cirDefM2E);
|
||||||
circuitMDouble = await tester(path.join(__dirname, "circuits", "montgomerydouble.circom"));
|
console.log("NConstrains Montgomery -> Edwards: " + circuitM2E.nConstraints);
|
||||||
await circuitMDouble.loadSymbols();
|
|
||||||
|
const cirDefMAdd = await compiler(path.join(__dirname, "circuits", "montgomeryadd.circom"));
|
||||||
|
circuitMAdd = new snarkjs.Circuit(cirDefMAdd);
|
||||||
|
console.log("NConstrains Montgomery Add: " + circuitMAdd.nConstraints);
|
||||||
|
|
||||||
|
const cirDefMDouble = await compiler(path.join(__dirname, "circuits", "montgomerydouble.circom"));
|
||||||
|
circuitMDouble = new snarkjs.Circuit(cirDefMDouble);
|
||||||
|
console.log("NConstrains Montgomery Double: " + circuitMDouble.nConstraints);
|
||||||
});
|
});
|
||||||
it("Convert Edwards to Montgomery and back again", async () => {
|
it("Convert Edwards to Montgomery and back again", async () => {
|
||||||
let w, xout, yout;
|
let w, xout, yout;
|
||||||
|
|
||||||
w = await circuitE2M.calculateWitness({ in: g}, true);
|
w = circuitE2M.calculateWitness({ in: g});
|
||||||
|
|
||||||
xout = w[circuitE2M.symbols["main.out[0]"].varIdx];
|
xout = w[circuitE2M.getSignalIdx("main.out[0]")];
|
||||||
yout = w[circuitE2M.symbols["main.out[1]"].varIdx];
|
yout = w[circuitE2M.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
mg = [xout, yout];
|
mg = [xout, yout];
|
||||||
|
|
||||||
w = await circuitM2E.calculateWitness({ in: [xout, yout]}, true);
|
w = circuitM2E.calculateWitness({ in: [xout, yout]});
|
||||||
|
|
||||||
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
|
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
|
||||||
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
|
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
assert(Fr.eq(xout, g[0]));
|
assert(xout.equals(g[0]));
|
||||||
assert(Fr.eq(yout, g[1]));
|
assert(yout.equals(g[1]));
|
||||||
});
|
});
|
||||||
it("Should double a point", async () => {
|
it("Should double a point", async () => {
|
||||||
let w, xout, yout;
|
let w, xout, yout;
|
||||||
|
|
||||||
g2 = babyJub.addPoint(g,g);
|
g2 = babyJub.addPoint(g,g);
|
||||||
|
|
||||||
w = await circuitMDouble.calculateWitness({ in: mg}, true);
|
w = circuitMDouble.calculateWitness({ in: mg});
|
||||||
|
|
||||||
xout = w[circuitE2M.symbols["main.out[0]"].varIdx];
|
xout = w[circuitE2M.getSignalIdx("main.out[0]")];
|
||||||
yout = w[circuitE2M.symbols["main.out[1]"].varIdx];
|
yout = w[circuitE2M.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
mg2 = [xout, yout];
|
mg2 = [xout, yout];
|
||||||
|
|
||||||
w = await circuitM2E.calculateWitness({ in: mg2}, true);
|
w = circuitM2E.calculateWitness({ in: mg2});
|
||||||
|
|
||||||
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
|
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
|
||||||
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
|
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals(g2[0]));
|
||||||
assert(Fr.eq(xout, g2[0]));
|
assert(yout.equals(g2[1]));
|
||||||
assert(Fr.eq(yout, g2[1]));
|
|
||||||
});
|
});
|
||||||
it("Should add a point", async () => {
|
it("Should add a point", async () => {
|
||||||
let w, xout, yout;
|
let w, xout, yout;
|
||||||
|
|
||||||
g3 = babyJub.addPoint(g,g2);
|
g3 = babyJub.addPoint(g,g2);
|
||||||
|
|
||||||
w = await circuitMAdd.calculateWitness({ in1: mg, in2: mg2}, true);
|
w = circuitMAdd.calculateWitness({ in1: mg, in2: mg2});
|
||||||
|
|
||||||
xout = w[circuitMAdd.symbols["main.out[0]"].varIdx];
|
xout = w[circuitMAdd.getSignalIdx("main.out[0]")];
|
||||||
yout = w[circuitMAdd.symbols["main.out[1]"].varIdx];
|
yout = w[circuitMAdd.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
mg3 = [xout, yout];
|
mg3 = [xout, yout];
|
||||||
|
|
||||||
w = await circuitM2E.calculateWitness({ in: mg3}, true);
|
w = circuitM2E.calculateWitness({ in: mg3});
|
||||||
|
|
||||||
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
|
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
|
||||||
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
|
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
assert(Fr.eq(xout, g3[0]));
|
assert(xout.equals(g3[0]));
|
||||||
assert(Fr.eq(yout, g3[1]));
|
assert(yout.equals(g3[1]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,98 +1,127 @@
|
|||||||
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const compiler = require("circom");
|
||||||
|
|
||||||
describe("Mux4 test", function() {
|
const assert = chai.assert;
|
||||||
this.timeout(100000);
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
|
||||||
|
describe("Mux4 test", () => {
|
||||||
it("Should create a constant multiplexer 4", async () => {
|
it("Should create a constant multiplexer 4", async () => {
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "mux4_1.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mux4_1.circom"));
|
||||||
|
|
||||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||||
|
|
||||||
|
// assert.equal(cirDef.nVars, 2);
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains Mux4: " + circuit.nConstraints);
|
||||||
|
|
||||||
const ct16 = [
|
const ct16 = [
|
||||||
Fr.e("123"),
|
bigInt("123"),
|
||||||
Fr.e("456"),
|
bigInt("456"),
|
||||||
Fr.e("789"),
|
bigInt("789"),
|
||||||
Fr.e("012"),
|
bigInt("012"),
|
||||||
Fr.e("111"),
|
bigInt("111"),
|
||||||
Fr.e("222"),
|
bigInt("222"),
|
||||||
Fr.e("333"),
|
bigInt("333"),
|
||||||
Fr.e("4546"),
|
bigInt("4546"),
|
||||||
Fr.e("134523"),
|
bigInt("134523"),
|
||||||
Fr.e("44356"),
|
bigInt("44356"),
|
||||||
Fr.e("15623"),
|
bigInt("15623"),
|
||||||
Fr.e("4566"),
|
bigInt("4566"),
|
||||||
Fr.e("1223"),
|
bigInt("1223"),
|
||||||
Fr.e("4546"),
|
bigInt("4546"),
|
||||||
Fr.e("4256"),
|
bigInt("4256"),
|
||||||
Fr.e("4456")
|
bigInt("4456")
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<16; i++) {
|
for (let i=0; i<16; i++) {
|
||||||
const w = await circuit.calculateWitness({ "selector": i }, true);
|
const w = circuit.calculateWitness({ "selector": i });
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(w[0].equals(bigInt(1)));
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: ct16[i]});
|
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
||||||
|
assert(w[circuit.getSignalIdx("main.out")].equals(ct16[i]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should create a constant multiplexer 3", async () => {
|
it("Should create a constant multiplexer 3", async () => {
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "mux3_1.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mux3_1.circom"));
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains Mux3: " + circuit.nConstraints);
|
||||||
|
|
||||||
const ct8 = [
|
const ct8 = [
|
||||||
Fr.e("37"),
|
bigInt("37"),
|
||||||
Fr.e("47"),
|
bigInt("47"),
|
||||||
Fr.e("53"),
|
bigInt("53"),
|
||||||
Fr.e("71"),
|
bigInt("71"),
|
||||||
Fr.e("89"),
|
bigInt("89"),
|
||||||
Fr.e("107"),
|
bigInt("107"),
|
||||||
Fr.e("163"),
|
bigInt("163"),
|
||||||
Fr.e("191")
|
bigInt("191")
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<8; i++) {
|
for (let i=0; i<8; i++) {
|
||||||
const w = await circuit.calculateWitness({ "selector": i }, true);
|
const w = circuit.calculateWitness({ "selector": i });
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(w[0].equals(bigInt(1)));
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: ct8[i]});
|
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
||||||
|
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should create a constant multiplexer 2", async () => {
|
it("Should create a constant multiplexer 2", async () => {
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "mux2_1.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mux2_1.circom"));
|
||||||
|
|
||||||
const ct4 = [
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
Fr.e("37"),
|
|
||||||
Fr.e("47"),
|
console.log("NConstrains Mux2: " + circuit.nConstraints);
|
||||||
Fr.e("53"),
|
|
||||||
Fr.e("71"),
|
const ct8 = [
|
||||||
|
bigInt("37"),
|
||||||
|
bigInt("47"),
|
||||||
|
bigInt("53"),
|
||||||
|
bigInt("71"),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<4; i++) {
|
for (let i=0; i<4; i++) {
|
||||||
const w = await circuit.calculateWitness({ "selector": i }, true);
|
const w = circuit.calculateWitness({ "selector": i });
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(w[0].equals(bigInt(1)));
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: ct4[i]});
|
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
||||||
|
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should create a constant multiplexer 1", async () => {
|
it("Should create a constant multiplexer 1", async () => {
|
||||||
|
|
||||||
const circuit = await tester(path.join(__dirname, "circuits", "mux1_1.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mux1_1.circom"));
|
||||||
|
|
||||||
const ct2 = [
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
Fr.e("37"),
|
|
||||||
Fr.e("47"),
|
console.log("NConstrains Mux1: " + circuit.nConstraints);
|
||||||
|
|
||||||
|
const ct8 = [
|
||||||
|
bigInt("37"),
|
||||||
|
bigInt("47"),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<2; i++) {
|
for (let i=0; i<2; i++) {
|
||||||
const w = await circuit.calculateWitness({ "selector": i }, true);
|
const w = circuit.calculateWitness({ "selector": i });
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(w[0].equals(bigInt(1)));
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: ct2[i]});
|
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
||||||
|
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,77 +1,100 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const assert = chai.assert;
|
||||||
const tester = require("circom").tester;
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
const PBASE =
|
const PBASE =
|
||||||
[
|
[
|
||||||
[Fr.e("10457101036533406547632367118273992217979173478358440826365724437999023779287"),Fr.e("19824078218392094440610104313265183977899662750282163392862422243483260492317")],
|
[bigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"),bigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317")],
|
||||||
[Fr.e("2671756056509184035029146175565761955751135805354291559563293617232983272177"),Fr.e("2663205510731142763556352975002641716101654201788071096152948830924149045094")],
|
[bigInt("2671756056509184035029146175565761955751135805354291559563293617232983272177"),bigInt("2663205510731142763556352975002641716101654201788071096152948830924149045094")],
|
||||||
[Fr.e("5802099305472655231388284418920769829666717045250560929368476121199858275951"),Fr.e("5980429700218124965372158798884772646841287887664001482443826541541529227896")],
|
[bigInt("5802099305472655231388284418920769829666717045250560929368476121199858275951"),bigInt("5980429700218124965372158798884772646841287887664001482443826541541529227896")],
|
||||||
[Fr.e("7107336197374528537877327281242680114152313102022415488494307685842428166594"),Fr.e("2857869773864086953506483169737724679646433914307247183624878062391496185654")],
|
[bigInt("7107336197374528537877327281242680114152313102022415488494307685842428166594"),bigInt("2857869773864086953506483169737724679646433914307247183624878062391496185654")],
|
||||||
[Fr.e("20265828622013100949498132415626198973119240347465898028410217039057588424236"),Fr.e("1160461593266035632937973507065134938065359936056410650153315956301179689506")]
|
[bigInt("20265828622013100949498132415626198973119240347465898028410217039057588424236"),bigInt("1160461593266035632937973507065134938065359936056410650153315956301179689506")]
|
||||||
];
|
];
|
||||||
|
|
||||||
describe("Double Pedersen test", function() {
|
describe("Double Pedersen test", function() {
|
||||||
let circuit;
|
let circuit;
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before( async() => {
|
before( async() => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen_test.circom"));
|
||||||
|
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "pedersen_test.circom"));
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
it("Should pedersen at zero", async () => {
|
it("Should pedersen at zero", async () => {
|
||||||
|
|
||||||
let w;
|
let w, xout, yout;
|
||||||
|
|
||||||
w = await circuit.calculateWitness({ in: ["0", "0"]}, true);
|
w = circuit.calculateWitness({ in: ["0", "0"]});
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: [0,1]});
|
xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals("0"));
|
||||||
|
assert(yout.equals("1"));
|
||||||
});
|
});
|
||||||
it("Should pedersen at one first generator", async () => {
|
it("Should pedersen at one first generator", async () => {
|
||||||
let w;
|
let w, xout, yout;
|
||||||
|
|
||||||
w = await circuit.calculateWitness({ in: ["1", "0"]}, true);
|
w = circuit.calculateWitness({ in: ["1", "0"]});
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: PBASE[0]});
|
xout = bigInt(w[circuit.getSignalIdx("main.out[0]")]);
|
||||||
|
yout = bigInt(w[circuit.getSignalIdx("main.out[1]")]);
|
||||||
|
|
||||||
|
assert(xout.equals(PBASE[0][0]));
|
||||||
|
assert(yout.equals(PBASE[0][1]));
|
||||||
});
|
});
|
||||||
it("Should pedersen at one second generator", async () => {
|
it("Should pedersen at one second generator", async () => {
|
||||||
let w;
|
let w, xout, yout;
|
||||||
|
|
||||||
w = await circuit.calculateWitness({ in: ["0", "1"]}, true);
|
w = circuit.calculateWitness({ in: ["0", "1"]});
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: PBASE[1]});
|
xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
assert(xout.equals(PBASE[1][0]));
|
||||||
|
assert(yout.equals(PBASE[1][1]));
|
||||||
|
|
||||||
});
|
});
|
||||||
it("Should pedersen at mixed generators", async () => {
|
it("Should pedersen at mixed generators", async () => {
|
||||||
let w;
|
let w, xout, yout;
|
||||||
w = await circuit.calculateWitness({ in: ["3", "7"]}, true);
|
w = circuit.calculateWitness({ in: ["3", "7"]});
|
||||||
|
|
||||||
|
xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
|
|
||||||
const r = babyJub.addPoint(
|
const r = babyJub.addPoint(
|
||||||
babyJub.mulPointEscalar(PBASE[0], 3),
|
babyJub.mulPointEscalar(PBASE[0], 3),
|
||||||
babyJub.mulPointEscalar(PBASE[1], 7)
|
babyJub.mulPointEscalar(PBASE[1], 7)
|
||||||
);
|
);
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: r});
|
assert(xout.equals(r[0]));
|
||||||
|
assert(yout.equals(r[1]));
|
||||||
|
|
||||||
});
|
});
|
||||||
it("Should pedersen all ones", async () => {
|
it("Should pedersen all ones", async () => {
|
||||||
let w;
|
let w, xout, yout;
|
||||||
|
|
||||||
const allOnes = Fr.sub(Fr.shl(Fr.e("1"), Fr.e(250)), Fr.e("1"));
|
const allOnes = bigInt("1").shl(250).sub(bigInt("1"));
|
||||||
w = await circuit.calculateWitness({ in: [allOnes, allOnes]}, true);
|
w = circuit.calculateWitness({ in: [allOnes, allOnes]});
|
||||||
|
|
||||||
|
xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
const r2 = babyJub.addPoint(
|
const r2 = babyJub.addPoint(
|
||||||
babyJub.mulPointEscalar(PBASE[0], allOnes),
|
babyJub.mulPointEscalar(PBASE[0], allOnes),
|
||||||
babyJub.mulPointEscalar(PBASE[1], allOnes)
|
babyJub.mulPointEscalar(PBASE[1], allOnes)
|
||||||
);
|
);
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: r2});
|
assert(xout.equals(r2[0]));
|
||||||
|
assert(yout.equals(r2[1]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const assert = chai.assert;
|
||||||
const tester = require("circom").tester;
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
const pedersen = require("../src/pedersenHash.js");
|
const pedersen = require("../src/pedersenHash.js");
|
||||||
@@ -11,39 +15,60 @@ describe("Pedersen test", function() {
|
|||||||
let circuit;
|
let circuit;
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before( async() => {
|
before( async() => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen2_test.circom"));
|
||||||
|
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "pedersen2_test.circom"));
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains Pedersen2: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
it("Should pedersen at zero", async () => {
|
it("Should pedersen at zero", async () => {
|
||||||
|
|
||||||
let w;
|
let w, xout, yout;
|
||||||
|
|
||||||
w = await circuit.calculateWitness({ in: 0}, true);
|
w = circuit.calculateWitness({ in: 0});
|
||||||
|
|
||||||
|
xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
const b = Buffer.alloc(32);
|
const b = Buffer.alloc(32);
|
||||||
|
|
||||||
const h = pedersen.hash(b);
|
const h = pedersen.hash(b);
|
||||||
const hP = babyJub.unpackPoint(h);
|
const hP = babyJub.unpackPoint(h);
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: hP});
|
/*
|
||||||
|
console.log(`[${xout.toString()}, ${yout.toString()}]`);
|
||||||
|
console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`);
|
||||||
|
*/
|
||||||
|
|
||||||
|
assert(xout.equals(hP[0]));
|
||||||
|
assert(yout.equals(hP[1]));
|
||||||
});
|
});
|
||||||
it("Should pedersen with 253 ones", async () => {
|
it("Should pedersen with 253 ones", async () => {
|
||||||
|
|
||||||
let w;
|
let w, xout, yout;
|
||||||
|
|
||||||
const n = Fr.sub(Fr.shl(Fr.one, Fr.e(253)), Fr.one);
|
const n = bigInt.one.shl(253).sub(bigInt.one);
|
||||||
|
console.log(n.toString(16));
|
||||||
|
|
||||||
w = await circuit.calculateWitness({ in: n}, true);
|
w = circuit.calculateWitness({ in: n});
|
||||||
|
|
||||||
|
xout = w[circuit.getSignalIdx("main.out[0]")];
|
||||||
|
yout = w[circuit.getSignalIdx("main.out[1]")];
|
||||||
|
|
||||||
const b = Buffer.alloc(32);
|
const b = Buffer.alloc(32);
|
||||||
for (let i=0; i<31; i++) b[i] = 0xFF;
|
for (let i=0; i<31; i++) b[i] = 0xFF;
|
||||||
b[31] = 0x1F;
|
b[31] = 0x1F;
|
||||||
|
|
||||||
|
|
||||||
const h = pedersen.hash(b);
|
const h = pedersen.hash(b);
|
||||||
const hP = babyJub.unpackPoint(h);
|
const hP = babyJub.unpackPoint(h);
|
||||||
|
|
||||||
await circuit.assertOut(w, {out: hP});
|
/*
|
||||||
|
console.log(`[${xout.toString()}, ${yout.toString()}]`);
|
||||||
|
console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`);
|
||||||
|
*/
|
||||||
|
|
||||||
|
assert(xout.equals(hP[0]));
|
||||||
|
assert(yout.equals(hP[1]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
@@ -8,16 +14,20 @@ describe("Point 2 bits test", function() {
|
|||||||
let circuit;
|
let circuit;
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before( async() => {
|
before( async() => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "pointbits_loopback.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "pointbits_loopback.circom"));
|
||||||
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains Point2Bits loopback: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
it("Should do the both convertions for 8Base", async () => {
|
it("Should do the both convertions for 8Base", async () => {
|
||||||
const w = await circuit.calculateWitness({ in: babyJub.Base8}, true);
|
const w = circuit.calculateWitness({ in: babyJub.Base8});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
});
|
});
|
||||||
it("Should do the both convertions for Zero point", async () => {
|
it("Should do the both convertions for Zero point", async () => {
|
||||||
const w = await circuit.calculateWitness({ in: [0, 1]}, true);
|
const w = circuit.calculateWitness({ in: [0, 1]});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
41
test/poseidon.js
Normal file
41
test/poseidon.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
const chai = require("chai");
|
||||||
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
const poseidon = require("../src/poseidon.js");
|
||||||
|
|
||||||
|
describe('poseidon primitives', () => {
|
||||||
|
it('poseidon two bigInt', () => {
|
||||||
|
const poseidonHash = poseidon.createHash();
|
||||||
|
const h1 = poseidonHash([bigInt(1), bigInt(2)]);
|
||||||
|
assert.equal(h1.toString(), '12242166908188651009877250812424843524687801523336557272219921456462821518061');
|
||||||
|
|
||||||
|
const h2 = poseidonHash([bigInt(3), bigInt(4)]);
|
||||||
|
assert.equal(h2.toString(), '17185195740979599334254027721507328033796809509313949281114643312710535000993');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('poseidon bigInt array (multiHash)', () => {
|
||||||
|
const msg = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
|
||||||
|
const msgBuff = Buffer.from(msg, 'utf-8');
|
||||||
|
const n = 31;
|
||||||
|
const msgArray = [];
|
||||||
|
const fullParts = Math.floor(msgBuff.length / n);
|
||||||
|
for (let i = 0; i < fullParts; i++) {
|
||||||
|
const v = bigInt.leBuff2int(msgBuff.slice(n * i, n * (i + 1)));
|
||||||
|
msgArray.push(v);
|
||||||
|
}
|
||||||
|
if (msgBuff.length % n !== 0) {
|
||||||
|
const v = bigInt.leBuff2int(msgBuff.slice(fullParts * n));
|
||||||
|
msgArray.push(v);
|
||||||
|
}
|
||||||
|
let h = poseidon.multiHash(msgArray);
|
||||||
|
assert.equal(h.toString(), '11821124228916291136371255062457365369197326845706357273715164664419275913793');
|
||||||
|
|
||||||
|
});
|
||||||
|
it('poseidon hash buffer', () => {
|
||||||
|
const msg = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
|
||||||
|
const msgBuff = Buffer.from(msg, 'utf-8');
|
||||||
|
let h = poseidon.hashBuffer(msgBuff);
|
||||||
|
assert.equal(h.toString(), '11821124228916291136371255062457365369197326845706357273715164664419275913793');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,57 +1,60 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
|
const compiler = require("circom");
|
||||||
|
var blake2b = require('blake2b');
|
||||||
|
|
||||||
const poseidon = require("../src/poseidon.js");
|
const poseidon = require("../src/poseidon.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
describe("Blake2b version test", function() {
|
||||||
|
it("Should give the expected output for blake2b version", async () => {
|
||||||
|
var output = new Uint8Array(32);
|
||||||
|
var input = Buffer.from('poseidon_constants');
|
||||||
|
h = blake2b(output.length).update(input).digest('hex')
|
||||||
|
assert.equal('e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1', h);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("Poseidon Circuit test", function () {
|
describe("Poseidon Circuit test", function () {
|
||||||
let circuit6;
|
let circuit;
|
||||||
let circuit3;
|
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
circuit6 = await tester(path.join(__dirname, "circuits", "poseidon6_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "poseidon_test.circom"));
|
||||||
circuit3 = await tester(path.join(__dirname, "circuits", "poseidon3_test.circom"));
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("Poseidon constraints: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([1, 2]) t=6", async () => {
|
it("Should check constrain of hash([1, 2])", async () => {
|
||||||
const w = await circuit6.calculateWitness({inputs: [1, 2, 0,0,0]}, true);
|
const w = circuit.calculateWitness({inputs: [1, 2]});
|
||||||
|
|
||||||
const res2 = poseidon([1,2,0,0,0]);
|
const res = w[circuit.getSignalIdx("main.out")];
|
||||||
assert.equal("1944517543886089121158331594914426541694339782056411886233994349799551050705", res2.toString());
|
|
||||||
await circuit6.assertOut(w, {out : res2});
|
const hash = poseidon.createHash(6, 8, 57);
|
||||||
await circuit6.checkConstraints(w);
|
|
||||||
|
const res2 = hash([1,2]);
|
||||||
|
assert.equal('12242166908188651009877250812424843524687801523336557272219921456462821518061', res2.toString());
|
||||||
|
assert.equal(res.toString(), res2.toString());
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([3, 4]) t=6", async () => {
|
it("Should check constrain of hash([3, 4])", async () => {
|
||||||
const w = await circuit6.calculateWitness({inputs: [3, 4,5,10,23]});
|
const w = circuit.calculateWitness({inputs: [3, 4]});
|
||||||
|
|
||||||
const res2 = poseidon([3, 4,5,10,23]);
|
const res = w[circuit.getSignalIdx("main.out")];
|
||||||
|
|
||||||
assert.equal("15043529598202765311255531083507141602555136943545139099151157943137780370931", res2.toString());
|
const hash = poseidon.createHash(6, 8, 57);
|
||||||
await circuit6.assertOut(w, {out : res2});
|
|
||||||
await circuit6.checkConstraints(w);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
const res2 = hash([3, 4]);
|
||||||
|
assert.equal('17185195740979599334254027721507328033796809509313949281114643312710535000993', res2.toString());
|
||||||
|
|
||||||
it("Should check constrain of hash([1, 2]) t=3", async () => {
|
assert.equal(res.toString(), res2.toString());
|
||||||
const w = await circuit3.calculateWitness({inputs: [1, 2]});
|
|
||||||
|
|
||||||
const res2 = poseidon([1,2]);
|
assert(circuit.checkWitness(w));
|
||||||
assert.equal("11309872961022349216464221841186646423561022368884850929991258903497301047946", res2.toString());
|
|
||||||
await circuit3.assertOut(w, {out : res2});
|
|
||||||
await circuit3.checkConstraints(w);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should check constrain of hash([3, 4]) t=3", async () => {
|
|
||||||
const w = await circuit3.calculateWitness({inputs: [3, 4]});
|
|
||||||
|
|
||||||
const res2 = poseidon([3, 4]);
|
|
||||||
assert.equal("5452722186384045185233705092171776011224530037417547968760104202263491217182", res2.toString());
|
|
||||||
await circuit3.assertOut(w, {out : res2});
|
|
||||||
await circuit3.checkConstraints(w);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,18 +2,19 @@ const ganache = require("ganache-cli");
|
|||||||
const Web3 = require("web3");
|
const Web3 = require("web3");
|
||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const poseidonGenContract = require("../src/poseidon_gencontract.js");
|
const poseidonGenContract = require("../src/poseidon_gencontract.js");
|
||||||
const poseidon = require("../src/poseidon.js");
|
const Poseidon = require("../src/poseidon.js");
|
||||||
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
||||||
|
|
||||||
describe("Poseidon Smart contract test", function () {
|
const SEED = "mimc";
|
||||||
|
|
||||||
|
describe("Poseidon Smart contract test", () => {
|
||||||
let testrpc;
|
let testrpc;
|
||||||
let web3;
|
let web3;
|
||||||
let poseidon6;
|
let mimc;
|
||||||
let poseidon3;
|
|
||||||
let accounts;
|
let accounts;
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 });
|
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 });
|
||||||
@@ -21,45 +22,28 @@ describe("Poseidon Smart contract test", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should deploy the contract", async () => {
|
it("Should deploy the contract", async () => {
|
||||||
const C6 = new web3.eth.Contract(poseidonGenContract.generateABI(5));
|
const C = new web3.eth.Contract(poseidonGenContract.abi);
|
||||||
const C3 = new web3.eth.Contract(poseidonGenContract.generateABI(2));
|
|
||||||
|
|
||||||
poseidon6 = await C6.deploy({
|
mimc = await C.deploy({
|
||||||
data: poseidonGenContract.createCode(5)
|
data: poseidonGenContract.createCode()
|
||||||
}).send({
|
}).send({
|
||||||
gas: 5000000,
|
gas: 2500000,
|
||||||
from: accounts[0]
|
|
||||||
});
|
|
||||||
poseidon3 = await C3.deploy({
|
|
||||||
data: poseidonGenContract.createCode(2)
|
|
||||||
}).send({
|
|
||||||
gas: 5000000,
|
|
||||||
from: accounts[0]
|
from: accounts[0]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should calculate the poseidon correctly t=6", async () => {
|
it("Shold calculate the mimic correctly", async () => {
|
||||||
|
|
||||||
const res = await poseidon6.methods.poseidon([1,2, 0, 0, 0]).call();
|
const res = await mimc.methods.poseidon([1,2]).call();
|
||||||
|
|
||||||
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
||||||
|
|
||||||
const res2 = poseidon([1,2, 0, 0, 0]);
|
const hash = Poseidon.createHash(6, 8, 57);
|
||||||
|
|
||||||
|
const res2 = hash([1,2]);
|
||||||
// console.log("Ref: " + bigInt(res2).toString(16));
|
// console.log("Ref: " + bigInt(res2).toString(16));
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
assert.equal(res.toString(), res2.toString());
|
||||||
});
|
});
|
||||||
it("Should calculate the poseidon correctly t=3", async () => {
|
|
||||||
|
|
||||||
const res = await poseidon3.methods.poseidon([1,2]).call();
|
|
||||||
|
|
||||||
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
|
||||||
|
|
||||||
const res2 = poseidon([1,2]);
|
|
||||||
// console.log("Ref: " + bigInt(res2).toString(16));
|
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
const compiler = require("circom");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const sha256 = require("./helpers/sha256");
|
const sha256 = require("./helpers/sha256");
|
||||||
|
|
||||||
const tester = require("circom").tester;
|
|
||||||
|
|
||||||
// const printSignal = require("./helpers/printsignal");
|
// const printSignal = require("./helpers/printsignal");
|
||||||
|
|
||||||
|
|
||||||
@@ -34,8 +34,7 @@ function bitArray2buffer(a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
describe("SHA256 test", function () {
|
describe("SHA256 test", () => {
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
|
|
||||||
it("Should work bits to array and array to bits", async () => {
|
it("Should work bits to array and array to bits", async () => {
|
||||||
@@ -46,13 +45,17 @@ describe("SHA256 test", function () {
|
|||||||
const a = buffer2bitArray(b);
|
const a = buffer2bitArray(b);
|
||||||
const b2 = bitArray2buffer(a);
|
const b2 = bitArray2buffer(a);
|
||||||
|
|
||||||
assert.equal(b.toString("hex"), b2.toString("hex"), true);
|
assert.equal(b.toString("hex"), b2.toString("hex"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should calculate a hash of 1 compressor", async () => {
|
it("Should calculate a hash of 1 compressor", async () => {
|
||||||
const cir = await tester(path.join(__dirname, "circuits", "sha256_2_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom"));
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
const witness = await cir.calculateWitness({ "a": "1", "b": "2" }, true);
|
console.log("Vars: "+circuit.nVars);
|
||||||
|
console.log("Constraints: "+circuit.nConstraints);
|
||||||
|
|
||||||
|
const witness = circuit.calculateWitness({ "a": "1", "b": "2" });
|
||||||
|
|
||||||
const b = new Buffer.alloc(54);
|
const b = new Buffer.alloc(54);
|
||||||
b[26] = 1;
|
b[26] = 1;
|
||||||
@@ -67,12 +70,21 @@ describe("SHA256 test", function () {
|
|||||||
|
|
||||||
assert.equal(hash, hash2);
|
assert.equal(hash, hash2);
|
||||||
|
|
||||||
assert(Fr.eq(witness[1], Fr.e(r)));
|
assert(witness[1].equals(snarkjs.bigInt(r)));
|
||||||
}).timeout(1000000);
|
}).timeout(1000000);
|
||||||
|
|
||||||
it("Should calculate a hash of 2 compressor", async () => {
|
it("Should calculate a hash of 2 compressor", async () => {
|
||||||
const cir = await tester(path.join(__dirname, "circuits", "sha256_test512.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test512.circom"), {reduceConstraints:false} );
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("Vars: "+circuit.nVars);
|
||||||
|
console.log("Constraints: "+circuit.nConstraints);
|
||||||
|
|
||||||
|
/*
|
||||||
|
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||||
|
|
||||||
|
const b = Buffer.from(testStr, 'utf8');
|
||||||
|
*/
|
||||||
const b = new Buffer.alloc(64);
|
const b = new Buffer.alloc(64);
|
||||||
for (let i=0; i<64; i++) {
|
for (let i=0; i<64; i++) {
|
||||||
b[i] = i+1;
|
b[i] = i+1;
|
||||||
@@ -83,7 +95,7 @@ describe("SHA256 test", function () {
|
|||||||
.digest("hex");
|
.digest("hex");
|
||||||
|
|
||||||
const arrIn = buffer2bitArray(b);
|
const arrIn = buffer2bitArray(b);
|
||||||
const witness = await cir.calculateWitness({ "in": arrIn }, true);
|
const witness = circuit.calculateWitness({ "in": arrIn } /*, {logOutput: true} */);
|
||||||
|
|
||||||
const arrOut = witness.slice(1, 257);
|
const arrOut = witness.slice(1, 257);
|
||||||
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
||||||
@@ -91,25 +103,34 @@ describe("SHA256 test", function () {
|
|||||||
assert.equal(hash, hash2);
|
assert.equal(hash, hash2);
|
||||||
|
|
||||||
}).timeout(1000000);
|
}).timeout(1000000);
|
||||||
|
|
||||||
|
|
||||||
it("Should calculate a hash of 2 compressor", async () => {
|
it("Should calculate a hash of 2 compressor", async () => {
|
||||||
const cir = await tester(path.join(__dirname, "circuits", "sha256_test448.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test448.circom"), {reduceConstraints:false} );
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("Vars: "+circuit.nVars);
|
||||||
|
console.log("Constraints: "+circuit.nConstraints);
|
||||||
|
|
||||||
|
|
||||||
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||||
|
|
||||||
const b = Buffer.from(testStr, "utf8");
|
const b = Buffer.from(testStr, 'utf8');
|
||||||
|
for (let i=0; i<64; i++) {
|
||||||
|
b[i] = i+1;
|
||||||
|
}
|
||||||
|
|
||||||
const hash = crypto.createHash("sha256")
|
const hash = crypto.createHash("sha256")
|
||||||
.update(b)
|
.update(b)
|
||||||
.digest("hex");
|
.digest("hex");
|
||||||
|
|
||||||
const arrIn = buffer2bitArray(b);
|
const arrIn = buffer2bitArray(b);
|
||||||
|
const witness = circuit.calculateWitness({ "in": arrIn } /*, {logOutput: true} */);
|
||||||
const witness = await cir.calculateWitness({ "in": arrIn }, true);
|
|
||||||
|
|
||||||
const arrOut = witness.slice(1, 257);
|
const arrOut = witness.slice(1, 257);
|
||||||
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
||||||
|
|
||||||
assert.equal(hash, hash2);
|
assert.equal(hash, hash2);
|
||||||
});
|
|
||||||
|
|
||||||
|
}).timeout(1000000);
|
||||||
});
|
});
|
||||||
|
|||||||
70
test/sign.js
70
test/sign.js
@@ -1,7 +1,11 @@
|
|||||||
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const snarkjs = require("snarkjs");
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const compiler = require("circom");
|
||||||
const tester = require("circom").tester;
|
|
||||||
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
@@ -10,71 +14,75 @@ function print(circuit, w, s) {
|
|||||||
function getBits(v, n) {
|
function getBits(v, n) {
|
||||||
const res = [];
|
const res = [];
|
||||||
for (let i=0; i<n; i++) {
|
for (let i=0; i<n; i++) {
|
||||||
if (Scalar.isOdd(Scalar.shr(v, i))) {
|
if (v.shr(i).isOdd()) {
|
||||||
res.push(Fr.one);
|
res.push(bigInt.one);
|
||||||
} else {
|
} else {
|
||||||
res.push(Fr.zero);
|
res.push(bigInt.zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
|
||||||
describe("Sign test", function() {
|
describe("Sign test", () => {
|
||||||
let circuit;
|
let circuit;
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
before( async() => {
|
before( async() => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "sign_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "sign_test.circom"));
|
||||||
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains: " + circuit.nConstraints);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of 0", async () => {
|
it("Sign of 0", async () => {
|
||||||
const inp = getBits(Scalar.e(0), 254);
|
const inp = getBits(bigInt.zero, 254);
|
||||||
const w = await circuit.calculateWitness({in: inp}, true);
|
const w = circuit.calculateWitness({in: inp});
|
||||||
|
|
||||||
await circuit.assertOut(w, {sign: 0});
|
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) );
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of 3", async () => {
|
it("Sign of 3", async () => {
|
||||||
const inp = getBits(Scalar.e(3), 254);
|
const inp = getBits(bigInt(3), 254);
|
||||||
const w = await circuit.calculateWitness({in: inp}, true);
|
const w = circuit.calculateWitness({in: inp});
|
||||||
|
|
||||||
await circuit.assertOut(w, {sign: 0});
|
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) );
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q/2", async () => {
|
it("Sign of q/2", async () => {
|
||||||
const inp = getBits(Scalar.shr(q, 1), 254);
|
const inp = getBits(q.shr(bigInt.one), 254);
|
||||||
const w = await circuit.calculateWitness({in: inp}, true);
|
const w = circuit.calculateWitness({in: inp});
|
||||||
|
|
||||||
await circuit.assertOut(w, {sign: 0});
|
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) );
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q/2+1", async () => {
|
it("Sign of q/2+1", async () => {
|
||||||
const inp = getBits(Scalar.add(Scalar.shr(q, 1), 1) , 254);
|
const inp = getBits(q.shr(bigInt.one).add(bigInt.one), 254);
|
||||||
const w = await circuit.calculateWitness({in: inp}, true);
|
const w = circuit.calculateWitness({in: inp});
|
||||||
|
|
||||||
await circuit.assertOut(w, {sign: 1});
|
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q-1", async () => {
|
it("Sign of q-1", async () => {
|
||||||
const inp = getBits(Scalar.sub(q, 1), 254);
|
const inp = getBits(q.sub(bigInt.one), 254);
|
||||||
const w = await circuit.calculateWitness({in: inp}, true);
|
const w = circuit.calculateWitness({in: inp});
|
||||||
|
|
||||||
await circuit.assertOut(w, {sign: 1});
|
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q", async () => {
|
it("Sign of q", async () => {
|
||||||
const inp = getBits(q, 254);
|
const inp = getBits(q, 254);
|
||||||
const w = await circuit.calculateWitness({in: inp}, true);
|
const w = circuit.calculateWitness({in: inp});
|
||||||
|
|
||||||
await circuit.assertOut(w, {sign: 1});
|
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of all ones", async () => {
|
it("Sign of all ones", async () => {
|
||||||
const inp = getBits(Scalar.sub(Scalar.shl(1,254),1), 254);
|
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
|
||||||
const w = await circuit.calculateWitness({in: inp}, true);
|
const w = circuit.calculateWitness({in: inp});
|
||||||
|
|
||||||
await circuit.assertOut(w, {sign: 1});
|
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,29 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
|
||||||
|
|
||||||
const smt = require("../src/smt.js");
|
const smt = require("../src/smt.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
|
||||||
|
function stringifyBigInts(o) {
|
||||||
|
if ((typeof(o) == "bigint") || (o instanceof bigInt)) {
|
||||||
|
return o.toString(10);
|
||||||
|
} else if (Array.isArray(o)) {
|
||||||
|
return o.map(stringifyBigInts);
|
||||||
|
} else if (typeof o == "object") {
|
||||||
|
const res = {};
|
||||||
|
for (let k in o) {
|
||||||
|
res[k] = stringifyBigInts(o[k]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe("SMT Javascript test", function () {
|
describe("SMT Javascript test", function () {
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before( async () => {
|
before( async () => {
|
||||||
@@ -13,22 +31,22 @@ describe("SMT Javascript test", function () {
|
|||||||
|
|
||||||
it("Should insert 2 elements and empty them", async () => {
|
it("Should insert 2 elements and empty them", async () => {
|
||||||
const tree = await smt.newMemEmptyTrie();
|
const tree = await smt.newMemEmptyTrie();
|
||||||
const key1 = Fr.e(111);
|
const key1 = bigInt(111);
|
||||||
const value1 = Fr.e(222);
|
const value1 = bigInt(222);
|
||||||
const key2 = Fr.e(333);
|
const key2 = bigInt(333);
|
||||||
const value2 = Fr.e(444);
|
const value2 = bigInt(444);
|
||||||
|
|
||||||
await tree.insert(key1,value1);
|
await tree.insert(key1,value1);
|
||||||
await tree.insert(key2,value2);
|
await tree.insert(key2,value2);
|
||||||
await tree.delete(key2);
|
await tree.delete(key2);
|
||||||
await tree.delete(key1);
|
await tree.delete(key1);
|
||||||
|
|
||||||
assert(Fr.isZero(tree.root));
|
assert(tree.root.isZero());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should insert 3 elements in dferent order and should be the same", async () => {
|
it("Should insert 3 elements in dferent order and should be the same", async () => {
|
||||||
const keys = [Fr.e(8), Fr.e(9), Fr.e(32)];
|
const keys = [bigInt(8), bigInt(9), bigInt(32)];
|
||||||
const values = [Fr.e(88), Fr.e(99), Fr.e(3232)];
|
const values = [bigInt(88), bigInt(99), bigInt(3232)];
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
const tree3 = await smt.newMemEmptyTrie();
|
const tree3 = await smt.newMemEmptyTrie();
|
||||||
@@ -60,11 +78,11 @@ describe("SMT Javascript test", function () {
|
|||||||
await tree6.insert(keys[1],values[1]);
|
await tree6.insert(keys[1],values[1]);
|
||||||
await tree6.insert(keys[0],values[0]);
|
await tree6.insert(keys[0],values[0]);
|
||||||
|
|
||||||
assert(Fr.eq(tree1.root, tree2.root));
|
assert(tree1.root.equals(tree2.root));
|
||||||
assert(Fr.eq(tree2.root, tree3.root));
|
assert(tree2.root.equals(tree3.root));
|
||||||
assert(Fr.eq(tree3.root, tree4.root));
|
assert(tree3.root.equals(tree4.root));
|
||||||
assert(Fr.eq(tree4.root, tree5.root));
|
assert(tree4.root.equals(tree5.root));
|
||||||
assert(Fr.eq(tree5.root, tree6.root));
|
assert(tree5.root.equals(tree6.root));
|
||||||
|
|
||||||
assert.equal(Object.keys(tree1.db.nodes).length, Object.keys(tree2.db.nodes).length);
|
assert.equal(Object.keys(tree1.db.nodes).length, Object.keys(tree2.db.nodes).length);
|
||||||
assert.equal(Object.keys(tree2.db.nodes).length, Object.keys(tree3.db.nodes).length);
|
assert.equal(Object.keys(tree2.db.nodes).length, Object.keys(tree3.db.nodes).length);
|
||||||
@@ -76,19 +94,19 @@ describe("SMT Javascript test", function () {
|
|||||||
await tree1.delete(keys[1]);
|
await tree1.delete(keys[1]);
|
||||||
await tree2.delete(keys[1]);
|
await tree2.delete(keys[1]);
|
||||||
await tree2.delete(keys[0]);
|
await tree2.delete(keys[0]);
|
||||||
assert(Fr.eq(tree1.root, tree2.root));
|
assert(tree1.root.equals(tree2.root));
|
||||||
|
|
||||||
await tree3.delete(keys[0]);
|
await tree3.delete(keys[0]);
|
||||||
await tree3.delete(keys[2]);
|
await tree3.delete(keys[2]);
|
||||||
await tree4.delete(keys[2]);
|
await tree4.delete(keys[2]);
|
||||||
await tree4.delete(keys[0]);
|
await tree4.delete(keys[0]);
|
||||||
assert(Fr.eq(tree3.root, tree4.root));
|
assert(tree3.root.equals(tree4.root));
|
||||||
|
|
||||||
await tree5.delete(keys[1]);
|
await tree5.delete(keys[1]);
|
||||||
await tree5.delete(keys[2]);
|
await tree5.delete(keys[2]);
|
||||||
await tree6.delete(keys[2]);
|
await tree6.delete(keys[2]);
|
||||||
await tree6.delete(keys[1]);
|
await tree6.delete(keys[1]);
|
||||||
assert(Fr.eq(tree5.root, tree6.root));
|
assert(tree5.root.equals(tree6.root));
|
||||||
|
|
||||||
await tree1.delete(keys[2]);
|
await tree1.delete(keys[2]);
|
||||||
await tree2.delete(keys[2]);
|
await tree2.delete(keys[2]);
|
||||||
@@ -97,12 +115,12 @@ describe("SMT Javascript test", function () {
|
|||||||
await tree5.delete(keys[0]);
|
await tree5.delete(keys[0]);
|
||||||
await tree6.delete(keys[0]);
|
await tree6.delete(keys[0]);
|
||||||
|
|
||||||
assert(Fr.isZero(tree1.root));
|
assert(tree1.root.isZero());
|
||||||
assert(Fr.isZero(tree2.root));
|
assert(tree2.root.isZero());
|
||||||
assert(Fr.isZero(tree3.root));
|
assert(tree3.root.isZero());
|
||||||
assert(Fr.isZero(tree4.root));
|
assert(tree4.root.isZero());
|
||||||
assert(Fr.isZero(tree5.root));
|
assert(tree5.root.isZero());
|
||||||
assert(Fr.isZero(tree6.root));
|
assert(tree6.root.isZero());
|
||||||
|
|
||||||
assert.equal(Object.keys(tree1.db.nodes).length, 0);
|
assert.equal(Object.keys(tree1.db.nodes).length, 0);
|
||||||
assert.equal(Object.keys(tree2.db.nodes).length, 0);
|
assert.equal(Object.keys(tree2.db.nodes).length, 0);
|
||||||
@@ -127,7 +145,7 @@ describe("SMT Javascript test", function () {
|
|||||||
const arr = [];
|
const arr = [];
|
||||||
const N = 100;
|
const N = 100;
|
||||||
for (let i=0; i<N; i++) {
|
for (let i=0; i<N; i++) {
|
||||||
arr.push(Fr.e(i));
|
arr.push(bigInt(i));
|
||||||
}
|
}
|
||||||
const insArr = perm(arr);
|
const insArr = perm(arr);
|
||||||
for (let i=0; i<N; i++) {
|
for (let i=0; i<N; i++) {
|
||||||
@@ -138,7 +156,7 @@ describe("SMT Javascript test", function () {
|
|||||||
await tree.delete(delArr[i]);
|
await tree.delete(delArr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(Fr.isZero(tree.root));
|
assert(tree.root.isZero());
|
||||||
assert.equal(Object.keys(tree.db.nodes).length, 0);
|
assert.equal(Object.keys(tree.db.nodes).length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -158,16 +176,7 @@ describe("SMT Javascript test", function () {
|
|||||||
await tree1.update(9, 999);
|
await tree1.update(9, 999);
|
||||||
await tree1.update(32, 323232);
|
await tree1.update(32, 323232);
|
||||||
|
|
||||||
assert(Fr.eq(tree1.root, tree2.root));
|
assert(tree1.root.equals(tree2.root));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should test update with same key-value", async () => {
|
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
|
||||||
|
|
||||||
await tree1.insert(8,88);
|
|
||||||
await tree1.update(8,88);
|
|
||||||
|
|
||||||
const res = await tree1.db.get(tree1.root);
|
|
||||||
assert.notEqual(res, undefined);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const tester = require("circom").tester;
|
const snarkjs = require("snarkjs");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const compiler = require("circom");
|
||||||
|
|
||||||
const smt = require("../src/smt.js");
|
const smt = require("../src/smt.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testInsert(tree, key, value, circuit ) {
|
async function testInsert(tree, key, value, circuit, log ) {
|
||||||
|
|
||||||
const res = await tree.insert(key,value);
|
const res = await tree.insert(key,value);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length<10) siblings.push(Fr.e(0));
|
while (siblings.length<10) siblings.push(bigInt(0));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
fnc: [1,0],
|
fnc: [1,0],
|
||||||
oldRoot: res.oldRoot,
|
oldRoot: res.oldRoot,
|
||||||
siblings: siblings,
|
siblings: siblings,
|
||||||
@@ -26,20 +28,19 @@ async function testInsert(tree, key, value, circuit ) {
|
|||||||
isOld0: res.isOld0 ? 1 : 0,
|
isOld0: res.isOld0 ? 1 : 0,
|
||||||
newKey: key,
|
newKey: key,
|
||||||
newValue: value
|
newValue: value
|
||||||
}, true);
|
}, log);
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
|
|
||||||
await circuit.assertOut(w, {newRoot: res.newRoot});
|
|
||||||
|
|
||||||
|
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
|
assert(root1.equals(res.newRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testDelete(tree, key, circuit) {
|
async function testDelete(tree, key, circuit) {
|
||||||
const res = await tree.delete(key);
|
const res = await tree.delete(key);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length<10) siblings.push(Fr.e(0));
|
while (siblings.length<10) siblings.push(bigInt(0));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
fnc: [1,1],
|
fnc: [1,1],
|
||||||
oldRoot: res.oldRoot,
|
oldRoot: res.oldRoot,
|
||||||
siblings: siblings,
|
siblings: siblings,
|
||||||
@@ -48,19 +49,20 @@ async function testDelete(tree, key, circuit) {
|
|||||||
isOld0: res.isOld0 ? 1 : 0,
|
isOld0: res.isOld0 ? 1 : 0,
|
||||||
newKey: res.delKey,
|
newKey: res.delKey,
|
||||||
newValue: res.delValue
|
newValue: res.delValue
|
||||||
}, true);
|
});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
||||||
|
|
||||||
await circuit.assertOut(w, {newRoot: res.newRoot});
|
assert(circuit.checkWitness(w));
|
||||||
|
assert(root1.equals(res.newRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testUpdate(tree, key, newValue, circuit) {
|
async function testUpdate(tree, key, newValue, circuit) {
|
||||||
const res = await tree.update(key, newValue);
|
const res = await tree.update(key, newValue);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length<10) siblings.push(Fr.e(0));
|
while (siblings.length<10) siblings.push(bigInt(0));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
fnc: [0,1],
|
fnc: [0,1],
|
||||||
oldRoot: res.oldRoot,
|
oldRoot: res.oldRoot,
|
||||||
siblings: siblings,
|
siblings: siblings,
|
||||||
@@ -71,47 +73,53 @@ async function testUpdate(tree, key, newValue, circuit) {
|
|||||||
newValue: res.newValue
|
newValue: res.newValue
|
||||||
});
|
});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
||||||
|
|
||||||
await circuit.assertOut(w, {newRoot: res.newRoot});
|
assert(circuit.checkWitness(w));
|
||||||
|
assert(root1.equals(res.newRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
describe("SMT Processor test", function () {
|
describe("SMT test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
let tree;
|
let tree;
|
||||||
|
|
||||||
this.timeout(10000000);
|
this.timeout(10000000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
|
||||||
await circuit.loadSymbols();
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains SMTProcessor: " + circuit.nConstraints);
|
||||||
|
|
||||||
tree = await smt.newMemEmptyTrie();
|
tree = await smt.newMemEmptyTrie();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should verify an insert to an empty tree", async () => {
|
it("Should verify an insert to an empty tree", async () => {
|
||||||
const key = Fr.e(111);
|
const key = bigInt(111);
|
||||||
const value = Fr.e(222);
|
const value = bigInt(222);
|
||||||
|
|
||||||
await testInsert(tree, key, value, circuit);
|
await testInsert(tree, key, value, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("It should add another element", async () => {
|
it("It should add another element", async () => {
|
||||||
const key = Fr.e(333);
|
const key = bigInt(333);
|
||||||
const value = Fr.e(444);
|
const value = bigInt(444);
|
||||||
|
|
||||||
await testInsert(tree, key, value, circuit);
|
await testInsert(tree, key, value, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it("Should remove an element", async () => {
|
it("Should remove an element", async () => {
|
||||||
await testDelete(tree, 111, circuit);
|
await testDelete(tree, 111, circuit);
|
||||||
await testDelete(tree, 333, circuit);
|
await testDelete(tree, 333, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should test convination of adding and removing 3 elements", async () => {
|
it("Should test convination of adding and removing 3 elements", async () => {
|
||||||
const keys = [Fr.e(8), Fr.e(9), Fr.e(32)];
|
const keys = [bigInt(8), bigInt(9), bigInt(32)];
|
||||||
const values = [Fr.e(88), Fr.e(99), Fr.e(3232)];
|
const values = [bigInt(88), bigInt(99), bigInt(3232)];
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
const tree3 = await smt.newMemEmptyTrie();
|
const tree3 = await smt.newMemEmptyTrie();
|
||||||
@@ -170,8 +178,8 @@ describe("SMT Processor test", function () {
|
|||||||
|
|
||||||
it("Should match a NOp with random vals", async () => {
|
it("Should match a NOp with random vals", async () => {
|
||||||
let siblings = [];
|
let siblings = [];
|
||||||
while (siblings.length<10) siblings.push(Fr.e(88));
|
while (siblings.length<10) siblings.push(bigInt(88));
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
fnc: [0,0],
|
fnc: [0,0],
|
||||||
oldRoot: 11,
|
oldRoot: 11,
|
||||||
siblings: siblings,
|
siblings: siblings,
|
||||||
@@ -182,12 +190,12 @@ describe("SMT Processor test", function () {
|
|||||||
newValue: 77
|
newValue: 77
|
||||||
});
|
});
|
||||||
|
|
||||||
const root1 = w[circuit.symbols["main.oldRoot"].varIdx];
|
const root1 = w[circuit.getSignalIdx("main.oldRoot")];
|
||||||
const root2 = w[circuit.symbols["main.newRoot"].varIdx];
|
const root2 = w[circuit.getSignalIdx("main.newRoot")];
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
assert(root1.equals(root2));
|
||||||
|
|
||||||
assert(Fr.eq(root1, root2));
|
|
||||||
});
|
});
|
||||||
it("Should update an element", async () => {
|
it("Should update an element", async () => {
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
@@ -205,4 +213,5 @@ describe("SMT Processor test", function () {
|
|||||||
await testUpdate(tree1, 9, 999, circuit);
|
await testUpdate(tree1, 9, 999, circuit);
|
||||||
await testUpdate(tree1, 32, 323232, circuit);
|
await testUpdate(tree1, 32, 323232, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const Fr = require("ffjavascript").bn128.Fr;
|
const snarkjs = require("snarkjs");
|
||||||
const tester = require("circom").tester;
|
const compiler = require("circom");
|
||||||
|
|
||||||
const smt = require("../src/smt.js");
|
const smt = require("../src/smt.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
@@ -17,9 +19,9 @@ async function testInclusion(tree, key, circuit) {
|
|||||||
|
|
||||||
assert(res.found);
|
assert(res.found);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length<10) siblings.push(Fr.e(0));
|
while (siblings.length<10) siblings.push(bigInt(0));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
fnc: 0,
|
fnc: 0,
|
||||||
root: tree.root,
|
root: tree.root,
|
||||||
@@ -29,10 +31,9 @@ async function testInclusion(tree, key, circuit) {
|
|||||||
isOld0: 0,
|
isOld0: 0,
|
||||||
key: key,
|
key: key,
|
||||||
value: res.foundValue
|
value: res.foundValue
|
||||||
}, true);
|
});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
|
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testExclusion(tree, key, circuit) {
|
async function testExclusion(tree, key, circuit) {
|
||||||
@@ -40,9 +41,9 @@ async function testExclusion(tree, key, circuit) {
|
|||||||
|
|
||||||
assert(!res.found);
|
assert(!res.found);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length<10) siblings.push(Fr.e(0));
|
while (siblings.length<10) siblings.push(bigInt(0));
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
fnc: 1,
|
fnc: 1,
|
||||||
root: tree.root,
|
root: tree.root,
|
||||||
@@ -54,18 +55,21 @@ async function testExclusion(tree, key, circuit) {
|
|||||||
value: 0
|
value: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("SMT Verifier test", function () {
|
describe("SMT test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
let tree;
|
let tree;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
circuit = await tester(path.join(__dirname, "circuits", "smtverifier10_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "smtverifier10_test.circom"));
|
||||||
|
|
||||||
|
circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
console.log("NConstrains SMTVerifier: " + circuit.nConstraints);
|
||||||
|
|
||||||
tree = await smt.newMemEmptyTrie();
|
tree = await smt.newMemEmptyTrie();
|
||||||
await tree.insert(7,77);
|
await tree.insert(7,77);
|
||||||
@@ -93,7 +97,7 @@ describe("SMT Verifier test", function () {
|
|||||||
let siblings = [];
|
let siblings = [];
|
||||||
for (let i=0; i<10; i++) siblings.push(i);
|
for (let i=0; i<10; i++) siblings.push(i);
|
||||||
|
|
||||||
const w = await circuit.calculateWitness({
|
const w = circuit.calculateWitness({
|
||||||
enabled: 0,
|
enabled: 0,
|
||||||
fnc: 0,
|
fnc: 0,
|
||||||
root: 1,
|
root: 1,
|
||||||
@@ -104,32 +108,7 @@ describe("SMT Verifier test", function () {
|
|||||||
key: 44,
|
key: 44,
|
||||||
value: 0
|
value: 0
|
||||||
});
|
});
|
||||||
|
assert(circuit.checkWitness(w));
|
||||||
|
|
||||||
await circuit.checkConstraints(w);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Check inclussion Adria case", async () => {
|
|
||||||
const e1_hi= Fr.e("17124152697573569611556136390143205198134245887034837071647643529178599000839");
|
|
||||||
const e1_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
|
||||||
|
|
||||||
const e2ok_hi= Fr.e("16498254692537945203721083102154618658340563351558973077349594629411025251262");
|
|
||||||
const e2ok_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
|
||||||
|
|
||||||
const e2fail_hi= Fr.e("17195092312975762537892237130737365903429674363577646686847513978084990105579");
|
|
||||||
const e2fail_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
|
||||||
|
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
|
||||||
await tree1.insert(e1_hi,e1_hv);
|
|
||||||
await tree1.insert(e2ok_hi,e2ok_hv);
|
|
||||||
|
|
||||||
await testInclusion(tree1, e2ok_hi, circuit);
|
|
||||||
|
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
|
||||||
await tree2.insert(e1_hi,e1_hv);
|
|
||||||
await tree2.insert(e2fail_hi,e2fail_hv);
|
|
||||||
|
|
||||||
await testInclusion(tree2, e2fail_hi, circuit);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user