Commit b775d350 authored by madengji's avatar madengji Committed by vipwzw

proof encode to tx

parent ce15f935
......@@ -73,8 +73,8 @@ grpcFuncWhitelist=["*"]
[mempool]
name="para"
poolCacheSize=10240
#平行链的最小feeRate为0
#minTxFeeRate=100000
#联盟链没有交易费,对应平行链minTxFeeRate需要设为0
minTxFeeRate=100000
maxTxNumPerAccount=10000
[consensus]
......
......@@ -39,16 +39,16 @@ func NewAuth() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
amount := circuit.SECRET_INPUT("amount")
amount := circuit.SECRET_INPUT("Amount")
//spend pubkey
receiverPubKey := circuit.SECRET_INPUT("receiverPubKey")
returnPubKey := circuit.SECRET_INPUT("returnPubKey")
authorizePriKey := circuit.SECRET_INPUT("authorizePriKey")
noteRandom := circuit.SECRET_INPUT("noteRandom")
receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubKey := circuit.SECRET_INPUT("ReturnPubKey")
authorizePriKey := circuit.SECRET_INPUT("AuthorizePriKey")
noteRandom := circuit.SECRET_INPUT("NoteRandom")
authPubKey := circuit.PUBLIC_INPUT("authorizePubKey")
authorizeHash := circuit.PUBLIC_INPUT("authorizeHash")
authPubKey := circuit.PUBLIC_INPUT("AuthorizePubKey")
authorizeHash := circuit.PUBLIC_INPUT("AuthorizeHash")
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
......@@ -58,9 +58,9 @@ func NewAuth() *frontend.R1CS {
circuit.MUSTBE_EQ(authorizeHash, mimc.Hash(&circuit, authPubKey, noteRandom))
//note hash random
authSpendHash := circuit.PUBLIC_INPUT("authorizeSpendHash")
authSpendHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
//spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("spendFlag")
spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag)
targetPubHash := circuit.SELECT(spendFlag, receiverPubKey, returnPubKey)
calcAuthSpendHash := mimc.Hash(&circuit, targetPubHash, amount, noteRandom)
......@@ -69,7 +69,7 @@ func NewAuth() *frontend.R1CS {
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
// specify note hash constraint
preImage := mimc.Hash(&circuit, receiverPubKey, returnPubKey, authPubKey, amount, noteRandom)
noteHash := circuit.SECRET_INPUT("noteHash")
noteHash := circuit.SECRET_INPUT("NoteHash")
circuit.MUSTBE_EQ(noteHash, preImage)
util.MerkelPathPart(&circuit, mimc, preImage)
......
......@@ -36,48 +36,51 @@ func TestAuthorizeSpend(t *testing.T) {
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "treeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Public, "authorizeHash", "1267825436937766239630340333349685320927256968591056373125946583184548355070")
good.Assign(backend.Public, "authorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Public, "TreeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "AuthorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Public, "AuthorizeHash", "1267825436937766239630340333349685320927256968591056373125946583184548355070")
good.Assign(backend.Public, "AuthorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Secret, "amount", "28242048")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePriKey", "17822967620457187568904804290291537271142779717280482398091401115827760898835")
good.Assign(backend.Secret, "spendFlag", "1")
good.Assign(backend.Secret, "noteRandom", "2824204835")
good.Assign(backend.Secret, "noteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
good.Assign(backend.Secret, "Amount", "28242048")
good.Assign(backend.Secret, "ReceiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "ReturnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "AuthorizePriKey", "17822967620457187568904804290291537271142779717280482398091401115827760898835")
good.Assign(backend.Secret, "SpendFlag", "1")
good.Assign(backend.Secret, "NoteRandom", "2824204835")
good.Assign(backend.Secret, "NoteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
good.Assign(backend.Secret, "path1", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "path2", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "path3", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "path4", "0")
good.Assign(backend.Secret, "path5", "0")
good.Assign(backend.Secret, "path6", "0")
good.Assign(backend.Secret, "path7", "0")
good.Assign(backend.Secret, "path8", "0")
good.Assign(backend.Secret, "path9", "0")
good.Assign(backend.Secret, "Path0", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "Path1", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "Path2", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "Path8", "0")
good.Assign(backend.Secret, "Path9", "0")
good.Assign(backend.Secret, "helper1", "1")
good.Assign(backend.Secret, "helper2", "1")
good.Assign(backend.Secret, "helper3", "1")
good.Assign(backend.Secret, "helper4", "0")
good.Assign(backend.Secret, "helper5", "0")
good.Assign(backend.Secret, "helper6", "0")
good.Assign(backend.Secret, "helper7", "0")
good.Assign(backend.Secret, "helper8", "0")
good.Assign(backend.Secret, "helper9", "0")
good.Assign(backend.Secret, "Helper0", "1")
good.Assign(backend.Secret, "Helper1", "1")
good.Assign(backend.Secret, "Helper2", "1")
good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "valid1", "1")
good.Assign(backend.Secret, "valid2", "1")
good.Assign(backend.Secret, "valid3", "1")
good.Assign(backend.Secret, "valid4", "0")
good.Assign(backend.Secret, "valid5", "0")
good.Assign(backend.Secret, "valid6", "0")
good.Assign(backend.Secret, "valid7", "0")
good.Assign(backend.Secret, "valid8", "0")
good.Assign(backend.Secret, "valid9", "0")
good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "Valid1", "1")
good.Assign(backend.Secret, "Valid2", "1")
good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "Valid6", "0")
good.Assign(backend.Secret, "Valid7", "0")
good.Assign(backend.Secret, "Valid8", "0")
good.Assign(backend.Secret, "Valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
......
public, treeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
public, authorizeHash,1267825436937766239630340333349685320927256968591056373125946583184548355070
public, authorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
secret, amount,28242048
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePriKey,17822967620457187568904804290291537271142779717280482398091401115827760898835
secret, spendFlag,1
secret, noteRandom,2824204835
secret, noteHash,3649361563603415612447884923592927672484439983354650489908367088830561161361
secret, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path4,0
secret, path5,0
secret, path6,0
secret, path7,0
secret, path8,0
secret, path9,0
secret, path10,0
secret, helper1,1
secret, helper2,1
secret, helper3,1
secret, helper4,1
secret, helper5,1
secret, helper6,1
secret, helper7,1
secret, helper8,1
secret, helper9,1
secret, helper10,1
secret, valid1,1
secret, valid2,1
secret, valid3,1
secret, valid4,0
secret, valid5,0
secret, valid6,0
secret, valid7,0
secret, valid8,0
secret, valid9,0
secret, valid10,0
public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
public, AuthorizeHash,1267825436937766239630340333349685320927256968591056373125946583184548355070
public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
secret, Amount,28242048
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, AuthorizePriKey,17822967620457187568904804290291537271142779717280482398091401115827760898835
secret, SpendFlag,1
secret, NoteRandom,2824204835
secret, NoteHash,3649361563603415612447884923592927672484439983354650489908367088830561161361
secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, Path3,0
secret, Path4,0
secret, Path5,0
secret, Path6,0
secret, Path7,0
secret, Path8,0
secret, Path9,0
secret, Helper0,1
secret, Helper1,1
secret, Helper2,1
secret, Helper3,1
secret, Helper4,1
secret, Helper5,1
secret, Helper6,1
secret, Helper7,1
secret, Helper8,1
secret, Helper9,1
secret, Valid0,1
secret, Valid1,1
secret, Valid2,1
secret, Valid3,0
secret, Valid4,0
secret, Valid5,0
secret, Valid6,0
secret, Valid7,0
secret, Valid8,0
secret, Valid9,0
......@@ -15,14 +15,14 @@ func main() {
//spend commit hash the circuit implementing
/*
public:
noteHash
amount
NoteHash
Amount
private:
receiverPubKey
returnPubKey
authorizePubKey
noteRandom
ReceiverPubKey
ReturnPubKey
AuthorizePubKey
NoteRandom
*/
func NewDeposit() *frontend.R1CS {
......@@ -31,22 +31,22 @@ func NewDeposit() *frontend.R1CS {
circuit := frontend.New()
//公共输入以验证
amount := circuit.PUBLIC_INPUT("amount")
amount := circuit.PUBLIC_INPUT("Amount")
//spend pubkey
receiverPubKey := circuit.SECRET_INPUT("receiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey")
receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
//note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom")
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.PUBLIC_INPUT("noteHash")
noteHash := circuit.PUBLIC_INPUT("NoteHash")
// specify note hash constraint
preImage := mimc.Hash(&circuit, receiverPubKey, returnPubkey, authPubkey, amount, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
......
public, noteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
public, amount,28242048
public, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
public, Amount,28242048
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, noteRandom,2824204835
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, NoteRandom,2824204835
......
public, treeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, shieldAmountX,14087975867275911077371231345227824611951436822132762463787130558957838320348
public, shieldAmountY,15113519960384204624879642069520481336224311978035289236693658603675385299879
public, authorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, nullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
secret, amount,28242048
secret, amountRandom,35
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, spendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, spendFlag,1
secret, authorizeFlag,1
secret, noteRandom,2824204835
secret, noteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path4,0
secret, path5,0
secret, path6,0
secret, path7,0
secret, path8,0
secret, path9,0
secret, helper1,1
secret, helper2,1
secret, helper3,1
secret, helper4,1
secret, helper5,1
secret, helper6,1
secret, helper7,1
secret, helper8,1
secret, helper9,1
secret, valid1,1
secret, valid2,1
secret, valid3,1
secret, valid4,0
secret, valid5,0
secret, valid6,0
secret, valid7,0
secret, valid8,0
secret, valid9,0
public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, ShieldAmountX,14087975867275911077371231345227824611951436822132762463787130558957838320348
public, ShieldAmountY,15113519960384204624879642069520481336224311978035289236693658603675385299879
public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, NullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
secret, Amount,28242048
secret, AmountRandom,35
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, SpendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, SpendFlag,1
secret, AuthorizeFlag,1
secret, NoteRandom,2824204835
secret, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, Path3,0
secret, Path4,0
secret, Path5,0
secret, Path6,0
secret, Path7,0
secret, Path8,0
secret, Path9,0
secret, Helper0,1
secret, Helper1,1
secret, Helper2,1
secret, Helper3,1
secret, Helper4,1
secret, Helper5,1
secret, Helper6,1
secret, Helper7,1
secret, Helper8,1
secret, Helper9,1
secret, Valid0,1
secret, Valid1,1
secret, Valid2,1
secret, Valid3,0
secret, Valid4,0
secret, Valid5,0
secret, Valid6,0
secret, Valid7,0
secret, Valid8,0
secret, Valid9,0
......@@ -42,18 +42,18 @@ func NewTransferInput() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
spendValue := circuit.SECRET_INPUT("amount")
spendValue := circuit.SECRET_INPUT("Amount")
//spend pubkey
spendPubkey := circuit.SECRET_INPUT("receiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey")
spendPrikey := circuit.SECRET_INPUT("spendPriKey")
spendPubkey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
spendPrikey := circuit.SECRET_INPUT("SpendPriKey")
//spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("spendFlag")
spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag)
//auth_check 0: not need auth check, 1:need check
authFlag := circuit.SECRET_INPUT("authorizeFlag")
authFlag := circuit.SECRET_INPUT("AuthorizeFlag")
circuit.MUSTBE_BOOLEAN(authFlag)
// hash function
......@@ -63,10 +63,10 @@ func NewTransferInput() *frontend.R1CS {
circuit.MUSTBE_EQ(targetPubHash, calcPubHash)
//note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom")
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//need check in database if not null
authHash := circuit.PUBLIC_INPUT("authorizeSpendHash")
authHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
nullValue := circuit.ALLOCATE(0)
//// specify auth hash constraint
......@@ -75,12 +75,12 @@ func NewTransferInput() *frontend.R1CS {
circuit.MUSTBE_EQ(authHash, targetAuthHash)
//need check in database if not null
nullifierHash := circuit.PUBLIC_INPUT("nullifierHash")
nullifierHash := circuit.PUBLIC_INPUT("NullifierHash")
calcNullifierHash := mimc.Hash(&circuit, noteRandom)
circuit.MUSTBE_EQ(nullifierHash, calcNullifierHash)
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
noteHash := circuit.SECRET_INPUT("noteHash")
noteHash := circuit.SECRET_INPUT("NoteHash")
calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue)
calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue)
// specify note hash constraint
......
......@@ -34,22 +34,22 @@ func NewTransferOutput() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
spendValue := circuit.SECRET_INPUT("amount")
spendValue := circuit.SECRET_INPUT("Amount")
//spend pubkey
spendPubkey := circuit.SECRET_INPUT("receiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey")
spendPubkey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
// hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
//note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom")
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.PUBLIC_INPUT("noteHash")
noteHash := circuit.PUBLIC_INPUT("NoteHash")
// specify note hash constraint
preImage := mimc.Hash(&circuit, spendPubkey, returnPubkey, authPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
......
......@@ -12,17 +12,17 @@ import (
func MerkelPathPart(circuit *frontend.CS, mimc mimc.MiMCGadget, noteHash *frontend.Constraint) {
var proofSet, helper, valid []*frontend.Constraint
merkleRoot := circuit.PUBLIC_INPUT("treeRootHash")
merkleRoot := circuit.PUBLIC_INPUT("TreeRootHash")
proofSet = append(proofSet, noteHash)
//helper[0],valid[0]占位, 方便接口只设置有效值
helper = append(helper, circuit.ALLOCATE("1"))
valid = append(valid, circuit.ALLOCATE("1"))
//depth:10, path num need be 9
for i := 1; i < 10; i++ {
proofSet = append(proofSet, circuit.SECRET_INPUT("path"+strconv.Itoa(i)))
helper = append(helper, circuit.SECRET_INPUT("helper"+strconv.Itoa(i)))
valid = append(valid, circuit.SECRET_INPUT("valid"+strconv.Itoa(i)))
for i := 0; i < 10; i++ {
proofSet = append(proofSet, circuit.SECRET_INPUT("Path"+strconv.Itoa(i)))
helper = append(helper, circuit.SECRET_INPUT("Helper"+strconv.Itoa(i)))
valid = append(valid, circuit.SECRET_INPUT("Valid"+strconv.Itoa(i)))
}
VerifyMerkleProof(circuit, mimc, merkleRoot, proofSet, helper, valid)
......@@ -65,8 +65,8 @@ func leafSum(circuit *frontend.CS, h mimc.MiMCGadget, data *frontend.Constraint)
func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
//cmt=transfer_value*G + random_value*H
cmtvalueX := circuit.PUBLIC_INPUT("shieldAmountX")
cmtvalueY := circuit.PUBLIC_INPUT("shieldAmountY")
cmtvalueX := circuit.PUBLIC_INPUT("ShieldAmountX")
cmtvalueY := circuit.PUBLIC_INPUT("ShieldAmountY")
// set curve parameters
edgadget, _ := twistededwards_gadget.NewEdCurveGadget(gurvy.BN256)
......@@ -84,7 +84,7 @@ func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
pointGSnark.X.Tag("xg")
pointGSnark.Y.Tag("yg")
transfer_random := circuit.SECRET_INPUT("amountRandom")
transfer_random := circuit.SECRET_INPUT("AmountRandom")
//circuit.MUSTBE_LESS_OR_EQ(random_value,10000000000,256)
//H is not G, H should be a point that no one know the prikey
var baseX_H, baseY_H fr_bn256.Element
......
public, treeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, authorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, nullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
public, amount,28242048
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, spendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, spendFlag,1
secret, authorizeFlag,1
secret, noteRandom,2824204835
secret, noteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path4,0
secret, path5,0
secret, path6,0
secret, path7,0
secret, path8,0
secret, path9,0
secret, path10,0
secret, helper1,1
secret, helper2,1
secret, helper3,1
secret, helper4,1
secret, helper5,1
secret, helper6,1
secret, helper7,1
secret, helper8,1
secret, helper9,1
secret, valid1,1
secret, valid2,1
secret, valid3,1
secret, valid4,0
secret, valid5,0
secret, valid6,0
secret, valid7,0
secret, valid8,0
secret, valid9,0
public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, NullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
public, Amount,28242048
secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, SpendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, SpendFlag,1
secret, AuthorizeFlag,1
secret, NoteRandom,2824204835
secret, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, Path3,0
secret, Path4,0
secret, Path5,0
secret, Path6,0
secret, Path7,0
secret, Path8,0
secret, Path9,0
secret, Helper0,1
secret, Helper1,1
secret, Helper2,1
secret, Helper3,1
secret, Helper4,1
secret, Helper5,1
secret, Helper6,1
secret, Helper7,1
secret, Helper8,1
secret, Helper9,1
secret, Valid0,1
secret, Valid1,1
secret, Valid2,1
secret, Valid3,0
secret, Valid4,0
secret, Valid5,0
secret, Valid6,0
secret, Valid7,0
secret, Valid8,0
secret, Valid9,0
......@@ -40,18 +40,18 @@ func NewWithdraw() *frontend.R1CS {
// create root constraint system
circuit := frontend.New()
spendValue := circuit.PUBLIC_INPUT("amount")
spendValue := circuit.PUBLIC_INPUT("Amount")
//spend pubkey
receiverPubKey := circuit.SECRET_INPUT("receiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey")
spendPrikey := circuit.SECRET_INPUT("spendPriKey")
receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
spendPrikey := circuit.SECRET_INPUT("SpendPriKey")
//spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("spendFlag")
spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag)
//auth_check 0: not need auth check, 1:need check
authFlag := circuit.SECRET_INPUT("authorizeFlag")
authFlag := circuit.SECRET_INPUT("AuthorizeFlag")
circuit.MUSTBE_BOOLEAN(authFlag)
// hash function
......@@ -61,10 +61,10 @@ func NewWithdraw() *frontend.R1CS {
circuit.MUSTBE_EQ(targetPubHash, calcPubHash)
//note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom")
noteRandom := circuit.SECRET_INPUT("NoteRandom")
//need check in database if not null
authHash := circuit.PUBLIC_INPUT("authorizeSpendHash")
authHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
nullValue := circuit.ALLOCATE(0)
// specify auth hash constraint
......@@ -74,7 +74,7 @@ func NewWithdraw() *frontend.R1CS {
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.SECRET_INPUT("noteHash")
noteHash := circuit.SECRET_INPUT("NoteHash")
calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue)
calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue)
// specify note hash constraint
......
......@@ -37,53 +37,120 @@ func TestWithdraw(t *testing.T) {
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "treeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "authorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Public, "nullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195")
good.Assign(backend.Public, "amount", "28242048")
good.Assign(backend.Public, "TreeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "AuthorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Public, "NullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195")
good.Assign(backend.Public, "Amount", "28242048")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "ReceiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "ReturnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "AuthorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "spendPriKey", "10190477835300927557649934238820360529458681672073866116232821892325659279502")
good.Assign(backend.Secret, "spendFlag", "1")
good.Assign(backend.Secret, "authorizeFlag", "1")
good.Assign(backend.Secret, "SpendPriKey", "10190477835300927557649934238820360529458681672073866116232821892325659279502")
good.Assign(backend.Secret, "SpendFlag", "1")
good.Assign(backend.Secret, "AuthorizeFlag", "1")
good.Assign(backend.Secret, "noteRandom", "2824204835")
good.Assign(backend.Secret, "NoteRandom", "2824204835")
good.Assign(backend.Secret, "noteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
good.Assign(backend.Secret, "NoteHash", "16308793397024662832064523892418908145900866571524124093537199035808550255649")
//nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
good.Assign(backend.Secret, "path1", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "path2", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "path3", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "path4", "0")
good.Assign(backend.Secret, "path5", "0")
good.Assign(backend.Secret, "path6", "0")
good.Assign(backend.Secret, "path7", "0")
good.Assign(backend.Secret, "path8", "0")
good.Assign(backend.Secret, "path9", "0")
good.Assign(backend.Secret, "helper1", "1")
good.Assign(backend.Secret, "helper2", "1")
good.Assign(backend.Secret, "helper3", "1")
good.Assign(backend.Secret, "helper4", "0")
good.Assign(backend.Secret, "helper5", "0")
good.Assign(backend.Secret, "helper6", "0")
good.Assign(backend.Secret, "helper7", "0")
good.Assign(backend.Secret, "helper8", "0")
good.Assign(backend.Secret, "helper9", "0")
good.Assign(backend.Secret, "valid1", "1")
good.Assign(backend.Secret, "valid2", "1")
good.Assign(backend.Secret, "valid3", "1")
good.Assign(backend.Secret, "valid4", "0")
good.Assign(backend.Secret, "valid5", "0")
good.Assign(backend.Secret, "valid6", "0")
good.Assign(backend.Secret, "valid7", "0")
good.Assign(backend.Secret, "valid8", "0")
good.Assign(backend.Secret, "valid9", "0")
good.Assign(backend.Secret, "Path0", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "Path1", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "Path2", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "Path8", "0")
good.Assign(backend.Secret, "Path9", "0")
good.Assign(backend.Secret, "Helper0", "1")
good.Assign(backend.Secret, "Helper1", "1")
good.Assign(backend.Secret, "Helper2", "1")
good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "Valid1", "1")
good.Assign(backend.Secret, "Valid2", "1")
good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "Valid6", "0")
good.Assign(backend.Secret, "Valid7", "0")
good.Assign(backend.Secret, "Valid8", "0")
good.Assign(backend.Secret, "Valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
}
func TestWithdraw2(t *testing.T) {
assert := groth16.NewAssert(t)
r1cs := NewWithdraw()
r1csBN256 := backend_bn256.Cast(r1cs)
{
good := backend.NewAssignment()
good.Assign(backend.Public, "TreeRootHash", "7407373673604276152801354004851383461539317977307945198624806503955302548700")
good.Assign(backend.Public, "AuthorizeSpendHash", "0")
good.Assign(backend.Public, "NullifierHash", "3911774040567972872956008387141175001419649692949203140089059098956773329188")
good.Assign(backend.Public, "Amount", "500000000")
good.Assign(backend.Secret, "ReceiverPubKey", "7244551457692363731356498279463138379576484998878425864678733206990733443457")
good.Assign(backend.Secret, "ReturnPubKey", "0")
good.Assign(backend.Secret, "AuthorizePubKey", "0")
good.Assign(backend.Secret, "SpendPriKey", "19115616183616714814727844928908633989028519974595353009754871398745087846141")
good.Assign(backend.Secret, "SpendFlag", "1")
good.Assign(backend.Secret, "AuthorizeFlag", "0")
good.Assign(backend.Secret, "NoteRandom", "13093524699504167542220418896875211339267114119238016501132859435646426190390")
good.Assign(backend.Secret, "NoteHash", "6441981280327245191543878922302235060888201984279829017462503030039593719666")
//nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
good.Assign(backend.Secret, "Path0", "16592081253758169453601069427813166612800474003570537799829885686701266956141")
good.Assign(backend.Secret, "Path1", "0")
good.Assign(backend.Secret, "Path2", "0")
good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "Path8", "0")
good.Assign(backend.Secret, "Path9", "0")
good.Assign(backend.Secret, "Helper0", "0")
good.Assign(backend.Secret, "Helper1", "0")
good.Assign(backend.Secret, "Helper2", "0")
good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "Valid1", "0")
good.Assign(backend.Secret, "Valid2", "0")
good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "Valid6", "0")
good.Assign(backend.Secret, "Valid7", "0")
good.Assign(backend.Secret, "Valid8", "0")
good.Assign(backend.Secret, "Valid9", "0")
assert.Solved(&r1csBN256, good, nil)
}
......
/*
Copyright © 2020 ConsenSys
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package gob
import (
"bytes"
"encoding/gob"
"encoding/hex"
"errors"
"io"
"log"
"os"
)
var (
ErrInvalidCurve = errors.New("trying to deserialize an object serialized with another curve")
)
// Write serialize object into file
// uses gob + gzip
func Write(path string, from interface{}) error {
// create file
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
return Serialize(f, from)
}
// Read read and deserialize input into object
// provided interface must be a pointer
// uses gob + gzip
func Read(path string, into interface{}) error {
// open file
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
fileinfo, err := f.Stat()
if err != nil {
log.Fatal(err)
}
fileSize := fileinfo.Size()
buffer := make([]byte, fileSize)
_, err = f.Read(buffer)
if err != nil {
log.Fatal(err)
}
var buf bytes.Buffer
buf.Write(buffer)
return Deserialize(&buf, into)
}
func ReadBuf(str string, into interface{}) error {
strByts, err := hex.DecodeString(str)
if err != nil {
log.Fatal(err)
}
var buf bytes.Buffer
buf.Write(strByts)
return Deserialize(&buf, into)
}
// Serialize object from into f
// uses gob
func Serialize(f io.Writer, from interface{}) error {
// gzip writer
encoder := gob.NewEncoder(f)
// encode our object
if err := encoder.Encode(from); err != nil {
return err
}
return nil
}
// Deserialize f into object into
// uses gob + gzip
func Deserialize(f io.Reader, into interface{}) error {
// gzip reader
decoder := gob.NewDecoder(f)
if err := decoder.Decode(into); err != nil {
return err
}
return nil
}
This diff is collapsed.
......@@ -38,7 +38,7 @@ func (a *action) authParamCheck(input *mixTy.AuthorizePublicInput) error {
//authorize pubkey hash should be configured already
var found bool
for _, k := range authPubKeys.Pks {
for _, k := range authPubKeys.Keys {
if input.AuthorizePubKey == k {
found = true
break
......@@ -85,13 +85,12 @@ func (a *action) authorizeVerify(proof *mixTy.ZkProofInfo) (*mixTy.AuthorizePubl
*/
func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt, error) {
var inputs []*mixTy.AuthorizePublicInput
for _, proof := range authorize.AuthCommits {
in, err := a.authorizeVerify(proof)
if err != nil {
return nil, err
}
inputs = append(inputs, in)
in, err := a.authorizeVerify(authorize.Proof)
if err != nil {
return nil, err
}
inputs = append(inputs, in)
receipt := &types.Receipt{Ty: types.ExecOk}
var auths, authSpends []string
......
......@@ -27,23 +27,23 @@ func isSuperManager(cfg *types.Chain33Config, addr string) bool {
func (a *action) Config(config *mixTy.MixConfigAction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
switch config.Ty {
case mixTy.MixConfigType_VerifyKey:
case mixTy.MixConfigType_Verify:
//必须是超级管理员才能配置
if !isSuperManager(cfg, a.fromaddr) {
return nil, errors.Wrapf(types.ErrNotAllow, "not super manager,%s", a.fromaddr)
}
return a.ConfigAddVerifyKey(config.GetVerifyKey())
case mixTy.MixConfigType_AuthPubKey:
case mixTy.MixConfigType_Auth:
//必须是超级管理员才能配置
if !isSuperManager(cfg, a.fromaddr) {
return nil, errors.Wrapf(types.ErrNotAllow, "not super manager,%s", a.fromaddr)
}
if config.Action == mixTy.MixConfigAct_Add {
return a.ConfigAddAuthPubKey(config.GetAuthPk())
return a.ConfigAddAuthPubKey(config.GetAuthKey())
} else {
return a.ConfigDeleteAuthPubKey(config.GetAuthPk())
return a.ConfigDeleteAuthPubKey(config.GetAuthKey())
}
case mixTy.MixConfigType_PaymentPubKey:
case mixTy.MixConfigType_Payment:
//个人配置,个人负责,可重配
return a.ConfigPaymentPubKey(config.GetPaymentKey())
}
......@@ -96,7 +96,7 @@ func (a *action) ConfigAddVerifyKey(newKey *mixTy.ZkVerifyKey) (*types.Receipt,
}
func makeConfigAuthKeyReceipt(data *mixTy.AuthPubKeys) *types.Receipt {
func makeConfigAuthKeyReceipt(data *mixTy.AuthKeys) *types.Receipt {
key := getAuthPubKeysKey()
return &types.Receipt{
Ty: types.ExecOk,
......@@ -110,13 +110,13 @@ func makeConfigAuthKeyReceipt(data *mixTy.AuthPubKeys) *types.Receipt {
}
func (a *action) getAuthKeys() (*mixTy.AuthPubKeys, error) {
func (a *action) getAuthKeys() (*mixTy.AuthKeys, error) {
key := getAuthPubKeysKey()
v, err := a.db.Get(key)
if err != nil {
return nil, errors.Wrapf(err, "get db")
}
var keys mixTy.AuthPubKeys
var keys mixTy.AuthKeys
err = types.Decode(v, &keys)
if err != nil {
return nil, errors.Wrapf(err, "decode db key")
......@@ -128,15 +128,15 @@ func (a *action) getAuthKeys() (*mixTy.AuthPubKeys, error) {
func (a *action) ConfigAddAuthPubKey(key string) (*types.Receipt, error) {
keys, err := a.getAuthKeys()
if isNotFound(errors.Cause(err)) {
keys := &mixTy.AuthPubKeys{}
keys.Pks = append(keys.Pks, key)
keys := &mixTy.AuthKeys{}
keys.Keys = append(keys.Keys, key)
return makeConfigAuthKeyReceipt(keys), nil
}
if err != nil {
return nil, err
}
keys.Pks = append(keys.Pks, key)
keys.Keys = append(keys.Keys, key)
return makeConfigAuthKeyReceipt(keys), nil
}
......@@ -146,12 +146,12 @@ func (a *action) ConfigDeleteAuthPubKey(key string) (*types.Receipt, error) {
return nil, err
}
var newKeys mixTy.AuthPubKeys
for _, v := range keys.Pks {
var newKeys mixTy.AuthKeys
for _, v := range keys.Keys {
if key == v {
continue
}
newKeys.Pks = append(newKeys.Pks, v)
newKeys.Keys = append(newKeys.Keys, v)
}
return makeConfigAuthKeyReceipt(&newKeys), nil
......@@ -187,13 +187,13 @@ func GetPaymentPubKey(db dbm.KV, addr string) (*mixTy.PaymentKey, error) {
}
func (a *action) ConfigPaymentPubKey(paykey *mixTy.PaymentKey) (*types.Receipt, error) {
if paykey == nil || len(paykey.ReceiverKey) == 0 || len(paykey.SecretKey.X) == 0 || len(paykey.SecretKey.Y) == 0 {
if paykey == nil || len(paykey.ReceiverKey) == 0 || len(paykey.EncryptKey) == 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "pubkey=%v", paykey)
}
//直接覆盖
return makeConfigPaymentKeyReceipt(&mixTy.PaymentKey{
Addr: a.fromaddr,
ReceiverKey: paykey.ReceiverKey,
SecretKey: paykey.SecretKey}), nil
EncryptKey: paykey.EncryptKey}), nil
}
......@@ -63,6 +63,9 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error)
if err != nil {
return "", 0, errors.Wrapf(err, "parseUint=%s", input.Amount)
}
if val <= 0 {
return "", 0, errors.Wrapf(err, "amount=%d should >0", val)
}
err = zkProofVerify(a.db, proof, mixTy.VerifyType_DEPOSIT)
if err != nil {
......@@ -81,14 +84,14 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error)
*/
func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error) {
//1. zk-proof校验
noteHash, val, err := a.depositVerify(deposit.Proof)
noteHash, amount, err := a.depositVerify(deposit.Proof)
if err != nil {
return nil, err
}
//校验存款额,目前只支持一次只存一张支票
if val != deposit.Amount {
return nil, errors.Wrapf(mixTy.ErrInputParaNotMatch, "deposit amount=%d not equal proof amount=%d", deposit.Amount, val)
}
////校验存款额,目前只支持一次只存一张支票
//if val != deposit.Amount {
// return nil, errors.Wrapf(mixTy.ErrInputParaNotMatch, "deposit amount=%d not equal proof amount=%d", deposit.Amount, val)
//}
//存款
cfg := a.api.GetConfig()
......@@ -98,7 +101,7 @@ func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error
}
//主链上存入toAddr为mix 执行器地址,平行链上为user.p.{}.mix执行器地址,execAddr和toAddr一致
execAddr := address.ExecAddress(string(a.tx.Execer))
receipt, err := accoutDb.ExecTransfer(a.fromaddr, execAddr, execAddr, int64(deposit.Amount))
receipt, err := accoutDb.ExecTransfer(a.fromaddr, execAddr, execAddr, int64(amount))
if err != nil {
return nil, errors.Wrapf(err, "ExecTransfer")
}
......
......@@ -66,3 +66,8 @@ func (m *Mix) Query_PaymentPubKey(addr *types.ReqString) (types.Message, error)
return GetPaymentPubKey(m.GetStateDB(), addr.Data)
}
// Query_PaymentPubKey 批量查询
func (m *Mix) Query_VerifyProof(req *mixTy.VerifyProofInfo) (types.Message, error) {
return nil, zkProofVerify(m.GetStateDB(), req.Proof, req.Ty)
}
......@@ -7,6 +7,7 @@ package executor
import (
"encoding/hex"
"encoding/json"
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/twistededwards"
......
......@@ -83,7 +83,7 @@ func (a *action) withdrawVerify(proof *mixTy.ZkProofInfo) (string, uint64, error
func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, error) {
var nulliferSet []string
var sumValue uint64
for _, k := range withdraw.SpendCommits {
for _, k := range withdraw.Proofs {
nulfier, v, err := a.withdrawVerify(k)
if err != nil {
return nil, err
......
......@@ -17,8 +17,6 @@ limitations under the License.
package zksnark
import (
"bytes"
"encoding/hex"
"encoding/json"
"github.com/consensys/gnark/backend"
......@@ -26,22 +24,12 @@ import (
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gurvy"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/pkg/errors"
)
func getByteBuff(input string) (*bytes.Buffer, error) {
var buffInput bytes.Buffer
res, err := hex.DecodeString(input)
if err != nil {
return nil, errors.Wrapf(err, "getByteBuff to %s", input)
}
buffInput.Write(res)
return &buffInput, nil
}
func deserializeInput(input string) (map[string]interface{}, error) {
buff, err := getByteBuff(input)
buff, err := mixTy.GetByteBuff(input)
if err != nil {
return nil, err
}
......@@ -58,13 +46,13 @@ func deserializeInput(input string) (map[string]interface{}, error) {
func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) {
curveID := gurvy.BN256
output, err := getByteBuff(verifyKeyStr)
output, err := mixTy.GetByteBuff(verifyKeyStr)
if err != nil {
return false, errors.Wrapf(err, "zk.verify")
return false, errors.Wrapf(err, "zkVerify.GetByteBuff")
}
var vk groth16_bn256.VerifyingKey
if err := gob.Deserialize(output, &vk, curveID); err != nil {
return false, errors.Wrapf(err, "zk.verify.Deserize.VK=%s", verifyKeyStr[:10])
return false, errors.Wrapf(err, "zkVerify.Deserize.VK=%s", verifyKeyStr[:10])
}
// parse input file
......@@ -78,20 +66,20 @@ func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) {
}
// load proof
output, err = getByteBuff(proofStr)
output, err = mixTy.GetByteBuff(proofStr)
if err != nil {
return false, errors.Wrapf(err, "proof")
return false, errors.Wrapf(err, "zkVerify.proof")
}
var proof groth16_bn256.Proof
if err := gob.Deserialize(output, &proof, curveID); err != nil {
return false, errors.Wrapf(err, "zk.verify.deserial.proof=%s", proofStr[:10])
return false, errors.Wrapf(err, "zkVerify.deserial.proof=%s", proofStr[:10])
}
// verify proof
//start := time.Now()
result, err := groth16_bn256.Verify(&proof, &vk, r1csInput)
if err != nil {
return false, errors.Wrapf(err, "zk.Verify")
return false, errors.Wrapf(err, "zkVerify.verify")
}
return result, nil
}
......@@ -26,23 +26,23 @@ message ZkVerifyKeys{
repeated ZkVerifyKey data = 1;
}
message AuthPubKeys{
repeated string pks = 1;
message AuthKeys{
repeated string keys = 1;
}
message PaymentKey{
string addr = 1;
string receiverKey = 2;
PubKey secretKey = 3;
string encryptKey = 3;
}
enum MixConfigType{
VerifyKey = 0;
Verify = 0;
//register unify authorize pubkey
AuthPubKey = 1;
Auth = 1;
//for spender's pay pubkey register,DH secret
//spender注册自己的payment公钥, 用来生成DiffHellman秘钥
PaymentPubKey = 2;
Payment = 2;
}
enum MixConfigAct{
......@@ -59,15 +59,15 @@ message MixConfigAction {
MixConfigAct Action = 2;
oneof value {
ZkVerifyKey verifyKey = 3;
string authPk = 4;
string authKey = 4;
PaymentKey paymentKey = 5;
}
}
//DH one time pubkey with secret
message DHSecret{
PubKey epk = 1;
string secret = 3;
string peerKey = 1;
string secret = 2;
}
//Diff-Helman 加密group, for spender, returner, authorizer to decrypt
......@@ -84,8 +84,7 @@ message ZkProofInfo {
}
message MixDepositAction {
uint64 amount = 1;
ZkProofInfo proof = 2;
ZkProofInfo proof = 1;
}
......@@ -98,12 +97,12 @@ message MixTransferAction {
message MixWithdrawAction {
uint64 amount = 1;
repeated ZkProofInfo spendCommits = 2;
repeated ZkProofInfo proofs = 2;
}
message MixAuthorizeAction {
repeated ZkProofInfo authCommits = 1;
ZkProofInfo proof = 1;
}
......@@ -161,6 +160,12 @@ message AuthorizePublicInput {
}
message VerifyProofInfo{
VerifyType ty = 1;
ZkProofInfo proof = 2;
}
//nullifer 存在value
message ExistValue {
bool data = 1;
......@@ -195,23 +200,16 @@ message TreeListResp{
// mix wallet part
// receiverPubKey = hash(spendPriKey) for zk-snark note spend
message PaymentKeyPair {
string receiverPubKey = 1;
string spendPriKey = 2;
string receiveKey = 1;
string spendKey = 2;
}
// pub = priv*G for diff-helman crypto
// out: take spender's tempPrikey*pubkey as password, tempPubkey show in note
// spender: take self prikey*tempPubkey as password to decode
message PubKey {
string X = 1;
string Y = 2;
}
message PrivKey{
string data = 1;
}
message ShareSecretKeyPair {
PrivKey privKey = 1;
PubKey receivingPk = 2;
message EncryptKeyPair {
string privKey = 1;
string pubKey = 2;
}
......@@ -219,7 +217,7 @@ message ShareSecretKeyPair {
//crypt pair for DH crypt/decrypt
message AccountPrivacyKey {
PaymentKeyPair paymentKey = 1;
ShareSecretKeyPair shareSecretKey = 2;
EncryptKeyPair encryptKey = 2;
}
message WalletAddrPrivacy {
......@@ -230,38 +228,45 @@ message WalletAddrPrivacy {
message SecretData{
string receiverPubKey = 1;
string returnPubKey = 2;
string authorizePubKey = 3;
string receiverKey = 1;
string returnKey = 2;
string authorizeKey = 3;
string amount = 4;
string noteRandom = 5;
}
message EncodedSecretData{
string encoded = 1;
SecretData rawData = 2;
}
message EncryptSecretData{
string secret = 1;
PubKey SecretPubKey = 2;
string peerKey = 2;
}
message DecryptSecretData{
string secret = 1;
PrivKey SecretPriKey = 2;
PubKey epk = 3;
string priKey = 2;
string peerKey = 3;
}
//一键式获取加密数据
message DepositProofReq{
string receiverAddr = 1;
//path+filename, filename can take default
message circuitPathInfo{
string path = 1;
}
message DepositInfo{
string addr = 1;
string returnAddr = 2;
string authorizeAddr = 3;
uint64 amount = 4;
}
//钱包生成deposit tx
message DepositTxReq{
DepositInfo deposit = 1;
circuitPathInfo zkPath = 2;
}
message DepositProofResp{
string noteHash = 1;
......@@ -275,15 +280,17 @@ message TreePathProof{
string treeRootHash = 1;
repeated string treePath = 2;
repeated uint32 helpers = 3;
repeated uint32 validPath = 4;
}
message WithdrawProofReq{
string noteHash = 1;
//可withdraw 多个note
message WithdrawTxReq{
uint64 totalAmount = 1;
string noteHashs = 2;
circuitPathInfo zkPath = 3;
}
message WithdrawProofResp{
message WithdrawProofRe{
SecretData secret = 1;
string nullifierHash = 2;
string authorizeSpendHash = 3;
......@@ -292,14 +299,17 @@ message WithdrawProofResp{
string spendFlag = 6;
string authorizeFlag = 7;
TreePathProof treeProof = 8;
}
message AuthProofReq{
//只授权一个note,超过一个,toAddr不好设置
message AuthTxReq{
string noteHash = 1;
uint32 toReturn = 2;
string authorizeToAddr = 3;
circuitPathInfo zkPath = 4;
}
message AuthProofResp{
message AuthProofRe{
SecretData proof = 1;
string authPubKey = 2;
string authPrivKey = 3;
......@@ -311,12 +321,19 @@ message AuthProofResp{
}
message TransferProofReq{
message TransferInputTxReq{
string noteHash = 1;
string toAddr = 2;
string toAuthAddr = 3;
string returnAddr = 4;
uint64 amount = 5;
circuitPathInfo zkPath = 2;
}
message TransferOutputTxReq{
DepositInfo deposit = 1;
circuitPathInfo zkPath = 2;
}
message TransferTxReq{
TransferInputTxReq input = 1;
TransferOutputTxReq output = 2;
}
//加密了的input/output amount
......@@ -344,8 +361,6 @@ message TransferOutputProof{
DHSecretGroup secrets = 3;
ShieldAmount shieldAmount = 4;
string amountRandom = 5;
}
message TransferProofResp{
......@@ -356,15 +371,25 @@ message TransferProofResp{
}
message ShieldAmountRst{
string noteRandom = 1;
string transferRandom = 2;
string inputRandom = 1;
string outputRandom = 2;
string changeRandom = 3;
ShieldAmount note = 4;
ShieldAmount transfer = 5;
ShieldAmount input = 4;
ShieldAmount output = 5;
ShieldAmount change = 6;
}
message CreateRawTxReq{
int32 actionTy = 1;
bytes data = 4;
string assetExec = 2;
string assetToken = 3;
string title = 6; //平行链名字
}
enum NoteStatus{
UNDEF = 0;
VALID = 1; //已授权可使用
......
......@@ -5,6 +5,7 @@
package rpc
import (
"encoding/hex"
"encoding/json"
"github.com/33cn/chain33/types"
......@@ -106,14 +107,14 @@ func (c *Jrpc) EnablePrivacy(in *types.ReqAddrs, result *json.RawMessage) error
return err
}
func (c *Jrpc) EncodeSecretData(in *mixTy.SecretData, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncodeSecretData", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
//func (c *Jrpc) EncodeSecretData(in *mixTy.SecretData, result *json.RawMessage) error {
// reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncodeSecretData", in)
// if err != nil {
// return err
// }
// *result, err = types.PBToJSON(reply)
// return err
//}
func (c *Jrpc) EncryptSecretData(in *mixTy.EncryptSecretData, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncryptSecretData", in)
......@@ -133,38 +134,48 @@ func (c *Jrpc) DecryptSecretData(in *mixTy.DecryptSecretData, result *json.RawMe
return err
}
func (c *Jrpc) DepositProof(in *mixTy.DepositProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "DepositProof", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
func (c *Jrpc) AuthProof(in *mixTy.AuthProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "AuthProof", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
func (c *Jrpc) TransferProof(in *mixTy.TransferProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "TransferProof", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
//
//func (c *Jrpc) DepositProof(in *mixTy.DepositTxReq, result *json.RawMessage) error {
// reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "DepositProof", in)
// if err != nil {
// return err
// }
// *result, err = types.PBToJSON(reply)
// return err
//}
//
//func (c *Jrpc) AuthProof(in *mixTy.AuthTxReq, result *json.RawMessage) error {
// reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "AuthProof", in)
// if err != nil {
// return err
// }
// *result, err = types.PBToJSON(reply)
// return err
//}
//
//func (c *Jrpc) TransferProof(in *mixTy.TransferTxReq, result *json.RawMessage) error {
// reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "TransferProof", in)
// if err != nil {
// return err
// }
// *result, err = types.PBToJSON(reply)
// return err
//}
//
//func (c *Jrpc) WithdrawProof(in *mixTy.WithdrawTxReq, result *json.RawMessage) error {
// reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "WithdrawProof", in)
// if err != nil {
// return err
// }
// *result, err = types.PBToJSON(reply)
// return err
//}
func (c *Jrpc) WithdrawProof(in *mixTy.WithdrawProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "WithdrawProof", in)
func (c *Jrpc) CreateRawTransaction(in *mixTy.CreateRawTxReq, result *interface{}) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "CreateRawTransaction", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
*result = hex.EncodeToString(types.Encode(reply))
return err
}
......@@ -13,6 +13,7 @@ var tlog = log15.New("module", MixX)
const (
MaxTreeLeaves = 1024
TreeLevel = 10
)
// 执行器的日志类型
......@@ -51,3 +52,26 @@ const (
//mix transfer tx fee
const Privacy2PrivacyTxFee = types.Coin
//circuits default file name
const (
DepositCircuit = "circuit_deposit.r1cs"
DepositPk = "circuit_deposit.pk"
DepositVk = "circuit_deposit.vk"
WithdrawCircuit = "circuit_withdraw.r1cs"
WithdrawPk = "circuit_withdraw.pk"
WithdrawVk = "circuit_withdraw.vk"
AuthCircuit = "circuit_auth.r1cs"
AuthPk = "circuit_auth.pk"
AuthVk = "circuit_auth.vk"
TransInputCircuit = "circuit_transfer_input.r1cs"
TransInputPk = "circuit_transfer_input.pk"
TransInputVk = "circuit_transfer_input.vk"
TransOutputCircuit = "circuit_transfer_output.r1cs"
TransOutputPk = "circuit_transfer_output.pk"
TransOutputVk = "circuit_transfer_output.vk"
)
This diff is collapsed.
......@@ -5,6 +5,7 @@
package types
import (
"bytes"
"encoding/hex"
"encoding/json"
"reflect"
......@@ -69,7 +70,7 @@ func (p *MixType) GetName() string {
func (p *MixType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogMixConfigVk: {Ty: reflect.TypeOf(ZkVerifyKeys{}), Name: "LogMixConfigVk"},
TyLogMixConfigAuth: {Ty: reflect.TypeOf(AuthPubKeys{}), Name: "LogMixConfigAuthPubKey"},
TyLogMixConfigAuth: {Ty: reflect.TypeOf(AuthKeys{}), Name: "LogMixConfigAuthPubKey"},
TyLogCurrentCommitTreeLeaves: {Ty: reflect.TypeOf(CommitTreeLeaves{}), Name: "LogCommitTreeLeaves"},
TyLogCurrentCommitTreeRoots: {Ty: reflect.TypeOf(CommitTreeRoots{}), Name: "LogCommitTreeRoots"},
TyLogMixConfigPaymentKey: {Ty: reflect.TypeOf(PaymentKey{}), Name: "LogConfigReceivingKey"},
......@@ -92,78 +93,6 @@ func (p *MixType) GetPayload() types.Message {
return &MixAction{}
}
//
//func DecodeDepositInput(input string) (*DepositPublicInput, error) {
// var v DepositPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//func DecodeWithdrawInput(input string) (*WithdrawPublicInput, error) {
// var v WithdrawPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//
//func DecodeTransferInput(input string) (*TransferInputPublicInput, error) {
// var v TransferInputPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//func DecodeTransferOut(input string) (*TransferOutputPublicInput, error) {
// var v TransferOutputPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//func DecodeAuthorizeInput(input string) (*AuthorizePublicInput, error) {
// var v AuthorizePublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
func DecodePubInput(ty VerifyType, input string) (interface{}, error) {
data, err := hex.DecodeString(input)
if err != nil {
......@@ -245,3 +174,30 @@ func CheckSumEqual(points ...*twistededwards.Point) bool {
return false
}
func GetByteBuff(input string) (*bytes.Buffer, error) {
var buffInput bytes.Buffer
res, err := hex.DecodeString(input)
if err != nil {
return nil, errors.Wrapf(err, "getByteBuff to %s", input)
}
buffInput.Write(res)
return &buffInput, nil
}
func Str2Byte(v string) []byte {
var fr fr.Element
fr.SetString(v)
return fr.Bytes()
}
func Byte2Str(v []byte) string {
var f fr.Element
f.SetBytes(v)
return f.String()
}
func GetFrRandom() string {
var f fr.Element
return f.SetRandom().String()
}
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.
package wallet
import (
"crypto"
"crypto/rand"
"errors"
"io"
"golang.org/x/crypto/curve25519"
)
type ecdh25519 struct{}
var curve25519Params = CurveParams{
Name: "Curve25519",
BitSize: 255,
}
// X25519 creates a new ecdh.KeyExchange with
// the elliptic curve Curve25519.
func X25519() KeyExchange {
return ecdh25519{}
}
func (ecdh25519) GenerateKey(random io.Reader) (private crypto.PrivateKey, public crypto.PublicKey, err error) {
if random == nil {
random = rand.Reader
}
var pri, pub [32]byte
_, err = io.ReadFull(random, pri[:])
if err != nil {
return
}
// From https://cr.yp.to/ecdh.html
pri[0] &= 248
pri[31] &= 127
pri[31] |= 64
curve25519.ScalarBaseMult(&pub, &pri)
private = pri
public = pub
return
}
func (ecdh25519) Params() CurveParams { return curve25519Params }
func (ecdh25519) PublicKey(private crypto.PrivateKey) (public crypto.PublicKey) {
var pri, pub [32]byte
if ok := checkType(&pri, private); !ok {
panic("ecdh: unexpected type of private key")
}
curve25519.ScalarBaseMult(&pub, &pri)
public = pub
return
}
func (ecdh25519) Check(peersPublic crypto.PublicKey) (err error) {
if ok := checkType(new([32]byte), peersPublic); !ok {
err = errors.New("unexptected type of peers public key")
}
return
}
func (ecdh25519) ComputeSecret(private crypto.PrivateKey, peersPublic crypto.PublicKey) (secret []byte) {
var pri, pub [32]byte
if ok := checkType(&pri, private); !ok {
panic("ecdh: unexpected type of private key")
}
if ok := checkType(&pub, peersPublic); !ok {
panic("ecdh: unexpected type of peers public key")
}
//curve25519.ScalarMult(&sec, &pri, &pub)
sec, err := curve25519.X25519(pri[:], pub[:])
if err != nil {
panic(err)
}
secret = sec[:]
return
}
func checkType(key *[32]byte, typeToCheck interface{}) (ok bool) {
switch t := typeToCheck.(type) {
case [32]byte:
copy(key[:], t[:])
ok = true
case *[32]byte:
copy(key[:], t[:])
ok = true
case []byte:
if len(t) == 32 {
copy(key[:], t)
ok = true
}
case *[]byte:
if len(*t) == 32 {
copy(key[:], *t)
ok = true
}
}
return
}
package wallet
import (
mixtypes "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/fr"
"github.com/consensys/gurvy/bn256/twistededwards"
)
type curveBn256ECDH struct {
}
// NewCurve25519ECDH creates a new ECDH instance that uses djb's curve25519
// elliptical curve.
func NewCurveBn256ECDH() ECDH {
return &curveBn256ECDH{}
}
func (e *curveBn256ECDH) GenerateKey(generator []byte) (*mixtypes.PrivKey, *mixtypes.PubKey) {
var sk fr.Element
if len(generator) <= 0 {
sk.SetRandom()
} else {
sk.SetBytes(generator)
}
ed := twistededwards.GetEdwardsCurve()
var point twistededwards.Point
point.ScalarMul(&ed.Base, sk)
priv := &mixtypes.PrivKey{
Data: sk.String(),
}
pub := &mixtypes.PubKey{
X: point.X.String(),
Y: point.Y.String(),
}
return priv, pub
}
func (e *curveBn256ECDH) GenerateSharedSecret(priv *mixtypes.PrivKey, pub *mixtypes.PubKey) ([]byte, error) {
var point, pubPoint twistededwards.Point
pubPoint.X.SetString(pub.X)
pubPoint.Y.SetString(pub.Y)
var frPriv fr.Element
frPriv.SetString(priv.Data)
point.ScalarMul(&pubPoint, frPriv)
return point.X.Bytes(), nil
}
package wallet
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGenerateSharedSecret(t *testing.T) {
bn256 := NewCurveBn256ECDH()
pri1, pub1 := bn256.GenerateKey(nil)
pri2, pub2 := bn256.GenerateKey(nil)
s1, _ := bn256.GenerateSharedSecret(pri1, pub2)
s2, _ := bn256.GenerateSharedSecret(pri2, pub1)
assert.Equal(t, s1, s2)
}
package wallet
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.
// Package ecdh implements the Diffie-Hellman key exchange
// using elliptic curves (ECDH). It directly provides ECDH
// implementations for the NIST curves P224, P256, P384,
// and Bernstein's Cruve25519.
//
// For generic curves this implementation of ECDH
// only uses the x-coordinate as the computed secret.
package wallet // import "github.com/aead/ecdh"
import (
mixtypes "github.com/33cn/plugin/plugin/dapp/mix/types"
"crypto"
"io"
)
// The main interface for ECDH key exchange.
type ECDH interface {
GenerateKey([]byte) (*mixtypes.PrivKey, *mixtypes.PubKey)
GenerateSharedSecret(*mixtypes.PrivKey, *mixtypes.PubKey) ([]byte, error)
// KeyExchange is the interface defining all functions
// necessary for ECDH.
type KeyExchange interface {
// GenerateKey generates a private/public key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
GenerateKey(rand io.Reader) (private crypto.PrivateKey, public crypto.PublicKey, err error)
// Params returns the curve parameters - like the field size.
Params() CurveParams
// PublicKey returns the public key corresponding to the given private one.
PublicKey(private crypto.PrivateKey) (public crypto.PublicKey)
// Check returns a non-nil error if the peers public key cannot used for the
// key exchange - for instance the public key isn't a point on the elliptic curve.
// It's recommended to check peer's public key before computing the secret.
Check(peersPublic crypto.PublicKey) (err error)
// ComputeSecret returns the secret value computed from the given private key
// and the peers public key.
ComputeSecret(private crypto.PrivateKey, peersPublic crypto.PublicKey) (secret []byte)
}
// CurveParams contains the parameters of an elliptic curve.
type CurveParams struct {
Name string // the canonical name of the curve
BitSize int // the size of the underlying field
}
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.
package wallet
import (
"bytes"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"testing"
)
// An example for the ECDH key-exchange using Curve25519.
func ExampleX25519() {
c25519 := X25519()
privateAlice, publicAlice, err := c25519.GenerateKey(rand.Reader)
if err != nil {
fmt.Printf("Failed to generate Alice's private/public key pair: %s\n", err)
}
privateBob, publicBob, err := c25519.GenerateKey(rand.Reader)
if err != nil {
fmt.Printf("Failed to generate Bob's private/public key pair: %s\n", err)
}
if err := c25519.Check(publicBob); err != nil {
fmt.Printf("Bob's public key is not on the curve: %s\n", err)
}
secretAlice := c25519.ComputeSecret(privateAlice, publicBob)
if err := c25519.Check(publicAlice); err != nil {
fmt.Printf("Alice's public key is not on the curve: %s\n", err)
}
secretBob := c25519.ComputeSecret(privateBob, publicAlice)
if !bytes.Equal(secretAlice, secretBob) {
fmt.Printf("key exchange failed - secret X coordinates not equal\n")
}
// Output:
}
func ExampleX25519_Params() {
c25519 := X25519()
p := c25519.Params()
fmt.Printf("Name: %s BitSize: %d", p.Name, p.BitSize)
// Output: Name: Curve25519 BitSize: 255
}
func TestX25519(t *testing.T) {
dh := X25519()
secret := make([]byte, 32)
var priBob [32]byte
for i := 0; i < 2; i++ {
priAlice, pubAlice, err := dh.GenerateKey(nil)
if err != nil {
t.Fatalf("alice: key pair generation failed: %s", err)
}
if _, err := io.ReadFull(rand.Reader, priBob[:]); err != nil {
t.Fatalf("carol: private key generation failed: %s", err)
}
pubBob := dh.PublicKey(&priBob)
secAlice := dh.ComputeSecret(priAlice, pubBob)
secBob := dh.ComputeSecret(&priBob, pubAlice)
if !bytes.Equal(secAlice, secBob) {
toStr := hex.EncodeToString
t.Fatalf("DH failed: secrets are not equal:\nAlice got: %s\nBob got: %s", toStr(secAlice), toStr(secBob))
}
if bytes.Equal(secret, secAlice) {
t.Fatalf("DH generates the same secret all the time")
}
copy(secret, secAlice)
}
}
// Benchmarks
func BenchmarkX25519(b *testing.B) {
curve := X25519()
privateAlice, _, err := curve.GenerateKey(rand.Reader)
if err != nil {
b.Fatalf("Failed to generate Alice's private/public key pair: %s", err)
}
_, publicBob, err := curve.GenerateKey(rand.Reader)
if err != nil {
b.Fatalf("Failed to generate Bob's private/public key pair: %s", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
curve.ComputeSecret(privateAlice, publicBob)
}
}
func BenchmarkKeyGenerateX25519(b *testing.B) {
curve := X25519()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _, err := curve.GenerateKey(rand.Reader)
if err != nil {
b.Fatalf("Failed to generate Alice's private/public key pair: %s", err)
}
}
}
......@@ -35,9 +35,9 @@ func (policy *mixPolicy) On_EnablePrivacy(req *types.ReqAddrs) (types.Message, e
return policy.enablePrivacy(req.Addrs)
}
func (policy *mixPolicy) On_EncodeSecretData(req *mixTy.SecretData) (types.Message, error) {
return encodeSecretData(req)
}
//func (policy *mixPolicy) On_EncodeSecretData(req *mixTy.SecretData) (types.Message, error) {
// return encodeSecretData(req)
//}
func (policy *mixPolicy) On_EncryptSecretData(req *mixTy.EncryptSecretData) (types.Message, error) {
return encryptSecretData(req)
......@@ -47,18 +47,22 @@ func (policy *mixPolicy) On_DecryptSecretData(req *mixTy.DecryptSecretData) (typ
return decryptSecretData(req)
}
func (policy *mixPolicy) On_DepositProof(req *mixTy.DepositProofReq) (types.Message, error) {
return policy.depositProof(req)
}
func (policy *mixPolicy) On_WithdrawProof(req *mixTy.WithdrawProofReq) (types.Message, error) {
return policy.withdrawProof(req)
}
func (policy *mixPolicy) On_AuthProof(req *mixTy.AuthProofReq) (types.Message, error) {
return policy.authProof(req)
}
//func (policy *mixPolicy) On_DepositProof(req *mixTy.CreateRawTxReq) (types.Message, error) {
// return policy.createDepositTx(req)
//}
//
//func (policy *mixPolicy) On_WithdrawProof(req *mixTy.CreateRawTxReq) (types.Message, error) {
// return policy.createWithdrawTx(req)
//}
//
//func (policy *mixPolicy) On_AuthProof(req *mixTy.CreateRawTxReq) (types.Message, error) {
// return policy.createAuthTx(req)
//}
//
//func (policy *mixPolicy) On_TransferProof(req *mixTy.CreateRawTxReq) (types.Message, error) {
// return policy.createTransferTx(req)
//}
func (policy *mixPolicy) On_TransferProof(req *mixTy.TransferProofReq) (types.Message, error) {
return policy.transferProof(req)
func (policy *mixPolicy) On_CreateRawTransaction(req *mixTy.CreateRawTxReq) (types.Message, error) {
return policy.createRawTx(req)
}
......@@ -6,6 +6,7 @@ package wallet
import (
"bytes"
"encoding/hex"
"github.com/33cn/chain33/system/dapp"
"github.com/pkg/errors"
......@@ -17,7 +18,6 @@ import (
wcom "github.com/33cn/chain33/wallet/common"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
mimcbn256 "github.com/consensys/gnark/crypto/hash/mimc/bn256"
fr_bn256 "github.com/consensys/gurvy/bn256/fr"
)
const CECBLOCKSIZE = 32
......@@ -25,19 +25,24 @@ const CECBLOCKSIZE = 32
// newPrivacyWithPrivKey create privacy from private key
//payment, payPrivKey=hash(privkey), payPubkey=hash(payPrivKey)
//DH crypt key, prikey=payPrikey, pubKey=payPrikey*G
func newPrivacyWithPrivKey(privKey []byte) (*mixTy.AccountPrivacyKey, error) {
func newPrivacyKey(privKey []byte) (*mixTy.AccountPrivacyKey, error) {
payPrivacyKey := mimcHashByte([][]byte{privKey})
paymentKey := &mixTy.PaymentKeyPair{}
paymentKey.SpendPriKey = getFrString(payPrivacyKey)
paymentKey.ReceiverPubKey = getFrString(mimcHashByte([][]byte{payPrivacyKey}))
shareSecretKey := &mixTy.ShareSecretKeyPair{}
ecdh := NewCurveBn256ECDH()
shareSecretKey.PrivKey, shareSecretKey.ReceivingPk = ecdh.GenerateKey(payPrivacyKey)
paymentKey.SpendKey = mixTy.Byte2Str(payPrivacyKey)
paymentKey.ReceiveKey = mixTy.Byte2Str(mimcHashByte([][]byte{payPrivacyKey}))
encryptKeyPair := &mixTy.EncryptKeyPair{}
//ecdh := NewCurveBn256ECDH()
ecdh := X25519()
pubkey := ecdh.PublicKey(payPrivacyKey)
//需要Hex编码,而不腻使用fr.string, 模范围不同
encryptKeyPair.PrivKey = hex.EncodeToString(payPrivacyKey)
pubData := pubkey.([32]byte)
encryptKeyPair.PubKey = hex.EncodeToString(pubData[:])
privacy := &mixTy.AccountPrivacyKey{}
privacy.PaymentKey = paymentKey
privacy.ShareSecretKey = shareSecretKey
privacy.EncryptKey = encryptKeyPair
return privacy, nil
}
......@@ -71,14 +76,22 @@ func encryptDataWithPadding(password, data []byte) []byte {
return wcom.CBCEncrypterPrivkey(password, paddingText)
}
func encryptData(receiverPubKey *mixTy.PubKey, data []byte) *mixTy.DHSecret {
ecdh := NewCurveBn256ECDH()
//generate ephemeral priv/pub key
ephPriv, ephPub := ecdh.GenerateKey(nil)
password, _ := ecdh.GenerateSharedSecret(ephPriv, receiverPubKey)
func encryptData(peerPubKey string, data []byte) (*mixTy.DHSecret, error) {
ecdh := X25519()
oncePriv, oncePub, err := ecdh.GenerateKey(nil)
if err != nil {
return nil, errors.Wrapf(err, "x25519 generate key")
}
peerPubByte, err := hex.DecodeString(peerPubKey)
if err != nil {
return nil, errors.Wrapf(err, "encrypt Decode peer pubkey=%s", peerPubKey)
}
password := ecdh.ComputeSecret(oncePriv, peerPubByte)
encrypt := encryptDataWithPadding(password, data)
return &mixTy.DHSecret{Epk: ephPub, Secret: common.ToHex(encrypt)}
pubData := oncePub.([32]byte)
return &mixTy.DHSecret{PeerKey: hex.EncodeToString(pubData[:]), Secret: common.ToHex(encrypt)}, nil
}
......@@ -87,29 +100,25 @@ func decryptDataWithPading(password, data []byte) ([]byte, error) {
return pKCS5UnPadding(plainData)
}
func decryptData(selfPrivKey *mixTy.PrivKey, oppositePubKey *mixTy.PubKey, cryptData []byte) ([]byte, error) {
ecdh := NewCurveBn256ECDH()
password, _ := ecdh.GenerateSharedSecret(selfPrivKey, oppositePubKey)
func decryptData(selfPrivKey string, peerPubKey string, cryptData []byte) ([]byte, error) {
ecdh := X25519()
self, err := hex.DecodeString(selfPrivKey)
if err != nil {
return nil, errors.Wrapf(err, "decrypt Decode self prikey=%s", selfPrivKey)
}
peer, err := hex.DecodeString(peerPubKey)
if err != nil {
return nil, errors.Wrapf(err, "decrypt Decode peer pubkey=%s", peerPubKey)
}
password := ecdh.ComputeSecret(self, peer)
return decryptDataWithPading(password, cryptData)
}
func getByte(v string) []byte {
var fr fr_bn256.Element
fr.SetString(v)
return fr.Bytes()
}
func getFrString(v []byte) string {
var f fr_bn256.Element
f.SetBytes(v)
return f.String()
}
func mimcHashString(params []string) []byte {
var sum []byte
for _, k := range params {
//fmt.Println("input:", k)
sum = append(sum, getByte(k)...)
sum = append(sum, mixTy.Str2Byte(k)...)
}
hash := mimcHashCalc(sum)
//fmt.Println("hash=", getFrString(hash))
......@@ -192,7 +201,7 @@ func (policy *mixPolicy) savePrivacyPair(addr string) (*mixTy.WalletAddrPrivacy,
}
bizlog.Info("savePrivacyPair", "pri", common.ToHex(priv.Bytes()), "addr", addr)
newPrivacy, err := newPrivacyWithPrivKey(priv.Bytes())
newPrivacy, err := newPrivacyKey(priv.Bytes())
if err != nil {
return nil, err
}
......@@ -395,3 +404,19 @@ func (policy *mixPolicy) showAccountNoteInfo(addrs []string) (*mixTy.WalletIndex
}
return &resps, nil
}
func (policy *mixPolicy) createRawTx(req *mixTy.CreateRawTxReq) (*types.Transaction, error) {
switch req.ActionTy {
case mixTy.MixActionDeposit:
return policy.createDepositTx(req)
case mixTy.MixActionWithdraw:
return policy.createWithdrawTx(req)
case mixTy.MixActionAuth:
return policy.createAuthTx(req)
case mixTy.MixActionTransfer:
return policy.createTransferTx(req)
default:
return nil, errors.Wrapf(types.ErrInvalidParam, "action=%d", req.ActionTy)
}
}
......@@ -60,7 +60,7 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t
//根据withdraw nullifier hash 更新数据状态为USED
case mixTy.MixActionWithdraw:
var nulls []string
for _, m := range v.GetWithdraw().SpendCommits {
for _, m := range v.GetWithdraw().Proofs {
out, err := mixTy.DecodePubInput(mixTy.VerifyType_WITHDRAW, m.PublicInput)
if err != nil {
bizlog.Error("processWithdraw decode", "pubInput", m.PublicInput)
......@@ -132,15 +132,13 @@ func (p *mixPolicy) processTransfer(transfer *mixTy.MixTransferAction, heightInd
}
func (p *mixPolicy) processAuth(auth *mixTy.MixAuthorizeAction, table *table.Table) {
for _, m := range auth.AuthCommits {
out, err := mixTy.DecodePubInput(mixTy.VerifyType_AUTHORIZE, m.PublicInput)
if err != nil {
bizlog.Error("processAuth decode", "pubInput", m.PublicInput)
continue
}
input := out.(*mixTy.AuthorizePublicInput)
updateAuthSpend(table, input.AuthorizeSpendHash)
out, err := mixTy.DecodePubInput(mixTy.VerifyType_AUTHORIZE, auth.Proof.PublicInput)
if err != nil {
bizlog.Error("processAuth decode", "pubInput", auth.Proof.PublicInput)
return
}
input := out.(*mixTy.AuthorizePublicInput)
updateAuthSpend(table, input.AuthorizeSpendHash)
}
func (p *mixPolicy) processNullifiers(nulls []string, table *table.Table) {
......@@ -318,14 +316,12 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys
return nil, errors.Wrapf(err, "decode secret data=%s", secretData)
}
tempPubKey := &mixTy.PubKey{X: dhSecret.Epk.X, Y: dhSecret.Epk.Y}
for _, key := range privacyKeys {
cryptData, err := common.FromHex(dhSecret.Secret)
if err != nil {
return nil, errors.Wrapf(err, "decode for notehash=%s,crypt=%s", noteHash, dhSecret.Secret)
}
decryptData, err := decryptData(key.Privacy.ShareSecretKey.PrivKey, tempPubKey, cryptData)
decryptData, err := decryptData(key.Privacy.EncryptKey.PrivKey, dhSecret.PeerKey, cryptData)
if err != nil {
bizlog.Debug("processSecret.decryptData fail", "decrypt for notehash", noteHash, "secret", secretData, "addr", key.Addr, "err", err)
continue
......@@ -338,33 +334,33 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys
continue
}
bizlog.Info("processSecret.decode rawData OK", "notehash", noteHash, "addr", key.Addr)
if rawData.ReceiverPubKey == key.Privacy.PaymentKey.ReceiverPubKey ||
rawData.ReturnPubKey == key.Privacy.PaymentKey.ReceiverPubKey ||
rawData.AuthorizePubKey == key.Privacy.PaymentKey.ReceiverPubKey {
if rawData.ReceiverKey == key.Privacy.PaymentKey.ReceiveKey ||
rawData.ReturnKey == key.Privacy.PaymentKey.ReceiveKey ||
rawData.AuthorizeKey == key.Privacy.PaymentKey.ReceiveKey {
//decrypted, save database
var info mixTy.WalletIndexInfo
info.NoteHash = noteHash
info.Nullifier = getFrString(mimcHashString([]string{rawData.NoteRandom}))
info.Nullifier = mixTy.Byte2Str(mimcHashString([]string{rawData.NoteRandom}))
//如果自己是spender,则记录有关spenderAuthHash,如果是returner,则记录returnerAuthHash
//如果授权为spenderAuthHash,则根据授权hash索引到本地数据库,spender更新本地为VALID,returner侧不变仍为FROZEN,花费后,两端都变为USED
//如果授权为returnerAuthHash,则returner更新本地为VALID,spender侧仍为FROZEN,
info.AuthorizeSpendHash = "0"
if len(rawData.AuthorizePubKey) > LENNULLKEY {
switch key.Privacy.PaymentKey.ReceiverPubKey {
case rawData.ReceiverPubKey:
if len(rawData.AuthorizeKey) > LENNULLKEY {
switch key.Privacy.PaymentKey.ReceiveKey {
case rawData.ReceiverKey:
info.Role = mixTy.Role_SPENDER
info.AuthorizeSpendHash = getFrString(mimcHashString([]string{rawData.ReceiverPubKey, rawData.Amount, rawData.NoteRandom}))
case rawData.ReturnPubKey:
info.AuthorizeSpendHash = mixTy.Byte2Str(mimcHashString([]string{rawData.ReceiverKey, rawData.Amount, rawData.NoteRandom}))
case rawData.ReturnKey:
info.Role = mixTy.Role_RETURNER
info.AuthorizeSpendHash = getFrString(mimcHashString([]string{rawData.ReturnPubKey, rawData.Amount, rawData.NoteRandom}))
case rawData.AuthorizePubKey:
info.AuthorizeSpendHash = mixTy.Byte2Str(mimcHashString([]string{rawData.ReturnKey, rawData.Amount, rawData.NoteRandom}))
case rawData.AuthorizeKey:
info.Role = mixTy.Role_AUTHORIZER
}
}
info.Status = mixTy.NoteStatus_VALID
//空的公钥为"0"字符,不是空字符
if len(rawData.AuthorizePubKey) > LENNULLKEY {
if len(rawData.AuthorizeKey) > LENNULLKEY {
info.Status = mixTy.NoteStatus_FROZEN
}
//账户地址
......
......@@ -16,94 +16,93 @@ func TestNewPrivacyWithPrivKey(t *testing.T) {
keyByte, err := hex.DecodeString(prikey)
assert.Equal(t, nil, err)
pairs, err := newPrivacyWithPrivKey(keyByte)
pairs, err := newPrivacyKey(keyByte)
assert.Equal(t, nil, err)
t.Log("payPri", pairs.PaymentKey.SpendKey, "payPub", pairs.PaymentKey.PayKey, "crytoPub", pairs.ShareSecretKey.ReceivingPk, "crytoPri", pairs.ShareSecretKey.PrivKey.Data)
t.Log("payPri", pairs.PaymentKey.SpendKey, "payPub", pairs.PaymentKey.ReceiveKey)
t.Log("crytoPub", pairs.EncryptKey.PubKey, "crytoPri", pairs.EncryptKey.PrivKey)
prikey2 := "1257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
keyByte2, err := hex.DecodeString(prikey2)
assert.Equal(t, nil, err)
pairs2, err := newPrivacyWithPrivKey(keyByte2)
assert.Equal(t, nil, err)
t.Log("payPri", pairs2.PaymentKey.SpendKey, "payPub", pairs2.PaymentKey.PayKey, "crytoPub", pairs2.ShareSecretKey.ReceivingPk, "crytoPri", pairs2.ShareSecretKey.PrivKey.Data)
//prikey2 := "1257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
//keyByte2, err := hex.DecodeString(prikey2)
//assert.Equal(t, nil, err)
//pairs2, err := newPrivacyKey(keyByte2)
//assert.Equal(t, nil, err)
//t.Log("payPri2", pairs2.PaymentKey.SpendKey, "payPub", pairs2.PaymentKey.ReceiveKey, "crytoPub", pairs2.EncryptKey.PubKey, "crytoPri", pairs2.EncryptKey.PrivKey)
secret1 := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835",
Amount: "28242048",
ReceiverKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizeKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835",
Amount: "28242048",
}
//secret2 := &mixTy.CryptoData{
// SpendPubKey:"18829345085195922012068709111582461121107908772422825655963168999800303848486",
// ReturnPubKey:"16067249407809359746114321133992130903102335882983385972747813693681808870497",
// AuthorizePubKey:"13519883267141251871527102103999205179714486518503885909948192364772977661583",
// NoteRandom:"2824204835",
// Amount:"28242048",
//}
data := encryptData(pairs.ShareSecretKey.ReceivingPk, types.Encode(secret1))
data, err := encryptData(pairs.EncryptKey.PubKey, types.Encode(secret1))
assert.Nil(t, err)
crypData, err := common.FromHex(data.Secret)
assert.Nil(t, err)
decryData1, err := decryptData(pairs.ShareSecretKey.PrivKey, data.Epk, crypData)
decryData1, err := decryptData(pairs.EncryptKey.PrivKey, data.PeerKey, crypData)
assert.Nil(t, err)
var val mixTy.SecretData
err = types.Decode(decryData1, &val)
assert.Nil(t, err)
assert.Equal(t, secret1.PaymentPubKey, val.PaymentPubKey)
assert.Equal(t, secret1.ReceiverKey, val.ReceiverKey)
}
func TestEncrypt(t *testing.T) {
secret1 := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835",
Amount: "28242048",
secret := &mixTy.SecretData{
ReceiverKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizeKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835",
Amount: "28242048",
}
password := "1314fuzamei"
cryptData := encryptDataWithPadding([]byte(password), types.Encode(secret1))
cryptData := encryptDataWithPadding([]byte(password), types.Encode(secret))
decryptData, err := decryptDataWithPading([]byte(password), cryptData)
assert.Nil(t, err)
var raw mixTy.SecretData
err = types.Decode(decryptData, &raw)
assert.Nil(t, err)
assert.Equal(t, raw.PaymentPubKey, secret1.PaymentPubKey)
assert.Equal(t, raw.ReceiverKey, secret.ReceiverKey)
}
func TestEncodeSecretData(t *testing.T) {
secret := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
Amount: "28242048",
ReceiverKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizeKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
Amount: "28242048",
}
ret, err := encodeSecretData(secret)
assert.Nil(t, err)
t.Log(ret)
//ret, err := encodeSecretData(secret)
//assert.Nil(t, err)
//t.Log(ret)
//test encryp data
prikey := "4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
keyByte, err := hex.DecodeString(prikey)
assert.Equal(t, nil, err)
privacy, err := newPrivacyWithPrivKey(keyByte)
privacy, err := newPrivacyKey(keyByte)
assert.Equal(t, nil, err)
ret := types.Encode(secret)
hexRet := hex.EncodeToString(ret)
//assert.Nil(t,err)
req := &mixTy.EncryptSecretData{ReceivingPk: privacy.ShareSecretKey.ReceivingPk, Secret: ret.Encoded}
req := &mixTy.EncryptSecretData{PeerKey: privacy.EncryptKey.PubKey, Secret: hexRet}
dhSecret, err := encryptSecretData(req)
assert.Nil(t, err)
t.Log(dhSecret)
//t.Log(dhSecret)
data, err := common.FromHex(dhSecret.Secret)
assert.Nil(t, err)
rawData, err := decryptData(privacy.ShareSecretKey.PrivKey, dhSecret.Epk, data)
rawData, err := decryptData(privacy.EncryptKey.PrivKey, dhSecret.PeerKey, data)
assert.Nil(t, err)
var rawSecret mixTy.SecretData
types.Decode(rawData, &rawSecret)
assert.Equal(t, rawSecret.PaymentPubKey, secret.PaymentPubKey)
assert.Equal(t, rawSecret.ReceiverKey, secret.ReceiverKey)
}
......@@ -106,6 +106,10 @@ func (policy *mixPolicy) OnWalletUnlocked(WalletUnLock *types.WalletUnLock) {
// OnAddBlockTx 响应区块交易添加的处理
func (policy *mixPolicy) OnAddBlockTx(block *types.BlockDetail, tx *types.Transaction, index int32, dbBatch db.Batch) *types.WalletTxDetail {
if tx == nil {
bizlog.Error("OnAddBlockTx tx is nil", "height", block.Block.Height, "index", index)
return nil
}
dbSet, err := policy.execAutoLocalMix(tx, block.Receipts[index], int(index), block.Block.Height)
if err != nil {
return nil
......
This diff is collapsed.
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package wallet
import (
"strings"
"github.com/33cn/chain33/common/address"
"github.com/pkg/errors"
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
type AuthorizeInput struct {
//public
TreeRootHash string `tag:"public"`
AuthorizePubKey string `tag:"public"`
AuthorizeHash string `tag:"public"`
AuthorizeSpendHash string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePriKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
Amount string `tag:"secret"`
SpendFlag string `tag:"secret"`
NoteHash string `tag:"secret"`
//tree path info
Path0 string `tag:"secret"`
Path1 string `tag:"secret"`
Path2 string `tag:"secret"`
Path3 string `tag:"secret"`
Path4 string `tag:"secret"`
Path5 string `tag:"secret"`
Path6 string `tag:"secret"`
Path7 string `tag:"secret"`
Path8 string `tag:"secret"`
Path9 string `tag:"secret"`
Helper0 string `tag:"secret"`
Helper1 string `tag:"secret"`
Helper2 string `tag:"secret"`
Helper3 string `tag:"secret"`
Helper4 string `tag:"secret"`
Helper5 string `tag:"secret"`
Helper6 string `tag:"secret"`
Helper7 string `tag:"secret"`
Helper8 string `tag:"secret"`
Helper9 string `tag:"secret"`
Valid0 string `tag:"secret"`
Valid1 string `tag:"secret"`
Valid2 string `tag:"secret"`
Valid3 string `tag:"secret"`
Valid4 string `tag:"secret"`
Valid5 string `tag:"secret"`
Valid6 string `tag:"secret"`
Valid7 string `tag:"secret"`
Valid8 string `tag:"secret"`
Valid9 string `tag:"secret"`
}
func (policy *mixPolicy) getAuthParms(req *mixTy.AuthTxReq) (*AuthorizeInput, error) {
note, err := policy.getNoteInfo(req.NoteHash, mixTy.NoteStatus_FROZEN)
if err != nil {
return nil, err
}
if note.Secret.ReceiverKey != req.AuthorizeToAddr && note.Secret.ReturnKey != req.AuthorizeToAddr {
return nil, errors.Wrapf(types.ErrInvalidParam, "note no match addr to AuthorizeToAddr=%s", req.AuthorizeToAddr)
}
//get spend privacy key
privacyKey, err := policy.getAccountPrivacyKey(note.Account)
if err != nil {
return nil, errors.Wrapf(err, "getAccountPrivacyKey addr=%s", note.Account)
}
if privacyKey.Privacy.PaymentKey.ReceiveKey != note.Secret.AuthorizeKey {
return nil, errors.Wrapf(types.ErrInvalidParam, "auth pubkey from note=%s, from privacyKey=%s,for account =%s",
note.Secret.AuthorizeKey, privacyKey.Privacy.PaymentKey.ReceiveKey, note.Account)
}
var input AuthorizeInput
initTreePath(&input)
input.NoteHash = note.NoteHash
input.Amount = note.Secret.Amount
input.ReceiverPubKey = note.Secret.ReceiverKey
input.ReturnPubKey = note.Secret.ReturnKey
input.AuthorizePubKey = note.Secret.AuthorizeKey
input.NoteRandom = note.Secret.NoteRandom
input.AuthorizePriKey = privacyKey.Privacy.PaymentKey.SpendKey
input.AuthorizeHash = mixTy.Byte2Str(mimcHashString([]string{input.AuthorizePubKey, note.Secret.NoteRandom}))
input.AuthorizeSpendHash = mixTy.Byte2Str(mimcHashString([]string{req.AuthorizeToAddr, note.Secret.Amount, note.Secret.NoteRandom}))
//default auto to receiver
input.SpendFlag = "1"
if input.ReturnPubKey != "0" && input.ReturnPubKey != req.AuthorizeToAddr {
//auth to returner
input.SpendFlag = "0"
}
//get tree path
treeProof, err := policy.getTreeProof(note.NoteHash)
if err != nil {
return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash)
}
input.TreeRootHash = treeProof.TreeRootHash
updateTreePath(&input, treeProof)
return &input, nil
}
func (policy *mixPolicy) createAuthTx(req *mixTy.CreateRawTxReq) (*types.Transaction, error) {
var auth mixTy.AuthTxReq
err := types.Decode(req.Data, &auth)
if err != nil {
return nil, errors.Wrap(err, "decode req fail")
}
input, err := policy.getAuthParms(&auth)
if err != nil {
return nil, err
}
proofInfo, err := getZkProofKeys(auth.ZkPath.Path+mixTy.AuthCircuit, auth.ZkPath.Path+mixTy.AuthPk, *input)
if err != nil {
return nil, errors.Wrapf(err, "getZkProofKeys note=%s", auth.NoteHash)
}
//verify
if err := policy.verifyProofOnChain(mixTy.VerifyType_AUTHORIZE, proofInfo, auth.ZkPath.Path+mixTy.AuthVk); err != nil {
return nil, errors.Wrapf(err, "verifyProof fail for note=%s", auth.NoteHash)
}
return policy.getAuthTx(strings.TrimSpace(req.Title+mixTy.MixX), proofInfo)
}
func (policy *mixPolicy) getAuthTx(execName string, proof *mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixAuthorizeAction{}
payload.Proof = proof
cfg := policy.getWalletOperate().GetAPI().GetConfig()
action := &mixTy.MixAction{
Ty: mixTy.MixActionAuth,
Value: &mixTy.MixAction_Authorize{Authorize: payload},
}
tx := &types.Transaction{
Execer: []byte(execName),
Payload: types.Encode(action),
To: address.ExecAddress(execName),
Expire: types.Now().Unix() + int64(300), //5 min
}
return types.FormatTx(cfg, execName, tx)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package wallet
import (
"encoding/hex"
"fmt"
"strconv"
"strings"
"github.com/33cn/chain33/common/address"
"github.com/pkg/errors"
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
fr_bn256 "github.com/consensys/gurvy/bn256/fr"
)
type DepositInput struct {
//public
NoteHash string `tag:"public"`
Amount string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePubKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
}
func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositProofResp, error) {
if req == nil || len(req.Addr) <= 0 {
return nil, errors.Wrap(types.ErrInvalidParam, "paymentAddr is nil")
}
if req.Amount <= 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "deposit amount=%d need big than 0", req.Amount)
}
var secret mixTy.SecretData
secret.Amount = strconv.FormatUint(req.Amount, 10)
//1. nullifier 获取随机值
var fr fr_bn256.Element
fr.SetRandom()
secret.NoteRandom = fr.String()
// 获取receiving addr对应的paymentKey
toKey, e := policy.getPaymentKey(req.Addr)
if e != nil {
return nil, errors.Wrapf(e, "get payment key for addr = %s", req.Addr)
}
secret.ReceiverKey = toKey.ReceiverKey
//获取return addr对应的key
var returnKey *mixTy.PaymentKey
var err error
//如果Input不填,缺省空为“0”字符串
secret.ReturnKey = "0"
if len(req.ReturnAddr) > 0 {
returnKey, err = policy.getPaymentKey(req.ReturnAddr)
if err != nil {
return nil, errors.Wrapf(err, "get payment key for return addr = %s", req.ReturnAddr)
}
secret.ReturnKey = returnKey.ReceiverKey
}
//获取auth addr对应的key
var authKey *mixTy.PaymentKey
secret.AuthorizeKey = "0"
if len(req.AuthorizeAddr) > 0 {
authKey, err = policy.getPaymentKey(req.AuthorizeAddr)
if err != nil {
return nil, errors.Wrapf(err, "get payment key for authorize addr = %s", req.AuthorizeAddr)
}
secret.AuthorizeKey = authKey.ReceiverKey
}
//DH加密
data := types.Encode(&secret)
var group mixTy.DHSecretGroup
secretData, err := encryptData(toKey.EncryptKey, data)
if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", req.Addr)
}
group.Receiver = hex.EncodeToString(types.Encode(secretData))
if returnKey != nil {
secretData, err = encryptData(returnKey.EncryptKey, data)
if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", req.ReturnAddr)
}
group.Returner = hex.EncodeToString(types.Encode(secretData))
}
if authKey != nil {
secretData, err = encryptData(authKey.EncryptKey, data)
if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", req.AuthorizeAddr)
}
group.Authorize = hex.EncodeToString(types.Encode(secretData))
}
var resp mixTy.DepositProofResp
resp.Proof = &secret
resp.Secrets = &group
keys := []string{
secret.ReceiverKey,
secret.ReturnKey,
secret.AuthorizeKey,
secret.Amount,
secret.NoteRandom,
}
resp.NoteHash = mixTy.Byte2Str(mimcHashString(keys))
return &resp, nil
}
func (policy *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transaction, error) {
var deposit mixTy.DepositTxReq
err := types.Decode(req.Data, &deposit)
if err != nil {
return nil, errors.Wrap(err, "decode req fail")
}
resp, err := policy.depositParams(deposit.Deposit)
if err != nil {
return nil, err
}
var input DepositInput
input.NoteHash = resp.NoteHash
input.Amount = resp.Proof.Amount
input.ReceiverPubKey = resp.Proof.ReceiverKey
input.AuthorizePubKey = resp.Proof.AuthorizeKey
input.ReturnPubKey = resp.Proof.ReturnKey
input.NoteRandom = resp.Proof.NoteRandom
proofInfo, err := getZkProofKeys(deposit.ZkPath.Path+mixTy.DepositCircuit, deposit.ZkPath.Path+mixTy.DepositPk, input)
if err != nil {
return nil, err
}
//线上验证proof,失败的原因有可能circuit,Pk和线上vk不匹配,或不是一起产生的版本
if err := policy.verifyProofOnChain(mixTy.VerifyType_DEPOSIT, proofInfo, deposit.ZkPath.Path+mixTy.DepositVk); err != nil {
return nil, errors.Wrap(err, "verifyProof fail")
}
fmt.Println("createDepositTx ok")
proofInfo.Secrets = resp.Secrets
return policy.getDepositTx(strings.TrimSpace(req.Title+mixTy.MixX), proofInfo)
}
func (policy *mixPolicy) getDepositTx(execName string, proof *mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixDepositAction{}
payload.Proof = proof
cfg := policy.getWalletOperate().GetAPI().GetConfig()
action := &mixTy.MixAction{
Ty: mixTy.MixActionDeposit,
Value: &mixTy.MixAction_Deposit{Deposit: payload},
}
tx := &types.Transaction{
Execer: []byte(execName),
Payload: types.Encode(action),
To: address.ExecAddress(execName),
Expire: types.Now().Unix() + int64(300), //5 min
}
fmt.Println("createDepositTx tx")
return types.FormatTx(cfg, execName, tx)
}
This diff is collapsed.
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package wallet
import (
"strconv"
"strings"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/pkg/errors"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
type WithdrawInput struct {
//public
TreeRootHash string `tag:"public"`
AuthorizeSpendHash string `tag:"public"`
NullifierHash string `tag:"public"`
Amount string `tag:"public"`
//secret
ReceiverPubKey string `tag:"secret"`
ReturnPubKey string `tag:"secret"`
AuthorizePubKey string `tag:"secret"`
NoteRandom string `tag:"secret"`
SpendPriKey string `tag:"secret"`
SpendFlag string `tag:"secret"`
AuthorizeFlag string `tag:"secret"`
//tree path info
NoteHash string `tag:"secret"`
Path0 string `tag:"secret"`
Path1 string `tag:"secret"`
Path2 string `tag:"secret"`
Path3 string `tag:"secret"`
Path4 string `tag:"secret"`
Path5 string `tag:"secret"`
Path6 string `tag:"secret"`
Path7 string `tag:"secret"`
Path8 string `tag:"secret"`
Path9 string `tag:"secret"`
Helper0 string `tag:"secret"`
Helper1 string `tag:"secret"`
Helper2 string `tag:"secret"`
Helper3 string `tag:"secret"`
Helper4 string `tag:"secret"`
Helper5 string `tag:"secret"`
Helper6 string `tag:"secret"`
Helper7 string `tag:"secret"`
Helper8 string `tag:"secret"`
Helper9 string `tag:"secret"`
Valid0 string `tag:"secret"`
Valid1 string `tag:"secret"`
Valid2 string `tag:"secret"`
Valid3 string `tag:"secret"`
Valid4 string `tag:"secret"`
Valid5 string `tag:"secret"`
Valid6 string `tag:"secret"`
Valid7 string `tag:"secret"`
Valid8 string `tag:"secret"`
Valid9 string `tag:"secret"`
}
func (policy *mixPolicy) getWithdrawParams(noteHash string) (*WithdrawInput, error) {
note, err := policy.getNoteInfo(noteHash, mixTy.NoteStatus_VALID)
if err != nil {
return nil, err
}
var input WithdrawInput
initTreePath(&input)
input.NullifierHash = note.Nullifier
input.NoteHash = note.NoteHash
input.AuthorizeSpendHash = note.AuthorizeSpendHash
input.Amount = note.Secret.Amount
input.ReceiverPubKey = note.Secret.ReceiverKey
input.ReturnPubKey = note.Secret.ReturnKey
input.AuthorizePubKey = note.Secret.AuthorizeKey
input.NoteRandom = note.Secret.NoteRandom
input.SpendFlag = "1"
if note.Role == mixTy.Role_RETURNER {
input.SpendFlag = "0"
}
input.AuthorizeFlag = "0"
if len(input.AuthorizeSpendHash) > LENNULLKEY {
input.AuthorizeFlag = "1"
}
//get spend privacy key
privacyKey, err := policy.getAccountPrivacyKey(note.Account)
if err != nil {
return nil, errors.Wrapf(err, "getAccountPrivacyKey addr=%s", note.Account)
}
input.SpendPriKey = privacyKey.Privacy.PaymentKey.SpendKey
//get tree path
treeProof, err := policy.getTreeProof(note.NoteHash)
if err != nil {
return nil, errors.Wrapf(err, "getTreeProof for hash=%s", note.NoteHash)
}
input.TreeRootHash = treeProof.TreeRootHash
updateTreePath(&input, treeProof)
return &input, nil
}
func (policy *mixPolicy) createWithdrawTx(req *mixTy.CreateRawTxReq) (*types.Transaction, error) {
var withdraw mixTy.WithdrawTxReq
err := types.Decode(req.Data, &withdraw)
if err != nil {
return nil, errors.Wrap(err, "decode req fail")
}
if withdraw.TotalAmount <= 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "totalAmount=%d", withdraw.TotalAmount)
}
notes := strings.Split(withdraw.NoteHashs, ",")
if len(notes) == 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "noteHashs=%s", withdraw.NoteHashs)
}
var proofs []*mixTy.ZkProofInfo
var sum uint64
for _, note := range notes {
input, err := policy.getWithdrawParams(note)
if err != nil {
return nil, errors.Wrapf(err, "getWithdrawParams note=%s", note)
}
proofInfo, err := getZkProofKeys(withdraw.ZkPath.Path+mixTy.WithdrawCircuit, withdraw.ZkPath.Path+mixTy.WithdrawPk, *input)
if err != nil {
return nil, errors.Wrapf(err, "getZkProofKeys note=%s", note)
}
//verify
if err := policy.verifyProofOnChain(mixTy.VerifyType_WITHDRAW, proofInfo, withdraw.ZkPath.Path+mixTy.WithdrawVk); err != nil {
return nil, errors.Wrapf(err, "verifyProof fail for note=%s", note)
}
v, err := strconv.Atoi(input.Amount)
if err != nil {
return nil, errors.Wrapf(err, "atoi fail for note=%s,amount=%s", note, input.Amount)
}
sum += uint64(v)
proofs = append(proofs, proofInfo)
}
if sum != withdraw.TotalAmount {
return nil, errors.Wrapf(types.ErrInvalidParam, "amount not match req=%d,note.sum=%d", withdraw.TotalAmount, sum)
}
return policy.getWithdrawTx(strings.TrimSpace(req.Title+mixTy.MixX), withdraw.TotalAmount, proofs)
}
func (policy *mixPolicy) getWithdrawTx(execName string, amount uint64, proofs []*mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixWithdrawAction{}
payload.Amount = amount
payload.Proofs = proofs
cfg := policy.getWalletOperate().GetAPI().GetConfig()
action := &mixTy.MixAction{
Ty: mixTy.MixActionWithdraw,
Value: &mixTy.MixAction_Withdraw{Withdraw: payload},
}
tx := &types.Transaction{
Execer: []byte(execName),
Payload: types.Encode(action),
To: address.ExecAddress(execName),
Expire: types.Now().Unix() + int64(300), //5 min
}
return types.FormatTx(cfg, execName, tx)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package wallet
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"reflect"
"strconv"
backend_bn256 "github.com/consensys/gnark/backend/bn256"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gurvy"
"github.com/pkg/errors"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gnark/backend"
groth16_bn256 "github.com/consensys/gnark/backend/bn256/groth16"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
)
//对secretData 编码为string,同时增加随机值
//func encodeSecretData(secret *mixTy.SecretData) (*mixTy.EncodedSecretData, error) {
// if secret == nil {
// return nil, errors.Wrap(types.ErrInvalidParam, "para is nil")
// }
// if len(secret.ReceiverKey) <= 0 {
// return nil, errors.Wrap(types.ErrInvalidParam, "spendPubKey is nil")
// }
// var val big.Int
// ret, succ := val.SetString(secret.Amount, 10)
// if !succ {
// return nil, errors.Wrapf(types.ErrInvalidParam, "wrong amount = %s", secret.Amount)
// }
// if ret.Sign() <= 0 {
// return nil, errors.Wrapf(types.ErrInvalidParam, "amount = %s, need bigger than 0", secret.Amount)
// }
//
// //获取随机值
// var fr fr_bn256.Element
// fr.SetRandom()
// secret.NoteRandom = fr.String()
// code := types.Encode(secret)
// var resp mixTy.EncodedSecretData
//
// resp.Encoded = common.ToHex(code)
// resp.RawData = secret
//
// return &resp, nil
//
//}
//产生随机秘钥和receivingPk对data DH加密,返回随机秘钥的公钥
func encryptSecretData(req *mixTy.EncryptSecretData) (*mixTy.DHSecret, error) {
secret, err := common.FromHex(req.Secret)
if err != nil {
return nil, errors.Wrap(err, "decode secret")
}
return encryptData(req.PeerKey, secret)
}
func decryptSecretData(req *mixTy.DecryptSecretData) (*mixTy.SecretData, error) {
secret, err := common.FromHex(req.Secret)
if err != nil {
return nil, errors.Wrap(err, "decode req.secret")
}
decrypt, err := decryptData(req.PriKey, req.PeerKey, secret)
if err != nil {
return nil, errors.Wrap(err, "decrypt secret")
}
var raw mixTy.SecretData
err = types.Decode(decrypt, &raw)
if err != nil {
return nil, errors.Wrap(mixTy.ErrDecryptDataFail, "decode decrypt.secret")
}
return &raw, nil
}
func (policy *mixPolicy) verifyProofOnChain(ty mixTy.VerifyType, proof *mixTy.ZkProofInfo, vkPath string) error {
//vkpath verify
if len(vkPath) > 0 {
vk, err := getVerifyKey(vkPath)
if err != nil {
return errors.Wrapf(err, "getVerifyKey path=%s", vkPath)
}
verifyKey, err := serializeObj(vk)
if err != nil {
return errors.Wrapf(err, "serial vk path=%s", vkPath)
}
pass, err := zksnark.Verify(verifyKey, proof.Proof, proof.PublicInput)
if err != nil || !pass {
return errors.Wrapf(err, "zk verify fail")
}
return nil
}
//线上验证proof,失败的原因有可能circuit,Pk和线上vk不匹配,或不是一起产生的版本
verify := &mixTy.VerifyProofInfo{
Ty: ty,
Proof: proof,
}
//onchain verify
_, err := policy.walletOperate.GetAPI().QueryChain(&types.ChainExecutor{
Driver: "mix",
FuncName: "VerifyProof",
Param: types.Encode(verify),
})
return err
}
func (policy *mixPolicy) getPaymentKey(addr string) (*mixTy.PaymentKey, error) {
msg, err := policy.walletOperate.GetAPI().QueryChain(&types.ChainExecutor{
Driver: "mix",
FuncName: "PaymentPubKey",
Param: types.Encode(&types.ReqString{Data: addr}),
})
if err != nil {
return nil, err
}
return msg.(*mixTy.PaymentKey), err
}
func (policy *mixPolicy) getPathProof(leaf string) (*mixTy.CommitTreeProve, error) {
msg, err := policy.walletOperate.GetAPI().QueryChain(&types.ChainExecutor{
Driver: "mix",
FuncName: "GetTreePath",
Param: types.Encode(&mixTy.TreeInfoReq{LeafHash: leaf}),
})
if err != nil {
return nil, err
}
return msg.(*mixTy.CommitTreeProve), nil
}
func (policy *mixPolicy) getNoteInfo(noteHash string, noteStatus mixTy.NoteStatus) (*mixTy.WalletIndexInfo, error) {
if policy.walletOperate.IsWalletLocked() {
return nil, types.ErrWalletIsLocked
}
var index mixTy.WalletMixIndexReq
index.NoteHash = noteHash
msg, err := policy.listMixInfos(&index)
if err != nil {
return nil, errors.Wrapf(err, "list noteHash=%s", noteHash)
}
resp := msg.(*mixTy.WalletIndexResp)
if len(resp.Notes) < 1 {
return nil, errors.Wrapf(err, "list not found noteHash=%s", noteHash)
}
note := msg.(*mixTy.WalletIndexResp).Notes[0]
if note.Status != noteStatus {
return nil, errors.Wrapf(types.ErrNotAllow, "wrong note status=%s", note.Status.String())
}
return note, nil
}
func (policy *mixPolicy) getTreeProof(leaf string) (*mixTy.TreePathProof, error) {
//get tree path
path, err := policy.getPathProof(leaf)
if err != nil {
return nil, errors.Wrapf(err, "get tree proof for noteHash=%s", leaf)
}
var proof mixTy.TreePathProof
proof.TreePath = path.ProofSet[1:]
proof.Helpers = path.Helpers
proof.TreeRootHash = path.RootHash
return &proof, nil
}
//文件信息过大,pk文件超过1M,作为参数传递不合适,这里传路径信息
func getCircuit(path string) (*backend_bn256.R1CS, error) {
var bigIntR1cs frontend.R1CS
if err := gob.Read(path, &bigIntR1cs, gurvy.BN256); err != nil {
return nil, errors.Wrapf(err, "getCircuit path=%s", path)
}
r1cs := backend_bn256.Cast(&bigIntR1cs)
return &r1cs, nil
}
func getProveKey(path string) (*groth16_bn256.ProvingKey, error) {
var pk groth16_bn256.ProvingKey
if err := gob.Read(path, &pk, gurvy.BN256); err != nil {
return nil, errors.Wrapf(err, "getProveKey path=%s", path)
}
return &pk, nil
}
func getVerifyKey(path string) (*groth16_bn256.VerifyingKey, error) {
var vk groth16_bn256.VerifyingKey
if err := gob.Read(path, &vk, gurvy.BN256); err != nil {
return nil, errors.Wrapf(err, "zk.verify.Deserize.VK=%s", path)
}
return &vk, nil
}
func createProof(circuit *backend_bn256.R1CS, pk *groth16_bn256.ProvingKey, inputs backend.Assignments) (*groth16_bn256.Proof, error) {
return groth16_bn256.Prove(circuit, pk, inputs)
}
func verifyProof(proof *groth16_bn256.Proof, vk *groth16_bn256.VerifyingKey, input backend.Assignments) bool {
ok, err := groth16_bn256.Verify(proof, vk, input)
if err != nil {
fmt.Println("err", err)
return false
}
return ok
}
func getAssignments(obj interface{}) (backend.Assignments, error) {
ty := reflect.TypeOf(obj)
tv := reflect.ValueOf(obj)
n := ty.NumField()
assigns := backend.NewAssignment()
for i := 0; i < n; i++ {
name := ty.Field(i).Name
v, ok := ty.Field(i).Tag.Lookup("tag")
if !ok {
return nil, errors.Wrapf(types.ErrNotFound, "fieldname=%s not set tag", ty.Field(i).Name)
}
if v != string(backend.Secret) && v != string(backend.Public) {
return nil, errors.Wrapf(types.ErrInvalidParam, "tag=%s not correct", v)
}
assigns.Assign(backend.Visibility(v), name, tv.FieldByName(name).Interface())
}
return assigns, nil
}
func serializeObj(from interface{}) (string, error) {
var buf bytes.Buffer
err := gob.Serialize(&buf, from, gurvy.BN256)
if err != nil {
return "", err
}
return hex.EncodeToString(buf.Bytes()), nil
}
func serialInputs(assignments backend.Assignments) (string, error) {
rst := make(map[string]interface{})
publics := assignments.DiscardSecrets()
for k, v := range publics {
rst[k] = v.Value.String()
}
out, err := json.Marshal(rst)
if err != nil {
return "", err
}
return hex.EncodeToString(out), nil
}
func initTreePath(obj interface{}) {
tv := reflect.ValueOf(obj)
for i := 0; i < mixTy.TreeLevel; i++ {
tv.Elem().FieldByName(fmt.Sprintf("Path%d", i)).SetString("0")
tv.Elem().FieldByName(fmt.Sprintf("Helper%d", i)).SetString("0")
tv.Elem().FieldByName(fmt.Sprintf("Valid%d", i)).SetString("0")
}
}
func updateTreePath(obj interface{}, treeProof *mixTy.TreePathProof) {
tv := reflect.ValueOf(obj)
for i, t := range treeProof.TreePath {
tv.Elem().FieldByName("Path" + strconv.Itoa(i)).SetString(t)
tv.Elem().FieldByName("Helper" + strconv.Itoa(i)).SetString(strconv.Itoa(int(treeProof.Helpers[i])))
tv.Elem().FieldByName("Valid" + strconv.Itoa(i)).SetString("1")
}
}
func getZkProofKeys(circuitFile, pkFile string, inputs interface{}) (*mixTy.ZkProofInfo, error) {
assignments, err := getAssignments(inputs)
if err != nil {
return nil, err
}
//从电路文件获取电路约束
circuit, err := getCircuit(circuitFile)
if err != nil {
return nil, err
}
//从pv 文件读取Pk结构
pk, err := getProveKey(pkFile)
if err != nil {
return nil, err
}
//产生zk 证明
proof, err := createProof(circuit, pk, assignments)
if err != nil {
return nil, err
}
//序列号成字符串
proofKey, err := serializeObj(proof)
if err != nil {
return nil, err
}
//序列号成字符串
proofInput, err := serialInputs(assignments)
if err != nil {
return nil, err
}
return &mixTy.ZkProofInfo{
Proof: proofKey,
PublicInput: proofInput,
}, nil
}
......@@ -3,9 +3,11 @@ package wallet
import (
"encoding/hex"
"fmt"
"reflect"
"testing"
"github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/stretchr/testify/assert"
)
......@@ -15,21 +17,21 @@ func TestGetCommitValue(t *testing.T) {
note = 100
transfer = 60
minFee = 1
_, err := getCommitValue(note, transfer, minFee)
_, err := getShieldValue(note, transfer, minFee)
assert.Nil(t, err)
//transfer > note
note = 100
transfer = 100
minFee = 1
_, err = getCommitValue(note, transfer, minFee)
_, err = getShieldValue(note, transfer, minFee)
t.Log(err)
assert.NotNil(t, err)
note = 100
transfer = 101
minFee = 0
_, err = getCommitValue(note, transfer, minFee)
_, err = getShieldValue(note, transfer, minFee)
t.Log(err)
assert.NotNil(t, err)
......@@ -37,7 +39,7 @@ func TestGetCommitValue(t *testing.T) {
note = 100
transfer = 99
minFee = 1
_, err = getCommitValue(note, transfer, minFee)
_, err = getShieldValue(note, transfer, minFee)
assert.Nil(t, err)
a := "0a9c010a4d3136323433323838333039363632323833373538343930323239313730303834393836343035373630373234353332323934333436353837323033353436363930353333373131303333323139124b3238383637383239373931373237373235343930333236303134303538313534363138303135353433383231393339363836333632313634323236303434353739313434393237383237331a82033078656663333331616261616139653039353966636536356163343364626534306364646139356534356261636163613161326166626265366637323533633132326233346264323337353932343066306237623836653363343635666131343065666332636665623861653035366234323163303665353062396532646564636236383963336536656435363636373731343235663736313931653831356665666633646432393965633535386261323731343238333131623130353364376265633864646163313733393632326238666138326438373336666531623332633835376438343330643634646637336530643265326238373932396335633762366437336534383365363130303561313361376531643730636637653834656132613235343166373235363834656266613737653235313232326466313039336230313964646165623963376134393763316538653737386462313730323636323536666666363332643437363738626633366634383361373334346666326330"
......@@ -50,4 +52,105 @@ func TestGetCommitValue(t *testing.T) {
assert.Nil(t, err)
fmt.Println("data", data)
var deposit mixTy.DepositProofResp
deposit.NoteHash = "notehashstr"
deposit.Proof = &mixTy.SecretData{
ReceiverKey: "receiverstr",
ReturnKey: "returnval",
}
deposit.Secrets = &mixTy.DHSecretGroup{
Receiver: "receiverstr",
Authorize: "authval",
}
ty := reflect.TypeOf(deposit)
val := reflect.ValueOf(deposit)
n := ty.NumField()
for i := 0; i < n; i++ {
fmt.Println("i=", i, "name=", ty.Field(i).Name, "valid", val.Field(i).IsZero(), "name", val.Field(i), "ty", val.FieldByName(ty.Field(i).Name))
}
//type strA struct{
// a backend.Assignment `secret:"public"`
// b backend.Assignment `secret:"private"`
//}
//tt := strA{}
//
//tt.a.Value.SetString("123",10)
//tt.a.IsPublic
//tt.a.Value.SetString("567",10)
//tp := reflect.TypeOf(tt)
//fmt.Println("tt",tp.Field(0).Tag.Get("secret"))
}
func TestGetAssignments(t *testing.T) {
deposit := DepositInput{
NoteHash: "111",
Amount: "222",
ReceiverPubKey: "333",
ReturnPubKey: "444",
AuthorizePubKey: "555",
NoteRandom: "666",
}
assigns, err := getAssignments(deposit)
assert.Nil(t, err)
val := assigns["NoteHash"].Value
assert.Equal(t, val.String(), deposit.NoteHash)
assert.Equal(t, assigns["NoteHash"].IsPublic, true)
assert.Equal(t, assigns["ReceiverPubKey"].IsPublic, false)
reduceAssign := assigns.DiscardSecrets()
_, ok := reduceAssign["ReceiverPubKey"]
assert.Equal(t, ok, false)
//tv := reflect.ValueOf(&deposit)
//tv.Elem().FieldByName("NoteHash").SetString("999")
////tv.FieldByName("NoteHash").Elem().SetString("999")
//assert.Equal(t,"999",deposit.NoteHash)
var in WithdrawInput
initTreePath(&in)
assert.Equal(t, "99", in.Path1)
}
func TestVerifyProof(t *testing.T) {
deposit := DepositInput{
NoteHash: "319044369386253980478484545601022272388174242630360020319556034291986094405",
Amount: "500000000",
ReceiverPubKey: "7244551457692363731356498279463138379576484998878425864678733206990733443457",
ReturnPubKey: "0",
AuthorizePubKey: "0",
NoteRandom: "21887946084880143097415438560893808581456164284155969619878297484093938793578",
}
assigns, err := getAssignments(deposit)
//从电路文件获取电路约束
circuit, err := getCircuit("../cmd/gnark/circuit/deposit/circuit_deposit.r1cs")
assert.Nil(t, err)
//从pv 文件读取Pk结构
pk, err := getProveKey("../cmd/gnark/circuit/deposit/circuit_deposit.pk")
assert.Nil(t, err)
proof, err := createProof(circuit, pk, assigns)
assert.Nil(t, err)
vk, err := getVerifyKey("../cmd/gnark/circuit/deposit/circuit_deposit.vk")
assert.Nil(t, err)
rst := verifyProof(proof, vk, assigns.DiscardSecrets())
assert.Equal(t, true, rst)
proofKey, err := serializeObj(proof)
assert.Nil(t, err)
verifyKey, err := serializeObj(vk)
assert.Nil(t, err)
proofInput, err := serialInputs(assigns)
//fmt.Println("proofinput",proofInput)
assert.Nil(t, err)
rt, err := zksnark.Verify(verifyKey, proofKey, proofInput)
assert.Nil(t, err)
assert.Equal(t, true, rt)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment