mirror of
https://github.com/logos-storage/nim-groth16.git
synced 2026-05-18 16:49:30 +00:00
141 lines
3.7 KiB
Nim
141 lines
3.7 KiB
Nim
|
|
import std/unittest
|
|
|
|
import groth16/bn128/fields
|
|
import groth16/files/r1cs
|
|
|
|
suite "R1CS operations":
|
|
|
|
test "R1CS creation":
|
|
let cfg = WitnessConfig(
|
|
nWires: 8,
|
|
nPubOut: 1,
|
|
nPubIn: 1,
|
|
nPrivIn: 3,
|
|
nLabels: 0
|
|
)
|
|
|
|
let constraint1: Constraint = (
|
|
A: @[(wireIdx: 1, value: minusOneFr), (wireIdx: 2, value: oneFr), (wireIdx: 7, value: oneFr)],
|
|
B: @[],
|
|
C: @[]
|
|
)
|
|
|
|
let constraint2: Constraint = (
|
|
A: @[(wireIdx: 3, value: oneFr)],
|
|
B: @[(wireIdx: 4, value: oneFr)],
|
|
C: @[(wireIdx: 6, value: oneFr)]
|
|
)
|
|
|
|
let constraints = @[constraint1, constraint2]
|
|
|
|
let r1cs = R1CS(
|
|
r: primeR,
|
|
cfg: cfg,
|
|
nConstr: constraints.len,
|
|
constraints: constraints,
|
|
wireToLabel: @[]
|
|
)
|
|
|
|
check r1cs.cfg.nWires == 8
|
|
check r1cs.nConstr == 2
|
|
check r1cs.constraints.len == 2
|
|
|
|
test "R1CS constraint structure":
|
|
let constraint: Constraint = (
|
|
A: @[(wireIdx: 0, value: oneFr), (wireIdx: 1, value: intToFr(2))],
|
|
B: @[(wireIdx: 2, value: intToFr(3))],
|
|
C: @[(wireIdx: 3, value: intToFr(4))]
|
|
)
|
|
|
|
check constraint.A.len == 2
|
|
check constraint.B.len == 1
|
|
check constraint.C.len == 1
|
|
check isEqualFr(constraint.A[0].value, oneFr)
|
|
check isEqualFr(constraint.A[1].value, intToFr(2))
|
|
|
|
test "R1CS witness config":
|
|
let cfg = WitnessConfig(
|
|
nWires: 10,
|
|
nPubOut: 2,
|
|
nPubIn: 3,
|
|
nPrivIn: 4,
|
|
nLabels: 1
|
|
)
|
|
|
|
check cfg.nWires == 10
|
|
check cfg.nPubOut == 2
|
|
check cfg.nPubIn == 3
|
|
check cfg.nPrivIn == 4
|
|
check cfg.nLabels == 1
|
|
|
|
test "R1CS term creation":
|
|
let term1: Term = (wireIdx: 5, value: intToFr(42))
|
|
let term2: Term = (wireIdx: 3, value: minusOneFr)
|
|
|
|
check term1.wireIdx == 5
|
|
check isEqualFr(term1.value, intToFr(42))
|
|
check term2.wireIdx == 3
|
|
check isEqualFr(term2.value, minusOneFr)
|
|
|
|
test "R1CS linear combination":
|
|
let linComb: LinComb = @[
|
|
(wireIdx: 0, value: oneFr),
|
|
(wireIdx: 1, value: intToFr(2)),
|
|
(wireIdx: 2, value: intToFr(3))
|
|
]
|
|
|
|
check linComb.len == 3
|
|
check linComb[0].wireIdx == 0
|
|
check isEqualFr(linComb[1].value, intToFr(2))
|
|
|
|
test "R1CS constraint evaluation":
|
|
let x = intToFr(5)
|
|
let y = intToFr(7)
|
|
let expected = x * y
|
|
|
|
let constraint: Constraint = (
|
|
A: @[(wireIdx: 0, value: x)],
|
|
B: @[(wireIdx: 1, value: y)],
|
|
C: @[(wireIdx: 2, value: expected)]
|
|
)
|
|
|
|
let product = constraint.A[0].value * constraint.B[0].value
|
|
check isEqualFr(product, constraint.C[0].value)
|
|
|
|
test "R1CS empty constraint":
|
|
let emptyConstraint: Constraint = (
|
|
A: @[],
|
|
B: @[],
|
|
C: @[]
|
|
)
|
|
|
|
check emptyConstraint.A.len == 0
|
|
check emptyConstraint.B.len == 0
|
|
check emptyConstraint.C.len == 0
|
|
|
|
test "R1CS multiple constraints":
|
|
let constraints = @[
|
|
(A: @[(wireIdx: 0, value: oneFr)], B: @[(wireIdx: 1, value: oneFr)], C: @[(wireIdx: 2, value: oneFr)]),
|
|
(A: @[(wireIdx: 2, value: oneFr)], B: @[(wireIdx: 3, value: oneFr)], C: @[(wireIdx: 4, value: oneFr)]),
|
|
(A: @[(wireIdx: 4, value: oneFr)], B: @[(wireIdx: 5, value: oneFr)], C: @[(wireIdx: 6, value: oneFr)])
|
|
]
|
|
|
|
check constraints.len == 3
|
|
for i, constraint in constraints:
|
|
check constraint.A.len > 0 or constraint.B.len > 0 or constraint.C.len > 0
|
|
|
|
test "R1CS wire to label mapping":
|
|
let wireToLabel = @[0, 1, 2, 3, 4]
|
|
let r1cs = R1CS(
|
|
r: primeR,
|
|
cfg: WitnessConfig(nWires: 5, nPubOut: 0, nPubIn: 0, nPrivIn: 0, nLabels: 0),
|
|
nConstr: 0,
|
|
constraints: @[],
|
|
wireToLabel: wireToLabel
|
|
)
|
|
|
|
check r1cs.wireToLabel.len == 5
|
|
check r1cs.wireToLabel[0] == 0
|
|
check r1cs.wireToLabel[4] == 4
|