nim-groth16/witness.nim

81 lines
2.4 KiB
Nim

#
# parsing the `.wtns` file computed by `circom` witness code genereators
#
# Note: the witness values are a flat array of size `nvars`, organized
# in the following order:
#
# [ 1 | public output | public input | private input | secret witness ]
#
# so we have
#
# nvars = 1 + pub + secret = 1 + npubout + npubin + nprivin + nsecret
#
# NOTE: Unlike the `.zkey` files, which encode field elements in the
# Montgomery representation, the `.wtns` file encode field elements in
# the standard representation!
#
import std/streams
import constantine/math/arithmetic except Fp, Fr
import constantine/math/io/io_bigints
import ./bn128
import ./container
#-------------------------------------------------------------------------------
type
Witness* = object
curve* : string
r* : BigInt[256]
nvars* : int
values* : seq[Fr]
#-------------------------------------------------------------------------------
proc parseSection1_header( stream: Stream, user: var Witness, sectionLen: int ) =
# echo "\nparsing witness header"
let (n8r, r) = parsePrimeField( stream ) # size of the scalar field
user.r = r;
# echo("r = ",toDecimalBig(r))
assert( sectionLen == 4 + n8r + 4 , "unexpected section length")
assert( n8r == 32 , "expecting 256 bit prime" )
assert( bool(r == primeR) , "expecting the alt-bn128 curve" )
user.curve = "bn128"
let nvars = int( stream.readUint32() )
user.nvars = nvars;
# echo("nvars = ",nvars)
#-------------------------------------------------------------------------------
proc parseSection2_witness( stream: Stream, user: var Witness, sectionLen: int ) =
assert( sectionLen == 32 * user.nvars )
user.values = loadValuesFrStd( user.nvars, stream )
#-------------------------------------------------------------------------------
proc wtnsCallback(stream: Stream, sectId: int, sectLen: int, user: var Witness) =
#echo(sectId)
case sectId
of 1: parseSection1_header( stream, user, sectLen )
of 2: parseSection2_witness( stream, user, sectLen )
else: discard
proc parseWitness* (fname: string): Witness =
var wtns : Witness
parseContainer( "wtns", 2, fname, wtns, wtnsCallback, proc (id: int): bool = id == 1 )
parseContainer( "wtns", 2, fname, wtns, wtnsCallback, proc (id: int): bool = id != 1 )
return wtns
#-------------------------------------------------------------------------------