2025-11-13 20:11:31 +01:00

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)
#-------------------------------------------------------------------------------