chainark

package module
v0.5.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2025 License: Apache-2.0 Imports: 9 Imported by: 5

README

chainark

a ZKP library to prove a chain of any given relationship, block chain, signature chain, etc. The relationship is defined by application developers, while this library focuses on how we can prove the entire relationship chain with only one proof. This library comes with an easy to understand example.

Under the hood, we have defined two roles:

  • Units, the circuit that application developers should implement to constraint the relationship to be proved;
  • Recursive, the rolling proof to attestate the chain structure from Genesis to the latest in the chain.

We have upgraded chainark to allow Units to have multiple implementations, providing a more compact proving system. In the attached example, we may have the unit to prove 1 relationship (nextId = hash(currentId)), or 2 (nextNextId = hash(hash(currentId))), etc.

Further, chainark also allows to have multiple implementation for Recursive circuits. A typical example is to have the recursive circuit directly (non-recursive) verify some relationship to further extend the link, resulting in the HybridCircuit. This has been added to the attached example as well.

When all the unit circuits, the recursive ciruit, and all the hybrid cricuits have sizes in the same 2's-power range (for this version, ($2^{23}$ ~ $2^{24}$)), there is an optional optimization that oculd be turned on to reduce the size of the recursive circuit. Turn on optimization by adding the optional parameter with value true to the chainark.NewRecursiveCircuit function call. This optimization may reduce over 1.2 ~ 3 million constraints (depending on gnark version) but the prerequisite might not hold in a future version of chainark or gnark. The example/setup2.sh demonstrates this feature by adding some extra costs to the circuit to adjust the constraint count of the circuits.

how to use

Besides following the example to write contraints for your own business logic, note that you also need to verify if SelfFps used during recursive verification are as expected, in order to verify a proof generated by the Recursive or Hybrid circuit. To simplify the API and prevent from missing crucial constraints, we have added a recursive verifier API to verify proof generated by the Recursive or Hybrid circuit.

security

If you found security issues in chainark, please send an email to hello@lightec.xyz. We appreciate your contributions. Once the zkBTC project goes live, we will be able to reward some tokens once the issue has been confirmed.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssertIDWitness

func AssertIDWitness[FR emulated.FieldParams](
	api frontend.API, id LinkageID, witnessValues []emulated.Element[FR], nbMaxBitsPerVar ...uint,
)

func GetPlaceholderFp added in v0.4.0

func GetPlaceholderFp() common_utils.FingerPrintBytes

func TestIDWitness added in v0.3.1

func TestIDWitness[FR emulated.FieldParams](
	api frontend.API, id LinkageID, witnessValues []emulated.Element[FR], nbMaxBitsPerVar ...uint,
) frontend.Variable

func TestRecursiveFps added in v0.5.1

func TestRecursiveFps[FR emulated.FieldParams](api frontend.API, witness plonk.Witness[FR], selfFps []common_utils.FingerPrint[FR],
	initialOffset, nbFpVars, nbSelfFps int) frontend.Variable

Types

type HybridCircuit added in v0.4.0

type HybridCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct {
	BeginID LinkageID `gnark:",public"`
	RelayID LinkageID
	EndID   LinkageID `gnark:",public"`

	SelfFps []common_utils.FingerPrint[FR] `gnark:",public"`

	FirstVKey    plonk.VerifyingKey[FR, G1El, G2El]
	FirstProof   plonk.Proof[FR, G1El, G2El]
	FirstWitness plonk.Witness[FR]

	SecondComp UnitCore[FR, G1El, G2El, GtEl]

	// constant values passed from outside
	ValidUnitFps []common_utils.FingerPrintBytes
	NbSelfFps    int
}

func NewHybridAssignment added in v0.4.0

func NewHybridAssignment[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	firstVkey plonk.VerifyingKey[FR, G1El, G2El],
	firstProof plonk.Proof[FR, G1El, G2El],
	firstWitness plonk.Witness[FR],
	recursiveFps []common_utils.FingerPrint[FR],
	beginID, relayID, endID LinkageID,
	extraComp UnitCore[FR, G1El, G2El, GtEl],
) *HybridCircuit[FR, G1El, G2El, GtEl]

func NewHybridCircuit added in v0.4.0

func NewHybridCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	nbIdVals, bitsPerIdVal int,
	ccsUnit constraint.ConstraintSystem,
	unitFpBytes []common_utils.FingerPrintBytes, nbSelfFps int,
	extraComp UnitCore[FR, G1El, G2El, GtEl],
) *HybridCircuit[FR, G1El, G2El, GtEl]

func (*HybridCircuit[FR, G1El, G2El, GtEl]) Define added in v0.4.0

func (c *HybridCircuit[FR, G1El, G2El, GtEl]) Define(api frontend.API) error

type LinkageID

type LinkageID struct {
	Vals       []frontend.Variable
	BitsPerVar int
}

func LinkageIDFromBytes

func LinkageIDFromBytes(data LinkageIDBytes, bitsPerVar int) LinkageID

func LinkageIDFromU8s

func LinkageIDFromU8s(api frontend.API, data []uints.U8, bitsPerVar int) LinkageID

func PlaceholderLinkageID

func PlaceholderLinkageID(nbEles, bitsPerVar int) LinkageID

func RetrieveIDFromElements added in v0.5.6

func RetrieveIDFromElements[FR emulated.FieldParams](
	api frontend.API, witnessValues []emulated.Element[FR], bitsPerVar uint,
) LinkageID

func (LinkageID) AssertIsEqual

func (id LinkageID) AssertIsEqual(api frontend.API, other LinkageID)

func (LinkageID) IsEqual

func (id LinkageID) IsEqual(api frontend.API, other LinkageID) frontend.Variable

func (LinkageID) ToU8s added in v0.5.6

func (id LinkageID) ToU8s(api frontend.API) []uints.U8

type LinkageIDBytes

type LinkageIDBytes []byte

type MultiRecursiveCircuit added in v0.4.0

type MultiRecursiveCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct {
	BeginID LinkageID `gnark:",public"`
	RelayID LinkageID
	EndID   LinkageID `gnark:",public"`

	SelfFps []common_utils.FingerPrint[FR] `gnark:",public"`

	FirstVKey    plonk.VerifyingKey[FR, G1El, G2El]
	FirstProof   plonk.Proof[FR, G1El, G2El]
	FirstWitness plonk.Witness[FR]

	SecondVKey    plonk.VerifyingKey[FR, G1El, G2El]
	SecondProof   plonk.Proof[FR, G1El, G2El]
	SecondWitness plonk.Witness[FR]

	// constant values passed from outside
	ValidUnitFps []common_utils.FingerPrintBytes
	NbSelfFps    int
	// contains filtered or unexported fields
}

func NewMultiRecursiveAssignment added in v0.4.0

func NewMultiRecursiveAssignment[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	firstVkey, secondVkey plonk.VerifyingKey[FR, G1El, G2El],
	firstProof, secondProof plonk.Proof[FR, G1El, G2El],
	firstWitness, secondWitness plonk.Witness[FR],
	recursiveFps []common_utils.FingerPrint[FR],
	beginID, relayID, endID LinkageID,
) *MultiRecursiveCircuit[FR, G1El, G2El, GtEl]

func NewMultiRecursiveCircuit added in v0.4.0

func NewMultiRecursiveCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	nbIdVals, bitsPerIdVal int,
	ccsUnit constraint.ConstraintSystem,
	unitFpBytes []common_utils.FingerPrintBytes, nbSelfFps int,
	opt ...bool) *MultiRecursiveCircuit[FR, G1El, G2El, GtEl]

func (*MultiRecursiveCircuit[FR, G1El, G2El, GtEl]) Define added in v0.4.0

func (c *MultiRecursiveCircuit[FR, G1El, G2El, GtEl]) Define(api frontend.API) error

type MultiUnit added in v0.4.0

type MultiUnit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct {
	BeginID          LinkageID                      `gnark:",public"`
	EndID            LinkageID                      `gnark:",public"`
	PlaceHolderFps   []common_utils.FingerPrint[FR] `gnark:",public"` // so that Unit could share the same witness alignment with Recursive
	NbPlaceHolderFps int
}

func NewMultiUnitAssignment added in v0.4.0

func NewMultiUnitAssignment[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	beginId, endId LinkageIDBytes, bitsPerIdVal int,
	nbHolders int,
) *MultiUnit[FR, G1El, G2El, GtEl]

func NewMultiUnitCircuit added in v0.4.0

func NewMultiUnitCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	nbIdVals, bitsPerIdVal, nbPlaceHolderFps int,
) *MultiUnit[FR, G1El, G2El, GtEl]

func (*MultiUnit[FR, G1El, G2El, GtEl]) Define added in v0.4.0

func (c *MultiUnit[FR, G1El, G2El, GtEl]) Define(api frontend.API) error

type RecursiveCircuit

type RecursiveCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct {
	*MultiRecursiveCircuit[FR, G1El, G2El, GtEl]
}

func NewRecursiveAssignment added in v0.2.0

func NewRecursiveAssignment[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	firstVkey, secondVkey plonk.VerifyingKey[FR, G1El, G2El],
	firstProof, secondProof plonk.Proof[FR, G1El, G2El],
	firstWitness, secondWitness plonk.Witness[FR],
	recursiveFp common_utils.FingerPrint[FR],
	beginID, relayID, endID LinkageID,
) *RecursiveCircuit[FR, G1El, G2El, GtEl]

func NewRecursiveCircuit added in v0.2.0

func NewRecursiveCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	nbIdVals, bitsPerIdVal int,
	ccsUnit constraint.ConstraintSystem,
	unitFpBytes []common_utils.FingerPrintBytes,
	opt ...bool) *RecursiveCircuit[FR, G1El, G2El, GtEl]

func (*RecursiveCircuit[FR, G1El, G2El, GtEl]) Define

func (c *RecursiveCircuit[FR, G1El, G2El, GtEl]) Define(api frontend.API) error

note that as we remove genesis, recursive could take in the first proof as unit, resulting in a genesis proof

type Unit added in v0.3.1

type Unit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct {
	*MultiUnit[FR, G1El, G2El, GtEl]
}

func NewUnitAssignment added in v0.3.1

func NewUnitAssignment[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	beginId, endId LinkageIDBytes, bitsPerIdVal int,
) *Unit[FR, G1El, G2El, GtEl]

func NewUnitCircuit added in v0.3.1

func NewUnitCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	nbIdVals, bitsPerIdVal int,
) *Unit[FR, G1El, G2El, GtEl]

func (*Unit[FR, G1El, G2El, GtEl]) Define added in v0.3.1

func (c *Unit[FR, G1El, G2El, GtEl]) Define(api frontend.API) error

type UnitCore added in v0.4.0

type UnitCore[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] interface {
	Define(api frontend.API) error
	GetBeginID() LinkageID
	GetEndID() LinkageID
}

type Verifier added in v0.5.2

type Verifier[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct {
	VKey    plonk.VerifyingKey[FR, G1El, G2El]
	Proof   plonk.Proof[FR, G1El, G2El]
	Witness plonk.Witness[FR]

	// circuit constants
	VkeyFpsBytes []common_utils.FingerPrintBytes
	NbIdVars     int
	NbFpVars     int
	NbSelfFps    int
}

func NewVerifierAssignment added in v0.5.2

func NewVerifierAssignment[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	vkey native_plonk.VerifyingKey,
	proof native_plonk.Proof,
	witness witness.Witness,
) (*Verifier[FR, G1El, G2El, GtEl], error)

func NewVerifierCircuit added in v0.5.2

func NewVerifierCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](
	ccs constraint.ConstraintSystem,
	vkeyFpsBytes []common_utils.FingerPrintBytes,
	nbIdVars, nbFpVars, nbSelfFps int,
) (*Verifier[FR, G1El, G2El, GtEl], error)

func (*Verifier[FR, G1El, G2El, GtEl]) Define added in v0.5.2

func (c *Verifier[FR, G1El, G2El, GtEl]) Define(api frontend.API) error

Directories

Path Synopsis
example
recursive command
unit command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL