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

proof encode to tx

parent ce15f935
...@@ -73,8 +73,8 @@ grpcFuncWhitelist=["*"] ...@@ -73,8 +73,8 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="para" name="para"
poolCacheSize=10240 poolCacheSize=10240
#平行链的最小feeRate为0 #联盟链没有交易费,对应平行链minTxFeeRate需要设为0
#minTxFeeRate=100000 minTxFeeRate=100000
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
......
...@@ -39,16 +39,16 @@ func NewAuth() *frontend.R1CS { ...@@ -39,16 +39,16 @@ func NewAuth() *frontend.R1CS {
// create root constraint system // create root constraint system
circuit := frontend.New() circuit := frontend.New()
amount := circuit.SECRET_INPUT("amount") amount := circuit.SECRET_INPUT("Amount")
//spend pubkey //spend pubkey
receiverPubKey := circuit.SECRET_INPUT("receiverPubKey") receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubKey := circuit.SECRET_INPUT("returnPubKey") returnPubKey := circuit.SECRET_INPUT("ReturnPubKey")
authorizePriKey := circuit.SECRET_INPUT("authorizePriKey") authorizePriKey := circuit.SECRET_INPUT("AuthorizePriKey")
noteRandom := circuit.SECRET_INPUT("noteRandom") noteRandom := circuit.SECRET_INPUT("NoteRandom")
authPubKey := circuit.PUBLIC_INPUT("authorizePubKey") authPubKey := circuit.PUBLIC_INPUT("AuthorizePubKey")
authorizeHash := circuit.PUBLIC_INPUT("authorizeHash") authorizeHash := circuit.PUBLIC_INPUT("AuthorizeHash")
// hash function // hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256) mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
...@@ -58,9 +58,9 @@ func NewAuth() *frontend.R1CS { ...@@ -58,9 +58,9 @@ func NewAuth() *frontend.R1CS {
circuit.MUSTBE_EQ(authorizeHash, mimc.Hash(&circuit, authPubKey, noteRandom)) circuit.MUSTBE_EQ(authorizeHash, mimc.Hash(&circuit, authPubKey, noteRandom))
//note hash random //note hash random
authSpendHash := circuit.PUBLIC_INPUT("authorizeSpendHash") authSpendHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
//spend_flag 0:return_pubkey, 1: spend_pubkey //spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("spendFlag") spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag) circuit.MUSTBE_BOOLEAN(spendFlag)
targetPubHash := circuit.SELECT(spendFlag, receiverPubKey, returnPubKey) targetPubHash := circuit.SELECT(spendFlag, receiverPubKey, returnPubKey)
calcAuthSpendHash := mimc.Hash(&circuit, targetPubHash, amount, noteRandom) calcAuthSpendHash := mimc.Hash(&circuit, targetPubHash, amount, noteRandom)
...@@ -69,7 +69,7 @@ func NewAuth() *frontend.R1CS { ...@@ -69,7 +69,7 @@ func NewAuth() *frontend.R1CS {
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费 //通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
// specify note hash constraint // specify note hash constraint
preImage := mimc.Hash(&circuit, receiverPubKey, returnPubKey, authPubKey, amount, noteRandom) preImage := mimc.Hash(&circuit, receiverPubKey, returnPubKey, authPubKey, amount, noteRandom)
noteHash := circuit.SECRET_INPUT("noteHash") noteHash := circuit.SECRET_INPUT("NoteHash")
circuit.MUSTBE_EQ(noteHash, preImage) circuit.MUSTBE_EQ(noteHash, preImage)
util.MerkelPathPart(&circuit, mimc, preImage) util.MerkelPathPart(&circuit, mimc, preImage)
......
...@@ -36,48 +36,51 @@ func TestAuthorizeSpend(t *testing.T) { ...@@ -36,48 +36,51 @@ func TestAuthorizeSpend(t *testing.T) {
r1csBN256 := backend_bn256.Cast(r1cs) r1csBN256 := backend_bn256.Cast(r1cs)
{ {
good := backend.NewAssignment() good := backend.NewAssignment()
good.Assign(backend.Public, "treeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310") good.Assign(backend.Public, "TreeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583") good.Assign(backend.Public, "AuthorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Public, "authorizeHash", "1267825436937766239630340333349685320927256968591056373125946583184548355070") good.Assign(backend.Public, "AuthorizeHash", "1267825436937766239630340333349685320927256968591056373125946583184548355070")
good.Assign(backend.Public, "authorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663") good.Assign(backend.Public, "AuthorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Secret, "amount", "28242048") good.Assign(backend.Secret, "Amount", "28242048")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705") good.Assign(backend.Secret, "ReceiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497") good.Assign(backend.Secret, "ReturnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePriKey", "17822967620457187568904804290291537271142779717280482398091401115827760898835") good.Assign(backend.Secret, "AuthorizePriKey", "17822967620457187568904804290291537271142779717280482398091401115827760898835")
good.Assign(backend.Secret, "spendFlag", "1") good.Assign(backend.Secret, "SpendFlag", "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")
good.Assign(backend.Secret, "path1", "19561523370160677851616596032513161448778901506614020103852017946679781620105") good.Assign(backend.Secret, "Path0", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "path2", "13898857070666440684265042188056372750257678232709763835292910585848522658637") good.Assign(backend.Secret, "Path1", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "path3", "15019169196974879571470243100379529757970866395477207575033769902587972032431") good.Assign(backend.Secret, "Path2", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "path4", "0") good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "path5", "0") good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "path6", "0") good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "path7", "0") good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "path8", "0") good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "path9", "0") good.Assign(backend.Secret, "Path8", "0")
good.Assign(backend.Secret, "Path9", "0")
good.Assign(backend.Secret, "helper1", "1") good.Assign(backend.Secret, "Helper0", "1")
good.Assign(backend.Secret, "helper2", "1") good.Assign(backend.Secret, "Helper1", "1")
good.Assign(backend.Secret, "helper3", "1") good.Assign(backend.Secret, "Helper2", "1")
good.Assign(backend.Secret, "helper4", "0") good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "helper5", "0") good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "helper6", "0") good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "helper7", "0") good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "helper8", "0") good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "helper9", "0") good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "valid1", "1") good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "valid2", "1") good.Assign(backend.Secret, "Valid1", "1")
good.Assign(backend.Secret, "valid3", "1") good.Assign(backend.Secret, "Valid2", "1")
good.Assign(backend.Secret, "valid4", "0") good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "valid5", "0") good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "valid6", "0") good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "valid7", "0") good.Assign(backend.Secret, "Valid6", "0")
good.Assign(backend.Secret, "valid8", "0") good.Assign(backend.Secret, "Valid7", "0")
good.Assign(backend.Secret, "valid9", "0") good.Assign(backend.Secret, "Valid8", "0")
good.Assign(backend.Secret, "Valid9", "0")
assert.Solved(&r1csBN256, good, nil) assert.Solved(&r1csBN256, good, nil)
} }
......
public, treeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310 public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583 public, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
public, authorizeHash,1267825436937766239630340333349685320927256968591056373125946583184548355070 public, AuthorizeHash,1267825436937766239630340333349685320927256968591056373125946583184548355070
public, authorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663 public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
secret, amount,28242048 secret, Amount,28242048
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705 secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497 secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePriKey,17822967620457187568904804290291537271142779717280482398091401115827760898835 secret, AuthorizePriKey,17822967620457187568904804290291537271142779717280482398091401115827760898835
secret, spendFlag,1 secret, SpendFlag,1
secret, noteRandom,2824204835 secret, NoteRandom,2824204835
secret, noteHash,3649361563603415612447884923592927672484439983354650489908367088830561161361 secret, NoteHash,3649361563603415612447884923592927672484439983354650489908367088830561161361
secret, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105 secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637 secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431 secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path4,0 secret, Path3,0
secret, path5,0 secret, Path4,0
secret, path6,0 secret, Path5,0
secret, path7,0 secret, Path6,0
secret, path8,0 secret, Path7,0
secret, path9,0 secret, Path8,0
secret, path10,0 secret, Path9,0
secret, helper1,1 secret, Helper0,1
secret, helper2,1 secret, Helper1,1
secret, helper3,1 secret, Helper2,1
secret, helper4,1 secret, Helper3,1
secret, helper5,1 secret, Helper4,1
secret, helper6,1 secret, Helper5,1
secret, helper7,1 secret, Helper6,1
secret, helper8,1 secret, Helper7,1
secret, helper9,1 secret, Helper8,1
secret, helper10,1 secret, Helper9,1
secret, valid1,1 secret, Valid0,1
secret, valid2,1 secret, Valid1,1
secret, valid3,1 secret, Valid2,1
secret, valid4,0 secret, Valid3,0
secret, valid5,0 secret, Valid4,0
secret, valid6,0 secret, Valid5,0
secret, valid7,0 secret, Valid6,0
secret, valid8,0 secret, Valid7,0
secret, valid9,0 secret, Valid8,0
secret, valid10,0 secret, Valid9,0
...@@ -15,14 +15,14 @@ func main() { ...@@ -15,14 +15,14 @@ func main() {
//spend commit hash the circuit implementing //spend commit hash the circuit implementing
/* /*
public: public:
noteHash NoteHash
amount Amount
private: private:
receiverPubKey ReceiverPubKey
returnPubKey ReturnPubKey
authorizePubKey AuthorizePubKey
noteRandom NoteRandom
*/ */
func NewDeposit() *frontend.R1CS { func NewDeposit() *frontend.R1CS {
...@@ -31,22 +31,22 @@ func NewDeposit() *frontend.R1CS { ...@@ -31,22 +31,22 @@ func NewDeposit() *frontend.R1CS {
circuit := frontend.New() circuit := frontend.New()
//公共输入以验证 //公共输入以验证
amount := circuit.PUBLIC_INPUT("amount") amount := circuit.PUBLIC_INPUT("Amount")
//spend pubkey //spend pubkey
receiverPubKey := circuit.SECRET_INPUT("receiverPubKey") receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey") returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey") authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
// hash function // hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256) mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
//note hash random //note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom") noteRandom := circuit.SECRET_INPUT("NoteRandom")
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费 //通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom) //preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.PUBLIC_INPUT("noteHash") noteHash := circuit.PUBLIC_INPUT("NoteHash")
// specify note hash constraint // specify note hash constraint
preImage := mimc.Hash(&circuit, receiverPubKey, returnPubkey, authPubkey, amount, noteRandom) preImage := mimc.Hash(&circuit, receiverPubKey, returnPubkey, authPubkey, amount, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage) circuit.MUSTBE_EQ(noteHash, preImage)
......
public, noteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649 public, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
public, amount,28242048 public, Amount,28242048
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705 secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497 secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583 secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, noteRandom,2824204835 secret, NoteRandom,2824204835
......
public, treeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310 public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, shieldAmountX,14087975867275911077371231345227824611951436822132762463787130558957838320348 public, ShieldAmountX,14087975867275911077371231345227824611951436822132762463787130558957838320348
public, shieldAmountY,15113519960384204624879642069520481336224311978035289236693658603675385299879 public, ShieldAmountY,15113519960384204624879642069520481336224311978035289236693658603675385299879
public, authorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663 public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, nullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195 public, NullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
secret, amount,28242048 secret, Amount,28242048
secret, amountRandom,35 secret, AmountRandom,35
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705 secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497 secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583 secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, spendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502 secret, SpendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, spendFlag,1 secret, SpendFlag,1
secret, authorizeFlag,1 secret, AuthorizeFlag,1
secret, noteRandom,2824204835 secret, NoteRandom,2824204835
secret, noteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649 secret, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105 secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637 secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431 secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path4,0 secret, Path3,0
secret, path5,0 secret, Path4,0
secret, path6,0 secret, Path5,0
secret, path7,0 secret, Path6,0
secret, path8,0 secret, Path7,0
secret, path9,0 secret, Path8,0
secret, Path9,0
secret, helper1,1 secret, Helper0,1
secret, helper2,1 secret, Helper1,1
secret, helper3,1 secret, Helper2,1
secret, helper4,1 secret, Helper3,1
secret, helper5,1 secret, Helper4,1
secret, helper6,1 secret, Helper5,1
secret, helper7,1 secret, Helper6,1
secret, helper8,1 secret, Helper7,1
secret, helper9,1 secret, Helper8,1
secret, Helper9,1
secret, Valid0,1
secret, valid1,1 secret, Valid1,1
secret, valid2,1 secret, Valid2,1
secret, valid3,1 secret, Valid3,0
secret, valid4,0 secret, Valid4,0
secret, valid5,0 secret, Valid5,0
secret, valid6,0 secret, Valid6,0
secret, valid7,0 secret, Valid7,0
secret, valid8,0 secret, Valid8,0
secret, valid9,0 secret, Valid9,0
...@@ -42,18 +42,18 @@ func NewTransferInput() *frontend.R1CS { ...@@ -42,18 +42,18 @@ func NewTransferInput() *frontend.R1CS {
// create root constraint system // create root constraint system
circuit := frontend.New() circuit := frontend.New()
spendValue := circuit.SECRET_INPUT("amount") spendValue := circuit.SECRET_INPUT("Amount")
//spend pubkey //spend pubkey
spendPubkey := circuit.SECRET_INPUT("receiverPubKey") spendPubkey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey") returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey") authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
spendPrikey := circuit.SECRET_INPUT("spendPriKey") spendPrikey := circuit.SECRET_INPUT("SpendPriKey")
//spend_flag 0:return_pubkey, 1: spend_pubkey //spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("spendFlag") spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag) circuit.MUSTBE_BOOLEAN(spendFlag)
//auth_check 0: not need auth check, 1:need check //auth_check 0: not need auth check, 1:need check
authFlag := circuit.SECRET_INPUT("authorizeFlag") authFlag := circuit.SECRET_INPUT("AuthorizeFlag")
circuit.MUSTBE_BOOLEAN(authFlag) circuit.MUSTBE_BOOLEAN(authFlag)
// hash function // hash function
...@@ -63,10 +63,10 @@ func NewTransferInput() *frontend.R1CS { ...@@ -63,10 +63,10 @@ func NewTransferInput() *frontend.R1CS {
circuit.MUSTBE_EQ(targetPubHash, calcPubHash) circuit.MUSTBE_EQ(targetPubHash, calcPubHash)
//note hash random //note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom") noteRandom := circuit.SECRET_INPUT("NoteRandom")
//need check in database if not null //need check in database if not null
authHash := circuit.PUBLIC_INPUT("authorizeSpendHash") authHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
nullValue := circuit.ALLOCATE(0) nullValue := circuit.ALLOCATE(0)
//// specify auth hash constraint //// specify auth hash constraint
...@@ -75,12 +75,12 @@ func NewTransferInput() *frontend.R1CS { ...@@ -75,12 +75,12 @@ func NewTransferInput() *frontend.R1CS {
circuit.MUSTBE_EQ(authHash, targetAuthHash) circuit.MUSTBE_EQ(authHash, targetAuthHash)
//need check in database if not null //need check in database if not null
nullifierHash := circuit.PUBLIC_INPUT("nullifierHash") nullifierHash := circuit.PUBLIC_INPUT("NullifierHash")
calcNullifierHash := mimc.Hash(&circuit, noteRandom) calcNullifierHash := mimc.Hash(&circuit, noteRandom)
circuit.MUSTBE_EQ(nullifierHash, calcNullifierHash) circuit.MUSTBE_EQ(nullifierHash, calcNullifierHash)
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费 //通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
noteHash := circuit.SECRET_INPUT("noteHash") noteHash := circuit.SECRET_INPUT("NoteHash")
calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue) calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue)
calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue) calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue)
// specify note hash constraint // specify note hash constraint
......
...@@ -34,22 +34,22 @@ func NewTransferOutput() *frontend.R1CS { ...@@ -34,22 +34,22 @@ func NewTransferOutput() *frontend.R1CS {
// create root constraint system // create root constraint system
circuit := frontend.New() circuit := frontend.New()
spendValue := circuit.SECRET_INPUT("amount") spendValue := circuit.SECRET_INPUT("Amount")
//spend pubkey //spend pubkey
spendPubkey := circuit.SECRET_INPUT("receiverPubKey") spendPubkey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey") returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey") authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
// hash function // hash function
mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256) mimc, _ := mimc.NewMiMCGadget("seed", gurvy.BN256)
//note hash random //note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom") noteRandom := circuit.SECRET_INPUT("NoteRandom")
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费 //通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom) //preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.PUBLIC_INPUT("noteHash") noteHash := circuit.PUBLIC_INPUT("NoteHash")
// specify note hash constraint // specify note hash constraint
preImage := mimc.Hash(&circuit, spendPubkey, returnPubkey, authPubkey, spendValue, noteRandom) preImage := mimc.Hash(&circuit, spendPubkey, returnPubkey, authPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage) circuit.MUSTBE_EQ(noteHash, preImage)
......
...@@ -12,17 +12,17 @@ import ( ...@@ -12,17 +12,17 @@ import (
func MerkelPathPart(circuit *frontend.CS, mimc mimc.MiMCGadget, noteHash *frontend.Constraint) { func MerkelPathPart(circuit *frontend.CS, mimc mimc.MiMCGadget, noteHash *frontend.Constraint) {
var proofSet, helper, valid []*frontend.Constraint var proofSet, helper, valid []*frontend.Constraint
merkleRoot := circuit.PUBLIC_INPUT("treeRootHash") merkleRoot := circuit.PUBLIC_INPUT("TreeRootHash")
proofSet = append(proofSet, noteHash) proofSet = append(proofSet, noteHash)
//helper[0],valid[0]占位, 方便接口只设置有效值 //helper[0],valid[0]占位, 方便接口只设置有效值
helper = append(helper, circuit.ALLOCATE("1")) helper = append(helper, circuit.ALLOCATE("1"))
valid = append(valid, circuit.ALLOCATE("1")) valid = append(valid, circuit.ALLOCATE("1"))
//depth:10, path num need be 9 //depth:10, path num need be 9
for i := 1; i < 10; i++ { for i := 0; i < 10; i++ {
proofSet = append(proofSet, circuit.SECRET_INPUT("path"+strconv.Itoa(i))) proofSet = append(proofSet, circuit.SECRET_INPUT("Path"+strconv.Itoa(i)))
helper = append(helper, circuit.SECRET_INPUT("helper"+strconv.Itoa(i))) helper = append(helper, circuit.SECRET_INPUT("Helper"+strconv.Itoa(i)))
valid = append(valid, circuit.SECRET_INPUT("valid"+strconv.Itoa(i))) valid = append(valid, circuit.SECRET_INPUT("Valid"+strconv.Itoa(i)))
} }
VerifyMerkleProof(circuit, mimc, merkleRoot, proofSet, helper, valid) VerifyMerkleProof(circuit, mimc, merkleRoot, proofSet, helper, valid)
...@@ -65,8 +65,8 @@ func leafSum(circuit *frontend.CS, h mimc.MiMCGadget, data *frontend.Constraint) ...@@ -65,8 +65,8 @@ func leafSum(circuit *frontend.CS, h mimc.MiMCGadget, data *frontend.Constraint)
func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) { func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
//cmt=transfer_value*G + random_value*H //cmt=transfer_value*G + random_value*H
cmtvalueX := circuit.PUBLIC_INPUT("shieldAmountX") cmtvalueX := circuit.PUBLIC_INPUT("ShieldAmountX")
cmtvalueY := circuit.PUBLIC_INPUT("shieldAmountY") cmtvalueY := circuit.PUBLIC_INPUT("ShieldAmountY")
// set curve parameters // set curve parameters
edgadget, _ := twistededwards_gadget.NewEdCurveGadget(gurvy.BN256) edgadget, _ := twistededwards_gadget.NewEdCurveGadget(gurvy.BN256)
...@@ -84,7 +84,7 @@ func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) { ...@@ -84,7 +84,7 @@ func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
pointGSnark.X.Tag("xg") pointGSnark.X.Tag("xg")
pointGSnark.Y.Tag("yg") 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) //circuit.MUSTBE_LESS_OR_EQ(random_value,10000000000,256)
//H is not G, H should be a point that no one know the prikey //H is not G, H should be a point that no one know the prikey
var baseX_H, baseY_H fr_bn256.Element var baseX_H, baseY_H fr_bn256.Element
......
public, treeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310 public, TreeRootHash,10531321614990797034921282585661869614556487056951485265320464926630499341310
public, authorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663 public, AuthorizeSpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, nullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195 public, NullifierHash,6747518781649068310795677405858353007442326529625450860668944156162052335195
public, amount,28242048 public, Amount,28242048
secret, receiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705 secret, ReceiverPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497 secret, ReturnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583 secret, AuthorizePubKey,13519883267141251871527102103999205179714486518503885909948192364772977661583
secret, spendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502 secret, SpendPriKey,10190477835300927557649934238820360529458681672073866116232821892325659279502
secret, spendFlag,1 secret, SpendFlag,1
secret, authorizeFlag,1 secret, AuthorizeFlag,1
secret, noteRandom,2824204835 secret, NoteRandom,2824204835
secret, noteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649 secret, NoteHash,16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105 secret, Path0,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637 secret, Path1,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431 secret, Path2,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path4,0 secret, Path3,0
secret, path5,0 secret, Path4,0
secret, path6,0 secret, Path5,0
secret, path7,0 secret, Path6,0
secret, path8,0 secret, Path7,0
secret, path9,0 secret, Path8,0
secret, path10,0 secret, Path9,0
secret, helper1,1
secret, helper2,1 secret, Helper0,1
secret, helper3,1 secret, Helper1,1
secret, helper4,1 secret, Helper2,1
secret, helper5,1 secret, Helper3,1
secret, helper6,1 secret, Helper4,1
secret, helper7,1 secret, Helper5,1
secret, helper8,1 secret, Helper6,1
secret, helper9,1 secret, Helper7,1
secret, Helper8,1
secret, Helper9,1
secret, valid1,1
secret, valid2,1 secret, Valid0,1
secret, valid3,1 secret, Valid1,1
secret, valid4,0 secret, Valid2,1
secret, valid5,0 secret, Valid3,0
secret, valid6,0 secret, Valid4,0
secret, valid7,0 secret, Valid5,0
secret, valid8,0 secret, Valid6,0
secret, valid9,0 secret, Valid7,0
secret, Valid8,0
secret, Valid9,0
...@@ -40,18 +40,18 @@ func NewWithdraw() *frontend.R1CS { ...@@ -40,18 +40,18 @@ func NewWithdraw() *frontend.R1CS {
// create root constraint system // create root constraint system
circuit := frontend.New() circuit := frontend.New()
spendValue := circuit.PUBLIC_INPUT("amount") spendValue := circuit.PUBLIC_INPUT("Amount")
//spend pubkey //spend pubkey
receiverPubKey := circuit.SECRET_INPUT("receiverPubKey") receiverPubKey := circuit.SECRET_INPUT("ReceiverPubKey")
returnPubkey := circuit.SECRET_INPUT("returnPubKey") returnPubkey := circuit.SECRET_INPUT("ReturnPubKey")
authPubkey := circuit.SECRET_INPUT("authorizePubKey") authPubkey := circuit.SECRET_INPUT("AuthorizePubKey")
spendPrikey := circuit.SECRET_INPUT("spendPriKey") spendPrikey := circuit.SECRET_INPUT("SpendPriKey")
//spend_flag 0:return_pubkey, 1: spend_pubkey //spend_flag 0:return_pubkey, 1: spend_pubkey
spendFlag := circuit.SECRET_INPUT("spendFlag") spendFlag := circuit.SECRET_INPUT("SpendFlag")
circuit.MUSTBE_BOOLEAN(spendFlag) circuit.MUSTBE_BOOLEAN(spendFlag)
//auth_check 0: not need auth check, 1:need check //auth_check 0: not need auth check, 1:need check
authFlag := circuit.SECRET_INPUT("authorizeFlag") authFlag := circuit.SECRET_INPUT("AuthorizeFlag")
circuit.MUSTBE_BOOLEAN(authFlag) circuit.MUSTBE_BOOLEAN(authFlag)
// hash function // hash function
...@@ -61,10 +61,10 @@ func NewWithdraw() *frontend.R1CS { ...@@ -61,10 +61,10 @@ func NewWithdraw() *frontend.R1CS {
circuit.MUSTBE_EQ(targetPubHash, calcPubHash) circuit.MUSTBE_EQ(targetPubHash, calcPubHash)
//note hash random //note hash random
noteRandom := circuit.SECRET_INPUT("noteRandom") noteRandom := circuit.SECRET_INPUT("NoteRandom")
//need check in database if not null //need check in database if not null
authHash := circuit.PUBLIC_INPUT("authorizeSpendHash") authHash := circuit.PUBLIC_INPUT("AuthorizeSpendHash")
nullValue := circuit.ALLOCATE(0) nullValue := circuit.ALLOCATE(0)
// specify auth hash constraint // specify auth hash constraint
...@@ -74,7 +74,7 @@ func NewWithdraw() *frontend.R1CS { ...@@ -74,7 +74,7 @@ func NewWithdraw() *frontend.R1CS {
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费 //通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
//preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom) //preImage=hash(spendPubkey, returnPubkey,AuthPubkey,spendValue,noteRandom)
noteHash := circuit.SECRET_INPUT("noteHash") noteHash := circuit.SECRET_INPUT("NoteHash")
calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue) calcReturnPubkey := circuit.SELECT(authFlag, returnPubkey, nullValue)
calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue) calcAuthPubkey := circuit.SELECT(authFlag, authPubkey, nullValue)
// specify note hash constraint // specify note hash constraint
......
...@@ -37,53 +37,120 @@ func TestWithdraw(t *testing.T) { ...@@ -37,53 +37,120 @@ func TestWithdraw(t *testing.T) {
r1csBN256 := backend_bn256.Cast(r1cs) r1csBN256 := backend_bn256.Cast(r1cs)
{ {
good := backend.NewAssignment() good := backend.NewAssignment()
good.Assign(backend.Public, "treeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310") good.Assign(backend.Public, "TreeRootHash", "10531321614990797034921282585661869614556487056951485265320464926630499341310")
good.Assign(backend.Public, "authorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663") good.Assign(backend.Public, "AuthorizeSpendHash", "14468512365438613046028281588661351435476168610934165547900473609197783547663")
good.Assign(backend.Public, "nullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195") good.Assign(backend.Public, "NullifierHash", "6747518781649068310795677405858353007442326529625450860668944156162052335195")
good.Assign(backend.Public, "amount", "28242048") good.Assign(backend.Public, "Amount", "28242048")
good.Assign(backend.Secret, "receiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705") good.Assign(backend.Secret, "ReceiverPubKey", "13735985067536865723202617343666111332145536963656464451727087263423649028705")
good.Assign(backend.Secret, "returnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497") good.Assign(backend.Secret, "ReturnPubKey", "16067249407809359746114321133992130903102335882983385972747813693681808870497")
good.Assign(backend.Secret, "authorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583") good.Assign(backend.Secret, "AuthorizePubKey", "13519883267141251871527102103999205179714486518503885909948192364772977661583")
good.Assign(backend.Secret, "spendPriKey", "10190477835300927557649934238820360529458681672073866116232821892325659279502") good.Assign(backend.Secret, "SpendPriKey", "10190477835300927557649934238820360529458681672073866116232821892325659279502")
good.Assign(backend.Secret, "spendFlag", "1") good.Assign(backend.Secret, "SpendFlag", "1")
good.Assign(backend.Secret, "authorizeFlag", "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" //nodehash="16308793397024662832064523892418908145900866571524124093537199035808550255649"
good.Assign(backend.Secret, "path1", "19561523370160677851616596032513161448778901506614020103852017946679781620105") good.Assign(backend.Secret, "Path0", "19561523370160677851616596032513161448778901506614020103852017946679781620105")
good.Assign(backend.Secret, "path2", "13898857070666440684265042188056372750257678232709763835292910585848522658637") good.Assign(backend.Secret, "Path1", "13898857070666440684265042188056372750257678232709763835292910585848522658637")
good.Assign(backend.Secret, "path3", "15019169196974879571470243100379529757970866395477207575033769902587972032431") good.Assign(backend.Secret, "Path2", "15019169196974879571470243100379529757970866395477207575033769902587972032431")
good.Assign(backend.Secret, "path4", "0") good.Assign(backend.Secret, "Path3", "0")
good.Assign(backend.Secret, "path5", "0") good.Assign(backend.Secret, "Path4", "0")
good.Assign(backend.Secret, "path6", "0") good.Assign(backend.Secret, "Path5", "0")
good.Assign(backend.Secret, "path7", "0") good.Assign(backend.Secret, "Path6", "0")
good.Assign(backend.Secret, "path8", "0") good.Assign(backend.Secret, "Path7", "0")
good.Assign(backend.Secret, "path9", "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, "Helper0", "1")
good.Assign(backend.Secret, "helper3", "1") good.Assign(backend.Secret, "Helper1", "1")
good.Assign(backend.Secret, "helper4", "0") good.Assign(backend.Secret, "Helper2", "1")
good.Assign(backend.Secret, "helper5", "0") good.Assign(backend.Secret, "Helper3", "0")
good.Assign(backend.Secret, "helper6", "0") good.Assign(backend.Secret, "Helper4", "0")
good.Assign(backend.Secret, "helper7", "0") good.Assign(backend.Secret, "Helper5", "0")
good.Assign(backend.Secret, "helper8", "0") good.Assign(backend.Secret, "Helper6", "0")
good.Assign(backend.Secret, "helper9", "0") good.Assign(backend.Secret, "Helper7", "0")
good.Assign(backend.Secret, "Helper8", "0")
good.Assign(backend.Secret, "valid1", "1") good.Assign(backend.Secret, "Helper9", "0")
good.Assign(backend.Secret, "valid2", "1")
good.Assign(backend.Secret, "valid3", "1") good.Assign(backend.Secret, "Valid0", "1")
good.Assign(backend.Secret, "valid4", "0") good.Assign(backend.Secret, "Valid1", "1")
good.Assign(backend.Secret, "valid5", "0") good.Assign(backend.Secret, "Valid2", "1")
good.Assign(backend.Secret, "valid6", "0") good.Assign(backend.Secret, "Valid3", "0")
good.Assign(backend.Secret, "valid7", "0") good.Assign(backend.Secret, "Valid4", "0")
good.Assign(backend.Secret, "valid8", "0") good.Assign(backend.Secret, "Valid5", "0")
good.Assign(backend.Secret, "valid9", "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) 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 { ...@@ -38,7 +38,7 @@ func (a *action) authParamCheck(input *mixTy.AuthorizePublicInput) error {
//authorize pubkey hash should be configured already //authorize pubkey hash should be configured already
var found bool var found bool
for _, k := range authPubKeys.Pks { for _, k := range authPubKeys.Keys {
if input.AuthorizePubKey == k { if input.AuthorizePubKey == k {
found = true found = true
break break
...@@ -85,13 +85,12 @@ func (a *action) authorizeVerify(proof *mixTy.ZkProofInfo) (*mixTy.AuthorizePubl ...@@ -85,13 +85,12 @@ func (a *action) authorizeVerify(proof *mixTy.ZkProofInfo) (*mixTy.AuthorizePubl
*/ */
func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt, error) { func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt, error) {
var inputs []*mixTy.AuthorizePublicInput var inputs []*mixTy.AuthorizePublicInput
for _, proof := range authorize.AuthCommits {
in, err := a.authorizeVerify(proof) in, err := a.authorizeVerify(authorize.Proof)
if err != nil { if err != nil {
return nil, err return nil, err
}
inputs = append(inputs, in)
} }
inputs = append(inputs, in)
receipt := &types.Receipt{Ty: types.ExecOk} receipt := &types.Receipt{Ty: types.ExecOk}
var auths, authSpends []string var auths, authSpends []string
......
...@@ -27,23 +27,23 @@ func isSuperManager(cfg *types.Chain33Config, addr string) bool { ...@@ -27,23 +27,23 @@ func isSuperManager(cfg *types.Chain33Config, addr string) bool {
func (a *action) Config(config *mixTy.MixConfigAction) (*types.Receipt, error) { func (a *action) Config(config *mixTy.MixConfigAction) (*types.Receipt, error) {
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
switch config.Ty { switch config.Ty {
case mixTy.MixConfigType_VerifyKey: case mixTy.MixConfigType_Verify:
//必须是超级管理员才能配置 //必须是超级管理员才能配置
if !isSuperManager(cfg, a.fromaddr) { if !isSuperManager(cfg, a.fromaddr) {
return nil, errors.Wrapf(types.ErrNotAllow, "not super manager,%s", a.fromaddr) return nil, errors.Wrapf(types.ErrNotAllow, "not super manager,%s", a.fromaddr)
} }
return a.ConfigAddVerifyKey(config.GetVerifyKey()) return a.ConfigAddVerifyKey(config.GetVerifyKey())
case mixTy.MixConfigType_AuthPubKey: case mixTy.MixConfigType_Auth:
//必须是超级管理员才能配置 //必须是超级管理员才能配置
if !isSuperManager(cfg, a.fromaddr) { if !isSuperManager(cfg, a.fromaddr) {
return nil, errors.Wrapf(types.ErrNotAllow, "not super manager,%s", a.fromaddr) return nil, errors.Wrapf(types.ErrNotAllow, "not super manager,%s", a.fromaddr)
} }
if config.Action == mixTy.MixConfigAct_Add { if config.Action == mixTy.MixConfigAct_Add {
return a.ConfigAddAuthPubKey(config.GetAuthPk()) return a.ConfigAddAuthPubKey(config.GetAuthKey())
} else { } else {
return a.ConfigDeleteAuthPubKey(config.GetAuthPk()) return a.ConfigDeleteAuthPubKey(config.GetAuthKey())
} }
case mixTy.MixConfigType_PaymentPubKey: case mixTy.MixConfigType_Payment:
//个人配置,个人负责,可重配 //个人配置,个人负责,可重配
return a.ConfigPaymentPubKey(config.GetPaymentKey()) return a.ConfigPaymentPubKey(config.GetPaymentKey())
} }
...@@ -96,7 +96,7 @@ func (a *action) ConfigAddVerifyKey(newKey *mixTy.ZkVerifyKey) (*types.Receipt, ...@@ -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() key := getAuthPubKeysKey()
return &types.Receipt{ return &types.Receipt{
Ty: types.ExecOk, Ty: types.ExecOk,
...@@ -110,13 +110,13 @@ func makeConfigAuthKeyReceipt(data *mixTy.AuthPubKeys) *types.Receipt { ...@@ -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() key := getAuthPubKeysKey()
v, err := a.db.Get(key) v, err := a.db.Get(key)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "get db") return nil, errors.Wrapf(err, "get db")
} }
var keys mixTy.AuthPubKeys var keys mixTy.AuthKeys
err = types.Decode(v, &keys) err = types.Decode(v, &keys)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "decode db key") return nil, errors.Wrapf(err, "decode db key")
...@@ -128,15 +128,15 @@ func (a *action) getAuthKeys() (*mixTy.AuthPubKeys, error) { ...@@ -128,15 +128,15 @@ func (a *action) getAuthKeys() (*mixTy.AuthPubKeys, error) {
func (a *action) ConfigAddAuthPubKey(key string) (*types.Receipt, error) { func (a *action) ConfigAddAuthPubKey(key string) (*types.Receipt, error) {
keys, err := a.getAuthKeys() keys, err := a.getAuthKeys()
if isNotFound(errors.Cause(err)) { if isNotFound(errors.Cause(err)) {
keys := &mixTy.AuthPubKeys{} keys := &mixTy.AuthKeys{}
keys.Pks = append(keys.Pks, key) keys.Keys = append(keys.Keys, key)
return makeConfigAuthKeyReceipt(keys), nil return makeConfigAuthKeyReceipt(keys), nil
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
keys.Pks = append(keys.Pks, key) keys.Keys = append(keys.Keys, key)
return makeConfigAuthKeyReceipt(keys), nil return makeConfigAuthKeyReceipt(keys), nil
} }
...@@ -146,12 +146,12 @@ func (a *action) ConfigDeleteAuthPubKey(key string) (*types.Receipt, error) { ...@@ -146,12 +146,12 @@ func (a *action) ConfigDeleteAuthPubKey(key string) (*types.Receipt, error) {
return nil, err return nil, err
} }
var newKeys mixTy.AuthPubKeys var newKeys mixTy.AuthKeys
for _, v := range keys.Pks { for _, v := range keys.Keys {
if key == v { if key == v {
continue continue
} }
newKeys.Pks = append(newKeys.Pks, v) newKeys.Keys = append(newKeys.Keys, v)
} }
return makeConfigAuthKeyReceipt(&newKeys), nil return makeConfigAuthKeyReceipt(&newKeys), nil
...@@ -187,13 +187,13 @@ func GetPaymentPubKey(db dbm.KV, addr string) (*mixTy.PaymentKey, error) { ...@@ -187,13 +187,13 @@ func GetPaymentPubKey(db dbm.KV, addr string) (*mixTy.PaymentKey, error) {
} }
func (a *action) ConfigPaymentPubKey(paykey *mixTy.PaymentKey) (*types.Receipt, 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 nil, errors.Wrapf(types.ErrInvalidParam, "pubkey=%v", paykey)
} }
//直接覆盖 //直接覆盖
return makeConfigPaymentKeyReceipt(&mixTy.PaymentKey{ return makeConfigPaymentKeyReceipt(&mixTy.PaymentKey{
Addr: a.fromaddr, Addr: a.fromaddr,
ReceiverKey: paykey.ReceiverKey, 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) ...@@ -63,6 +63,9 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error)
if err != nil { if err != nil {
return "", 0, errors.Wrapf(err, "parseUint=%s", input.Amount) 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) err = zkProofVerify(a.db, proof, mixTy.VerifyType_DEPOSIT)
if err != nil { if err != nil {
...@@ -81,14 +84,14 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error) ...@@ -81,14 +84,14 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error)
*/ */
func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error) { func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error) {
//1. zk-proof校验 //1. zk-proof校验
noteHash, val, err := a.depositVerify(deposit.Proof) noteHash, amount, err := a.depositVerify(deposit.Proof)
if err != nil { if err != nil {
return nil, err return nil, err
} }
//校验存款额,目前只支持一次只存一张支票 ////校验存款额,目前只支持一次只存一张支票
if val != deposit.Amount { //if val != deposit.Amount {
return nil, errors.Wrapf(mixTy.ErrInputParaNotMatch, "deposit amount=%d not equal proof amount=%d", deposit.Amount, val) // return nil, errors.Wrapf(mixTy.ErrInputParaNotMatch, "deposit amount=%d not equal proof amount=%d", deposit.Amount, val)
} //}
//存款 //存款
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
...@@ -98,7 +101,7 @@ func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error ...@@ -98,7 +101,7 @@ func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error
} }
//主链上存入toAddr为mix 执行器地址,平行链上为user.p.{}.mix执行器地址,execAddr和toAddr一致 //主链上存入toAddr为mix 执行器地址,平行链上为user.p.{}.mix执行器地址,execAddr和toAddr一致
execAddr := address.ExecAddress(string(a.tx.Execer)) 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 { if err != nil {
return nil, errors.Wrapf(err, "ExecTransfer") return nil, errors.Wrapf(err, "ExecTransfer")
} }
......
...@@ -66,3 +66,8 @@ func (m *Mix) Query_PaymentPubKey(addr *types.ReqString) (types.Message, error) ...@@ -66,3 +66,8 @@ func (m *Mix) Query_PaymentPubKey(addr *types.ReqString) (types.Message, error)
return GetPaymentPubKey(m.GetStateDB(), addr.Data) 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 ...@@ -7,6 +7,7 @@ package executor
import ( import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/twistededwards" "github.com/consensys/gurvy/bn256/twistededwards"
......
...@@ -83,7 +83,7 @@ func (a *action) withdrawVerify(proof *mixTy.ZkProofInfo) (string, uint64, error ...@@ -83,7 +83,7 @@ func (a *action) withdrawVerify(proof *mixTy.ZkProofInfo) (string, uint64, error
func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, error) { func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, error) {
var nulliferSet []string var nulliferSet []string
var sumValue uint64 var sumValue uint64
for _, k := range withdraw.SpendCommits { for _, k := range withdraw.Proofs {
nulfier, v, err := a.withdrawVerify(k) nulfier, v, err := a.withdrawVerify(k)
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -17,8 +17,6 @@ limitations under the License. ...@@ -17,8 +17,6 @@ limitations under the License.
package zksnark package zksnark
import ( import (
"bytes"
"encoding/hex"
"encoding/json" "encoding/json"
"github.com/consensys/gnark/backend" "github.com/consensys/gnark/backend"
...@@ -26,22 +24,12 @@ import ( ...@@ -26,22 +24,12 @@ import (
"github.com/consensys/gnark/encoding/gob" "github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gurvy" "github.com/consensys/gurvy"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/pkg/errors" "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) { func deserializeInput(input string) (map[string]interface{}, error) {
buff, err := getByteBuff(input) buff, err := mixTy.GetByteBuff(input)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -58,13 +46,13 @@ func deserializeInput(input string) (map[string]interface{}, error) { ...@@ -58,13 +46,13 @@ func deserializeInput(input string) (map[string]interface{}, error) {
func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) { func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) {
curveID := gurvy.BN256 curveID := gurvy.BN256
output, err := getByteBuff(verifyKeyStr) output, err := mixTy.GetByteBuff(verifyKeyStr)
if err != nil { if err != nil {
return false, errors.Wrapf(err, "zk.verify") return false, errors.Wrapf(err, "zkVerify.GetByteBuff")
} }
var vk groth16_bn256.VerifyingKey var vk groth16_bn256.VerifyingKey
if err := gob.Deserialize(output, &vk, curveID); err != nil { 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 // parse input file
...@@ -78,20 +66,20 @@ func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) { ...@@ -78,20 +66,20 @@ func Verify(verifyKeyStr, proofStr, pubInputStr string) (bool, error) {
} }
// load proof // load proof
output, err = getByteBuff(proofStr) output, err = mixTy.GetByteBuff(proofStr)
if err != nil { if err != nil {
return false, errors.Wrapf(err, "proof") return false, errors.Wrapf(err, "zkVerify.proof")
} }
var proof groth16_bn256.Proof var proof groth16_bn256.Proof
if err := gob.Deserialize(output, &proof, curveID); err != nil { 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 // verify proof
//start := time.Now() //start := time.Now()
result, err := groth16_bn256.Verify(&proof, &vk, r1csInput) result, err := groth16_bn256.Verify(&proof, &vk, r1csInput)
if err != nil { if err != nil {
return false, errors.Wrapf(err, "zk.Verify") return false, errors.Wrapf(err, "zkVerify.verify")
} }
return result, nil return result, nil
} }
...@@ -26,23 +26,23 @@ message ZkVerifyKeys{ ...@@ -26,23 +26,23 @@ message ZkVerifyKeys{
repeated ZkVerifyKey data = 1; repeated ZkVerifyKey data = 1;
} }
message AuthPubKeys{ message AuthKeys{
repeated string pks = 1; repeated string keys = 1;
} }
message PaymentKey{ message PaymentKey{
string addr = 1; string addr = 1;
string receiverKey = 2; string receiverKey = 2;
PubKey secretKey = 3; string encryptKey = 3;
} }
enum MixConfigType{ enum MixConfigType{
VerifyKey = 0; Verify = 0;
//register unify authorize pubkey //register unify authorize pubkey
AuthPubKey = 1; Auth = 1;
//for spender's pay pubkey register,DH secret //for spender's pay pubkey register,DH secret
//spender注册自己的payment公钥, 用来生成DiffHellman秘钥 //spender注册自己的payment公钥, 用来生成DiffHellman秘钥
PaymentPubKey = 2; Payment = 2;
} }
enum MixConfigAct{ enum MixConfigAct{
...@@ -59,15 +59,15 @@ message MixConfigAction { ...@@ -59,15 +59,15 @@ message MixConfigAction {
MixConfigAct Action = 2; MixConfigAct Action = 2;
oneof value { oneof value {
ZkVerifyKey verifyKey = 3; ZkVerifyKey verifyKey = 3;
string authPk = 4; string authKey = 4;
PaymentKey paymentKey = 5; PaymentKey paymentKey = 5;
} }
} }
//DH one time pubkey with secret //DH one time pubkey with secret
message DHSecret{ message DHSecret{
PubKey epk = 1; string peerKey = 1;
string secret = 3; string secret = 2;
} }
//Diff-Helman 加密group, for spender, returner, authorizer to decrypt //Diff-Helman 加密group, for spender, returner, authorizer to decrypt
...@@ -84,8 +84,7 @@ message ZkProofInfo { ...@@ -84,8 +84,7 @@ message ZkProofInfo {
} }
message MixDepositAction { message MixDepositAction {
uint64 amount = 1; ZkProofInfo proof = 1;
ZkProofInfo proof = 2;
} }
...@@ -98,12 +97,12 @@ message MixTransferAction { ...@@ -98,12 +97,12 @@ message MixTransferAction {
message MixWithdrawAction { message MixWithdrawAction {
uint64 amount = 1; uint64 amount = 1;
repeated ZkProofInfo spendCommits = 2; repeated ZkProofInfo proofs = 2;
} }
message MixAuthorizeAction { message MixAuthorizeAction {
repeated ZkProofInfo authCommits = 1; ZkProofInfo proof = 1;
} }
...@@ -161,6 +160,12 @@ message AuthorizePublicInput { ...@@ -161,6 +160,12 @@ message AuthorizePublicInput {
} }
message VerifyProofInfo{
VerifyType ty = 1;
ZkProofInfo proof = 2;
}
//nullifer 存在value //nullifer 存在value
message ExistValue { message ExistValue {
bool data = 1; bool data = 1;
...@@ -195,23 +200,16 @@ message TreeListResp{ ...@@ -195,23 +200,16 @@ message TreeListResp{
// mix wallet part // mix wallet part
// receiverPubKey = hash(spendPriKey) for zk-snark note spend // receiverPubKey = hash(spendPriKey) for zk-snark note spend
message PaymentKeyPair { message PaymentKeyPair {
string receiverPubKey = 1; string receiveKey = 1;
string spendPriKey = 2; string spendKey = 2;
} }
// pub = priv*G for diff-helman crypto // pub = priv*G for diff-helman crypto
// out: take spender's tempPrikey*pubkey as password, tempPubkey show in note // out: take spender's tempPrikey*pubkey as password, tempPubkey show in note
// spender: take self prikey*tempPubkey as password to decode // spender: take self prikey*tempPubkey as password to decode
message PubKey { message EncryptKeyPair {
string X = 1; string privKey = 1;
string Y = 2; string pubKey = 2;
}
message PrivKey{
string data = 1;
}
message ShareSecretKeyPair {
PrivKey privKey = 1;
PubKey receivingPk = 2;
} }
...@@ -219,7 +217,7 @@ message ShareSecretKeyPair { ...@@ -219,7 +217,7 @@ message ShareSecretKeyPair {
//crypt pair for DH crypt/decrypt //crypt pair for DH crypt/decrypt
message AccountPrivacyKey { message AccountPrivacyKey {
PaymentKeyPair paymentKey = 1; PaymentKeyPair paymentKey = 1;
ShareSecretKeyPair shareSecretKey = 2; EncryptKeyPair encryptKey = 2;
} }
message WalletAddrPrivacy { message WalletAddrPrivacy {
...@@ -230,38 +228,45 @@ message WalletAddrPrivacy { ...@@ -230,38 +228,45 @@ message WalletAddrPrivacy {
message SecretData{ message SecretData{
string receiverPubKey = 1; string receiverKey = 1;
string returnPubKey = 2; string returnKey = 2;
string authorizePubKey = 3; string authorizeKey = 3;
string amount = 4; string amount = 4;
string noteRandom = 5; string noteRandom = 5;
} }
message EncodedSecretData{
string encoded = 1;
SecretData rawData = 2;
}
message EncryptSecretData{ message EncryptSecretData{
string secret = 1; string secret = 1;
PubKey SecretPubKey = 2; string peerKey = 2;
} }
message DecryptSecretData{ message DecryptSecretData{
string secret = 1; string secret = 1;
PrivKey SecretPriKey = 2; string priKey = 2;
PubKey epk = 3; string peerKey = 3;
} }
//一键式获取加密数据 //path+filename, filename can take default
message DepositProofReq{ message circuitPathInfo{
string receiverAddr = 1; string path = 1;
}
message DepositInfo{
string addr = 1;
string returnAddr = 2; string returnAddr = 2;
string authorizeAddr = 3; string authorizeAddr = 3;
uint64 amount = 4; uint64 amount = 4;
} }
//钱包生成deposit tx
message DepositTxReq{
DepositInfo deposit = 1;
circuitPathInfo zkPath = 2;
}
message DepositProofResp{ message DepositProofResp{
string noteHash = 1; string noteHash = 1;
...@@ -275,15 +280,17 @@ message TreePathProof{ ...@@ -275,15 +280,17 @@ message TreePathProof{
string treeRootHash = 1; string treeRootHash = 1;
repeated string treePath = 2; repeated string treePath = 2;
repeated uint32 helpers = 3; repeated uint32 helpers = 3;
repeated uint32 validPath = 4;
} }
message WithdrawProofReq{ //可withdraw 多个note
string noteHash = 1; message WithdrawTxReq{
uint64 totalAmount = 1;
string noteHashs = 2;
circuitPathInfo zkPath = 3;
} }
message WithdrawProofResp{ message WithdrawProofRe{
SecretData secret = 1; SecretData secret = 1;
string nullifierHash = 2; string nullifierHash = 2;
string authorizeSpendHash = 3; string authorizeSpendHash = 3;
...@@ -292,14 +299,17 @@ message WithdrawProofResp{ ...@@ -292,14 +299,17 @@ message WithdrawProofResp{
string spendFlag = 6; string spendFlag = 6;
string authorizeFlag = 7; string authorizeFlag = 7;
TreePathProof treeProof = 8; TreePathProof treeProof = 8;
} }
message AuthProofReq{ //只授权一个note,超过一个,toAddr不好设置
message AuthTxReq{
string noteHash = 1; string noteHash = 1;
uint32 toReturn = 2; string authorizeToAddr = 3;
circuitPathInfo zkPath = 4;
} }
message AuthProofResp{ message AuthProofRe{
SecretData proof = 1; SecretData proof = 1;
string authPubKey = 2; string authPubKey = 2;
string authPrivKey = 3; string authPrivKey = 3;
...@@ -311,12 +321,19 @@ message AuthProofResp{ ...@@ -311,12 +321,19 @@ message AuthProofResp{
} }
message TransferProofReq{ message TransferInputTxReq{
string noteHash = 1; string noteHash = 1;
string toAddr = 2; circuitPathInfo zkPath = 2;
string toAuthAddr = 3; }
string returnAddr = 4;
uint64 amount = 5; message TransferOutputTxReq{
DepositInfo deposit = 1;
circuitPathInfo zkPath = 2;
}
message TransferTxReq{
TransferInputTxReq input = 1;
TransferOutputTxReq output = 2;
} }
//加密了的input/output amount //加密了的input/output amount
...@@ -344,8 +361,6 @@ message TransferOutputProof{ ...@@ -344,8 +361,6 @@ message TransferOutputProof{
DHSecretGroup secrets = 3; DHSecretGroup secrets = 3;
ShieldAmount shieldAmount = 4; ShieldAmount shieldAmount = 4;
string amountRandom = 5; string amountRandom = 5;
} }
message TransferProofResp{ message TransferProofResp{
...@@ -356,15 +371,25 @@ message TransferProofResp{ ...@@ -356,15 +371,25 @@ message TransferProofResp{
} }
message ShieldAmountRst{ message ShieldAmountRst{
string noteRandom = 1; string inputRandom = 1;
string transferRandom = 2; string outputRandom = 2;
string changeRandom = 3; string changeRandom = 3;
ShieldAmount note = 4; ShieldAmount input = 4;
ShieldAmount transfer = 5; ShieldAmount output = 5;
ShieldAmount change = 6; ShieldAmount change = 6;
} }
message CreateRawTxReq{
int32 actionTy = 1;
bytes data = 4;
string assetExec = 2;
string assetToken = 3;
string title = 6; //平行链名字
}
enum NoteStatus{ enum NoteStatus{
UNDEF = 0; UNDEF = 0;
VALID = 1; //已授权可使用 VALID = 1; //已授权可使用
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package rpc package rpc
import ( import (
"encoding/hex"
"encoding/json" "encoding/json"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
...@@ -106,14 +107,14 @@ func (c *Jrpc) EnablePrivacy(in *types.ReqAddrs, result *json.RawMessage) error ...@@ -106,14 +107,14 @@ func (c *Jrpc) EnablePrivacy(in *types.ReqAddrs, result *json.RawMessage) error
return err return err
} }
func (c *Jrpc) EncodeSecretData(in *mixTy.SecretData, result *json.RawMessage) error { //func (c *Jrpc) EncodeSecretData(in *mixTy.SecretData, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncodeSecretData", in) // reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncodeSecretData", in)
if err != nil { // if err != nil {
return err // return err
} // }
*result, err = types.PBToJSON(reply) // *result, err = types.PBToJSON(reply)
return err // return err
} //}
func (c *Jrpc) EncryptSecretData(in *mixTy.EncryptSecretData, result *json.RawMessage) error { func (c *Jrpc) EncryptSecretData(in *mixTy.EncryptSecretData, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncryptSecretData", in) reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncryptSecretData", in)
...@@ -133,38 +134,48 @@ func (c *Jrpc) DecryptSecretData(in *mixTy.DecryptSecretData, result *json.RawMe ...@@ -133,38 +134,48 @@ func (c *Jrpc) DecryptSecretData(in *mixTy.DecryptSecretData, result *json.RawMe
return err return err
} }
func (c *Jrpc) DepositProof(in *mixTy.DepositProofReq, result *json.RawMessage) error { //
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "DepositProof", in) //func (c *Jrpc) DepositProof(in *mixTy.DepositTxReq, result *json.RawMessage) error {
if err != nil { // reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "DepositProof", in)
return err // if err != nil {
} // return err
*result, err = types.PBToJSON(reply) // }
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) //func (c *Jrpc) AuthProof(in *mixTy.AuthTxReq, result *json.RawMessage) error {
if err != nil { // reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "AuthProof", in)
return err // if err != nil {
} // return err
*result, err = types.PBToJSON(reply) // }
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) //func (c *Jrpc) TransferProof(in *mixTy.TransferTxReq, result *json.RawMessage) error {
if err != nil { // reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "TransferProof", in)
return err // if err != nil {
} // return err
*result, err = types.PBToJSON(reply) // }
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 { func (c *Jrpc) CreateRawTransaction(in *mixTy.CreateRawTxReq, result *interface{}) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "WithdrawProof", in) reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "CreateRawTransaction", in)
if err != nil { if err != nil {
return err return err
} }
*result, err = types.PBToJSON(reply) *result = hex.EncodeToString(types.Encode(reply))
return err return err
} }
...@@ -13,6 +13,7 @@ var tlog = log15.New("module", MixX) ...@@ -13,6 +13,7 @@ var tlog = log15.New("module", MixX)
const ( const (
MaxTreeLeaves = 1024 MaxTreeLeaves = 1024
TreeLevel = 10
) )
// 执行器的日志类型 // 执行器的日志类型
...@@ -51,3 +52,26 @@ const ( ...@@ -51,3 +52,26 @@ const (
//mix transfer tx fee //mix transfer tx fee
const Privacy2PrivacyTxFee = types.Coin 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 @@ ...@@ -5,6 +5,7 @@
package types package types
import ( import (
"bytes"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"reflect" "reflect"
...@@ -69,7 +70,7 @@ func (p *MixType) GetName() string { ...@@ -69,7 +70,7 @@ func (p *MixType) GetName() string {
func (p *MixType) GetLogMap() map[int64]*types.LogInfo { func (p *MixType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{ return map[int64]*types.LogInfo{
TyLogMixConfigVk: {Ty: reflect.TypeOf(ZkVerifyKeys{}), Name: "LogMixConfigVk"}, 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"}, TyLogCurrentCommitTreeLeaves: {Ty: reflect.TypeOf(CommitTreeLeaves{}), Name: "LogCommitTreeLeaves"},
TyLogCurrentCommitTreeRoots: {Ty: reflect.TypeOf(CommitTreeRoots{}), Name: "LogCommitTreeRoots"}, TyLogCurrentCommitTreeRoots: {Ty: reflect.TypeOf(CommitTreeRoots{}), Name: "LogCommitTreeRoots"},
TyLogMixConfigPaymentKey: {Ty: reflect.TypeOf(PaymentKey{}), Name: "LogConfigReceivingKey"}, TyLogMixConfigPaymentKey: {Ty: reflect.TypeOf(PaymentKey{}), Name: "LogConfigReceivingKey"},
...@@ -92,78 +93,6 @@ func (p *MixType) GetPayload() types.Message { ...@@ -92,78 +93,6 @@ func (p *MixType) GetPayload() types.Message {
return &MixAction{} 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) { func DecodePubInput(ty VerifyType, input string) (interface{}, error) {
data, err := hex.DecodeString(input) data, err := hex.DecodeString(input)
if err != nil { if err != nil {
...@@ -245,3 +174,30 @@ func CheckSumEqual(points ...*twistededwards.Point) bool { ...@@ -245,3 +174,30 @@ func CheckSumEqual(points ...*twistededwards.Point) bool {
return false 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 ( import (
mixtypes "github.com/33cn/plugin/plugin/dapp/mix/types" "crypto"
"io"
) )
// The main interface for ECDH key exchange. // KeyExchange is the interface defining all functions
type ECDH interface { // necessary for ECDH.
GenerateKey([]byte) (*mixtypes.PrivKey, *mixtypes.PubKey) type KeyExchange interface {
GenerateSharedSecret(*mixtypes.PrivKey, *mixtypes.PubKey) ([]byte, error) // 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 ...@@ -35,9 +35,9 @@ func (policy *mixPolicy) On_EnablePrivacy(req *types.ReqAddrs) (types.Message, e
return policy.enablePrivacy(req.Addrs) return policy.enablePrivacy(req.Addrs)
} }
func (policy *mixPolicy) On_EncodeSecretData(req *mixTy.SecretData) (types.Message, error) { //func (policy *mixPolicy) On_EncodeSecretData(req *mixTy.SecretData) (types.Message, error) {
return encodeSecretData(req) // return encodeSecretData(req)
} //}
func (policy *mixPolicy) On_EncryptSecretData(req *mixTy.EncryptSecretData) (types.Message, error) { func (policy *mixPolicy) On_EncryptSecretData(req *mixTy.EncryptSecretData) (types.Message, error) {
return encryptSecretData(req) return encryptSecretData(req)
...@@ -47,18 +47,22 @@ func (policy *mixPolicy) On_DecryptSecretData(req *mixTy.DecryptSecretData) (typ ...@@ -47,18 +47,22 @@ func (policy *mixPolicy) On_DecryptSecretData(req *mixTy.DecryptSecretData) (typ
return decryptSecretData(req) return decryptSecretData(req)
} }
func (policy *mixPolicy) On_DepositProof(req *mixTy.DepositProofReq) (types.Message, error) { //func (policy *mixPolicy) On_DepositProof(req *mixTy.CreateRawTxReq) (types.Message, error) {
return policy.depositProof(req) // return policy.createDepositTx(req)
} //}
//
func (policy *mixPolicy) On_WithdrawProof(req *mixTy.WithdrawProofReq) (types.Message, error) { //func (policy *mixPolicy) On_WithdrawProof(req *mixTy.CreateRawTxReq) (types.Message, error) {
return policy.withdrawProof(req) // return policy.createWithdrawTx(req)
} //}
//
func (policy *mixPolicy) On_AuthProof(req *mixTy.AuthProofReq) (types.Message, error) { //func (policy *mixPolicy) On_AuthProof(req *mixTy.CreateRawTxReq) (types.Message, error) {
return policy.authProof(req) // 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) { func (policy *mixPolicy) On_CreateRawTransaction(req *mixTy.CreateRawTxReq) (types.Message, error) {
return policy.transferProof(req) return policy.createRawTx(req)
} }
...@@ -6,6 +6,7 @@ package wallet ...@@ -6,6 +6,7 @@ package wallet
import ( import (
"bytes" "bytes"
"encoding/hex"
"github.com/33cn/chain33/system/dapp" "github.com/33cn/chain33/system/dapp"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -17,7 +18,6 @@ import ( ...@@ -17,7 +18,6 @@ import (
wcom "github.com/33cn/chain33/wallet/common" wcom "github.com/33cn/chain33/wallet/common"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
mimcbn256 "github.com/consensys/gnark/crypto/hash/mimc/bn256" mimcbn256 "github.com/consensys/gnark/crypto/hash/mimc/bn256"
fr_bn256 "github.com/consensys/gurvy/bn256/fr"
) )
const CECBLOCKSIZE = 32 const CECBLOCKSIZE = 32
...@@ -25,19 +25,24 @@ const CECBLOCKSIZE = 32 ...@@ -25,19 +25,24 @@ const CECBLOCKSIZE = 32
// newPrivacyWithPrivKey create privacy from private key // newPrivacyWithPrivKey create privacy from private key
//payment, payPrivKey=hash(privkey), payPubkey=hash(payPrivKey) //payment, payPrivKey=hash(privkey), payPubkey=hash(payPrivKey)
//DH crypt key, prikey=payPrikey, pubKey=payPrikey*G //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}) payPrivacyKey := mimcHashByte([][]byte{privKey})
paymentKey := &mixTy.PaymentKeyPair{} paymentKey := &mixTy.PaymentKeyPair{}
paymentKey.SpendPriKey = getFrString(payPrivacyKey) paymentKey.SpendKey = mixTy.Byte2Str(payPrivacyKey)
paymentKey.ReceiverPubKey = getFrString(mimcHashByte([][]byte{payPrivacyKey})) paymentKey.ReceiveKey = mixTy.Byte2Str(mimcHashByte([][]byte{payPrivacyKey}))
shareSecretKey := &mixTy.ShareSecretKeyPair{} encryptKeyPair := &mixTy.EncryptKeyPair{}
ecdh := NewCurveBn256ECDH() //ecdh := NewCurveBn256ECDH()
shareSecretKey.PrivKey, shareSecretKey.ReceivingPk = ecdh.GenerateKey(payPrivacyKey) 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 := &mixTy.AccountPrivacyKey{}
privacy.PaymentKey = paymentKey privacy.PaymentKey = paymentKey
privacy.ShareSecretKey = shareSecretKey privacy.EncryptKey = encryptKeyPair
return privacy, nil return privacy, nil
} }
...@@ -71,14 +76,22 @@ func encryptDataWithPadding(password, data []byte) []byte { ...@@ -71,14 +76,22 @@ func encryptDataWithPadding(password, data []byte) []byte {
return wcom.CBCEncrypterPrivkey(password, paddingText) return wcom.CBCEncrypterPrivkey(password, paddingText)
} }
func encryptData(receiverPubKey *mixTy.PubKey, data []byte) *mixTy.DHSecret { func encryptData(peerPubKey string, data []byte) (*mixTy.DHSecret, error) {
ecdh := NewCurveBn256ECDH() ecdh := X25519()
//generate ephemeral priv/pub key oncePriv, oncePub, err := ecdh.GenerateKey(nil)
ephPriv, ephPub := ecdh.GenerateKey(nil) if err != nil {
password, _ := ecdh.GenerateSharedSecret(ephPriv, receiverPubKey) 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) 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) { ...@@ -87,29 +100,25 @@ func decryptDataWithPading(password, data []byte) ([]byte, error) {
return pKCS5UnPadding(plainData) return pKCS5UnPadding(plainData)
} }
func decryptData(selfPrivKey *mixTy.PrivKey, oppositePubKey *mixTy.PubKey, cryptData []byte) ([]byte, error) { func decryptData(selfPrivKey string, peerPubKey string, cryptData []byte) ([]byte, error) {
ecdh := NewCurveBn256ECDH() ecdh := X25519()
password, _ := ecdh.GenerateSharedSecret(selfPrivKey, oppositePubKey) 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) 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 { func mimcHashString(params []string) []byte {
var sum []byte var sum []byte
for _, k := range params { for _, k := range params {
//fmt.Println("input:", k) //fmt.Println("input:", k)
sum = append(sum, getByte(k)...) sum = append(sum, mixTy.Str2Byte(k)...)
} }
hash := mimcHashCalc(sum) hash := mimcHashCalc(sum)
//fmt.Println("hash=", getFrString(hash)) //fmt.Println("hash=", getFrString(hash))
...@@ -192,7 +201,7 @@ func (policy *mixPolicy) savePrivacyPair(addr string) (*mixTy.WalletAddrPrivacy, ...@@ -192,7 +201,7 @@ func (policy *mixPolicy) savePrivacyPair(addr string) (*mixTy.WalletAddrPrivacy,
} }
bizlog.Info("savePrivacyPair", "pri", common.ToHex(priv.Bytes()), "addr", addr) bizlog.Info("savePrivacyPair", "pri", common.ToHex(priv.Bytes()), "addr", addr)
newPrivacy, err := newPrivacyWithPrivKey(priv.Bytes()) newPrivacy, err := newPrivacyKey(priv.Bytes())
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -395,3 +404,19 @@ func (policy *mixPolicy) showAccountNoteInfo(addrs []string) (*mixTy.WalletIndex ...@@ -395,3 +404,19 @@ func (policy *mixPolicy) showAccountNoteInfo(addrs []string) (*mixTy.WalletIndex
} }
return &resps, nil 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 ...@@ -60,7 +60,7 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t
//根据withdraw nullifier hash 更新数据状态为USED //根据withdraw nullifier hash 更新数据状态为USED
case mixTy.MixActionWithdraw: case mixTy.MixActionWithdraw:
var nulls []string var nulls []string
for _, m := range v.GetWithdraw().SpendCommits { for _, m := range v.GetWithdraw().Proofs {
out, err := mixTy.DecodePubInput(mixTy.VerifyType_WITHDRAW, m.PublicInput) out, err := mixTy.DecodePubInput(mixTy.VerifyType_WITHDRAW, m.PublicInput)
if err != nil { if err != nil {
bizlog.Error("processWithdraw decode", "pubInput", m.PublicInput) bizlog.Error("processWithdraw decode", "pubInput", m.PublicInput)
...@@ -132,15 +132,13 @@ func (p *mixPolicy) processTransfer(transfer *mixTy.MixTransferAction, heightInd ...@@ -132,15 +132,13 @@ func (p *mixPolicy) processTransfer(transfer *mixTy.MixTransferAction, heightInd
} }
func (p *mixPolicy) processAuth(auth *mixTy.MixAuthorizeAction, table *table.Table) { func (p *mixPolicy) processAuth(auth *mixTy.MixAuthorizeAction, table *table.Table) {
for _, m := range auth.AuthCommits { out, err := mixTy.DecodePubInput(mixTy.VerifyType_AUTHORIZE, auth.Proof.PublicInput)
out, err := mixTy.DecodePubInput(mixTy.VerifyType_AUTHORIZE, m.PublicInput) if err != nil {
if err != nil { bizlog.Error("processAuth decode", "pubInput", auth.Proof.PublicInput)
bizlog.Error("processAuth decode", "pubInput", m.PublicInput) return
continue
}
input := out.(*mixTy.AuthorizePublicInput)
updateAuthSpend(table, input.AuthorizeSpendHash)
} }
input := out.(*mixTy.AuthorizePublicInput)
updateAuthSpend(table, input.AuthorizeSpendHash)
} }
func (p *mixPolicy) processNullifiers(nulls []string, table *table.Table) { func (p *mixPolicy) processNullifiers(nulls []string, table *table.Table) {
...@@ -318,14 +316,12 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys ...@@ -318,14 +316,12 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys
return nil, errors.Wrapf(err, "decode secret data=%s", secretData) 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 { for _, key := range privacyKeys {
cryptData, err := common.FromHex(dhSecret.Secret) cryptData, err := common.FromHex(dhSecret.Secret)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "decode for notehash=%s,crypt=%s", noteHash, dhSecret.Secret) 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 { if err != nil {
bizlog.Debug("processSecret.decryptData fail", "decrypt for notehash", noteHash, "secret", secretData, "addr", key.Addr, "err", err) bizlog.Debug("processSecret.decryptData fail", "decrypt for notehash", noteHash, "secret", secretData, "addr", key.Addr, "err", err)
continue continue
...@@ -338,33 +334,33 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys ...@@ -338,33 +334,33 @@ func (p *mixPolicy) decodeSecret(noteHash string, secretData string, privacyKeys
continue continue
} }
bizlog.Info("processSecret.decode rawData OK", "notehash", noteHash, "addr", key.Addr) bizlog.Info("processSecret.decode rawData OK", "notehash", noteHash, "addr", key.Addr)
if rawData.ReceiverPubKey == key.Privacy.PaymentKey.ReceiverPubKey || if rawData.ReceiverKey == key.Privacy.PaymentKey.ReceiveKey ||
rawData.ReturnPubKey == key.Privacy.PaymentKey.ReceiverPubKey || rawData.ReturnKey == key.Privacy.PaymentKey.ReceiveKey ||
rawData.AuthorizePubKey == key.Privacy.PaymentKey.ReceiverPubKey { rawData.AuthorizeKey == key.Privacy.PaymentKey.ReceiveKey {
//decrypted, save database //decrypted, save database
var info mixTy.WalletIndexInfo var info mixTy.WalletIndexInfo
info.NoteHash = noteHash info.NoteHash = noteHash
info.Nullifier = getFrString(mimcHashString([]string{rawData.NoteRandom})) info.Nullifier = mixTy.Byte2Str(mimcHashString([]string{rawData.NoteRandom}))
//如果自己是spender,则记录有关spenderAuthHash,如果是returner,则记录returnerAuthHash //如果自己是spender,则记录有关spenderAuthHash,如果是returner,则记录returnerAuthHash
//如果授权为spenderAuthHash,则根据授权hash索引到本地数据库,spender更新本地为VALID,returner侧不变仍为FROZEN,花费后,两端都变为USED //如果授权为spenderAuthHash,则根据授权hash索引到本地数据库,spender更新本地为VALID,returner侧不变仍为FROZEN,花费后,两端都变为USED
//如果授权为returnerAuthHash,则returner更新本地为VALID,spender侧仍为FROZEN, //如果授权为returnerAuthHash,则returner更新本地为VALID,spender侧仍为FROZEN,
info.AuthorizeSpendHash = "0" info.AuthorizeSpendHash = "0"
if len(rawData.AuthorizePubKey) > LENNULLKEY { if len(rawData.AuthorizeKey) > LENNULLKEY {
switch key.Privacy.PaymentKey.ReceiverPubKey { switch key.Privacy.PaymentKey.ReceiveKey {
case rawData.ReceiverPubKey: case rawData.ReceiverKey:
info.Role = mixTy.Role_SPENDER info.Role = mixTy.Role_SPENDER
info.AuthorizeSpendHash = getFrString(mimcHashString([]string{rawData.ReceiverPubKey, rawData.Amount, rawData.NoteRandom})) info.AuthorizeSpendHash = mixTy.Byte2Str(mimcHashString([]string{rawData.ReceiverKey, rawData.Amount, rawData.NoteRandom}))
case rawData.ReturnPubKey: case rawData.ReturnKey:
info.Role = mixTy.Role_RETURNER info.Role = mixTy.Role_RETURNER
info.AuthorizeSpendHash = getFrString(mimcHashString([]string{rawData.ReturnPubKey, rawData.Amount, rawData.NoteRandom})) info.AuthorizeSpendHash = mixTy.Byte2Str(mimcHashString([]string{rawData.ReturnKey, rawData.Amount, rawData.NoteRandom}))
case rawData.AuthorizePubKey: case rawData.AuthorizeKey:
info.Role = mixTy.Role_AUTHORIZER info.Role = mixTy.Role_AUTHORIZER
} }
} }
info.Status = mixTy.NoteStatus_VALID info.Status = mixTy.NoteStatus_VALID
//空的公钥为"0"字符,不是空字符 //空的公钥为"0"字符,不是空字符
if len(rawData.AuthorizePubKey) > LENNULLKEY { if len(rawData.AuthorizeKey) > LENNULLKEY {
info.Status = mixTy.NoteStatus_FROZEN info.Status = mixTy.NoteStatus_FROZEN
} }
//账户地址 //账户地址
......
...@@ -16,94 +16,93 @@ func TestNewPrivacyWithPrivKey(t *testing.T) { ...@@ -16,94 +16,93 @@ func TestNewPrivacyWithPrivKey(t *testing.T) {
keyByte, err := hex.DecodeString(prikey) keyByte, err := hex.DecodeString(prikey)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
pairs, err := newPrivacyWithPrivKey(keyByte) pairs, err := newPrivacyKey(keyByte)
assert.Equal(t, nil, err) 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" //prikey2 := "1257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
keyByte2, err := hex.DecodeString(prikey2) //keyByte2, err := hex.DecodeString(prikey2)
assert.Equal(t, nil, err) //assert.Equal(t, nil, err)
pairs2, err := newPrivacyWithPrivKey(keyByte2) //pairs2, err := newPrivacyKey(keyByte2)
assert.Equal(t, nil, err) //assert.Equal(t, nil, err)
t.Log("payPri", pairs2.PaymentKey.SpendKey, "payPub", pairs2.PaymentKey.PayKey, "crytoPub", pairs2.ShareSecretKey.ReceivingPk, "crytoPri", pairs2.ShareSecretKey.PrivKey.Data) //t.Log("payPri2", pairs2.PaymentKey.SpendKey, "payPub", pairs2.PaymentKey.ReceiveKey, "crytoPub", pairs2.EncryptKey.PubKey, "crytoPri", pairs2.EncryptKey.PrivKey)
secret1 := &mixTy.SecretData{ secret1 := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705", ReceiverKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497", ReturnKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583", AuthorizeKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835", NoteRandom: "2824204835",
Amount: "28242048", Amount: "28242048",
} }
//secret2 := &mixTy.CryptoData{
// SpendPubKey:"18829345085195922012068709111582461121107908772422825655963168999800303848486", data, err := encryptData(pairs.EncryptKey.PubKey, types.Encode(secret1))
// ReturnPubKey:"16067249407809359746114321133992130903102335882983385972747813693681808870497", assert.Nil(t, err)
// AuthorizePubKey:"13519883267141251871527102103999205179714486518503885909948192364772977661583",
// NoteRandom:"2824204835",
// Amount:"28242048",
//}
data := encryptData(pairs.ShareSecretKey.ReceivingPk, types.Encode(secret1))
crypData, err := common.FromHex(data.Secret) crypData, err := common.FromHex(data.Secret)
assert.Nil(t, err) 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) assert.Nil(t, err)
var val mixTy.SecretData var val mixTy.SecretData
err = types.Decode(decryData1, &val) err = types.Decode(decryData1, &val)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, secret1.PaymentPubKey, val.PaymentPubKey) assert.Equal(t, secret1.ReceiverKey, val.ReceiverKey)
} }
func TestEncrypt(t *testing.T) { func TestEncrypt(t *testing.T) {
secret1 := &mixTy.SecretData{ secret := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705", ReceiverKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497", ReturnKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583", AuthorizeKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835", NoteRandom: "2824204835",
Amount: "28242048", Amount: "28242048",
} }
password := "1314fuzamei" password := "1314fuzamei"
cryptData := encryptDataWithPadding([]byte(password), types.Encode(secret1)) cryptData := encryptDataWithPadding([]byte(password), types.Encode(secret))
decryptData, err := decryptDataWithPading([]byte(password), cryptData) decryptData, err := decryptDataWithPading([]byte(password), cryptData)
assert.Nil(t, err) assert.Nil(t, err)
var raw mixTy.SecretData var raw mixTy.SecretData
err = types.Decode(decryptData, &raw) err = types.Decode(decryptData, &raw)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, raw.PaymentPubKey, secret1.PaymentPubKey) assert.Equal(t, raw.ReceiverKey, secret.ReceiverKey)
} }
func TestEncodeSecretData(t *testing.T) { func TestEncodeSecretData(t *testing.T) {
secret := &mixTy.SecretData{ secret := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705", ReceiverKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497", ReturnKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583", AuthorizeKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
Amount: "28242048", Amount: "28242048",
} }
ret, err := encodeSecretData(secret) //ret, err := encodeSecretData(secret)
assert.Nil(t, err) //assert.Nil(t, err)
t.Log(ret) //t.Log(ret)
//test encryp data //test encryp data
prikey := "4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01" prikey := "4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
keyByte, err := hex.DecodeString(prikey) keyByte, err := hex.DecodeString(prikey)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
privacy, err := newPrivacyWithPrivKey(keyByte) privacy, err := newPrivacyKey(keyByte)
assert.Equal(t, nil, err) 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) dhSecret, err := encryptSecretData(req)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(dhSecret) //t.Log(dhSecret)
data, err := common.FromHex(dhSecret.Secret) data, err := common.FromHex(dhSecret.Secret)
assert.Nil(t, err) 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) assert.Nil(t, err)
var rawSecret mixTy.SecretData var rawSecret mixTy.SecretData
types.Decode(rawData, &rawSecret) 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) { ...@@ -106,6 +106,10 @@ func (policy *mixPolicy) OnWalletUnlocked(WalletUnLock *types.WalletUnLock) {
// OnAddBlockTx 响应区块交易添加的处理 // OnAddBlockTx 响应区块交易添加的处理
func (policy *mixPolicy) OnAddBlockTx(block *types.BlockDetail, tx *types.Transaction, index int32, dbBatch db.Batch) *types.WalletTxDetail { 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) dbSet, err := policy.execAutoLocalMix(tx, block.Receipts[index], int(index), block.Block.Height)
if err != nil { if err != nil {
return 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 ...@@ -3,9 +3,11 @@ package wallet
import ( import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"reflect"
"testing" "testing"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
...@@ -15,21 +17,21 @@ func TestGetCommitValue(t *testing.T) { ...@@ -15,21 +17,21 @@ func TestGetCommitValue(t *testing.T) {
note = 100 note = 100
transfer = 60 transfer = 60
minFee = 1 minFee = 1
_, err := getCommitValue(note, transfer, minFee) _, err := getShieldValue(note, transfer, minFee)
assert.Nil(t, err) assert.Nil(t, err)
//transfer > note //transfer > note
note = 100 note = 100
transfer = 100 transfer = 100
minFee = 1 minFee = 1
_, err = getCommitValue(note, transfer, minFee) _, err = getShieldValue(note, transfer, minFee)
t.Log(err) t.Log(err)
assert.NotNil(t, err) assert.NotNil(t, err)
note = 100 note = 100
transfer = 101 transfer = 101
minFee = 0 minFee = 0
_, err = getCommitValue(note, transfer, minFee) _, err = getShieldValue(note, transfer, minFee)
t.Log(err) t.Log(err)
assert.NotNil(t, err) assert.NotNil(t, err)
...@@ -37,7 +39,7 @@ func TestGetCommitValue(t *testing.T) { ...@@ -37,7 +39,7 @@ func TestGetCommitValue(t *testing.T) {
note = 100 note = 100
transfer = 99 transfer = 99
minFee = 1 minFee = 1
_, err = getCommitValue(note, transfer, minFee) _, err = getShieldValue(note, transfer, minFee)
assert.Nil(t, err) assert.Nil(t, err)
a := "0a9c010a4d3136323433323838333039363632323833373538343930323239313730303834393836343035373630373234353332323934333436353837323033353436363930353333373131303333323139124b3238383637383239373931373237373235343930333236303134303538313534363138303135353433383231393339363836333632313634323236303434353739313434393237383237331a82033078656663333331616261616139653039353966636536356163343364626534306364646139356534356261636163613161326166626265366637323533633132326233346264323337353932343066306237623836653363343635666131343065666332636665623861653035366234323163303665353062396532646564636236383963336536656435363636373731343235663736313931653831356665666633646432393965633535386261323731343238333131623130353364376265633864646163313733393632326238666138326438373336666531623332633835376438343330643634646637336530643265326238373932396335633762366437336534383365363130303561313361376531643730636637653834656132613235343166373235363834656266613737653235313232326466313039336230313964646165623963376134393763316538653737386462313730323636323536666666363332643437363738626633366634383361373334346666326330" a := "0a9c010a4d3136323433323838333039363632323833373538343930323239313730303834393836343035373630373234353332323934333436353837323033353436363930353333373131303333323139124b3238383637383239373931373237373235343930333236303134303538313534363138303135353433383231393339363836333632313634323236303434353739313434393237383237331a82033078656663333331616261616139653039353966636536356163343364626534306364646139356534356261636163613161326166626265366637323533633132326233346264323337353932343066306237623836653363343635666131343065666332636665623861653035366234323163303665353062396532646564636236383963336536656435363636373731343235663736313931653831356665666633646432393965633535386261323731343238333131623130353364376265633864646163313733393632326238666138326438373336666531623332633835376438343330643634646637336530643265326238373932396335633762366437336534383365363130303561313361376531643730636637653834656132613235343166373235363834656266613737653235313232326466313039336230313964646165623963376134393763316538653737386462313730323636323536666666363332643437363738626633366634383361373334346666326330"
...@@ -50,4 +52,105 @@ func TestGetCommitValue(t *testing.T) { ...@@ -50,4 +52,105 @@ func TestGetCommitValue(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
fmt.Println("data", data) 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