zkbas-crypto

module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Aug 3, 2022 License: Apache-2.0

README

zkbas-crypto

github.com/bnb-chain/zkbas-crypto is the crypto library for Zecrey Protocol. It implements not only basic cryptography algorithms, such as commitment scheme, ECC utils, finite field utils, ElGamal Encryption, .etc, but also advanced cryptography algorithms, such as BulletProofs, Twisted ElGamal Encryption, Sigma Protocols, Zecrey Privacy Proofs. What's more, it provides many implementations based on different Elliptic Curves. It also includes the core crypto algorithm of the Zecrey Protocol, such as ComRangeProof, Privacy Proof, circuit of Zecrey. Zecrey is based on the curve which is called baby jubjub or twisted bn254, so the implementation of baby jubjub is the core part.

Project Structure

ZECREY-CRYPTO
├─.github
│  ├─ISSUE_TEMPLATE
│  └─workflows
├─accumulators // merkle tree implementation
│  └─merkleTree
├─commitment // commitment scheme
│  ├─secp256k1
│  │  └─pedersen
│  └─twistededwards
│      └─tebn254
│          └─pedersen // perdersen commitment
├─ecc // ellptic curves wrapper
│  ├─zbls381
│  ├─zbn254
│  ├─zp256
│  └─ztwistededwards // twisted edwards curve
│      └─tebn254 // baby jubjub
├─elgamal // elgamal algorithms
│  ├─bls381
│  │  ├─elgamal
│  │  └─twistedElgamal
│  ├─bn254
│  │  ├─elgamal
│  │  └─twistedElgamal
│  ├─secp256k1
│  │  ├─elgamal
│  │  └─twistedElgamal
│  └─twistededwards
│      └─tebn254
│          ├─elgamal
│          └─twistedElgamal
├─ffmath // finite fields utils
├─hash // hash algorithms
│  └─bn254
│      └─zmimc
├─rangeProofs // range proofs
│  ├─secp256k1
│  │  └─bulletProofs // bullet proofs
│  └─twistededwards
│      └─tebn254
│          ├─binaryRange // binary range proofs
│          ├─bulletProofs // bullet proofs
│          ├─commitRange
│          └─ctrange // confidential transaction range proof(core algorithms of zkbas)
├─sigmaProtocol // basic sigma protocols
│  ├─secp256k1
│  │  ├─binary
│  │  ├─chaum-pedersen
│  │  ├─linear
│  │  ├─okamoto
│  │  └─schnorr
│  └─twistededwards
│      └─tebn254
│          ├─binary
│          ├─chaum-pedersen
│          ├─linear
│          ├─okamoto
│          └─schnorr
├─util // common utils
├─wasm // wasm for zkbas algorithms
├─circuit // circuit implementation
│  └─bn254
│      ├─groth16
│      ├─mockAccount
│      ├─plonk
│      ├─solidity
│      ├─std // zkbas algorithms circuit
│      ├─transactions // core circuit
│      └─zsha256
└─twistededwards // zkbas privacy proof implementation
   └─tebn254
      ─zecrey

ZKbas Privacy Proofs

CTRange Proof
Example

rangeProofs/twistededwards/tebn254/ctrange/ctrange_test.go:

func TestVerify(t *testing.T) {
	b := int64(5)
	elapse := time.Now()
	_, proof, err := Prove(b, curve.G, curve.H)
	if err != nil {
		t.Fatal(err)
	}
	fmt.Println("1:", time.Since(elapse))
	proofBytes := proof.Bytes()
	proof2, err := FromBytes(proofBytes)
	if err != nil {
		t.Fatal(err)
	}
	elapse = time.Now()
	res, err := proof2.Verify()
	if err != nil {
		t.Fatal(err)
	}
	fmt.Println("2:", time.Since(elapse))
	assert.Equal(t, true, res, "invalid proof")
}
Unlock
Example

twistededwards/tebn254/zero/unlock.go:

func TestUnlockProof_Verify(t *testing.T) {
	sk, pk := twistedElgamal.GenKeyPair()
	chainId := uint32(0)
	assetId := uint32(0)
	balance := uint64(10)
	deltaAmount := uint64(2)
	b_fee := uint64(100)
	feeEnc, _ := twistedElgamal.Enc(big.NewInt(int64(b_fee)), curve.RandomValue(), pk)
	proof, err := ProveUnlock(
		sk, chainId, assetId, balance, deltaAmount,
		feeEnc,
		b_fee, uint32(1), 1,
	)
	if err != nil {
		t.Fatal(err)
	}
	fmt.Println("sk:", sk.String())
	fmt.Println("pk:", curve.ToString(pk))
	fmt.Println("fee enc:", feeEnc.String())
	proofStr := proof.String()
	proof2, err := ParseUnlockProofStr(proofStr)
	if err != nil {
		t.Fatal(err)
	}
	res, err := proof2.Verify()
	if err != nil {
		t.Fatal(err)
	}
	assert.Equal(t, true, res, "invalid proof")
}
Transfer
Example

zero/twistededwards/tebn254/zero/transfer_test.go:

func TestCorrectInfoProve(t *testing.T) {
	sk1, pk1 := twistedElgamal.GenKeyPair()
	b1 := uint64(8)
	r1 := curve.RandomValue()
	_, pk2 := twistedElgamal.GenKeyPair()
	b2 := big.NewInt(2)
	r2 := curve.RandomValue()
	_, pk3 := twistedElgamal.GenKeyPair()
	b3 := big.NewInt(3)
	r3 := curve.RandomValue()
	b1Enc, err := twistedElgamal.Enc(big.NewInt(int64(b1)), r1, pk1)
	b2Enc, err := twistedElgamal.Enc(b2, r2, pk2)
	b3Enc, err := twistedElgamal.Enc(b3, r3, pk3)
	if err != nil {
		t.Error(err)
	}
	fmt.Println("sk1:", sk1.String())
	fmt.Println("pk1:", curve.ToString(pk1))
	fmt.Println("pk2:", curve.ToString(pk2))
	fmt.Println("pk3:", curve.ToString(pk3))
	fmt.Println("b1Enc:", b1Enc.String())
	fmt.Println("b2Enc:", b2Enc.String())
	fmt.Println("b3Enc:", b3Enc.String())
	elapse := time.Now()
	fee := uint64(1)
	relation, err := NewTransferProofRelation(1, fee)
	if err != nil {
		t.Error(err)
	}
	err = relation.AddStatement(b2Enc, pk2, 0, 2, nil)
	if err != nil {
		t.Error(err)
	}
	err = relation.AddStatement(b1Enc, pk1, b1, -3, sk1)
	if err != nil {
		t.Error(err)
	}
	err = relation.AddStatement(b3Enc, pk3, 0, 0, nil)
	if err != nil {
		t.Error(err)
	}
	proof, err := ProveTransfer(relation)
	if err != nil {
		t.Error(err)
	}
	fmt.Println("prove time:", time.Since(elapse))
	elapse = time.Now()
	proofStr := proof.String()
	proof2, err := ParseTransferProofStr(proofStr)
	if err != nil {
		t.Fatal(err)
	}
	res, err := proof2.Verify()
	if err != nil {
		t.Error(err)
	}
	fmt.Println("verify time:", time.Since(elapse))
	assert.Equal(t, true, res, "invalid proof")
}

Swap
Example

zero/twistededwards/tebn254/zero/swap_test.go:

func TestSwapProof2_Verify(t *testing.T) {
	b_u_A := uint64(2000)
	assetAId := uint32(1)
	assetBId := uint32(2)
	b_A_Delta := uint64(1000)
	b_B_Delta := uint64(970)
	MinB_B_Delta := uint64(960)
	b_poolA := uint64(40000)
	b_poolB := uint64(40000)
	feeRate := uint32(30)
	treasuryRate := uint32(10)
	GasFee := uint64(30)
	sk_u, Pk_u := twistedElgamal.GenKeyPair()
	_, Pk_pool := twistedElgamal.GenKeyPair()
	_, Pk_treasury := twistedElgamal.GenKeyPair()
	C_uA, _ := twistedElgamal.Enc(big.NewInt(int64(b_u_A)), curve.RandomValue(), Pk_u)
	b_fee := uint64(1000)
	//b_fee := b_u_A
	C_fee, _ := twistedElgamal.Enc(big.NewInt(int64(b_fee)), curve.RandomValue(), Pk_u)
	fmt.Println("sk_u:", sk_u.String())
	fmt.Println("C_u_A:", C_uA.String())
	fmt.Println("pk_u:", curve.ToString(Pk_u))
	fmt.Println("Pk_treasury:", curve.ToString(Pk_treasury))
	fmt.Println("C_u_A:", C_uA.String())
	fmt.Println("C_fee:", C_fee.String())
	relation, err := NewSwapRelation(
		C_uA,
		Pk_u, Pk_treasury,
		assetAId, assetBId,
		b_A_Delta, b_u_A,
		MinB_B_Delta,
		feeRate, treasuryRate,
		sk_u,
		C_fee,
		b_fee, uint32(2), GasFee,
	)
	if err != nil {
		t.Fatal(err)
	}
	elapse := time.Now()
	proof, err := ProveSwap(relation)
	if err != nil {
		t.Fatal(err)
	}
	// set params
	err = proof.AddPoolInfo(Pk_pool, b_B_Delta, b_poolA, b_poolB)
	if err != nil {
		t.Fatal(err)
	}
	log.Println("prove time:", time.Since(elapse))
	proofStr := proof.String()
	proof2, err := ParseSwapProofStr(proofStr)
	if err != nil {
		t.Fatal(err)
	}
	res, err := proof2.Verify()
	if err != nil {
		t.Fatal(err)
	}
	assert.Equal(t, true, res, "invalid proof")
}
Add Liquidity
Example

zero/twistededwards/tebn254/zero/addLiquidity_test.go:

func TestAddLiquidityProof_Verify(t *testing.T) {
	b_uA := uint64(8)
	b_uB := uint64(4)
	assetAId := uint32(1)
	assetBId := uint32(2)
	b_A_Delta := uint64(1)
	b_B_Delta := uint64(1)
	b_Dao_A := uint64(10)
	b_Dao_B := uint64(10)
	sk_u, Pk_u := twistedElgamal.GenKeyPair()
	_, Pk_pool := twistedElgamal.GenKeyPair()
	C_uA, _ := twistedElgamal.Enc(big.NewInt(int64(b_uA)), curve.RandomValue(), Pk_u)
	C_uB, _ := twistedElgamal.Enc(big.NewInt(int64(b_uB)), curve.RandomValue(), Pk_u)
	b_fee := uint64(100)
	C_fee, _ := twistedElgamal.Enc(big.NewInt(int64(b_fee)), curve.RandomValue(), Pk_u)
	GasFeeAssetId := uint32(3)
	GasFee := uint64(10)
	fmt.Println("sk:",sk_u.String())
	fmt.Println("Pk_u:",curve.ToString(Pk_u))
	fmt.Println("Pk_pool:",curve.ToString(Pk_pool))
	fmt.Println("C_u_A:",C_uA.String())
	fmt.Println("C_u_B:",C_uB.String())
	fmt.Println("C_fee:",C_fee.String())
	relation, err := NewAddLiquidityRelation(
		C_uA, C_uB,
		Pk_pool, Pk_u,
		assetAId, assetBId,
		b_uA, b_uB,
		b_A_Delta, b_B_Delta,
		sk_u,
		// fee part
		C_fee, b_fee, GasFeeAssetId, GasFee,
	)
	if err != nil {
		t.Fatal(err)
	}
	elapse := time.Now()
	proof, err := ProveAddLiquidity(relation)
	if err != nil {
		t.Fatal(err)
	}
	proof.AddPoolInfo(b_Dao_A, b_Dao_B)
	log.Println("prove time:", time.Since(elapse))
	proofStr := proof.String()
	proof2, err := ParseAddLiquidityProofStr(proofStr)
	if err != nil {
		t.Fatal(err)
	}
	res, err := proof2.Verify()
	if err != nil {
		t.Fatal(err)
	}
	assert.Equal(t, true, res, "invalid proof")
}
Remove Liquidity
Example

zero/twistededwards/tebn254/zero/removeLiquidity_test.go:

func TestRemoveLiquidityProof_Verify(t *testing.T) {
	//b_u_A := uint64(8)
	//b_u_B := uint64(4)
	B_LP := uint64(100)
	assetAId := uint32(1)
	assetBId := uint32(2)
	B_A_Delta := uint64(10)
	B_B_Delta := uint64(10)
	MinB_A_Delta := uint64(1)
	MinB_B_Delta := uint64(1)
	Delta_LP := uint64(10)
	b_pool_A := uint64(1000)
	b_pool_B := uint64(1000)
	Sk_u, Pk_u := twistedElgamal.GenKeyPair()
	_, Pk_pool := twistedElgamal.GenKeyPair()
	//C_uA, _ := twistedElgamal.Enc(big.NewInt(int64(b_u_A)), curve.RandomValue(), Pk_u)
	//C_uB, _ := twistedElgamal.Enc(big.NewInt(int64(b_u_B)), curve.RandomValue(), Pk_u)
	C_u_LP, _ := twistedElgamal.Enc(big.NewInt(int64(B_LP)), curve.RandomValue(), Pk_u)
	// fee
	B_fee := uint64(100)
	C_fee, _ := twistedElgamal.Enc(big.NewInt(int64(B_fee)), curve.RandomValue(), Pk_u)
	GasFeeAssetId := uint32(1)
	GasFee := uint64(1)
	fmt.Println("Sk_u:", Sk_u.String())
	fmt.Println("Pk_u:", curve.ToString(Pk_u))
	fmt.Println("C_u_LP:", C_u_LP.String())
	fmt.Println("C_fee:", C_fee.String())
	relation, err := NewRemoveLiquidityRelation(
		C_u_LP,
		Pk_u,
		B_LP,
		Delta_LP,
		MinB_A_Delta, MinB_B_Delta,
		assetAId, assetBId,
		Sk_u,
		// fee part
		C_fee, B_fee, GasFeeAssetId, GasFee,
	)
	if err != nil {
		t.Fatal(err)
	}
	elapse := time.Now()
	proof, err := ProveRemoveLiquidity(relation)
	if err != nil {
		t.Fatal(err)
	}
	err = proof.AddPoolInfo(Pk_pool, B_A_Delta, B_B_Delta, b_pool_A, b_pool_B, curve.RandomValue(), curve.RandomValue())
	if err != nil {
		t.Fatal(err)
	}
	log.Println("prove time:", time.Since(elapse))
	proofStr := proof.String()
	proof2, err := ParseRemoveLiquidityProofStr(proofStr)
	if err != nil {
		t.Fatal(err)
	}
	res, err := proof2.Verify()
	if err != nil {
		t.Fatal(err)
	}
	assert.Equal(t, true, res, "invalid proof")
}
Withdraw
Example

zero/twistededwards/tebn254/zero/withdraw_test.go:

func TestProveWithdraw(t *testing.T) {
	sk, pk := twistedElgamal.GenKeyPair()
	b := uint64(8)
	r := curve.RandomValue()
	bEnc, err := twistedElgamal.Enc(big.NewInt(int64(b)), r, pk)
	if err != nil {
		t.Error(err)
	}
	b_fee := uint64(10)
	bEnc2, _ := twistedElgamal.Enc(big.NewInt(int64(b_fee)), r, pk)
	bStar := uint64(2)
	fee := uint64(1)
	fmt.Println("sk:", sk.String())
	fmt.Println("pk:", curve.ToString(pk))
	fmt.Println("benc:", bEnc.String())
	fmt.Println("benc2:", bEnc2.String())
	addr := "0xE9b15a2D396B349ABF60e53ec66Bcf9af262D449"
	assetId := uint32(1)
	feeAssetId := uint32(2)
	relation, err := NewWithdrawRelation(
		1,
		bEnc,
		pk,
		b, bStar,
		sk,
		assetId, addr,
		bEnc2, b_fee, feeAssetId, fee,
	)
	if err != nil {
		t.Error(err)
	}
	elapse := time.Now()
	withdrawProof, err := ProveWithdraw(relation)
	if err != nil {
		t.Error(err)
	}
	proofStr := withdrawProof.String()
	proof, err := ParseWithdrawProofStr(proofStr)
	if err != nil {
		t.Fatal(err)
	}
	fmt.Println("prove time:", time.Since(elapse))
	res, err := proof.Verify()
	if err != nil {
		t.Fatal(err)
	}
	assert.Equal(t, res, true, "withdraw proof works correctly")
}

ZkBAS Proofs Circuit

/*
	AccountConstraints: account constraints
*/
type AccountConstraints struct {
	// account index
	AccountIndex Variable
	// account name
	AccountName Variable
	// account public key
	AccountPk Point
	// account state tree root
	StateRoot Variable
	// assets info for each account per tx
	AssetsInfo [NbAccountAssetsPerAccount]AccountAssetConstraints
	// locked assets info for each account per tx
	LockedAssetInfo AccountAssetLockConstraints
	// liquidity assets info for each account per tx
	LiquidityInfo AccountLiquidityConstraints
	// account assets root
	AccountAssetsRoot Variable
	// account locked assets root
	AccountLockedAssetsRoot Variable
	// account liquidity root
	AccountLiquidityRoot Variable
}

/*
	AccountAssetConstraints: account asset tree related constraints
*/
type AccountAssetConstraints struct {
	// asset id
	AssetId Variable
	// twisted ElGamal Encryption balance
	BalanceEnc ElGamalEncConstraints
}

/*
	AccountAssetLockConstraints: account locked asset tree related constraints
*/
type AccountAssetLockConstraints struct {
	// chain id
	ChainId Variable
	// asset id
	AssetId Variable
	// locked amount
	LockedAmount Variable
}

/*
	AccountAssetLockConstraints: account liquidity asset tree related constraints
*/
type AccountLiquidityConstraints struct {
	// pair index
	PairIndex Variable
	// asset a id
	AssetAId Variable
	// asset b id
	AssetBId Variable
	// asset a balance
	AssetA Variable
	// asset b balance
	AssetB Variable
	// asset a random value
	AssetAR Variable
	// asset b random value
	AssetBR Variable
	// LP twisted ElGamal encryption
	LpEnc ElGamalEncConstraints
}
type TxConstraints struct {
	// tx type
	TxType Variable
	// deposit info
	DepositTxInfo DepositOrLockTxConstraints
	// lock info
	LockTxInfo DepositOrLockTxConstraints
	// unlock proof
	UnlockProof UnlockProofConstraints
	// transfer proof
	TransferProof TransferProofConstraints
	// swap proof
	SwapProof SwapProofConstraints
	// add liquidity proof
	AddLiquidityProof AddLiquidityProofConstraints
	// remove liquidity proof
	RemoveLiquidityProof RemoveLiquidityProofConstraints
	// withdraw proof
	WithdrawProof WithdrawProofConstraints
	// common verification part
	// range proofs
	RangeProofs [MaxRangeProofCount]CtRangeProofConstraints
	// account root before
	AccountRootBefore Variable
	// account before info, size is 4
	AccountsInfoBefore [NbAccountsPerTx]AccountConstraints
	// before account merkle proof
	MerkleProofsAccountBefore       [NbAccountsPerTx][AccountMerkleLevels]Variable
	MerkleProofsHelperAccountBefore [NbAccountsPerTx][AccountMerkleHelperLevels]Variable
	// before account asset merkle proof
	MerkleProofsAccountAssetsBefore       [NbAccountsPerTx][NbAccountAssetsPerAccount][AssetMerkleLevels]Variable
	MerkleProofsHelperAccountAssetsBefore [NbAccountsPerTx][NbAccountAssetsPerAccount][AssetMerkleHelperLevels]Variable
	// before account asset lock merkle proof
	MerkleProofsAccountLockedAssetsBefore       [NbAccountsPerTx][LockedAssetMerkleLevels]Variable
	MerkleProofsHelperAccountLockedAssetsBefore [NbAccountsPerTx][LockedAssetMerkleHelperLevels]Variable
	// before account liquidity merkle proof
	MerkleProofsAccountLiquidityBefore       [NbAccountsPerTx][LiquidityMerkleLevels]Variable
	MerkleProofsHelperAccountLiquidityBefore [NbAccountsPerTx][LiquidityMerkleHelperLevels]Variable
	// account root after
	AccountRootAfter Variable
	// account after info, size is 4
	AccountsInfoAfter [NbAccountsPerTx]AccountConstraints
	// after account merkle proof
	MerkleProofsAccountAfter       [NbAccountsPerTx][AccountMerkleLevels]Variable
	MerkleProofsHelperAccountAfter [NbAccountsPerTx][AccountMerkleHelperLevels]Variable
	// after account asset merkle proof
	MerkleProofsAccountAssetsAfter       [NbAccountsPerTx][NbAccountAssetsPerAccount][AssetMerkleLevels]Variable
	MerkleProofsHelperAccountAssetsAfter [NbAccountsPerTx][NbAccountAssetsPerAccount][AssetMerkleHelperLevels]Variable
	// after account asset lock merkle proof
	MerkleProofsAccountLockedAssetsAfter       [NbAccountsPerTx][LockedAssetMerkleLevels]Variable
	MerkleProofsHelperAccountLockedAssetsAfter [NbAccountsPerTx][LockedAssetMerkleHelperLevels]Variable
	// after account liquidity merkle proof
	MerkleProofsAccountLiquidityAfter       [NbAccountsPerTx][LiquidityMerkleLevels]Variable
	MerkleProofsHelperAccountLiquidityAfter [NbAccountsPerTx][LiquidityMerkleHelperLevels]Variable
}
type BlockConstraints struct {
	// public inputs
	OldRoot         Variable `gnark:",public"`
	NewRoot         Variable `gnark:",public"`
	BlockCommitment Variable `gnark:",public"`
	// tx info
	Txs [TxsCountPerBlock]TxConstraints
    // TODO add basic info
}

Contributions

Welcome to make contributions to github.com/bnb-chain/zkbas-crypto. Thanks!

Jump to

Keyboard shortcuts

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