mirror of
https://github.com/logos-storage/circom-witnessgen.git
synced 2026-01-02 13:03:09 +00:00
150 lines
3.6 KiB
Nim
150 lines
3.6 KiB
Nim
|
|
import std/sugar
|
|
import std/tables
|
|
|
|
import pkg/constantine/math/io/io_bigints
|
|
|
|
import ./field
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
type
|
|
|
|
Inputs* = Table[string, seq[F]]
|
|
|
|
UnoOp* = enum
|
|
Neg,
|
|
Id,
|
|
Lnot,
|
|
Bnot
|
|
|
|
DuoOp* = enum
|
|
Mul,
|
|
Div,
|
|
Add,
|
|
Sub,
|
|
Pow,
|
|
Idiv,
|
|
Mod,
|
|
Eq,
|
|
Neq,
|
|
Lt,
|
|
Gt,
|
|
Leq,
|
|
Geq,
|
|
Land,
|
|
Lor,
|
|
Shl,
|
|
Shr,
|
|
Bor,
|
|
Band,
|
|
Bxor
|
|
|
|
TresOp* = enum
|
|
TernCond
|
|
|
|
BigUInt* = object
|
|
bytes*: seq[byte]
|
|
|
|
InputNode* = object
|
|
idx*: uint32
|
|
|
|
ConstantNode* = object
|
|
bigVal*: BigUInt
|
|
|
|
UnoOpNode*[T] = object
|
|
op*: UnoOp
|
|
arg1*: T
|
|
|
|
DuoOpNode*[T] = object
|
|
op*: DuoOp
|
|
arg1*: T
|
|
arg2*: T
|
|
|
|
TresOpNode*[T] = object
|
|
op*: TresOp
|
|
arg1*: T
|
|
arg2*: T
|
|
arg3*: T
|
|
|
|
NodeKind* = enum Input, Const, Uno, Duo, Tres
|
|
|
|
Node*[T] = object
|
|
case kind*: NodeKind
|
|
of Input: inp*: InputNode
|
|
of Const: kst*: ConstantNode
|
|
of Uno: uno*: UnoOpNode[T]
|
|
of Duo: duo*: DuoOpNode[T]
|
|
of Tres: tres*: TresOpNode[T]
|
|
|
|
SignalDescription* = object
|
|
offset*: uint32
|
|
length*: uint32
|
|
|
|
WitnessMapping* = object
|
|
mapping*: seq[uint32]
|
|
|
|
CircuitInputs* = seq[(string, SignalDescription)]
|
|
|
|
Prime* = object
|
|
primeNumber*: BigUInt
|
|
primeName*: string
|
|
|
|
GraphMetaData* = object
|
|
witnessMapping*: WitnessMapping
|
|
inputSignals*: CircuitInputs
|
|
prime*: Prime
|
|
|
|
Graph* = object
|
|
nodes*: seq[Node[uint32]]
|
|
meta*: GraphMetaData
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
func unwrapBigUInt*(x: BigUInt): seq[byte] = x.bytes
|
|
|
|
func bigFromBigUInt*(big: BigUInt): B =
|
|
let bytes = unwrapBigUInt(big)
|
|
var buf: seq[byte] = newSeq[byte](32)
|
|
for i, x in bytes.pairs():
|
|
buf[i] = x
|
|
var output : B
|
|
unmarshal(output, buf, littleEndian)
|
|
return output
|
|
|
|
func fromBigUInt*(big: BigUInt): F =
|
|
return bigToF(bigFromBigUInt(big))
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
proc fmapUno[S,T]( fun: (S) -> T , node: UnoOpNode[S]): UnoOpNode[T] =
|
|
UnoOpNode[T]( op: node.op, arg1: fun(node.arg1) )
|
|
|
|
proc fmapDuo[S,T]( fun: (S) -> T , node: DuoOpNode[S]): DuoOpNode[T] =
|
|
DuoOpNode[T]( op: node.op, arg1: fun(node.arg1), arg2: fun(node.arg2) )
|
|
|
|
proc fmapTres[S,T]( fun: (S) -> T , node: TresOpNode[S]): TresOpNode[T] =
|
|
TresOpNode[T]( op: node.op, arg1: fun(node.arg1), arg2: fun(node.arg2), arg3: fun(node.arg3) )
|
|
|
|
proc fmap* [S,T]( fun: (S) -> T , node: Node[S]): Node[T] =
|
|
case node.kind:
|
|
of Input: Node[T](kind: Input , inp: node.inp )
|
|
of Const: Node[T](kind: Const , kst: node.kst )
|
|
of Uno: Node[T](kind: Uno , uno: fmapUno( fun, node.uno ) )
|
|
of Duo: Node[T](kind: Duo , duo: fmapDuo( fun, node.duo ) )
|
|
of Tres: Node[T](kind: Tres , tres: fmapTres(fun, node.tres) )
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
proc showNodeUint32*( node: Node[uint32] ): string =
|
|
case node.kind:
|
|
of Input: "Input idx=" & ($node.inp.idx)
|
|
of Const: "Const kst=" & bigToDecimal(bigFromBigUInt(node.kst.bigVal))
|
|
of Uno: "Uno op=" & ($node.uno.op ) & " | arg1=" & ($node.uno.arg1 )
|
|
of Duo: "Duo op=" & ($node.duo.op ) & " | arg1=" & ($node.duo.arg1 ) & " | arg2=" & ($node.duo.arg2 )
|
|
of Tres: "Tres op=" & ($node.tres.op) & " | arg1=" & ($node.tres.arg1) & " | arg2=" & ($node.tres.arg2) & " | arg3=" & ($node.tres.arg3)
|
|
|
|
proc printNodeUint32*( node: Node[uint32] ) = echo showNodeUint32(node)
|
|
|
|
#-------------------------------------------------------------------------------
|