exporting R1CS files (for row reordering purposes)

This commit is contained in:
Balazs Komuves 2026-06-16 02:38:18 +02:00
parent a66865e5f7
commit e532d67046
No known key found for this signature in database
GPG Key ID: F63B7AEF18435562
4 changed files with 100 additions and 3 deletions

View File

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

View File

@ -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"
#-------------------------------------------------------------------------------

View File

@ -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...
#
#-------------------------------------------------------------------------------

View File

@ -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/).