mirror of
https://github.com/logos-storage/nim-groth16.git
synced 2026-01-03 14:13:08 +00:00
81 lines
2.4 KiB
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
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|