Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
9ff24cd5
Commit
9ff24cd5
authored
Nov 17, 2020
by
madengji
Committed by
vipwzw
Sep 18, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add merkle tree
parent
0baa7ba6
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
981 additions
and
237 deletions
+981
-237
transferOutput_test.go
plugin/dapp/mix/cmd/gnark/circuit/transferOutput_test.go
+0
-2
authorizeInput
plugin/dapp/mix/cmd/gnark/input/authorizeInput
+15
-18
depositInput
plugin/dapp/mix/cmd/gnark/input/depositInput
+6
-6
transferInput
plugin/dapp/mix/cmd/gnark/input/transferInput
+1
-1
transferOutput
plugin/dapp/mix/cmd/gnark/input/transferOutput
+8
-8
withdrawInput
plugin/dapp/mix/cmd/gnark/input/withdrawInput
+17
-19
action.go
plugin/dapp/mix/executor/action.go
+13
-0
authorize.go
plugin/dapp/mix/executor/authorize.go
+7
-9
committree.go
plugin/dapp/mix/executor/committree.go
+35
-31
committree_test.go
plugin/dapp/mix/executor/committree_test.go
+68
-0
config.go
plugin/dapp/mix/executor/config.go
+1
-1
deposit.go
plugin/dapp/mix/executor/deposit.go
+3
-5
readers.go
plugin/dapp/mix/executor/merkletree/readers.go
+72
-0
tree.go
plugin/dapp/mix/executor/merkletree/tree.go
+342
-0
verify.go
plugin/dapp/mix/executor/merkletree/verify.go
+180
-0
mix.go
plugin/dapp/mix/executor/mix.go
+2
-4
query.go
plugin/dapp/mix/executor/query.go
+19
-0
transfer.go
plugin/dapp/mix/executor/transfer.go
+2
-2
withdraw.go
plugin/dapp/mix/executor/withdraw.go
+17
-19
mix.proto
plugin/dapp/mix/proto/mix.proto
+16
-12
mix.pb.go
plugin/dapp/mix/types/mix.pb.go
+157
-100
No files found.
plugin/dapp/mix/cmd/gnark/circuit/transferOutput_test.go
View file @
9ff24cd5
...
@@ -45,8 +45,6 @@ func TestTransferOutput(t *testing.T) {
...
@@ -45,8 +45,6 @@ func TestTransferOutput(t *testing.T) {
good
.
Assign
(
backend
.
Secret
,
"noteRandom"
,
"2824204835"
)
good
.
Assign
(
backend
.
Secret
,
"noteRandom"
,
"2824204835"
)
good
.
Assign
(
backend
.
Secret
,
"noteHash"
,
"16308793397024662832064523892418908145900866571524124093537199035808550255649"
)
assert
.
Solved
(
&
r1csBN256
,
good
,
nil
)
assert
.
Solved
(
&
r1csBN256
,
good
,
nil
)
}
}
...
...
plugin/dapp/mix/cmd/gnark/input/authorizeInput
View file @
9ff24cd5
public, treeRootHash,
0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, treeRootHash,
10531321614990797034921282585661869614556487056951485265320464926630499341310
public, authorizePubKey,
994003913012591722647777982320043119076773027366753197021939544019171743967
3
public, authorizePubKey,
1351988326714125187152710210399920517971448651850388590994819236477297766158
3
public, authorizeHash,
0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, authorizeHash,
1267825436937766239630340333349685320927256968591056373125946583184548355070
public, authorizeSpendHash,
0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, authorizeSpendHash,
14468512365438613046028281588661351435476168610934165547900473609197783547663
secret, spendAmount,28242048
secret, spendAmount,28242048
secret, spendPubKey,9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, spendPubKey,13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, returnPubKey,16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, authorizePriKey,17822967620457187568904804290291537271142779717280482398091401115827760898835
secret, authorizePriKey,19226210204356004706765360050059680583735587569269469539941275797408975356275
secret, spendFlag,1
secret, spendFlag,0
secret, noteRandom,2824204835
secret, noteRandom,28242048
secret, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path0,1e44c73ba7980b0450a8e997c9d9c78be5a9d7ceaf597df781469a1c9db4e4c9
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path1,191a80e377af9e0d04e1d75e8d702d4c2db21b952b9fff6bcca31f9e9fd5de00
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path2,220dc2041a8c81086a9bc8084e7f9ee0788ae2c8b7928e0b2e2672339b2933b3
secret, path4,0
secret, path3,295d631fcf0ed0d34742ac560fe7a0c0585225cff9194806d4d9d8e1f00e1747
secret, path4,215849ad7bd4344a807f4f0c9aefd2131572e3cb21a8b21aa96e8a11c4a214e5
secret, path5,0
secret, path5,0
secret, path6,0
secret, path6,0
secret, path7,0
secret, path7,0
...
@@ -36,11 +34,10 @@ secret, helper9,1
...
@@ -36,11 +34,10 @@ secret, helper9,1
secret, helper10,1
secret, helper10,1
secret, valid0,1
secret, valid1,1
secret, valid1,1
secret, valid2,1
secret, valid2,1
secret, valid3,1
secret, valid3,1
secret, valid4,
1
secret, valid4,
0
secret, valid5,0
secret, valid5,0
secret, valid6,0
secret, valid6,0
secret, valid7,0
secret, valid7,0
...
...
plugin/dapp/mix/cmd/gnark/input/depositInput
View file @
9ff24cd5
public, nodeHash,
0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, nodeHash,
16308793397024662832064523892418908145900866571524124093537199035808550255649
public, amount,
1000
public, amount,
28242048
secret, spendPubKey,
9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, spendPubKey,
13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,
9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, returnPubKey,
16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,
994003913012591722647777982320043119076773027366753197021939544019171743967
3
secret, authorizePubKey,
1351988326714125187152710210399920517971448651850388590994819236477297766158
3
secret, noteRandom,28242048
secret, noteRandom,28242048
35
...
...
plugin/dapp/mix/cmd/gnark/input/transferInput
View file @
9ff24cd5
...
@@ -14,8 +14,8 @@ secret, spendPriKey,101904778353009275576499342388203605294586816720738661162328
...
@@ -14,8 +14,8 @@ secret, spendPriKey,101904778353009275576499342388203605294586816720738661162328
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, path1,19561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path2,13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path3,15019169196974879571470243100379529757970866395477207575033769902587972032431
...
...
plugin/dapp/mix/cmd/gnark/input/transferOutput
View file @
9ff24cd5
public, commitValueX,
9940039130125917226477779823200431190767730273667531970219395440191717439673
public, commitValueX,
14087975867275911077371231345227824611951436822132762463787130558957838320348
public, commitValueY,
9940039130125917226477779823200431190767730273667531970219395440191717439673
public, commitValueY,
15113519960384204624879642069520481336224311978035289236693658603675385299879
public, nodeHash,
0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, nodeHash,
16308793397024662832064523892418908145900866571524124093537199035808550255649
secret, spendAmount,28242048
secret, spendAmount,28242048
secret, spendRandom,
28242048
secret, spendRandom,
35
secret, spendPubKey,
9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, spendPubKey,
13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,
9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, returnPubKey,
16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,
994003913012591722647777982320043119076773027366753197021939544019171743967
3
secret, authorizePubKey,
1351988326714125187152710210399920517971448651850388590994819236477297766158
3
secret, noteRandom,28242048
secret, noteRandom,28242048
35
plugin/dapp/mix/cmd/gnark/input/withdrawInput
View file @
9ff24cd5
public, treeRootHash,
0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, treeRootHash,
10531321614990797034921282585661869614556487056951485265320464926630499341310
public, authorize
Hash,0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, authorize
SpendHash,14468512365438613046028281588661351435476168610934165547900473609197783547663
public, nullifierHash,
0x2afea5c28f761f42f35cca471170ca072cbe4b69b6b18c4a3b45637e974783c4
public, nullifierHash,
6747518781649068310795677405858353007442326529625450860668944156162052335195
public, amount,28242048
public, amount,28242048
secret, spendPubKey,
9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, spendPubKey,
13735985067536865723202617343666111332145536963656464451727087263423649028705
secret, returnPubKey,
9940039130125917226477779823200431190767730273667531970219395440191717439673
secret, returnPubKey,
16067249407809359746114321133992130903102335882983385972747813693681808870497
secret, authorizePubKey,
994003913012591722647777982320043119076773027366753197021939544019171743967
3
secret, authorizePubKey,
1351988326714125187152710210399920517971448651850388590994819236477297766158
3
secret, spendPriKey,1
9226210204356004706765360050059680583735587569269469539941275797408975356275
secret, spendPriKey,1
0190477835300927557649934238820360529458681672073866116232821892325659279502
secret, spendFlag,
0
secret, spendFlag,
1
secret, authorizeFlag,
0
secret, authorizeFlag,
1
secret, noteRandom,28242048
secret, noteRandom,28242048
35
secret,
path0,1e44c73ba7980b0450a8e997c9d9c78be5a9d7ceaf597df781469a1c9db4e4c
9
secret,
noteHash,1630879339702466283206452389241890814590086657152412409353719903580855025564
9
secret, path1,19
1a80e377af9e0d04e1d75e8d702d4c2db21b952b9fff6bcca31f9e9fd5de00
secret, path1,19
561523370160677851616596032513161448778901506614020103852017946679781620105
secret, path2,
220dc2041a8c81086a9bc8084e7f9ee0788ae2c8b7928e0b2e2672339b2933b3
secret, path2,
13898857070666440684265042188056372750257678232709763835292910585848522658637
secret, path3,
295d631fcf0ed0d34742ac560fe7a0c0585225cff9194806d4d9d8e1f00e1747
secret, path3,
15019169196974879571470243100379529757970866395477207575033769902587972032431
secret, path4,
215849ad7bd4344a807f4f0c9aefd2131572e3cb21a8b21aa96e8a11c4a214e5
secret, path4,
0
secret, path5,0
secret, path5,0
secret, path6,0
secret, path6,0
secret, path7,0
secret, path7,0
...
@@ -33,19 +33,17 @@ secret, helper6,1
...
@@ -33,19 +33,17 @@ secret, helper6,1
secret, helper7,1
secret, helper7,1
secret, helper8,1
secret, helper8,1
secret, helper9,1
secret, helper9,1
secret, helper10,1
secret, valid0,1
secret, valid1,1
secret, valid1,1
secret, valid2,1
secret, valid2,1
secret, valid3,1
secret, valid3,1
secret, valid4,
1
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
secret, valid10,0
plugin/dapp/mix/executor/action.go
View file @
9ff24cd5
...
@@ -7,6 +7,7 @@ package executor
...
@@ -7,6 +7,7 @@ package executor
import
(
import
(
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/client"
"github.com/consensys/gurvy/bn256/fr"
dbm
"github.com/33cn/chain33/common/db"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/system/dapp"
...
@@ -79,3 +80,15 @@ func makeReceipt(key []byte, logTy int32, data proto.Message) *types.Receipt {
...
@@ -79,3 +80,15 @@ func makeReceipt(key []byte, logTy int32, data proto.Message) *types.Receipt {
},
},
}
}
}
}
func
transferFr2Bytes
(
v
string
)
[]
byte
{
var
leaf
fr
.
Element
leaf
.
SetString
(
v
)
return
leaf
.
Bytes
()
}
func
transferFr2String
(
val
[]
byte
)
string
{
var
leaf
fr
.
Element
leaf
.
SetBytes
(
val
)
return
leaf
.
String
()
}
plugin/dapp/mix/executor/authorize.go
View file @
9ff24cd5
...
@@ -8,8 +8,6 @@ import (
...
@@ -8,8 +8,6 @@ import (
"encoding/hex"
"encoding/hex"
"encoding/json"
"encoding/json"
"github.com/33cn/chain33/common"
"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"
...
@@ -19,18 +17,18 @@ import (
...
@@ -19,18 +17,18 @@ import (
func
(
a
*
action
)
authParamCheck
(
input
*
mixTy
.
AuthorizePublicInput
)
error
{
func
(
a
*
action
)
authParamCheck
(
input
*
mixTy
.
AuthorizePublicInput
)
error
{
//check tree rootHash exist
//check tree rootHash exist
if
!
checkTreeRootHashExist
(
a
.
db
,
input
.
TreeRootHash
)
{
if
!
checkTreeRootHashExist
(
a
.
db
,
transferFr2Bytes
(
input
.
TreeRootHash
)
)
{
return
errors
.
Wrapf
(
mixTy
.
ErrTreeRootHashNotFound
,
"roothash=%s"
,
common
.
ToHex
(
input
.
TreeRootHash
)
)
return
errors
.
Wrapf
(
mixTy
.
ErrTreeRootHashNotFound
,
"roothash=%s"
,
input
.
TreeRootHash
)
}
}
//authorize key should not exist
//authorize key should not exist
authKey
:=
calcAuthorizeHashKey
(
common
.
ToHex
(
input
.
AuthorizeHash
)
)
authKey
:=
calcAuthorizeHashKey
(
input
.
AuthorizeHash
)
_
,
err
:=
a
.
db
.
Get
(
authKey
)
_
,
err
:=
a
.
db
.
Get
(
authKey
)
if
err
==
nil
{
if
err
==
nil
{
return
errors
.
Wrapf
(
mixTy
.
ErrAuthorizeHashExist
,
"auth=%s"
,
common
.
ToHex
(
input
.
AuthorizeHash
)
)
return
errors
.
Wrapf
(
mixTy
.
ErrAuthorizeHashExist
,
"auth=%s"
,
input
.
AuthorizeHash
)
}
}
if
!
isNotFound
(
err
)
{
if
!
isNotFound
(
err
)
{
return
errors
.
Wrapf
(
err
,
"auth=%s"
,
common
.
ToHex
(
input
.
AuthorizeHash
)
)
return
errors
.
Wrapf
(
err
,
"auth=%s"
,
input
.
AuthorizeHash
)
}
}
authPubKeys
,
err
:=
a
.
getAuthKeys
()
authPubKeys
,
err
:=
a
.
getAuthKeys
()
...
@@ -97,9 +95,9 @@ func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt,
...
@@ -97,9 +95,9 @@ func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt,
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
}
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
}
for
_
,
in
:=
range
inputs
{
for
_
,
in
:=
range
inputs
{
r
:=
makeReceipt
(
calcAuthorizeHashKey
(
common
.
ToHex
(
in
.
AuthorizeHash
)
),
mixTy
.
TyLogAuthorizeSet
,
&
mixTy
.
ExistValue
{
Data
:
true
})
r
:=
makeReceipt
(
calcAuthorizeHashKey
(
in
.
AuthorizeHash
),
mixTy
.
TyLogAuthorizeSet
,
&
mixTy
.
ExistValue
{
Data
:
true
})
mergeReceipt
(
receipt
,
r
)
mergeReceipt
(
receipt
,
r
)
r
=
makeReceipt
(
calcAuthorizeSpendHashKey
(
common
.
ToHex
(
in
.
AuthorizeSpendHash
)
),
mixTy
.
TyLogAuthorizeSpendSet
,
&
mixTy
.
ExistValue
{
Data
:
true
})
r
=
makeReceipt
(
calcAuthorizeSpendHashKey
(
in
.
AuthorizeSpendHash
),
mixTy
.
TyLogAuthorizeSpendSet
,
&
mixTy
.
ExistValue
{
Data
:
true
})
mergeReceipt
(
receipt
,
r
)
mergeReceipt
(
receipt
,
r
)
}
}
...
...
plugin/dapp/mix/executor/committree.go
View file @
9ff24cd5
...
@@ -6,28 +6,17 @@ package executor
...
@@ -6,28 +6,17 @@ package executor
import
(
import
(
"bytes"
"bytes"
"strconv"
"strings"
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/mix/executor/merkletree"
mixTy
"github.com/33cn/plugin/plugin/dapp/mix/types"
mixTy
"github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/NebulousLabs/merkletree"
"github.com/consensys/gnark/crypto/hash/mimc/bn256"
"github.com/consensys/gnark/crypto/hash/mimc/bn256"
"github.com/pkg/errors"
"github.com/pkg/errors"
)
)
//func makeTreeReceipt(key []byte, logTy int32, data proto.Message) *types.Receipt {
// return &types.Receipt{
// Ty: types.ExecOk,
// KV: []*types.KeyValue{
// {Key: key, Value: types.Encode(data)},
// },
// Logs: []*types.ReceiptLog{
// {Ty: logTy, Log: types.Encode(data)},
// },
// }
//}
func
makeTreeLeavesReceipt
(
data
*
mixTy
.
CommitTreeLeaves
)
*
types
.
Receipt
{
func
makeTreeLeavesReceipt
(
data
*
mixTy
.
CommitTreeLeaves
)
*
types
.
Receipt
{
return
makeReceipt
(
calcCurrentCommitLeavesKey
(),
mixTy
.
TyLogCurrentCommitTreeLeaves
,
data
)
return
makeReceipt
(
calcCurrentCommitLeavesKey
(),
mixTy
.
TyLogCurrentCommitTreeLeaves
,
data
)
}
}
...
@@ -42,8 +31,8 @@ func makeCurrentTreeReceipt(leaves *mixTy.CommitTreeLeaves, roots *mixTy.CommitT
...
@@ -42,8 +31,8 @@ func makeCurrentTreeReceipt(leaves *mixTy.CommitTreeLeaves, roots *mixTy.CommitT
return
mergeReceipt
(
r1
,
r2
)
return
mergeReceipt
(
r1
,
r2
)
}
}
func
makeTreeRootLeavesReceipt
(
root
[]
byte
,
data
*
mixTy
.
CommitTreeLeaves
)
*
types
.
Receipt
{
func
makeTreeRootLeavesReceipt
(
root
string
,
data
*
mixTy
.
CommitTreeLeaves
)
*
types
.
Receipt
{
return
makeReceipt
(
calcCommitTreeRootLeaves
(
common
.
ToHex
(
root
)
),
mixTy
.
TyLogCommitTreeRootLeaves
,
data
)
return
makeReceipt
(
calcCommitTreeRootLeaves
(
root
),
mixTy
.
TyLogCommitTreeRootLeaves
,
data
)
}
}
func
makeTreeArchiveRootsReceipt
(
data
*
mixTy
.
CommitTreeRoots
)
*
types
.
Receipt
{
func
makeTreeArchiveRootsReceipt
(
data
*
mixTy
.
CommitTreeRoots
)
*
types
.
Receipt
{
...
@@ -68,8 +57,8 @@ func getCurrentCommitTreeLeaves(db dbm.KV) (*mixTy.CommitTreeLeaves, error) {
...
@@ -68,8 +57,8 @@ func getCurrentCommitTreeLeaves(db dbm.KV) (*mixTy.CommitTreeLeaves, error) {
return
getCommitLeaves
(
db
,
calcCurrentCommitLeavesKey
())
return
getCommitLeaves
(
db
,
calcCurrentCommitLeavesKey
())
}
}
func
getCommitRootLeaves
(
db
dbm
.
KV
,
rootHash
[]
byte
)
(
*
mixTy
.
CommitTreeLeaves
,
error
)
{
func
getCommitRootLeaves
(
db
dbm
.
KV
,
rootHash
string
)
(
*
mixTy
.
CommitTreeLeaves
,
error
)
{
return
getCommitLeaves
(
db
,
calcCommitTreeRootLeaves
(
common
.
ToHex
(
rootHash
)
))
return
getCommitLeaves
(
db
,
calcCommitTreeRootLeaves
(
rootHash
))
}
}
func
getCommitTreeRoots
(
db
dbm
.
KV
,
key
[]
byte
)
(
*
mixTy
.
CommitTreeRoots
,
error
)
{
func
getCommitTreeRoots
(
db
dbm
.
KV
,
key
[]
byte
)
(
*
mixTy
.
CommitTreeRoots
,
error
)
{
...
@@ -130,7 +119,7 @@ func initNewLeaves(leaf []byte) *types.Receipt {
...
@@ -130,7 +119,7 @@ func initNewLeaves(leaf []byte) *types.Receipt {
}
}
func
archiveRoots
(
db
dbm
.
KV
,
root
[]
byte
,
leaves
*
mixTy
.
CommitTreeLeaves
)
(
*
types
.
Receipt
,
error
)
{
func
archiveRoots
(
db
dbm
.
KV
,
root
[]
byte
,
leaves
*
mixTy
.
CommitTreeLeaves
)
(
*
types
.
Receipt
,
error
)
{
receiptRootLeaves
:=
makeTreeRootLeavesReceipt
(
root
,
leaves
)
receiptRootLeaves
:=
makeTreeRootLeavesReceipt
(
transferFr2String
(
root
)
,
leaves
)
archiveRoots
,
err
:=
getArchiveCommitRoots
(
db
)
archiveRoots
,
err
:=
getArchiveCommitRoots
(
db
)
if
isNotFound
(
errors
.
Cause
(
err
))
{
if
isNotFound
(
errors
.
Cause
(
err
))
{
...
@@ -216,14 +205,16 @@ func checkTreeRootHashExist(db dbm.KV, hash []byte) bool {
...
@@ -216,14 +205,16 @@ func checkTreeRootHashExist(db dbm.KV, hash []byte) bool {
func
getProveData
(
targetLeaf
[]
byte
,
leaves
[][]
byte
)
(
*
mixTy
.
CommitTreeProve
,
error
)
{
func
getProveData
(
targetLeaf
[]
byte
,
leaves
[][]
byte
)
(
*
mixTy
.
CommitTreeProve
,
error
)
{
index
:=
0
index
:=
0
found
:=
false
for
i
,
key
:=
range
leaves
{
for
i
,
key
:=
range
leaves
{
if
bytes
.
Equal
(
key
,
targetLeaf
)
{
if
bytes
.
Equal
(
key
,
targetLeaf
)
{
index
=
i
index
=
i
found
=
true
break
break
}
}
}
}
//index=0的leaf是占位"00",不会和leaf相等
//index=0的leaf是占位"00",不会和leaf相等
if
index
==
0
{
if
!
found
{
return
nil
,
mixTy
.
ErrLeafNotFound
return
nil
,
mixTy
.
ErrLeafNotFound
}
}
...
@@ -232,22 +223,35 @@ func getProveData(targetLeaf []byte, leaves [][]byte) (*mixTy.CommitTreeProve, e
...
@@ -232,22 +223,35 @@ func getProveData(targetLeaf []byte, leaves [][]byte) (*mixTy.CommitTreeProve, e
for
_
,
key
:=
range
leaves
{
for
_
,
key
:=
range
leaves
{
tree
.
Push
(
key
)
tree
.
Push
(
key
)
}
}
root
,
s
et
,
proofIndex
,
num
:=
tree
.
Prove
()
root
,
proofS
et
,
proofIndex
,
num
:=
tree
.
Prove
()
var
prove
mixTy
.
CommitTreeProve
var
prove
mixTy
.
CommitTreeProve
prove
.
RootHash
=
common
.
ToHex
(
root
)
prove
.
RootHash
=
transferFr2String
(
root
)
prove
.
ProofIndex
=
uint32
(
proofIndex
)
prove
.
ProofIndex
=
uint32
(
proofIndex
)
prove
.
NumLeaves
=
uint32
(
num
)
prove
.
NumLeaves
=
uint32
(
num
)
for
_
,
s
:=
range
set
{
//set[0] 是targetLeaf
prove
.
ProofSet
=
append
(
prove
.
ProofSet
,
common
.
ToHex
(
s
))
for
_
,
s
:=
range
proofSet
{
prove
.
ProofSet
=
append
(
prove
.
ProofSet
,
transferFr2String
(
s
))
}
helpers
:=
merkletree
.
GenerateProofHelper
(
proofSet
,
proofIndex
,
num
)
var
helpStr
[]
string
for
_
,
i
:=
range
helpers
{
helpStr
=
append
(
helpStr
,
strconv
.
Itoa
(
i
))
}
}
prove
.
Helpers
=
strings
.
Join
(
helpStr
,
","
)
return
&
prove
,
nil
return
&
prove
,
nil
}
}
func
CalcTreeProve
(
db
dbm
.
KV
,
rootHash
,
leaf
[]
byte
)
(
*
mixTy
.
CommitTreeProve
,
error
)
{
func
CalcTreeProve
(
db
dbm
.
KV
,
rootHash
,
leaf
string
)
(
*
mixTy
.
CommitTreeProve
,
error
)
{
if
len
(
leaf
)
<=
0
{
return
nil
,
errors
.
Wrap
(
types
.
ErrInvalidParam
,
"leaf is null"
)
}
leaves
,
err
:=
getCurrentCommitTreeLeaves
(
db
)
leaves
,
err
:=
getCurrentCommitTreeLeaves
(
db
)
if
err
==
nil
{
if
err
==
nil
{
p
,
err
:=
getProveData
(
leaf
,
leaves
.
Data
)
p
,
err
:=
getProveData
(
transferFr2Bytes
(
leaf
)
,
leaves
.
Data
)
if
err
==
nil
{
if
err
==
nil
{
return
p
,
nil
return
p
,
nil
}
}
...
@@ -258,9 +262,9 @@ func CalcTreeProve(db dbm.KV, rootHash, leaf []byte) (*mixTy.CommitTreeProve, er
...
@@ -258,9 +262,9 @@ func CalcTreeProve(db dbm.KV, rootHash, leaf []byte) (*mixTy.CommitTreeProve, er
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
p
,
err
:=
getProveData
(
leaf
,
leaves
.
Data
)
p
,
err
:=
getProveData
(
transferFr2Bytes
(
leaf
)
,
leaves
.
Data
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
Wrapf
(
err
,
"hash=%s,leaf=%s"
,
common
.
ToHex
(
rootHash
),
common
.
ToHex
(
leaf
)
)
return
nil
,
errors
.
Wrapf
(
err
,
"hash=%s,leaf=%s"
,
rootHash
,
leaf
)
}
}
return
p
,
nil
return
p
,
nil
}
}
...
@@ -268,9 +272,9 @@ func CalcTreeProve(db dbm.KV, rootHash, leaf []byte) (*mixTy.CommitTreeProve, er
...
@@ -268,9 +272,9 @@ func CalcTreeProve(db dbm.KV, rootHash, leaf []byte) (*mixTy.CommitTreeProve, er
roots
,
err
:=
getArchiveCommitRoots
(
db
)
roots
,
err
:=
getArchiveCommitRoots
(
db
)
if
err
==
nil
{
if
err
==
nil
{
for
_
,
root
:=
range
roots
.
Data
{
for
_
,
root
:=
range
roots
.
Data
{
leaves
,
err
:=
getCommitRootLeaves
(
db
,
root
)
leaves
,
err
:=
getCommitRootLeaves
(
db
,
transferFr2String
(
root
)
)
if
err
==
nil
{
if
err
==
nil
{
p
,
err
:=
getProveData
(
leaf
,
leaves
.
Data
)
p
,
err
:=
getProveData
(
transferFr2Bytes
(
leaf
)
,
leaves
.
Data
)
if
err
==
nil
{
if
err
==
nil
{
return
p
,
nil
return
p
,
nil
}
}
...
@@ -279,6 +283,6 @@ func CalcTreeProve(db dbm.KV, rootHash, leaf []byte) (*mixTy.CommitTreeProve, er
...
@@ -279,6 +283,6 @@ func CalcTreeProve(db dbm.KV, rootHash, leaf []byte) (*mixTy.CommitTreeProve, er
}
}
}
}
return
nil
,
errors
.
Wrapf
(
err
,
"hash=%s,leaf=%s"
,
common
.
ToHex
(
rootHash
),
common
.
ToHex
(
leaf
)
)
return
nil
,
errors
.
Wrapf
(
err
,
"hash=%s,leaf=%s"
,
rootHash
,
leaf
)
}
}
plugin/dapp/mix/executor/committree_test.go
0 → 100644
View file @
9ff24cd5
// 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
executor
import
(
"testing"
"github.com/stretchr/testify/assert"
)
/*
leaf0 = "16308793397024662832064523892418908145900866571524124093537199035808550255649"
hexstr 240e732fc90c3a88a11f3f60bbbe412f6b4b56d007cf34fdb2500195071c7c21
leaf1 = 21467822781369104390668289189963532506973289112396605437823854946060028754354
leaf hash 17799daf83d82530d70343bc44578bdabafcb134332d4949883695a1ec9d1ba9
leaf2= 4178471437305290899835614805415999986197321812505352791035422725360758750328
leaf hash 29ded1ba9ed45d829f458ce511e013a8d11058db9d6f03fea14267082087b151
leaf3= 10407830929890509544473717262275616077696950294748419792758056545898949331744
leaf hash 1b757026b07fd17150c5d23081bddd52e77dc26b0c7c46b4e0150ca7ccfed35a
leaf4= 11032604436245646157001636966356016502073301224837385665550497706958264582086
leaf hash 24a8d61af8e16abaf9ccb1051c882799121c6ece1094655b5b93f837aead2f30
merkleroot= 6988991286454436061784929049510388415076132311642532433013500389938249229356
0 proof str= 21467822781369104390668289189963532506973289112396605437823854946060028754354
1 proof str= 12096317366724227951683802305909172775715878134489527031786909074403605889217
2 proof str= 14541527209424185878803689752018034974129079647509824805270353433359922459228
3 proof str= 16581570556767364549626991605903512613557832602774591000372759906303762837296
*/
func
TestGetProveData
(
t
*
testing
.
T
)
{
leaves
:=
[]
string
{
"16308793397024662832064523892418908145900866571524124093537199035808550255649"
,
"21467822781369104390668289189963532506973289112396605437823854946060028754354"
,
"4178471437305290899835614805415999986197321812505352791035422725360758750328"
,
"10407830929890509544473717262275616077696950294748419792758056545898949331744"
,
"11032604436245646157001636966356016502073301224837385665550497706958264582086"
,
}
proves
:=
[]
string
{
"21467822781369104390668289189963532506973289112396605437823854946060028754354"
,
"12096317366724227951683802305909172775715878134489527031786909074403605889217"
,
"14541527209424185878803689752018034974129079647509824805270353433359922459228"
,
"16581570556767364549626991605903512613557832602774591000372759906303762837296"
,
}
var
leave
[][]
byte
for
_
,
l
:=
range
leaves
{
leave
=
append
(
leave
,
transferFr2Bytes
(
l
))
}
ret
,
err
:=
getProveData
(
leave
[
1
],
leave
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
uint32
(
5
),
ret
.
NumLeaves
)
assert
.
Equal
(
t
,
uint32
(
1
),
ret
.
ProofIndex
)
assert
.
Equal
(
t
,
"6988991286454436061784929049510388415076132311642532433013500389938249229356"
,
ret
.
RootHash
)
assert
.
Equal
(
t
,
len
(
proves
),
len
(
ret
.
ProofSet
))
for
i
,
k
:=
range
proves
{
assert
.
Equal
(
t
,
k
,
ret
.
ProofSet
[
i
])
}
assert
.
Equal
(
t
,
"0,1,1"
,
ret
.
Helpers
)
}
plugin/dapp/mix/executor/config.go
View file @
9ff24cd5
...
@@ -26,7 +26,7 @@ func isSuperManager(cfg *types.Chain33Config, addr string) bool {
...
@@ -26,7 +26,7 @@ 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
()
if
!
isSuperManager
(
cfg
,
a
.
fromaddr
)
{
if
!
isSuperManager
(
cfg
,
a
.
fromaddr
)
{
return
nil
,
types
.
ErrNotAllow
return
nil
,
errors
.
Wrapf
(
types
.
ErrNotAllow
,
"not super manager,%s"
,
a
.
fromaddr
)
}
}
switch
config
.
Ty
{
switch
config
.
Ty
{
case
mixTy
.
MixConfigType_VerifyKey
:
case
mixTy
.
MixConfigType_VerifyKey
:
...
...
plugin/dapp/mix/executor/deposit.go
View file @
9ff24cd5
...
@@ -9,8 +9,6 @@ import (
...
@@ -9,8 +9,6 @@ import (
"encoding/json"
"encoding/json"
"strconv"
"strconv"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
"github.com/33cn/plugin/plugin/dapp/mix/executor/zksnark"
...
@@ -20,8 +18,8 @@ import (
...
@@ -20,8 +18,8 @@ import (
"github.com/pkg/errors"
"github.com/pkg/errors"
)
)
func
makeNullifierSetReceipt
(
hash
[]
byte
,
data
proto
.
Message
)
*
types
.
Receipt
{
func
makeNullifierSetReceipt
(
hash
string
,
data
proto
.
Message
)
*
types
.
Receipt
{
return
makeReceipt
(
calcNullifierHashKey
(
common
.
ToHex
(
hash
)
),
mixTy
.
TyLogNulliferSet
,
data
)
return
makeReceipt
(
calcNullifierHashKey
(
hash
),
mixTy
.
TyLogNulliferSet
,
data
)
}
}
...
@@ -72,7 +70,7 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) ([]byte, uint64, error)
...
@@ -72,7 +70,7 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) ([]byte, uint64, error)
return
nil
,
0
,
err
return
nil
,
0
,
err
}
}
return
input
.
NodeHash
,
val
,
nil
return
transferFr2Bytes
(
input
.
NodeHash
)
,
val
,
nil
}
}
...
...
plugin/dapp/mix/executor/merkletree/readers.go
0 → 100644
View file @
9ff24cd5
// from https://gitlab.com/NebulousLabs/merkletree
package
merkletree
import
(
"errors"
"hash"
"io"
)
// ReadAll will read segments of size 'segmentSize' and push them into the tree
// until EOF is reached. Success will return 'err == nil', not 'err == EOF'. No
// padding is added to the data, so the last element may be smaller than
// 'segmentSize'.
func
(
t
*
Tree
)
ReadAll
(
r
io
.
Reader
,
segmentSize
int
)
error
{
for
{
segment
:=
make
([]
byte
,
segmentSize
)
n
,
readErr
:=
io
.
ReadFull
(
r
,
segment
)
if
readErr
==
io
.
EOF
{
// All data has been read.
break
}
else
if
readErr
==
io
.
ErrUnexpectedEOF
{
// This is the last segment, and there aren't enough bytes to fill
// the entire segment. Note that the next call will return io.EOF.
segment
=
segment
[
:
n
]
}
else
if
readErr
!=
nil
{
return
readErr
}
t
.
Push
(
segment
)
}
return
nil
}
// ReaderRoot returns the Merkle root of the data read from the reader, where
// each leaf is 'segmentSize' long and 'h' is used as the hashing function. All
// leaves will be 'segmentSize' bytes except the last leaf, which will not be
// padded out if there are not enough bytes remaining in the reader.
func
ReaderRoot
(
r
io
.
Reader
,
h
hash
.
Hash
,
segmentSize
int
)
(
root
[]
byte
,
err
error
)
{
tree
:=
New
(
h
)
err
=
tree
.
ReadAll
(
r
,
segmentSize
)
if
err
!=
nil
{
return
}
root
=
tree
.
Root
()
return
}
// BuildReaderProof returns a proof that certain data is in the merkle tree
// created by the data in the reader. The merkle root, set of proofs, and the
// number of leaves in the Merkle tree are all returned. All leaves will we
// 'segmentSize' bytes except the last leaf, which will not be padded out if
// there are not enough bytes remaining in the reader.
func
BuildReaderProof
(
r
io
.
Reader
,
h
hash
.
Hash
,
segmentSize
int
,
index
uint64
)
(
root
[]
byte
,
proofSet
[][]
byte
,
numLeaves
uint64
,
err
error
)
{
tree
:=
New
(
h
)
err
=
tree
.
SetIndex
(
index
)
if
err
!=
nil
{
// This code should be unreachable - SetIndex will only return an error
// if the tree is not empty, and yet the tree should be empty at this
// point.
panic
(
err
)
}
err
=
tree
.
ReadAll
(
r
,
segmentSize
)
if
err
!=
nil
{
return
}
root
,
proofSet
,
_
,
numLeaves
=
tree
.
Prove
()
if
len
(
proofSet
)
==
0
{
err
=
errors
.
New
(
"index was not reached while creating proof"
)
return
}
return
}
plugin/dapp/mix/executor/merkletree/tree.go
0 → 100644
View file @
9ff24cd5
// from https://gitlab.com/NebulousLabs/merkletree
package
merkletree
import
(
"encoding/hex"
"errors"
"fmt"
"hash"
)
// A Tree takes data as leaves and returns the Merkle root. Each call to 'Push'
// adds one leaf to the Merkle tree. Calling 'Root' returns the Merkle root.
// The Tree also constructs proof that a single leaf is a part of the tree. The
// leaf can be chosen with 'SetIndex'. The memory footprint of Tree grows in
// O(log(n)) in the number of leaves.
type
Tree
struct
{
// The Tree is stored as a stack of subtrees. Each subtree has a height,
// and is the Merkle root of 2^height leaves. A Tree with 11 nodes is
// represented as a subtree of height 3 (8 nodes), a subtree of height 1 (2
// nodes), and a subtree of height 0 (1 node). Head points to the smallest
// tree. When a new leaf is inserted, it is inserted as a subtree of height
// 0. If there is another subtree of the same height, both can be removed,
// combined, and then inserted as a subtree of height n + 1.
head
*
subTree
hash
hash
.
Hash
// Helper variables used to construct proofs that the data at 'proofIndex'
// is in the Merkle tree. The proofSet is constructed as elements are being
// added to the tree. The first element of the proof set is the original
// data used to create the leaf at index 'proofIndex'. proofTree indicates
// if the tree will be used to create a merkle proof.
currentIndex
uint64
proofIndex
uint64
proofSet
[][]
byte
proofTree
bool
// The cachedTree flag indicates that the tree is cached, meaning that
// different code is used in 'Push' for creating a new head subtree. Adding
// this flag is somewhat gross, but eliminates needing to duplicate the
// entire 'Push' function when writing the cached tree.
cachedTree
bool
}
// A subTree contains the Merkle root of a complete (2^height leaves) subTree
// of the Tree. 'sum' is the Merkle root of the subTree. If 'next' is not nil,
// it will be a tree with a higher height.
type
subTree
struct
{
next
*
subTree
height
int
// Int is okay because a height over 300 is physically unachievable.
sum
[]
byte
}
// sum returns the hash of the input data using the specified algorithm.
func
sum
(
h
hash
.
Hash
,
data
...
[]
byte
)
[]
byte
{
h
.
Reset
()
for
_
,
d
:=
range
data
{
// the Hash interface specifies that Write never returns an error
_
,
_
=
h
.
Write
(
d
)
}
return
h
.
Sum
(
nil
)
}
// leafSum returns the hash created from data inserted to form a leaf. Leaf
// sums are calculated using:
// Hash(0x00 || data)
func
leafSum
(
h
hash
.
Hash
,
data
[]
byte
)
[]
byte
{
//return sum(h, leafHashPrefix, data)
return
sum
(
h
,
data
)
}
// nodeSum returns the hash created from two sibling nodes being combined into
// a parent node. Node sums are calculated using:
// Hash(0x01 || left sibling sum || right sibling sum)
func
nodeSum
(
h
hash
.
Hash
,
a
,
b
[]
byte
)
[]
byte
{
//return sum(h, nodeHashPrefix, a, b)
return
sum
(
h
,
a
,
b
)
}
// joinSubTrees combines two equal sized subTrees into a larger subTree.
func
joinSubTrees
(
h
hash
.
Hash
,
a
,
b
*
subTree
)
*
subTree
{
// if DEBUG {
// if b.next != a {
// panic("invalid subtree join - 'a' is not paired with 'b'")
// }
// if a.height < b.height {
// panic("invalid subtree presented - height mismatch")
// }
// }
return
&
subTree
{
next
:
a
.
next
,
height
:
a
.
height
+
1
,
sum
:
nodeSum
(
h
,
a
.
sum
,
b
.
sum
),
}
}
// New creates a new Tree. The provided hash will be used for all hashing
// operations within the Tree.
func
New
(
h
hash
.
Hash
)
*
Tree
{
return
&
Tree
{
hash
:
h
,
}
}
// Prove creates a proof that the leaf at the established index (established by
// SetIndex) is an element of the Merkle tree. Prove will return a nil proof
// set if used incorrectly. Prove does not modify the Tree. Prove can only be
// called if SetIndex has been called previously.
func
(
t
*
Tree
)
Prove
()
(
merkleRoot
[]
byte
,
proofSet
[][]
byte
,
proofIndex
uint64
,
numLeaves
uint64
)
{
if
!
t
.
proofTree
{
panic
(
"wrong usage: can't call prove on a tree if SetIndex wasn't called"
)
}
// Return nil if the Tree is empty, or if the proofIndex hasn't yet been
// reached.
if
t
.
head
==
nil
||
len
(
t
.
proofSet
)
==
0
{
return
t
.
Root
(),
nil
,
t
.
proofIndex
,
t
.
currentIndex
}
proofSet
=
t
.
proofSet
// The set of subtrees must now be collapsed into a single root. The proof
// set already contains all of the elements that are members of a complete
// subtree. Of what remains, there will be at most 1 element provided from
// a sibling on the right, and all of the other proofs will be provided
// from a sibling on the left. This results from the way orphans are
// treated. All subtrees smaller than the subtree containing the proofIndex
// will be combined into a single subtree that gets combined with the
// proofIndex subtree as a single right sibling. All subtrees larger than
// the subtree containing the proofIndex will be combined with the subtree
// containing the proof index as left siblings.
// Start at the smallest subtree and combine it with larger subtrees until
// it would be combining with the subtree that contains the proof index. We
// can recognize the subtree containing the proof index because the height
// of that subtree will be one less than the current length of the proof
// set.
current
:=
t
.
head
for
current
.
next
!=
nil
&&
current
.
next
.
height
<
len
(
proofSet
)
-
1
{
current
=
joinSubTrees
(
t
.
hash
,
current
.
next
,
current
)
}
// Sanity check - check that either 'current' or 'current.next' is the
// subtree containing the proof index.
// if DEBUG {
// if current.height != len(t.proofSet)-1 && (current.next != nil && current.next.height != len(t.proofSet)-1) {
// panic("could not find the subtree containing the proof index")
// }
// }
// If the current subtree is not the subtree containing the proof index,
// then it must be an aggregate subtree that is to the right of the subtree
// containing the proof index, and the next subtree is the subtree
// containing the proof index.
if
current
.
next
!=
nil
&&
current
.
next
.
height
==
len
(
proofSet
)
-
1
{
proofSet
=
append
(
proofSet
,
current
.
sum
)
current
=
current
.
next
}
// The current subtree must be the subtree containing the proof index. This
// subtree does not need an entry, as the entry was created during the
// construction of the Tree. Instead, skip to the next subtree.
current
=
current
.
next
// All remaining subtrees will be added to the proof set as a left sibling,
// completing the proof set.
for
current
!=
nil
{
proofSet
=
append
(
proofSet
,
current
.
sum
)
current
=
current
.
next
}
return
t
.
Root
(),
proofSet
,
t
.
proofIndex
,
t
.
currentIndex
}
// Push will add data to the set, building out the Merkle tree and Root. The
// tree does not remember all elements that are added, instead only keeping the
// log(n) elements that are necessary to build the Merkle root and keeping the
// log(n) elements necessary to build a proof that a piece of data is in the
// Merkle tree.
func
(
t
*
Tree
)
Push
(
data
[]
byte
)
{
// The first element of a proof is the data at the proof index. If this
// data is being inserted at the proof index, it is added to the proof set.
if
t
.
currentIndex
==
t
.
proofIndex
{
t
.
proofSet
=
append
(
t
.
proofSet
,
data
)
}
// Hash the data to create a subtree of height 0. The sum of the new node
// is going to be the data for cached trees, and is going to be the result
// of calling leafSum() on the data for standard trees. Doing a check here
// prevents needing to duplicate the entire 'Push' function for the trees.
t
.
head
=
&
subTree
{
next
:
t
.
head
,
height
:
0
,
}
if
t
.
cachedTree
{
t
.
head
.
sum
=
data
}
else
{
t
.
head
.
sum
=
leafSum
(
t
.
hash
,
data
)
fmt
.
Println
(
"leaf hash"
,
hex
.
EncodeToString
(
t
.
head
.
sum
))
}
// Join subTrees if possible.
t
.
joinAllSubTrees
()
// Update the index.
t
.
currentIndex
++
// Sanity check - From head to tail of the stack, the height should be
// strictly increasing.
// if DEBUG {
// current := t.head
// height := current.height
// for current.next != nil {
// current = current.next
// if current.height <= height {
// panic("subtrees are out of order")
// }
// height = current.height
// }
// }
}
// PushSubTree pushes a cached subtree into the merkle tree. The subtree has to
// be smaller than the smallest subtree in the merkle tree, it has to be
// balanced and it can't contain the element that needs to be proven. Since we
// can't tell if a subTree is balanced, we can't sanity check for unbalanced
// trees. Therefore an unbalanced tree will cause silent errors, pain and
// misery for the person who wants to debug the resulting error.
func
(
t
*
Tree
)
PushSubTree
(
height
int
,
sum
[]
byte
)
error
{
// Check if the cached tree that is pushed contains the element at
// proofIndex. This is not allowed.
newIndex
:=
t
.
currentIndex
+
1
<<
uint64
(
height
)
if
t
.
proofTree
&&
(
t
.
currentIndex
==
t
.
proofIndex
||
(
t
.
currentIndex
<
t
.
proofIndex
&&
t
.
proofIndex
<
newIndex
))
{
return
errors
.
New
(
"the cached tree shouldn't contain the element to prove"
)
}
// We can only add the cached tree if its depth is <= the depth of the
// current subtree.
if
t
.
head
!=
nil
&&
height
>
t
.
head
.
height
{
return
fmt
.
Errorf
(
"can't add a subtree that is larger than the smallest subtree %v > %v"
,
height
,
t
.
head
.
height
)
}
// Insert the cached tree as the new head.
t
.
head
=
&
subTree
{
height
:
height
,
next
:
t
.
head
,
sum
:
sum
,
}
// Join subTrees if possible.
t
.
joinAllSubTrees
()
// Update the index.
t
.
currentIndex
=
newIndex
// Sanity check - From head to tail of the stack, the height should be
// strictly increasing.
// if DEBUG {
// current := t.head
// height := current.height
// for current.next != nil {
// current = current.next
// if current.height <= height {
// panic("subtrees are out of order")
// }
// height = current.height
// }
// }
return
nil
}
// Root returns the Merkle root of the data that has been pushed.
func
(
t
*
Tree
)
Root
()
[]
byte
{
// If the Tree is empty, return nil.
if
t
.
head
==
nil
{
return
nil
}
// The root is formed by hashing together subTrees in order from least in
// height to greatest in height. The taller subtree is the first subtree in
// the join.
current
:=
t
.
head
for
current
.
next
!=
nil
{
current
=
joinSubTrees
(
t
.
hash
,
current
.
next
,
current
)
}
// Return a copy to prevent leaking a pointer to internal data.
return
append
(
current
.
sum
[
:
0
:
0
],
current
.
sum
...
)
}
// SetIndex will tell the Tree to create a storage proof for the leaf at the
// input index. SetIndex must be called on an empty tree.
func
(
t
*
Tree
)
SetIndex
(
i
uint64
)
error
{
if
t
.
head
!=
nil
{
return
errors
.
New
(
"cannot call SetIndex on Tree if Tree has not been reset"
)
}
t
.
proofTree
=
true
t
.
proofIndex
=
i
return
nil
}
// joinAllSubTrees inserts the subTree at t.head into the Tree. As long as the
// height of the next subTree is the same as the height of the current subTree,
// the two will be combined into a single subTree of height n+1.
func
(
t
*
Tree
)
joinAllSubTrees
()
{
for
t
.
head
.
next
!=
nil
&&
t
.
head
.
height
==
t
.
head
.
next
.
height
{
// Before combining subtrees, check whether one of the subtree hashes
// needs to be added to the proof set. This is going to be true IFF the
// subtrees being combined are one height higher than the previous
// subtree added to the proof set. The height of the previous subtree
// added to the proof set is equal to len(t.proofSet) - 1.
if
t
.
head
.
height
==
len
(
t
.
proofSet
)
-
1
{
// One of the subtrees needs to be added to the proof set. The
// subtree that needs to be added is the subtree that does not
// contain the proofIndex. Because the subtrees being compared are
// the smallest and rightmost trees in the Tree, this can be
// determined by rounding the currentIndex down to the number of
// nodes in the subtree and comparing that index to the proofIndex.
leaves
:=
uint64
(
1
<<
uint
(
t
.
head
.
height
))
mid
:=
(
t
.
currentIndex
/
leaves
)
*
leaves
if
t
.
proofIndex
<
mid
{
t
.
proofSet
=
append
(
t
.
proofSet
,
t
.
head
.
sum
)
}
else
{
t
.
proofSet
=
append
(
t
.
proofSet
,
t
.
head
.
next
.
sum
)
}
// Sanity check - the proofIndex should never be less than the
// midpoint minus the number of leaves in each subtree.
// if DEBUG {
// if t.proofIndex < mid-leaves {
// panic("proof being added with weird values")
// }
// }
}
// Join the two subTrees into one subTree with a greater height. Then
// compare the new subTree to the next subTree.
t
.
head
=
joinSubTrees
(
t
.
hash
,
t
.
head
.
next
,
t
.
head
)
}
}
plugin/dapp/mix/executor/merkletree/verify.go
0 → 100644
View file @
9ff24cd5
// from https://gitlab.com/NebulousLabs/merkletree
package
merkletree
import
(
"bytes"
"hash"
)
// VerifyProof takes a Merkle root, a proofSet, and a proofIndex and returns
// true if the first element of the proof set is a leaf of data in the Merkle
// root. False is returned if the proof set or Merkle root is nil, and if
// 'numLeaves' equals 0.
func
VerifyProof
(
h
hash
.
Hash
,
merkleRoot
[]
byte
,
proofSet
[][]
byte
,
proofIndex
uint64
,
numLeaves
uint64
)
bool
{
// Return false for nonsense input. A switch statement is used so that the
// cover tool will reveal if a case is not covered by the test suite. This
// would not be possible using a single if statement due to the limitations
// of the cover tool.
if
merkleRoot
==
nil
{
return
false
}
if
proofIndex
>=
numLeaves
{
return
false
}
// In a Merkle tree, every node except the root node has a sibling.
// Combining the two siblings in the correct order will create the parent
// node. Each of the remaining hashes in the proof set is a sibling to a
// node that can be built from all of the previous elements of the proof
// set. The next node is built by taking:
//
// H(0x01 || sibling A || sibling B)
//
// The difficulty of the algorithm lies in determining whether the supplied
// hash is sibling A or sibling B. This information can be determined by
// using the proof index and the total number of leaves in the tree.
//
// A pair of two siblings forms a subtree. The subtree is complete if it
// has 1 << height total leaves. When the subtree is complete, the position
// of the proof index within the subtree can be determined by looking at
// the bounds of the subtree and determining if the proof index is in the
// first or second half of the subtree.
//
// When the subtree is not complete, either 1 or 0 of the remaining hashes
// will be sibling B. All remaining hashes after that will be sibling A.
// This is true because of the way that orphans are merged into the Merkle
// tree - an orphan at height n is elevated to height n + 1, and only
// hashed when it is no longer an orphan. Each subtree will therefore merge
// with at most 1 orphan to the right before becoming an orphan itself.
// Orphan nodes are always merged with larger subtrees to the left.
//
// One vulnerability with the proof verification is that the proofSet may
// not be long enough. Before looking at an element of proofSet, a check
// needs to be made that the element exists.
// The first element of the set is the original data. A sibling at height 1
// is created by getting the leafSum of the original data.
height
:=
0
if
len
(
proofSet
)
<=
height
{
return
false
}
sum
:=
leafSum
(
h
,
proofSet
[
height
])
height
++
// While the current subtree (of height 'height') is complete, determine
// the position of the next sibling using the complete subtree algorithm.
// 'stableEnd' tells us the ending index of the last full subtree. It gets
// initialized to 'proofIndex' because the first full subtree was the
// subtree of height 1, created above (and had an ending index of
// 'proofIndex').
stableEnd
:=
proofIndex
for
{
// Determine if the subtree is complete. This is accomplished by
// rounding down the proofIndex to the nearest 1 << 'height', adding 1
// << 'height', and comparing the result to the number of leaves in the
// Merkle tree.
subTreeStartIndex
:=
(
proofIndex
/
(
1
<<
uint
(
height
)))
*
(
1
<<
uint
(
height
))
// round down to the nearest 1 << height
subTreeEndIndex
:=
subTreeStartIndex
+
(
1
<<
(
uint
(
height
)))
-
1
// subtract 1 because the start index is inclusive
if
subTreeEndIndex
>=
numLeaves
{
// If the Merkle tree does not have a leaf at index
// 'subTreeEndIndex', then the subtree of the current height is not
// a complete subtree.
break
}
stableEnd
=
subTreeEndIndex
// Determine if the proofIndex is in the first or the second half of
// the subtree.
if
len
(
proofSet
)
<=
height
{
return
false
}
if
proofIndex
-
subTreeStartIndex
<
1
<<
uint
(
height
-
1
)
{
sum
=
nodeSum
(
h
,
sum
,
proofSet
[
height
])
}
else
{
sum
=
nodeSum
(
h
,
proofSet
[
height
],
sum
)
}
height
++
}
// Determine if the next hash belongs to an orphan that was elevated. This
// is the case IFF 'stableEnd' (the last index of the largest full subtree)
// is equal to the number of leaves in the Merkle tree.
if
stableEnd
!=
numLeaves
-
1
{
if
len
(
proofSet
)
<=
height
{
return
false
}
sum
=
nodeSum
(
h
,
sum
,
proofSet
[
height
])
height
++
}
// All remaining elements in the proof set will belong to a left sibling.
for
height
<
len
(
proofSet
)
{
sum
=
nodeSum
(
h
,
proofSet
[
height
],
sum
)
height
++
}
// Compare our calculated Merkle root to the desired Merkle root.
if
bytes
.
Equal
(
sum
,
merkleRoot
)
{
return
true
}
return
false
}
// GenerateProofHelper generates an array of 1 or 0 telling if during the proof verification
// the hash to compute is h(sum, proof[i]) or h(proof[i], sum). The size of the resulting slice is
// len(proofSet)-1.
// cf gitlab.com/NebulousLabs/merkletree for the algorithm
func
GenerateProofHelper
(
proofSet
[][]
byte
,
proofIndex
,
numLeaves
uint64
)
[]
int
{
res
:=
make
([]
int
,
len
(
proofSet
)
-
1
)
height
:=
1
// While the current subtree (of height 'height') is complete, determine
// the position of the next sibling using the complete subtree algorithm.
// 'stableEnd' tells us the ending index of the last full subtree. It gets
// initialized to 'proofIndex' because the first full subtree was the
// subtree of height 1, created above (and had an ending index of
// 'proofIndex').
stableEnd
:=
proofIndex
for
{
// Determine if the subtree is complete. This is accomplished by
// rounding down the proofIndex to the nearest 1 << 'height', adding 1
// << 'height', and comparing the result to the number of leaves in the
// Merkle tree.
subTreeStartIndex
:=
(
proofIndex
/
(
1
<<
uint
(
height
)))
*
(
1
<<
uint
(
height
))
// round down to the nearest 1 << height
subTreeEndIndex
:=
subTreeStartIndex
+
(
1
<<
(
uint
(
height
)))
-
1
// subtract 1 because the start index is inclusive
if
subTreeEndIndex
>=
numLeaves
{
// If the Merkle tree does not have a leaf at index
// 'subTreeEndIndex', then the subtree of the current height is not
// a complete subtree.
break
}
stableEnd
=
subTreeEndIndex
if
proofIndex
-
subTreeStartIndex
<
1
<<
uint
(
height
-
1
)
{
res
[
height
-
1
]
=
1
}
else
{
res
[
height
-
1
]
=
0
}
height
++
}
// Determine if the next hash belongs to an orphan that was elevated. This
// is the case IFF 'stableEnd' (the last index of the largest full subtree)
// is equal to the number of leaves in the Merkle tree.
if
stableEnd
!=
numLeaves
-
1
{
res
[
height
-
1
]
=
1
height
++
}
// All remaining elements in the proof set will belong to a left sibling.
for
height
<
len
(
proofSet
)
{
res
[
height
-
1
]
=
0
height
++
}
return
res
}
plugin/dapp/mix/executor/mix.go
View file @
9ff24cd5
...
@@ -5,8 +5,6 @@
...
@@ -5,8 +5,6 @@
package
executor
package
executor
import
(
import
(
pt
"github.com/33cn/plugin/plugin/dapp/paracross/types"
log
"github.com/33cn/chain33/common/log/log15"
log
"github.com/33cn/chain33/common/log/log15"
drivers
"github.com/33cn/chain33/system/dapp"
drivers
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
...
@@ -49,6 +47,6 @@ func newMix() drivers.Driver {
...
@@ -49,6 +47,6 @@ func newMix() drivers.Driver {
}
}
// GetDriverName return paracross driver name
// GetDriverName return paracross driver name
func
(
c
*
Mix
)
GetDriverName
()
string
{
func
(
m
*
Mix
)
GetDriverName
()
string
{
return
pt
.
Para
X
return
mixTy
.
Mix
X
}
}
plugin/dapp/mix/executor/query.go
0 → 100644
View file @
9ff24cd5
// 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
executor
import
(
"github.com/33cn/chain33/types"
mixTy
"github.com/33cn/plugin/plugin/dapp/mix/types"
)
// Query_GetTitle query paracross title
func
(
m
*
Mix
)
Query_GetTreePath
(
in
*
mixTy
.
TreePathReq
)
(
types
.
Message
,
error
)
{
if
in
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
return
CalcTreeProve
(
m
.
GetStateDB
(),
in
.
RootHash
,
in
.
LeafHash
)
}
plugin/dapp/mix/executor/transfer.go
View file @
9ff24cd5
...
@@ -31,7 +31,7 @@ func (a *action) transferInputVerify(proof *mixTy.ZkProofInfo) (*mixTy.TransferI
...
@@ -31,7 +31,7 @@ func (a *action) transferInputVerify(proof *mixTy.ZkProofInfo) (*mixTy.TransferI
return
nil
,
errors
.
Wrapf
(
err
,
"unmarshal string=%s"
,
proof
.
PublicInput
)
return
nil
,
errors
.
Wrapf
(
err
,
"unmarshal string=%s"
,
proof
.
PublicInput
)
}
}
err
=
a
.
spendVerify
(
input
.
TreeRootHash
,
input
.
NullifierHash
,
input
.
AuthorizeHash
)
err
=
a
.
spendVerify
(
input
.
TreeRootHash
,
input
.
NullifierHash
,
input
.
Authorize
Spend
Hash
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -138,7 +138,7 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er
...
@@ -138,7 +138,7 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er
//push new commit to merkle tree
//push new commit to merkle tree
for
_
,
h
:=
range
outputs
{
for
_
,
h
:=
range
outputs
{
rpt
,
err
:=
pushTree
(
a
.
db
,
h
.
NodeHash
)
rpt
,
err
:=
pushTree
(
a
.
db
,
transferFr2Bytes
(
h
.
NodeHash
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
plugin/dapp/mix/executor/withdraw.go
View file @
9ff24cd5
...
@@ -9,37 +9,35 @@ import (
...
@@ -9,37 +9,35 @@ import (
"encoding/json"
"encoding/json"
"strconv"
"strconv"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/address"
"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/pkg/errors"
"github.com/pkg/errors"
)
)
func
(
a
*
action
)
spendVerify
(
treeRootHash
,
nulliferHash
,
authorize
Hash
[]
byte
)
error
{
func
(
a
*
action
)
spendVerify
(
treeRootHash
,
nulliferHash
,
authorize
SpendHash
string
)
error
{
//zk-proof校验
//zk-proof校验
//check tree rootHash exist
//check tree rootHash exist
if
!
checkTreeRootHashExist
(
a
.
db
,
tr
eeRootHash
)
{
if
!
checkTreeRootHashExist
(
a
.
db
,
tr
ansferFr2Bytes
(
treeRootHash
)
)
{
return
errors
.
Wrapf
(
mixTy
.
ErrTreeRootHashNotFound
,
"roothash=%s"
,
common
.
ToHex
(
treeRootHash
)
)
return
errors
.
Wrapf
(
mixTy
.
ErrTreeRootHashNotFound
,
"roothash=%s"
,
treeRootHash
)
}
}
//nullifier should not exist
//nullifier should not exist
nullifierKey
:=
calcNullifierHashKey
(
common
.
ToHex
(
nulliferHash
)
)
nullifierKey
:=
calcNullifierHashKey
(
nulliferHash
)
_
,
err
:=
a
.
db
.
Get
(
nullifierKey
)
_
,
err
:=
a
.
db
.
Get
(
nullifierKey
)
if
err
==
nil
{
if
err
==
nil
{
return
errors
.
Wrapf
(
mixTy
.
ErrNulliferHashExist
,
"nullifier=%s"
,
common
.
ToHex
(
nulliferHash
)
)
return
errors
.
Wrapf
(
mixTy
.
ErrNulliferHashExist
,
"nullifier=%s"
,
nulliferHash
)
}
}
if
!
isNotFound
(
err
)
{
if
!
isNotFound
(
err
)
{
return
errors
.
Wrapf
(
err
,
"nullifier=%s"
,
common
.
ToHex
(
nulliferHash
)
)
return
errors
.
Wrapf
(
err
,
"nullifier=%s"
,
nulliferHash
)
}
}
// authorize should exist if needed
// authorize should exist if needed
if
len
(
authorizeHash
)
>
0
{
if
len
(
authorize
Spend
Hash
)
>
0
{
authKey
:=
calcAuthorizeHashKey
(
common
.
ToHex
(
authorizeHash
)
)
authKey
:=
calcAuthorizeHashKey
(
authorizeSpendHash
)
_
,
err
=
a
.
db
.
Get
(
authKey
)
_
,
err
=
a
.
db
.
Get
(
authKey
)
if
err
!=
nil
{
if
err
!=
nil
{
return
errors
.
Wrapf
(
err
,
"authorize=%s"
,
common
.
ToHex
(
authorizeHash
)
)
return
errors
.
Wrapf
(
err
,
"authorize=%s"
,
authorizeSpendHash
)
}
}
}
}
...
@@ -47,29 +45,29 @@ func (a *action) spendVerify(treeRootHash, nulliferHash, authorizeHash []byte) e
...
@@ -47,29 +45,29 @@ func (a *action) spendVerify(treeRootHash, nulliferHash, authorizeHash []byte) e
}
}
func
(
a
*
action
)
withdrawVerify
(
proof
*
mixTy
.
ZkProofInfo
)
(
[]
byte
,
uint64
,
error
)
{
func
(
a
*
action
)
withdrawVerify
(
proof
*
mixTy
.
ZkProofInfo
)
(
string
,
uint64
,
error
)
{
var
input
mixTy
.
WithdrawPublicInput
var
input
mixTy
.
WithdrawPublicInput
data
,
err
:=
hex
.
DecodeString
(
proof
.
PublicInput
)
data
,
err
:=
hex
.
DecodeString
(
proof
.
PublicInput
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
0
,
errors
.
Wrapf
(
err
,
"decode string=%s"
,
proof
.
PublicInput
)
return
""
,
0
,
errors
.
Wrapf
(
err
,
"decode string=%s"
,
proof
.
PublicInput
)
}
}
err
=
json
.
Unmarshal
(
data
,
&
input
)
err
=
json
.
Unmarshal
(
data
,
&
input
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
0
,
errors
.
Wrapf
(
err
,
"unmarshal string=%s"
,
proof
.
PublicInput
)
return
""
,
0
,
errors
.
Wrapf
(
err
,
"unmarshal string=%s"
,
proof
.
PublicInput
)
}
}
val
,
err
:=
strconv
.
ParseUint
(
input
.
Amount
,
10
,
64
)
val
,
err
:=
strconv
.
ParseUint
(
input
.
Amount
,
10
,
64
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
0
,
errors
.
Wrapf
(
err
,
"parseUint=%s"
,
input
.
Amount
)
return
""
,
0
,
errors
.
Wrapf
(
err
,
"parseUint=%s"
,
input
.
Amount
)
}
}
err
=
a
.
spendVerify
(
input
.
TreeRootHash
,
input
.
NullifierHash
,
input
.
AuthorizeHash
)
err
=
a
.
spendVerify
(
input
.
TreeRootHash
,
input
.
NullifierHash
,
input
.
Authorize
Spend
Hash
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
0
,
err
return
""
,
0
,
err
}
}
err
=
a
.
zkProofVerify
(
proof
,
mixTy
.
VerifyType_WITHDRAW
)
err
=
a
.
zkProofVerify
(
proof
,
mixTy
.
VerifyType_WITHDRAW
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
0
,
err
return
""
,
0
,
err
}
}
return
input
.
NullifierHash
,
val
,
nil
return
input
.
NullifierHash
,
val
,
nil
...
@@ -82,7 +80,7 @@ func (a *action) withdrawVerify(proof *mixTy.ZkProofInfo) ([]byte, uint64, error
...
@@ -82,7 +80,7 @@ func (a *action) withdrawVerify(proof *mixTy.ZkProofInfo) ([]byte, uint64, error
3. set nullifier exist
3. set nullifier exist
*/
*/
func
(
a
*
action
)
Withdraw
(
withdraw
*
mixTy
.
MixWithdrawAction
)
(
*
types
.
Receipt
,
error
)
{
func
(
a
*
action
)
Withdraw
(
withdraw
*
mixTy
.
MixWithdrawAction
)
(
*
types
.
Receipt
,
error
)
{
var
nulliferSet
[]
[]
byte
var
nulliferSet
[]
string
var
sumValue
uint64
var
sumValue
uint64
for
_
,
k
:=
range
withdraw
.
SpendCommits
{
for
_
,
k
:=
range
withdraw
.
SpendCommits
{
nulfier
,
v
,
err
:=
a
.
withdrawVerify
(
k
)
nulfier
,
v
,
err
:=
a
.
withdrawVerify
(
k
)
...
...
plugin/dapp/mix/proto/mix.proto
View file @
9ff24cd5
...
@@ -102,39 +102,39 @@ message MixAction {
...
@@ -102,39 +102,39 @@ message MixAction {
message
DepositPublicInput
{
message
DepositPublicInput
{
bytes
nodeHash
=
1
;
string
nodeHash
=
1
;
string
amount
=
2
;
string
amount
=
2
;
}
}
message
WithdrawPublicInput
{
message
WithdrawPublicInput
{
bytes
treeRootHash
=
1
;
string
treeRootHash
=
1
;
bytes
nullifierHash
=
2
;
string
nullifierHash
=
2
;
bytes
authorize
Hash
=
3
;
string
authorizeSpend
Hash
=
3
;
string
amount
=
4
;
string
amount
=
4
;
}
}
message
TransferInputPublicInput
{
message
TransferInputPublicInput
{
bytes
treeRootHash
=
1
;
string
treeRootHash
=
1
;
string
commitValueX
=
2
;
string
commitValueX
=
2
;
string
commitValueY
=
3
;
string
commitValueY
=
3
;
bytes
authorize
Hash
=
4
;
string
authorizeSpend
Hash
=
4
;
bytes
nullifierHash
=
5
;
string
nullifierHash
=
5
;
}
}
message
TransferOutputPublicInput
{
message
TransferOutputPublicInput
{
bytes
nodeHash
=
1
;
string
nodeHash
=
1
;
string
commitValueX
=
2
;
string
commitValueX
=
2
;
string
commitValueY
=
3
;
string
commitValueY
=
3
;
}
}
message
AuthorizePublicInput
{
message
AuthorizePublicInput
{
bytes
treeRootHash
=
1
;
string
treeRootHash
=
1
;
string
authorizePubKey
=
2
;
string
authorizePubKey
=
2
;
bytes
authorizeHash
=
3
;
string
authorizeHash
=
3
;
bytes
authorizeSpendHash
=
4
;
string
authorizeSpendHash
=
4
;
}
}
...
@@ -156,9 +156,13 @@ message CommitTreeProve {
...
@@ -156,9 +156,13 @@ message CommitTreeProve {
repeated
string
proofSet
=
2
;
repeated
string
proofSet
=
2
;
uint32
proofIndex
=
3
;
uint32
proofIndex
=
3
;
uint32
numLeaves
=
4
;
uint32
numLeaves
=
4
;
string
helpers
=
5
;
}
}
message
TreePathReq
{
string
rootHash
=
1
;
string
leafHash
=
2
;
}
...
...
plugin/dapp/mix/types/mix.pb.go
View file @
9ff24cd5
...
@@ -5,9 +5,8 @@ package types
...
@@ -5,9 +5,8 @@ package types
import
(
import
(
fmt
"fmt"
fmt
"fmt"
math
"math"
proto
"github.com/golang/protobuf/proto"
proto
"github.com/golang/protobuf/proto"
math
"math"
)
)
// Reference imports to suppress errors if they are not otherwise used.
// Reference imports to suppress errors if they are not otherwise used.
...
@@ -768,7 +767,7 @@ func (*MixAction) XXX_OneofWrappers() []interface{} {
...
@@ -768,7 +767,7 @@ func (*MixAction) XXX_OneofWrappers() []interface{} {
}
}
type
DepositPublicInput
struct
{
type
DepositPublicInput
struct
{
NodeHash
[]
byte
`protobuf:"bytes,1,opt,name=nodeHash,proto3" json:"nodeHash,omitempty"`
NodeHash
string
`protobuf:"bytes,1,opt,name=nodeHash,proto3" json:"nodeHash,omitempty"`
Amount
string
`protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"`
Amount
string
`protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
...
@@ -800,11 +799,11 @@ func (m *DepositPublicInput) XXX_DiscardUnknown() {
...
@@ -800,11 +799,11 @@ func (m *DepositPublicInput) XXX_DiscardUnknown() {
var
xxx_messageInfo_DepositPublicInput
proto
.
InternalMessageInfo
var
xxx_messageInfo_DepositPublicInput
proto
.
InternalMessageInfo
func
(
m
*
DepositPublicInput
)
GetNodeHash
()
[]
byte
{
func
(
m
*
DepositPublicInput
)
GetNodeHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
NodeHash
return
m
.
NodeHash
}
}
return
nil
return
""
}
}
func
(
m
*
DepositPublicInput
)
GetAmount
()
string
{
func
(
m
*
DepositPublicInput
)
GetAmount
()
string
{
...
@@ -815,9 +814,9 @@ func (m *DepositPublicInput) GetAmount() string {
...
@@ -815,9 +814,9 @@ func (m *DepositPublicInput) GetAmount() string {
}
}
type
WithdrawPublicInput
struct
{
type
WithdrawPublicInput
struct
{
TreeRootHash
[]
byte
`protobuf:"bytes,1,opt,name=treeRootHash,proto3" json:"treeRootHash,omitempty"`
TreeRootHash
string
`protobuf:"bytes,1,opt,name=treeRootHash,proto3" json:"treeRootHash,omitempty"`
NullifierHash
[]
byte
`protobuf:"bytes,2,opt,name=nullifierHash,proto3" json:"nullifierHash,omitempty"`
NullifierHash
string
`protobuf:"bytes,2,opt,name=nullifierHash,proto3" json:"nullifierHash,omitempty"`
Authorize
Hash
[]
byte
`protobuf:"bytes,3,opt,name=authorizeHash,proto3" json:"authorize
Hash,omitempty"`
Authorize
SpendHash
string
`protobuf:"bytes,3,opt,name=authorizeSpendHash,proto3" json:"authorizeSpend
Hash,omitempty"`
Amount
string
`protobuf:"bytes,4,opt,name=amount,proto3" json:"amount,omitempty"`
Amount
string
`protobuf:"bytes,4,opt,name=amount,proto3" json:"amount,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
...
@@ -849,25 +848,25 @@ func (m *WithdrawPublicInput) XXX_DiscardUnknown() {
...
@@ -849,25 +848,25 @@ func (m *WithdrawPublicInput) XXX_DiscardUnknown() {
var
xxx_messageInfo_WithdrawPublicInput
proto
.
InternalMessageInfo
var
xxx_messageInfo_WithdrawPublicInput
proto
.
InternalMessageInfo
func
(
m
*
WithdrawPublicInput
)
GetTreeRootHash
()
[]
byte
{
func
(
m
*
WithdrawPublicInput
)
GetTreeRootHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
TreeRootHash
return
m
.
TreeRootHash
}
}
return
nil
return
""
}
}
func
(
m
*
WithdrawPublicInput
)
GetNullifierHash
()
[]
byte
{
func
(
m
*
WithdrawPublicInput
)
GetNullifierHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
NullifierHash
return
m
.
NullifierHash
}
}
return
nil
return
""
}
}
func
(
m
*
WithdrawPublicInput
)
GetAuthorize
Hash
()
[]
byte
{
func
(
m
*
WithdrawPublicInput
)
GetAuthorize
SpendHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
AuthorizeHash
return
m
.
Authorize
Spend
Hash
}
}
return
nil
return
""
}
}
func
(
m
*
WithdrawPublicInput
)
GetAmount
()
string
{
func
(
m
*
WithdrawPublicInput
)
GetAmount
()
string
{
...
@@ -878,11 +877,11 @@ func (m *WithdrawPublicInput) GetAmount() string {
...
@@ -878,11 +877,11 @@ func (m *WithdrawPublicInput) GetAmount() string {
}
}
type
TransferInputPublicInput
struct
{
type
TransferInputPublicInput
struct
{
TreeRootHash
[]
byte
`protobuf:"bytes,1,opt,name=treeRootHash,proto3" json:"treeRootHash,omitempty"`
TreeRootHash
string
`protobuf:"bytes,1,opt,name=treeRootHash,proto3" json:"treeRootHash,omitempty"`
CommitValueX
string
`protobuf:"bytes,2,opt,name=commitValueX,proto3" json:"commitValueX,omitempty"`
CommitValueX
string
`protobuf:"bytes,2,opt,name=commitValueX,proto3" json:"commitValueX,omitempty"`
CommitValueY
string
`protobuf:"bytes,3,opt,name=commitValueY,proto3" json:"commitValueY,omitempty"`
CommitValueY
string
`protobuf:"bytes,3,opt,name=commitValueY,proto3" json:"commitValueY,omitempty"`
Authorize
Hash
[]
byte
`protobuf:"bytes,4,opt,name=authorizeHash,proto3" json:"authorize
Hash,omitempty"`
Authorize
SpendHash
string
`protobuf:"bytes,4,opt,name=authorizeSpendHash,proto3" json:"authorizeSpend
Hash,omitempty"`
NullifierHash
[]
byte
`protobuf:"bytes,5,opt,name=nullifierHash,proto3" json:"nullifierHash,omitempty"`
NullifierHash
string
`protobuf:"bytes,5,opt,name=nullifierHash,proto3" json:"nullifierHash,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
XXX_sizecache
int32
`json:"-"`
...
@@ -913,11 +912,11 @@ func (m *TransferInputPublicInput) XXX_DiscardUnknown() {
...
@@ -913,11 +912,11 @@ func (m *TransferInputPublicInput) XXX_DiscardUnknown() {
var
xxx_messageInfo_TransferInputPublicInput
proto
.
InternalMessageInfo
var
xxx_messageInfo_TransferInputPublicInput
proto
.
InternalMessageInfo
func
(
m
*
TransferInputPublicInput
)
GetTreeRootHash
()
[]
byte
{
func
(
m
*
TransferInputPublicInput
)
GetTreeRootHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
TreeRootHash
return
m
.
TreeRootHash
}
}
return
nil
return
""
}
}
func
(
m
*
TransferInputPublicInput
)
GetCommitValueX
()
string
{
func
(
m
*
TransferInputPublicInput
)
GetCommitValueX
()
string
{
...
@@ -934,22 +933,22 @@ func (m *TransferInputPublicInput) GetCommitValueY() string {
...
@@ -934,22 +933,22 @@ func (m *TransferInputPublicInput) GetCommitValueY() string {
return
""
return
""
}
}
func
(
m
*
TransferInputPublicInput
)
GetAuthorize
Hash
()
[]
byte
{
func
(
m
*
TransferInputPublicInput
)
GetAuthorize
SpendHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
AuthorizeHash
return
m
.
Authorize
Spend
Hash
}
}
return
nil
return
""
}
}
func
(
m
*
TransferInputPublicInput
)
GetNullifierHash
()
[]
byte
{
func
(
m
*
TransferInputPublicInput
)
GetNullifierHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
NullifierHash
return
m
.
NullifierHash
}
}
return
nil
return
""
}
}
type
TransferOutputPublicInput
struct
{
type
TransferOutputPublicInput
struct
{
NodeHash
[]
byte
`protobuf:"bytes,1,opt,name=nodeHash,proto3" json:"nodeHash,omitempty"`
NodeHash
string
`protobuf:"bytes,1,opt,name=nodeHash,proto3" json:"nodeHash,omitempty"`
CommitValueX
string
`protobuf:"bytes,2,opt,name=commitValueX,proto3" json:"commitValueX,omitempty"`
CommitValueX
string
`protobuf:"bytes,2,opt,name=commitValueX,proto3" json:"commitValueX,omitempty"`
CommitValueY
string
`protobuf:"bytes,3,opt,name=commitValueY,proto3" json:"commitValueY,omitempty"`
CommitValueY
string
`protobuf:"bytes,3,opt,name=commitValueY,proto3" json:"commitValueY,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
...
@@ -982,11 +981,11 @@ func (m *TransferOutputPublicInput) XXX_DiscardUnknown() {
...
@@ -982,11 +981,11 @@ func (m *TransferOutputPublicInput) XXX_DiscardUnknown() {
var
xxx_messageInfo_TransferOutputPublicInput
proto
.
InternalMessageInfo
var
xxx_messageInfo_TransferOutputPublicInput
proto
.
InternalMessageInfo
func
(
m
*
TransferOutputPublicInput
)
GetNodeHash
()
[]
byte
{
func
(
m
*
TransferOutputPublicInput
)
GetNodeHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
NodeHash
return
m
.
NodeHash
}
}
return
nil
return
""
}
}
func
(
m
*
TransferOutputPublicInput
)
GetCommitValueX
()
string
{
func
(
m
*
TransferOutputPublicInput
)
GetCommitValueX
()
string
{
...
@@ -1004,10 +1003,10 @@ func (m *TransferOutputPublicInput) GetCommitValueY() string {
...
@@ -1004,10 +1003,10 @@ func (m *TransferOutputPublicInput) GetCommitValueY() string {
}
}
type
AuthorizePublicInput
struct
{
type
AuthorizePublicInput
struct
{
TreeRootHash
[]
byte
`protobuf:"bytes,1,opt,name=treeRootHash,proto3" json:"treeRootHash,omitempty"`
TreeRootHash
string
`protobuf:"bytes,1,opt,name=treeRootHash,proto3" json:"treeRootHash,omitempty"`
AuthorizePubKey
string
`protobuf:"bytes,2,opt,name=authorizePubKey,proto3" json:"authorizePubKey,omitempty"`
AuthorizePubKey
string
`protobuf:"bytes,2,opt,name=authorizePubKey,proto3" json:"authorizePubKey,omitempty"`
AuthorizeHash
[]
byte
`protobuf:"bytes,3,opt,name=authorizeHash,proto3" json:"authorizeHash,omitempty"`
AuthorizeHash
string
`protobuf:"bytes,3,opt,name=authorizeHash,proto3" json:"authorizeHash,omitempty"`
AuthorizeSpendHash
[]
byte
`protobuf:"bytes,4,opt,name=authorizeSpendHash,proto3" json:"authorizeSpendHash,omitempty"`
AuthorizeSpendHash
string
`protobuf:"bytes,4,opt,name=authorizeSpendHash,proto3" json:"authorizeSpendHash,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
XXX_sizecache
int32
`json:"-"`
...
@@ -1038,11 +1037,11 @@ func (m *AuthorizePublicInput) XXX_DiscardUnknown() {
...
@@ -1038,11 +1037,11 @@ func (m *AuthorizePublicInput) XXX_DiscardUnknown() {
var
xxx_messageInfo_AuthorizePublicInput
proto
.
InternalMessageInfo
var
xxx_messageInfo_AuthorizePublicInput
proto
.
InternalMessageInfo
func
(
m
*
AuthorizePublicInput
)
GetTreeRootHash
()
[]
byte
{
func
(
m
*
AuthorizePublicInput
)
GetTreeRootHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
TreeRootHash
return
m
.
TreeRootHash
}
}
return
nil
return
""
}
}
func
(
m
*
AuthorizePublicInput
)
GetAuthorizePubKey
()
string
{
func
(
m
*
AuthorizePublicInput
)
GetAuthorizePubKey
()
string
{
...
@@ -1052,18 +1051,18 @@ func (m *AuthorizePublicInput) GetAuthorizePubKey() string {
...
@@ -1052,18 +1051,18 @@ func (m *AuthorizePublicInput) GetAuthorizePubKey() string {
return
""
return
""
}
}
func
(
m
*
AuthorizePublicInput
)
GetAuthorizeHash
()
[]
byte
{
func
(
m
*
AuthorizePublicInput
)
GetAuthorizeHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
AuthorizeHash
return
m
.
AuthorizeHash
}
}
return
nil
return
""
}
}
func
(
m
*
AuthorizePublicInput
)
GetAuthorizeSpendHash
()
[]
byte
{
func
(
m
*
AuthorizePublicInput
)
GetAuthorizeSpendHash
()
string
{
if
m
!=
nil
{
if
m
!=
nil
{
return
m
.
AuthorizeSpendHash
return
m
.
AuthorizeSpendHash
}
}
return
nil
return
""
}
}
type
ExistValue
struct
{
type
ExistValue
struct
{
...
@@ -1188,6 +1187,7 @@ type CommitTreeProve struct {
...
@@ -1188,6 +1187,7 @@ type CommitTreeProve struct {
ProofSet
[]
string
`protobuf:"bytes,2,rep,name=proofSet,proto3" json:"proofSet,omitempty"`
ProofSet
[]
string
`protobuf:"bytes,2,rep,name=proofSet,proto3" json:"proofSet,omitempty"`
ProofIndex
uint32
`protobuf:"varint,3,opt,name=proofIndex,proto3" json:"proofIndex,omitempty"`
ProofIndex
uint32
`protobuf:"varint,3,opt,name=proofIndex,proto3" json:"proofIndex,omitempty"`
NumLeaves
uint32
`protobuf:"varint,4,opt,name=numLeaves,proto3" json:"numLeaves,omitempty"`
NumLeaves
uint32
`protobuf:"varint,4,opt,name=numLeaves,proto3" json:"numLeaves,omitempty"`
Helpers
string
`protobuf:"bytes,5,opt,name=helpers,proto3" json:"helpers,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
XXX_sizecache
int32
`json:"-"`
...
@@ -1246,6 +1246,60 @@ func (m *CommitTreeProve) GetNumLeaves() uint32 {
...
@@ -1246,6 +1246,60 @@ func (m *CommitTreeProve) GetNumLeaves() uint32 {
return
0
return
0
}
}
func
(
m
*
CommitTreeProve
)
GetHelpers
()
string
{
if
m
!=
nil
{
return
m
.
Helpers
}
return
""
}
type
TreePathReq
struct
{
RootHash
string
`protobuf:"bytes,1,opt,name=rootHash,proto3" json:"rootHash,omitempty"`
LeafHash
string
`protobuf:"bytes,2,opt,name=leafHash,proto3" json:"leafHash,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
}
func
(
m
*
TreePathReq
)
Reset
()
{
*
m
=
TreePathReq
{}
}
func
(
m
*
TreePathReq
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
TreePathReq
)
ProtoMessage
()
{}
func
(
*
TreePathReq
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_5c21d519a9be369a
,
[]
int
{
20
}
}
func
(
m
*
TreePathReq
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_TreePathReq
.
Unmarshal
(
m
,
b
)
}
func
(
m
*
TreePathReq
)
XXX_Marshal
(
b
[]
byte
,
deterministic
bool
)
([]
byte
,
error
)
{
return
xxx_messageInfo_TreePathReq
.
Marshal
(
b
,
m
,
deterministic
)
}
func
(
m
*
TreePathReq
)
XXX_Merge
(
src
proto
.
Message
)
{
xxx_messageInfo_TreePathReq
.
Merge
(
m
,
src
)
}
func
(
m
*
TreePathReq
)
XXX_Size
()
int
{
return
xxx_messageInfo_TreePathReq
.
Size
(
m
)
}
func
(
m
*
TreePathReq
)
XXX_DiscardUnknown
()
{
xxx_messageInfo_TreePathReq
.
DiscardUnknown
(
m
)
}
var
xxx_messageInfo_TreePathReq
proto
.
InternalMessageInfo
func
(
m
*
TreePathReq
)
GetRootHash
()
string
{
if
m
!=
nil
{
return
m
.
RootHash
}
return
""
}
func
(
m
*
TreePathReq
)
GetLeafHash
()
string
{
if
m
!=
nil
{
return
m
.
LeafHash
}
return
""
}
func
init
()
{
func
init
()
{
proto
.
RegisterEnum
(
"types.VerifyType"
,
VerifyType_name
,
VerifyType_value
)
proto
.
RegisterEnum
(
"types.VerifyType"
,
VerifyType_name
,
VerifyType_value
)
proto
.
RegisterEnum
(
"types.ZkCurveId"
,
ZkCurveId_name
,
ZkCurveId_value
)
proto
.
RegisterEnum
(
"types.ZkCurveId"
,
ZkCurveId_name
,
ZkCurveId_value
)
...
@@ -1271,6 +1325,7 @@ func init() {
...
@@ -1271,6 +1325,7 @@ func init() {
proto
.
RegisterType
((
*
CommitTreeLeaves
)(
nil
),
"types.CommitTreeLeaves"
)
proto
.
RegisterType
((
*
CommitTreeLeaves
)(
nil
),
"types.CommitTreeLeaves"
)
proto
.
RegisterType
((
*
CommitTreeRoots
)(
nil
),
"types.CommitTreeRoots"
)
proto
.
RegisterType
((
*
CommitTreeRoots
)(
nil
),
"types.CommitTreeRoots"
)
proto
.
RegisterType
((
*
CommitTreeProve
)(
nil
),
"types.CommitTreeProve"
)
proto
.
RegisterType
((
*
CommitTreeProve
)(
nil
),
"types.CommitTreeProve"
)
proto
.
RegisterType
((
*
TreePathReq
)(
nil
),
"types.TreePathReq"
)
}
}
func
init
()
{
func
init
()
{
...
@@ -1278,67 +1333,69 @@ func init() {
...
@@ -1278,67 +1333,69 @@ func init() {
}
}
var
fileDescriptor_5c21d519a9be369a
=
[]
byte
{
var
fileDescriptor_5c21d519a9be369a
=
[]
byte
{
// 986 bytes of a gzipped FileDescriptorProto
// 1013 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xac
,
0x96
,
0xdd
,
0x6e
,
0x1a
,
0x47
,
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xac
,
0x56
,
0xdd
,
0x6e
,
0xe3
,
0x54
,
0x14
,
0xc7
,
0xd9
,
0xe5
,
0xcb
,
0x7b
,
0x00
,
0x7b
,
0x3d
,
0xb1
,
0x52
,
0x52
,
0x55
,
0x15
,
0xdd
,
0x26
,
0x10
,
0x8e
,
0xf3
,
0x5b
,
0x4f
,
0x92
,
0xd6
,
0x3d
,
0x5b
,
0x2d
,
0x5e
,
0x84
,
0x50
,
0x30
,
0xbb
,
0x4b
,
0x29
,
0xa2
,
0x12
,
0x6a
,
0x71
,
0xeb
,
0xb4
,
0xea
,
0x15
,
0xb6
,
0xa9
,
0xa0
,
0x89
,
0x01
,
0x0d
,
0xeb
,
0x14
,
0xa4
,
0x08
,
0x52
,
0xe8
,
0x82
,
0xb8
,
0x4a
,
0xdb
,
0xa0
,
0x84
,
0xdd
,
0x26
,
0xd1
,
0x89
,
0xbb
,
0xb8
,
0xb5
,
0xd4
,
0x4a
,
0x6b
,
0x18
,
0xea
,
0x51
,
0x60
,
0x17
,
0x2d
,
0xb3
,
0x18
,
0x7a
,
0xd3
,
0xcb
,
0x85
,
0x4a
,
0x20
,
0xb9
,
0xc9
,
0x09
,
0xb1
,
0x9a
,
0xd8
,
0xc6
,
0x39
,
0x4e
,
0x13
,
0x6e
,
0x78
,
0x16
,
0x3e
,
0x45
,
0x5f
,
0xa3
,
0x17
,
0x7d
,
0x8c
,
0x4a
,
0x7d
,
0x9f
,
0x6a
,
0x3e
,
0xf6
,
0x8b
,
0x60
,
0x25
,
0xae
,
0x78
,
0x03
,
0x2e
,
0x78
,
0x0f
,
0xee
,
0x78
,
0x18
,
0x74
,
0x7e
,
0xfc
,
0x17
,
0x1a
,
0x95
,
0x4a
,
0x96
,
0x7a
,
0xc7
,
0x9c
,
0xfd
,
0x9d
,
0x33
,
0xe7
,
0x7f
,
0xce
,
0x61
,
0x66
,
0xc0
,
0x98
,
0xd3
,
0x75
,
0x7b
,
0xe7
,
0x19
,
0x7f
,
0x33
,
0xe7
,
0xfb
,
0x66
,
0xe6
,
0xfc
,
0x80
,
0xba
,
0xb0
,
0xd7
,
0x4d
,
0xcf
,
0x73
,
0xe1
,
0x7b
,
0xcc
,
0x43
,
0x79
,
0xb6
,
0x59
,
0x90
,
0xa5
,
0xb5
,
0x82
,
0xd2
,
0xf5
,
0x9b
,
0xd7
,
0x77
,
0xa9
,
0x8b
,
0x0a
,
0x74
,
0xe3
,
0x91
,
0xa5
,
0xb1
,
0x82
,
0xf2
,
0xf5
,
0xed
,
0x5b
,
0xe2
,
0xdb
,
0xc4
,
0xa7
,
0xd3
,
0xcd
,
0x4b
,
0xb2
,
0x41
,
0x0d
,
0x28
,
0x8e
,
0x03
,
0x7f
,
0x45
,
0x7a
,
0x93
,
0xaa
,
0xd3
,
0xcd
,
0x6b
,
0xb2
,
0x41
,
0x0d
,
0x28
,
0x8d
,
0x03
,
0x7f
,
0x45
,
0x7a
,
0x13
,
0x5d
,
0xa9
,
0x29
,
0x56
,
0xd3
,
0xea
,
0xfb
,
0x2d
,
0xb3
,
0x29
,
0xb8
,
0xe6
,
0xf5
,
0x9b
,
0x33
,
0x69
,
0xc7
,
0x21
,
0x80
,
0xf5
,
0xfd
,
0x96
,
0xd6
,
0xe4
,
0xb8
,
0xe6
,
0xf5
,
0xed
,
0x99
,
0xf0
,
0xe3
,
0x10
,
0x80
,
0x5e
,
0x40
,
0x9e
,
0x41
,
0x8e
,
0x7f
,
0xab
,
0xea
,
0x02
,
0x3c
,
0x54
,
0xa0
,
0x8c
,
0x65
,
0x6f
,
0x16
,
0x04
,
0x8b
,
0x9e
,
0xfd
,
0xd3
,
0xb3
,
0x1c
,
0x78
,
0x28
,
0x81
,
0x22
,
0x97
,
0xb9
,
0xf1
,
0x08
,
0xe6
,
0xbf
,
0xd1
,
0xcf
,
0xe8
,
0x08
,
0xf2
,
0x2b
,
0x67
,
0x16
,
0x90
,
0x6a
,
0xb6
,
0xa6
,
0xd5
,
0x0d
,
0x2c
,
0x17
,
0xd6
,
0x11
,
0x14
,
0x56
,
0xd6
,
0x3c
,
0x20
,
0x7a
,
0xae
,
0xa6
,
0xd4
,
0x55
,
0x2c
,
0x0c
,
0xe3
,
0x04
,
0x2a
,
0x09
,
0x94
,
0x13
,
0xfb
,
0x2e
,
0xd1
,
0x73
,
0xc8
,
0x4d
,
0x1c
,
0xe6
,
0x54
,
0xb5
,
0x5a
,
0xb6
,
0x5e
,
0x89
,
0x75
,
0x97
,
0xe8
,
0x25
,
0xe4
,
0x27
,
0x16
,
0xb5
,
0x74
,
0xa5
,
0x96
,
0xab
,
0x97
,
0x5b
,
0x28
,
0x6a
,
0xa1
,
0x68
,
0xd7
,
0x08
,
0xc1
,
0xe2
,
0xbb
,
0xf5
,
0x09
,
0x94
,
0xda
,
0x01
,
0xbb
,
0x1d
,
0x06
,
0x5a
,
0x35
,
0x82
,
0x60
,
0xfe
,
0xdf
,
0xf8
,
0x08
,
0xca
,
0xed
,
0x80
,
0xce
,
0x86
,
0xc1
,
0x0d
,
0x0f
,
0x37
,
0xc2
,
0x0d
,
0x25
,
0xdc
,
0x0c
,
0x85
,
0x7c
,
0x06
,
0x07
,
0x1c
,
0xf1
,
0x7c
,
0xfa
,
0x1b
,
0x91
,
0x43
,
0x89
,
0x30
,
0x55
,
0x42
,
0x3e
,
0x81
,
0x03
,
0x06
,
0x71
,
0x7d
,
0xfb
,
0x57
,
0x22
,
0x70
,
0x3b
,
0xdc
,
0x3d
,
0x39
,
0xfc
,
0xab
,
0xc1
,
0xc1
,
0x05
,
0x5d
,
0x9f
,
0x79
,
0xee
,
0x94
,
0xfe
,
0xda
,
0x1e
,
0x38
,
0xfc
,
0xad
,
0xc0
,
0xc1
,
0x85
,
0xbd
,
0x3e
,
0x73
,
0x9d
,
0xa9
,
0xfd
,
0x73
,
0x7b
,
0x4c
,
0x6d
,
0x33
,
0xea
,
0xb9
,
0xe8
,
0x29
,
0xe8
,
0xf6
,
0x46
,
0x69
,
0x3f
,
0x52
,
0x59
,
0x44
,
0x8c
,
0x50
,
0xa5
,
0xd7
,
0x41
,
0xcf
,
0x21
,
0x6b
,
0x6e
,
0xa4
,
0xf6
,
0x23
,
0xc9
,
0x22
,
0xc2
,
0x70
,
0x55
,
0x59
,
0x73
,
0xdb
,
0x1b
,
0xf4
,
0x39
,
0x14
,
0x24
,
0xaf
,
0xc4
,
0x3f
,
0xda
,
0x26
,
0xdb
,
0x63
,
0x86
,
0x15
,
0x82
,
0x83
,
0x3e
,
0x85
,
0xa2
,
0xc0
,
0x4b
,
0xf1
,
0x4f
,
0xb6
,
0x91
,
0xed
,
0x31
,
0xc5
,
0x12
,
0x82
,
0x5a
,
0x5a
,
0x60
,
0xac
,
0x42
,
0x15
,
0x22
,
0x81
,
0x9d
,
0xfa
,
0xba
,
0x19
,
0x1c
,
0x63
,
0xa8
,
0x05
,
0x45
,
0xa0
,
0xae
,
0x42
,
0x15
,
0x9c
,
0xc0
,
0xbd
,
0xfa
,
0xba
,
0x19
,
0x1c
,
0xc3
,
0x50
,
0x0b
,
0x4a
,
0x56
,
0x27
,
0x60
,
0xb7
,
0xdc
,
0x23
,
0x27
,
0x3c
,
0x1e
,
0x2b
,
0x8f
,
0x2d
,
0x65
,
0xdd
,
0x0c
,
0x0e
,
0xc1
,
0x40
,
0x67
,
0x2c
,
0x22
,
0xcf
,
0x23
,
0x9e
,
0xca
,
0x88
,
0x2d
,
0x65
,
0xdd
,
0x0c
,
0x0e
,
0x81
,
0xa7
,
0xd3
,
0xa2
,
0x12
,
0x69
,
0x75
,
0x78
,
0x4f
,
0x87
,
0xbe
,
0xe7
,
0x4d
,
0x7b
,
0xee
,
0xd4
,
0xe3
,
0xe2
,
0x25
,
0x29
,
0xd2
,
0xe8
,
0xb0
,
0x9e
,
0x0e
,
0x7d
,
0xd7
,
0x9d
,
0xf6
,
0x9c
,
0xa9
,
0xcb
,
0xc4
,
0x7b
,
0x17
,
0x7c
,
0x21
,
0x54
,
0x19
,
0x58
,
0x2e
,
0x50
,
0x0d
,
0x4a
,
0x8b
,
0xe0
,
0x66
,
0x46
,
0xc7
,
0x3d
,
0xcc
,
0xe0
,
0xaa
,
0x54
,
0x2c
,
0x0c
,
0x54
,
0x83
,
0xb2
,
0x17
,
0xdc
,
0xcc
,
0xed
,
0x71
,
0xcf
,
0xf1
,
0x77
,
0x11
,
0x30
,
0xa1
,
0xc3
,
0xc0
,
0x49
,
0x93
,
0xf5
,
0x0b
,
0x98
,
0x17
,
0x74
,
0x7d
,
0x4e
,
0x16
,
0x02
,
0xca
,
0x75
,
0xa8
,
0x38
,
0xe9
,
0x32
,
0x7e
,
0x02
,
0xed
,
0xc2
,
0x5e
,
0x9f
,
0x13
,
0xcf
,
0x5d
,
0xde
,
0x92
,
0x32
,
0xa5
,
0xe5
,
0x31
,
0x14
,
0x9c
,
0xb9
,
0x17
,
0xb8
,
0x4c
,
0x04
,
0xcb
,
0x61
,
0xb5
,
0xda
,
0x54
,
0x6a
,
0x79
,
0x0a
,
0x45
,
0x6b
,
0xe1
,
0x06
,
0x0e
,
0xe5
,
0xc9
,
0xf2
,
0x58
,
0x5a
,
0xa8
,
0x42
,
0x2d
,
0x00
,
0x97
,
0xdc
,
0x9d
,
0x79
,
0xf3
,
0x39
,
0x65
,
0xcb
,
0xaa
,
0xbe
,
0xd5
,
0xc4
,
0x28
,
0x05
,
0xe0
,
0x90
,
0xbb
,
0x33
,
0x77
,
0xb1
,
0xb0
,
0xe9
,
0x52
,
0xcf
,
0x6e
,
0x35
,
0x31
,
0xe2
,
0x82
,
0x17
,
0x9c
,
0xa0
,
0x2c
,
0x0a
,
0x87
,
0x17
,
0x74
,
0x6d
,
0xfb
,
0x8e
,
0xbb
,
0x9c
,
0x12
,
0x5f
,
0x6d
,
0x13
,
0x28
,
0xc3
,
0x86
,
0xc3
,
0x0b
,
0x7b
,
0x6d
,
0xfa
,
0x96
,
0xb3
,
0x9c
,
0x12
,
0x5f
,
0x2e
,
0x50
,
0x50
,
0x87
,
0x3c
,
0x15
,
0x09
,
0x69
,
0xf7
,
0xc6
,
0x90
,
0x00
,
0x6a
,
0x40
,
0xc1
,
0x0b
,
0x98
,
0xcc
,
0x87
,
0x82
,
0xcd
,
0x09
,
0x29
,
0x3b
,
0x73
,
0x08
,
0x00
,
0x6a
,
0x40
,
0xd1
,
0x0d
,
0xa8
,
0xe0
,
0xbe
,
0xfd
,
0x3e
,
0x54
,
0x11
,
0xd6
,
0x58
,
0x6c
,
0x75
,
0x45
,
0xd9
,
0xed
,
0xc4
,
0x77
,
0xee
,
0xde
,
0xa1
,
0x0b
,
0x2a
,
0x11
,
0xc6
,
0x98
,
0x2f
,
0x75
,
0x65
,
0xd3
,
0xd9
,
0xc4
,
0xb7
,
0xee
,
0x1e
,
0xd0
,
0x72
,
0xe5
,
0x04
,
0xca
,
0xcb
,
0x05
,
0x71
,
0x27
,
0xef
,
0x56
,
0x93
,
0xe2
,
0xac
,
0x1f
,
0x00
,
0x5d
,
0xd0
,
0x02
,
0x95
,
0xa5
,
0x47
,
0x9c
,
0xc9
,
0xc3
,
0x6a
,
0x52
,
0x38
,
0xe3
,
0x3b
,
0x40
,
0x17
,
0xf6
,
0x3a
,
0x75
,
0xd4
,
0x20
,
0xb5
,
0xcb
,
0x57
,
0x50
,
0xe2
,
0x0d
,
0x0a
,
0x83
,
0xdd
,
0x2f
,
0x2b
,
0x89
,
0x59
,
0x6a
,
0x90
,
0x5c
,
0xe5
,
0x0b
,
0x28
,
0xb3
,
0x06
,
0x85
,
0xc9
,
0x76
,
0xcb
,
0x4a
,
0xc2
,
0x8c
,
0x3f
,
0x7f
,
0xe9
,
0x60
,
0xf0
,
0x60
,
0x32
,
0xc6
,
0x3e
,
0xe8
,
0x4c
,
0x0e
,
0x65
,
0x1e
,
0xeb
,
0x6c
,
0x83
,
0xb3
,
0xa0
,
0xb2
,
0x64
,
0x22
,
0xc7
,
0x3e
,
0x64
,
0xa9
,
0x18
,
0xca
,
0x02
,
0xce
,
0xd2
,
0x0d
,
0xfa
,
0xbe
,
0x80
,
0xc2
,
0x58
,
0x8c
,
0x99
,
0x68
,
0x5b
,
0x3c
,
0x1c
,
0x5b
,
0xc3
,
0xdc
,
0xcd
,
0x60
,
0xc5
,
0x0c
,
0x8a
,
0x63
,
0x3e
,
0x66
,
0xbc
,
0x6d
,
0xf1
,
0x70
,
0x6c
,
0x0d
,
0x73
,
0x37
,
0x83
,
0x25
,
0x0e
,
0xa1
,
0x63
,
0x28
,
0x4e
,
0x64
,
0x23
,
0xd5
,
0x04
,
0x7e
,
0x10
,
0xbb
,
0xa4
,
0x3a
,
0xcc
,
0x07
,
0x4a
,
0x1d
,
0x43
,
0x69
,
0x22
,
0x1a
,
0x29
,
0x27
,
0xf0
,
0xbd
,
0x38
,
0x24
,
0xd5
,
0x61
,
0x36
,
0x50
,
0x12
,
0x91
,
0xe8
,
0x04
,
0xf6
,
0xee
,
0x54
,
0xc9
,
0xd4
,
0x14
,
0x56
,
0x63
,
0xaf
,
0x74
,
0x31
,
0xbb
,
0x19
,
0x89
,
0x4e
,
0x60
,
0xef
,
0x4e
,
0x96
,
0x4c
,
0x4e
,
0xa1
,
0x1e
,
0x47
,
0xa5
,
0x8b
,
0xd9
,
0xcd
,
0xe0
,
0x1c
,
0xb1
,
0xdc
,
0x8f
,
0xa9
,
0xae
,
0x56
,
0xf3
,
0xdb
,
0x7e
,
0xe9
,
0x7e
,
0x73
,
0xbf
,
0x90
,
0x45
,
0x08
,
0xcb
,
0xe2
,
0xa8
,
0xec
,
0xaa
,
0x5e
,
0xd8
,
0x8e
,
0x4b
,
0xf7
,
0x9b
,
0xc5
,
0x85
,
0x58
,
0xf4
,
0xdf
,
0x82
,
0xe1
,
0x84
,
0xd5
,
0xab
,
0x16
,
0x84
,
0xe3
,
0x93
,
0xd8
,
0x71
,
0xab
,
0xb0
,
0xfc
,
0xff
,
0x35
,
0xa8
,
0x56
,
0x58
,
0x3d
,
0xbd
,
0xc8
,
0x03
,
0x9f
,
0xc5
,
0x81
,
0x5b
,
0x85
,
0x65
,
0xfb
,
0x25
,
0x12
,
0xd1
,
0xf1
,
0xec
,
0x77
,
0x01
,
0x29
,
0x3d
,
0xc3
,
0x78
,
0x94
,
0xd1
,
0x87
,
0xb0
,
0xe7
,
0x7a
,
0x42
,
0xc7
,
0xb3
,
0xdf
,
0x05
,
0x24
,
0xf5
,
0x0c
,
0xe3
,
0x51
,
0x46
,
0xef
,
0xc3
,
0x9e
,
0xe3
,
0x4e
,
0x13
,
0xd2
,
0x75
,
0x96
,
0xb7
,
0xa2
,
0x8c
,
0x65
,
0x1c
,
0xad
,
0x13
,
0x63
,
0x20
,
0xff
,
0x03
,
0x6a
,
0x48
,
0xd7
,
0x5a
,
0xce
,
0xe4
,
0x2e
,
0x88
,
0xec
,
0xc4
,
0x18
,
0x88
,
0x3d
,
0x20
,
0x2d
,
0xe3
,
0x0f
,
0x65
,
0xfd
,
0xa9
,
0xc1
,
0xa3
,
0x50
,
0x64
,
0x32
,
0x96
,
0x05
,
0x65
,
0xe6
,
0x13
,
0x82
,
0x3d
,
0x8f
,
0x05
,
0x9e
,
0x84
,
0x22
,
0x93
,
0xb9
,
0x0c
,
0xa8
,
0x50
,
0x9f
,
0x10
,
0xec
,
0xba
,
0x34
,
0x91
,
0x2f
,
0x25
,
0xe2
,
0xa5
,
0x6c
,
0xe8
,
0x29
,
0x54
,
0xdc
,
0x60
,
0x36
,
0xa3
,
0x53
,
0x4a
,
0x7c
,
0x01
,
0xe9
,
0xe5
,
0x43
,
0xcf
,
0xa1
,
0xea
,
0x04
,
0xf3
,
0xb9
,
0x3d
,
0xb5
,
0x89
,
0xcf
,
0x41
,
0x22
,
0x75
,
0xda
,
0x02
,
0x4a
,
0x1b
,
0x39
,
0x15
,
0x29
,
0x10
,
0x54
,
0x56
,
0x52
,
0x29
,
0x63
,
0x22
,
0xbf
,
0x5c
,
0x2a
,
0x89
,
0x9a
,
0x80
,
0x22
,
0x05
,
0x23
,
0x36
,
0x49
,
0x1c
,
0x2a
,
0x8e
,
0xa8
,
0x7b
,
0xfe
,
0x24
,
0x98
,
0xbf
,
0x7f
,
0x34
,
0xa8
,
0x86
,
0xc5
,
0x14
,
0x99
,
0x3d
,
0x34
,
0x49
,
0x0b
,
0xca
,
0x63
,
0x31
,
0x6e
,
0xe6
,
0x53
,
0x4c
,
0xff
,
0x51
,
0x40
,
0x0f
,
0xcb
,
0xca
,
0x39
,
0x3e
,
0x96
,
0xae
,
0x01
,
0x95
,
0x31
,
0xaf
,
0x79
,
0xe5
,
0x7e
,
0x54
,
0xf2
,
0x53
,
0xb6
,
0x2d
,
0xe6
,
0x27
,
0x75
,
0x7e
,
0xa6
,
0x6c
,
0x6f
,
0x1f
,
0xbc
,
0xb7
,
0xac
,
0x86
,
0xdf
,
0x4b
,
0xb6
,
0x29
,
0xdf
,
0x16
,
0xe6
,
0x07
,
0x49
,
0x33
,
0xe5
,
0xcb
,
0xc8
,
0xed
,
0x92
,
0xf1
,
0x56
,
0x49
,
0xf2
,
0x3b
,
0x4a
,
0x62
,
0xfd
,
0x0e
,
0x4f
,
0x42
,
0x4d
,
0xdb
,
0x21
,
0x28
,
0xbf
,
0x53
,
0xd0
,
0x7f
,
0xca
,
0x54
,
0xb8
,
0xa7
,
0x4c
,
0xc6
,
0x6f
,
0xf0
,
0x2c
,
0x03
,
0xf1
,
0xd7
,
0x7d
,
0xdf
,
0x2e
,
0xfe
,
0x4f
,
0x62
,
0xac
,
0xbf
,
0x35
,
0x38
,
0x4a
,
0x9e
,
0xb1
,
0x54
,
0x37
,
0xe0
,
0xdb
,
0xf9
,
0xff
,
0x76
,
0xf6
,
0x1d
,
0xc9
,
0x32
,
0xfe
,
0x52
,
0xe0
,
0x28
,
0x79
,
0x0f
,
0xaa
,
0x68
,
0x1d
,
0x0e
,
0x9c
,
0xf4
,
0xf9
,
0xac
,
0xf2
,
0xd8
,
0x36
,
0xbf
,
0x67
,
0xeb
,
0x9b
,
0xee
,
0x3e
,
0xaa
,
0xb6
,
0x75
,
0x38
,
0xb0
,
0xd2
,
0x67
,
0xb6
,
0xe4
,
0xb1
,
0xed
,
0x66
,
0xd5
,
0x88
,
0x80
,
0x22
,
0xc3
,
0x88
,
0x1f
,
0x35
,
0x89
,
0xf2
,
0xee
,
0xf8
,
0x62
,
0xd5
,
0x00
,
0x3a
,
0x6b
,
0xba
,
0x5c
,
0x89
,
0x49
,
0x48
,
0x3b
,
0x1f
,
0x5b
,
0x63
,
0xa3
,
0x06
,
0xd0
,
0x59
,
0xdb
,
0x4b
,
0xa1
,
0x25
,
0x94
,
0x5a
,
0x12
,
0x77
,
0xa3
,
0x56
,
0xdf
,
0x53
,
0x77
,
0xe3
,
0x73
,
0x30
,
0xe5
,
0x11
,
0x63
,
0xfb
,
0x71
,
0x5f
,
0x2a
,
0xf5
,
0x3d
,
0x79
,
0x5f
,
0xbe
,
0x04
,
0x4d
,
0x1c
,
0x3b
,
0xa6
,
0x4f
,
0xc8
,
0x1b
,
0x84
,
0xbc
,
0x22
,
0xce
,
0x8a
,
0xa4
,
0xef
,
0xd0
,
0xb2
,
0xe2
,
0x9e
,
0xc1
,
0x41
,
0xcc
,
0x71
,
0x7d
,
0x62
,
0xad
,
0x48
,
0xfa
,
0x5e
,
0xad
,
0x48
,
0xdc
,
0x0b
,
0x38
,
0x88
,
0x71
,
0x4c
,
0xdf
,
0xfd
,
0xb0
,
0xbb
,
0xb1
,
0x3f
,
0xb4
,
0x24
,
0x37
,
0xf4
,
0xbd
,
0x15
,
0xe1
,
0x5d
,
0xf2
,
0x93
,
0x45
,
0x32
,
0x70
,
0xdf
,
0x95
,
0x24
,
0x6e
,
0xe8
,
0xbb
,
0x2b
,
0xc2
,
0xba
,
0xe4
,
0xa7
,
0x8b
,
0x14
,
0xd9
,
0xec
,
0x1f
,
0xb4
,
0xe6
,
0xdf
,
0xc4
,
0xed
,
0x33
,
0x22
,
0xf2
,
0xd4
,
0x36
,
0x70
,
0xb4
,
0x46
,
0x1f
,
0x03
,
0x2c
,
0xbf
,
0x91
,
0x46
,
0x44
,
0x9c
,
0xe4
,
0x2a
,
0x8e
,
0x6c
,
0xf4
,
0x21
,
0x80
,
0x27
,
0x0e
,
0xc8
,
0x09
,
0xe4
,
0x61
,
0x38
,
0x21
,
0x6b
,
0x51
,
0x8f
,
0x0a
,
0x4e
,
0x58
,
0xd0
,
0x47
,
0x60
,
0xb8
,
0xc1
,
0x5c
,
0x59
,
0xf3
,
0x7a
,
0x54
,
0x71
,
0xc2
,
0x83
,
0x3e
,
0x00
,
0xd5
,
0x09
,
0x16
,
0x82
,
0x33
,
0xaf
,
0x41
,
0xe6
,
0x2c
,
0x6a
,
0x50
,
0xc1
,
0xb1
,
0xa1
,
0xf1
,
0x33
,
0x40
,
0xfc
,
0xf2
,
0x40
,
0x25
,
0x28
,
0x9e
,
0x15
,
0xc7
,
0x0e
,
0xa4
,
0x43
,
0x69
,
0x46
,
0xe6
,
0x1e
,
0xf1
,
0x97
,
0x72
,
0xb0
,
0x42
,
0x93
,
0xdd
,
0x77
,
0x86
,
0x83
,
0x51
,
0xcf
,
0x36
,
0x33
,
0xa8
,
0x0c
,
0x7b
,
0x57
,
0x3d
,
0xbb
,
0x7b
,
0x8e
,
0xdb
,
0x90
,
0x9c
,
0x9c
,
0x45
,
0x67
,
0x98
,
0xfc
,
0xf2
,
0x10
,
0xbd
,
0x39
,
0xb1
,
0xa6
,
0x89
,
0x5d
,
0x1c
,
0x57
,
0xa6
,
0x86
,
0x0e
,
0xa1
,
0x62
,
0xe3
,
0x76
,
0x7f
,
0xf4
,
0x7d
,
0x07
,
0xf7
,
0xfa
,
0xc3
,
0x4b
,
0xd9
,
0x8d
,
0x1f
,
0x01
,
0xe2
,
0xe7
,
0x0e
,
0x2a
,
0x43
,
0xe9
,
0xbc
,
0x33
,
0x1c
,
0x8c
,
0x7a
,
0xa6
,
0xdb
,
0xd4
,
0x11
,
0x82
,
0xfd
,
0xd0
,
0x34
,
0xb8
,
0xb4
,
0xb9
,
0x2d
,
0x8b
,
0x2a
,
0x60
,
0xb4
,
0x2f
,
0x96
,
0x41
,
0x15
,
0xd8
,
0xbb
,
0xea
,
0x99
,
0xdd
,
0x73
,
0xdc
,
0xbe
,
0xd2
,
0x14
,
0x74
,
0x08
,
0x55
,
0xed
,
0xee
,
0x00
,
0xf7
,
0xae
,
0x3b
,
0x66
,
0xae
,
0xf1
,
0x1d
,
0x18
,
0xd1
,
0x0b
,
0x88
,
0x47
,
0xbf
,
0x13
,
0xb7
,
0xfb
,
0xa3
,
0x6f
,
0x3b
,
0xb8
,
0xd7
,
0x1f
,
0x5e
,
0x9a
,
0x5a
,
0x16
,
0x21
,
0xd8
,
0x0f
,
0xec
,
0xbf
,
0xec
,
0x0f
,
0xae
,
0xfa
,
0x66
,
0x06
,
0x01
,
0x14
,
0x4e
,
0x5f
,
0x8d
,
0x8e
,
0x5f
,
0xbc
,
0x5d
,
0x83
,
0x4b
,
0x93
,
0xf9
,
0x72
,
0xa8
,
0x0a
,
0x6a
,
0xfb
,
0xd2
,
0xec
,
0x0e
,
0x70
,
0xef
,
0xba
,
0x30
,
0xb5
,
0xf0
,
0xf7
,
0x37
,
0x5f
,
0x9a
,
0x3a
,
0x32
,
0x20
,
0x7f
,
0xda
,
0x6f
,
0x7d
,
0x7d
,
0x62
,
0xa3
,
0xe5
,
0x1b
,
0xdf
,
0x80
,
0x1a
,
0x3d
,
0xbb
,
0x58
,
0xf6
,
0xcb
,
0xfe
,
0xeb
,
0xfe
,
0xe0
,
0xaa
,
0x66
,
0x1b
,
0x4d
,
0xa8
,
0xa4
,
0x9e
,
0x10
,
0x3c
,
0x78
,
0x74
,
0xef
,
0x9b
,
0x19
,
0xb4
,
0x0f
,
0x10
,
0xaf
,
0x65
,
0x10
,
0x40
,
0xf1
,
0xf4
,
0xcd
,
0xe8
,
0xf8
,
0xd5
,
0x2b
,
0x4d
,
0x09
,
0xbf
,
0xbf
,
0xfa
,
0xbf
,
0x69
,
0x4c
,
0xad
,
0xf1
,
0x29
,
0x94
,
0x93
,
0x27
,
0x39
,
0x2a
,
0x42
,
0xb6
,
0x3d
,
0x99
,
0xc8
,
0x5c
,
0xcb
,
0x22
,
0x15
,
0x0a
,
0xa7
,
0xfd
,
0xd6
,
0x97
,
0x27
,
0x5a
,
0xae
,
0xd1
,
0x84
,
0x6a
,
0xea
,
0xbd
,
0xce
,
0xc9
,
0x8c
,
0x30
,
0x62
,
0x6a
,
0x37
,
0x05
,
0xf1
,
0x8c
,
0x3b
,
0xfe
,
0x2f
,
0x00
,
0x00
,
0xdd
,
0xc2
,
0x92
,
0x47
,
0x8f
,
0x0d
,
0x2d
,
0x83
,
0xf6
,
0x01
,
0xe2
,
0x87
,
0x94
,
0xa6
,
0x34
,
0x3e
,
0xff
,
0xff
,
0x0c
,
0x83
,
0xfc
,
0xbb
,
0xd3
,
0x09
,
0x00
,
0x00
,
0x86
,
0x4a
,
0xf2
,
0xfa
,
0x40
,
0x25
,
0xc8
,
0xb5
,
0x27
,
0x13
,
0xb1
,
0xd6
,
0x39
,
0x99
,
0x13
,
0x4a
,
0x34
,
0xe5
,
0xa6
,
0xc8
,
0xdf
,
0x8e
,
0xc7
,
0xff
,
0x06
,
0x00
,
0x00
,
0xff
,
0xff
,
0x98
,
0xff
,
0x1c
,
0xdb
,
0x48
,
0x0a
,
0x00
,
0x00
,
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment