mirror of
https://github.com/logos-storage/nim-groth16.git
synced 2026-07-21 16:09:25 +00:00
exporting R1CS files (for row reordering purposes)
This commit is contained in:
parent
a66865e5f7
commit
e532d67046
@ -94,3 +94,18 @@ proc parseContainer*[T] ( expectedMagic: string
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
proc writeGlobalHeader*( stream: Stream, magic: string, version: int, nsections: int ) =
|
||||
write[uint32]( stream , magicWord(magic) )
|
||||
write[uint32]( stream , version.uint32 )
|
||||
write[uint32]( stream , nsections.uint32 )
|
||||
|
||||
# WTF seriously...
|
||||
proc writeBytes*( stream: Stream, data: seq[byte] ) =
|
||||
stream.writeData( addr(data[0]), data.len )
|
||||
|
||||
proc writeSection*( stream: Stream, sectionId: int, sectionData: seq[byte] ) =
|
||||
write[uint32]( stream , sectionId.uint32 )
|
||||
write[uint64]( stream , sectionData.len.uint64 )
|
||||
writeBytes( stream , sectionData )
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -19,11 +19,11 @@
|
||||
# nPubIn : word32 = number of public inputs
|
||||
# nPrivIn : word32 = number of private inputs
|
||||
# nLabels : word64 = number of labels (variable names in the circom source code)
|
||||
# nConstr : word32 = number of constraints
|
||||
#
|
||||
# 2: Constraints
|
||||
# --------------
|
||||
# nConstr : word32 = number of constraints
|
||||
# then an array of constraints:
|
||||
# An array of constraints:
|
||||
# A : LinComb
|
||||
# B : LinComb
|
||||
# C : LinComb
|
||||
@ -190,3 +190,83 @@ proc parseR1CS* (fname: string): R1CS =
|
||||
return r1cs
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# writing R1CS files (required for reordering the rows)
|
||||
|
||||
proc writeWitnessConfig(stream: Stream, cfg: WitnessConfig ) =
|
||||
write[uint32]( stream , cfg.nWires.uint32 ) # total number of wires (or witness variables)
|
||||
write[uint32]( stream , cfg.nPubOut.uint32 ) # number of public outputs
|
||||
write[uint32]( stream , cfg.nPubIn.uint32 ) # number of public inputs
|
||||
write[uint32]( stream , cfg.nPrivIn.uint32 ) # number of private inputs
|
||||
write[uint64]( stream , cfg.nLabels.uint32 ) # number of labels
|
||||
|
||||
proc writeR1CSHeader(stream: Stream, r1cs: R1CS ) =
|
||||
write[uint32]( stream , 32 ) # n8r
|
||||
write( stream , r1cs.r ) # the value of r
|
||||
writeWitnessConfig( stream , r1cs.cfg ) # witness config
|
||||
write[uint32]( stream , r1cs.nConstr.uint32 ) # number of constraints
|
||||
|
||||
proc r1csHeaderSection*(r1cs: R1CS): seq[byte] =
|
||||
var stream = newStringStream()
|
||||
stream.writeR1CSHeader(r1cs)
|
||||
stream.flush()
|
||||
stream.setPosition(0)
|
||||
let bytes = cast[seq[byte]](stream.readAll()) # WTF nim
|
||||
stream.close()
|
||||
return bytes
|
||||
|
||||
proc r1csWireToLabelSection*(r1cs: R1CS): seq[byte] =
|
||||
var stream = newStringStream()
|
||||
for x in r1cs.wireToLabel:
|
||||
write[uint64]( stream , x.uint64 )
|
||||
stream.flush()
|
||||
stream.setPosition(0)
|
||||
let bytes = cast[seq[byte]](stream.readAll()) # WTF nim
|
||||
stream.close()
|
||||
return bytes
|
||||
|
||||
proc writeFr(stream: Stream, x: Fr[BN254_Snarks]) =
|
||||
var big : BigInt[254] # fucking constantine
|
||||
big = x.toBig()
|
||||
stream.write(big)
|
||||
|
||||
proc writeTerm(stream: Stream, term: Term ) =
|
||||
write[uint32]( stream , term.wireIdx.uint32 )
|
||||
writeFr( stream , term.value )
|
||||
|
||||
proc writeLinComb(stream: Stream, lc: LinComb ) =
|
||||
write[uint32]( stream , lc.len.uint32 )
|
||||
for term in lc:
|
||||
writeTerm(stream, term)
|
||||
|
||||
proc writeConstraint(stream: Stream, con: Constraint ) =
|
||||
writeLinComb( stream, con.A )
|
||||
writeLinComb( stream, con.B )
|
||||
writeLinComb( stream, con.C )
|
||||
|
||||
proc r1csConstraintsSection*(r1cs: R1CS): seq[byte] =
|
||||
var stream = newStringStream()
|
||||
for c in r1cs.constraints:
|
||||
writeConstraint( stream, c )
|
||||
stream.flush()
|
||||
stream.setPosition(0)
|
||||
let bytes = cast[seq[byte]](stream.readAll()) # WTF nim
|
||||
stream.close()
|
||||
return bytes
|
||||
|
||||
proc exportR1CS*(fname: string, r1cs: R1CS) =
|
||||
let section1 = r1csHeaderSection( r1cs)
|
||||
let section2 = r1csConstraintsSection(r1cs)
|
||||
let section3 = r1csWireToLabelSection(r1cs)
|
||||
echo $section1.len
|
||||
echo $section2.len
|
||||
echo $section3.len
|
||||
var stream = newFileStream(fname, fmWrite)
|
||||
writeGlobalHeader( stream , "r1cs" , 1 , 3 )
|
||||
writeSection( stream , 2 , section2 )
|
||||
writeSection( stream , 1 , section1 )
|
||||
writeSection( stream , 3 , section3 )
|
||||
stream.flush()
|
||||
stream.close()
|
||||
echo "fuck"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
# Number-theoretic transform
|
||||
# (that is, FFT for polynomials over finite fields)
|
||||
#
|
||||
# TODO: flip the order of arguments, so that the domain is first...
|
||||
#
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -11,6 +11,6 @@ for more details.
|
||||
This is essentially free (the overhead is minimal, so already when doing 2 proofs
|
||||
with same shared part of the witness, it's worth do it).
|
||||
|
||||
A more advanced version, but also with a more heave trade-off, is developed in
|
||||
A more advanced version, but one which also comes with a heavy trade-off, is developed in
|
||||
[`groth16/dynamic`](../dynamic/).
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user