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

support deposit multi target

parent b775d350
...@@ -416,8 +416,8 @@ func createConfigPubKey(cmd *cobra.Command, args []string) { ...@@ -416,8 +416,8 @@ func createConfigPubKey(cmd *cobra.Command, args []string) {
func mixConfigPaymentPubKeyParaCmd() *cobra.Command { func mixConfigPaymentPubKeyParaCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "pay", Use: "register",
Short: "mix payment pub key config cmd", Short: "receiver key register cmd",
Run: createConfigPayPubKey, Run: createConfigPayPubKey,
} }
addPayPubKeyConfigFlags(cmd) addPayPubKeyConfigFlags(cmd)
...@@ -629,7 +629,7 @@ func showMixTxs(cmd *cobra.Command, args []string) { ...@@ -629,7 +629,7 @@ func showMixTxs(cmd *cobra.Command, args []string) {
func ShowPaymentPubKeyCmd() *cobra.Command { func ShowPaymentPubKeyCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "paykey", Use: "paykey",
Short: "show addr's payment pub key info", Short: "show peer addr payment key info",
Run: showPayment, Run: showPayment,
} }
addShowPaymentflags(cmd) addShowPaymentflags(cmd)
...@@ -637,7 +637,7 @@ func ShowPaymentPubKeyCmd() *cobra.Command { ...@@ -637,7 +637,7 @@ func ShowPaymentPubKeyCmd() *cobra.Command {
} }
func addShowPaymentflags(cmd *cobra.Command) { func addShowPaymentflags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "s", "", "mix tx hash") cmd.Flags().StringP("addr", "a", "", "account addr")
cmd.MarkFlagRequired("addr") cmd.MarkFlagRequired("addr")
} }
...@@ -677,7 +677,7 @@ func WalletCmd() *cobra.Command { ...@@ -677,7 +677,7 @@ func WalletCmd() *cobra.Command {
func ShowAccountPrivacyInfo() *cobra.Command { func ShowAccountPrivacyInfo() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "keys", Use: "keys",
Short: "show account privacy keys", Short: "show account note privacy keys",
Run: accountPrivacy, Run: accountPrivacy,
} }
accountPrivacyCmdFlags(cmd) accountPrivacyCmdFlags(cmd)
...@@ -685,17 +685,27 @@ func ShowAccountPrivacyInfo() *cobra.Command { ...@@ -685,17 +685,27 @@ func ShowAccountPrivacyInfo() *cobra.Command {
} }
func accountPrivacyCmdFlags(cmd *cobra.Command) { func accountPrivacyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("account", "a", "", "accounts") cmd.Flags().StringP("addr", "a", "", "user wallet addr")
cmd.MarkFlagRequired("account")
cmd.Flags().StringP("priv", "p", "", "user wallet privacy key,option")
cmd.Flags().Uint32P("detail", "d", 0, "if get payment priv keys,option")
} }
func accountPrivacy(cmd *cobra.Command, args []string) { func accountPrivacy(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
account, _ := cmd.Flags().GetString("account") priv, _ := cmd.Flags().GetString("priv")
addr, _ := cmd.Flags().GetString("addr")
detail, _ := cmd.Flags().GetUint32("detail")
if len(priv) == 0 && len(addr) == 0 {
fmt.Println("err: one of addr or priv should be fill")
return
}
var res mixTy.WalletAddrPrivacy var res mixTy.WalletAddrPrivacy
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.ShowAccountPrivacyInfo", &types.ReqString{Data: account}, &res) ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.ShowAccountPrivacyInfo", &mixTy.PaymentKeysReq{PrivKey: priv, Addr: addr, Detail: int32(detail)}, &res)
ctx.Run() ctx.Run()
} }
...@@ -1023,14 +1033,14 @@ func CreateDepositRawTxCmd() *cobra.Command { ...@@ -1023,14 +1033,14 @@ func CreateDepositRawTxCmd() *cobra.Command {
} }
func depositSecretCmdFlags(cmd *cobra.Command) { func depositSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("receiver", "t", "", "receiver addr") cmd.Flags().StringP("targets", "t", "", "target addrs,seperated by ','")
cmd.MarkFlagRequired("receiver") cmd.MarkFlagRequired("targets")
cmd.Flags().StringP("return", "r", "", "return addr,optional") cmd.Flags().StringP("return", "r", "", "return addr,optional")
cmd.Flags().StringP("authorize", "a", "", "authorize addr,optional") cmd.Flags().StringP("authorize", "a", "", "authorize addr,optional")
cmd.Flags().Uint64P("amount", "m", 0, "amount") cmd.Flags().StringP("amount", "m", "", "amounts,seperated by ','")
cmd.MarkFlagRequired("amount") cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("token", "s", "BTY", "asset token, default BTY") cmd.Flags().StringP("token", "s", "BTY", "asset token, default BTY")
...@@ -1044,33 +1054,30 @@ func depositSecretCmdFlags(cmd *cobra.Command) { ...@@ -1044,33 +1054,30 @@ func depositSecretCmdFlags(cmd *cobra.Command) {
func depositSecret(cmd *cobra.Command, args []string) { func depositSecret(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName") paraName, _ := cmd.Flags().GetString("paraName")
receiver, _ := cmd.Flags().GetString("receiver") targets, _ := cmd.Flags().GetString("targets")
returnAddr, _ := cmd.Flags().GetString("return") returnAddr, _ := cmd.Flags().GetString("return")
authorize, _ := cmd.Flags().GetString("authorize") authorize, _ := cmd.Flags().GetString("authorize")
amount, _ := cmd.Flags().GetUint64("amount") amount, _ := cmd.Flags().GetString("amount")
assetExec, _ := cmd.Flags().GetString("exec") assetExec, _ := cmd.Flags().GetString("exec")
token, _ := cmd.Flags().GetString("token") token, _ := cmd.Flags().GetString("token")
path, _ := cmd.Flags().GetString("path") path, _ := cmd.Flags().GetString("path")
deposit := &mixTy.DepositInfo{ deposit := &mixTy.DepositInfo{
Addr: receiver, ReceiverAddrs: targets,
ReturnAddr: returnAddr, ReturnAddr: returnAddr,
AuthorizeAddr: authorize, AuthorizeAddr: authorize,
Amount: amount, Amounts: amount,
}
circuits := &mixTy.CircuitPathInfo{
Path: path,
} }
tx := &mixTy.DepositTxReq{ tx := &mixTy.DepositTxReq{
Deposit: deposit, Deposit: deposit,
ZkPath: circuits, ZkPath: path,
} }
params := &mixTy.CreateRawTxReq{ params := &mixTy.CreateRawTxReq{
ActionTy: mixTy.MixActionDeposit, ActionTy: mixTy.MixActionDeposit,
Data: types.Encode(tx), Data: types.Encode(tx),
//Value:&mixTy.CreateRawTxReq_Deposit{Deposit:tx},
AssetExec: assetExec, AssetExec: assetExec,
AssetToken: token, AssetToken: token,
Title: paraName, Title: paraName,
...@@ -1092,17 +1099,17 @@ func CreateTransferRawTxCmd() *cobra.Command { ...@@ -1092,17 +1099,17 @@ func CreateTransferRawTxCmd() *cobra.Command {
} }
func transferSecretCmdFlags(cmd *cobra.Command) { func transferSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("noteHash", "n", "", "note hash to spend") cmd.Flags().StringP("noteHash", "n", "", "note hash to spend, seperate by ',' ")
cmd.MarkFlagRequired("noteHash") cmd.MarkFlagRequired("noteHash")
cmd.Flags().StringP("toAddr", "t", "", "transfer to addr") cmd.Flags().StringP("toAddr", "t", "", "transfer to addr, only one addr")
cmd.MarkFlagRequired("toAddr") cmd.MarkFlagRequired("toAddr")
cmd.Flags().StringP("auth", "a", "", "transfer to auth addr,optional") cmd.Flags().StringP("auth", "a", "", "transfer to auth addr,optional")
cmd.Flags().StringP("returner", "r", "", "transfer to returner addr,optional") cmd.Flags().StringP("returner", "r", "", "transfer to returner addr,optional")
cmd.Flags().Uint64P("amount", "m", 0, "transfer amount") cmd.Flags().StringP("amount", "m", "", "transfer amount")
cmd.MarkFlagRequired("amount") cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("token", "s", "BTY", "asset token, default BTY") cmd.Flags().StringP("token", "s", "BTY", "asset token, default BTY")
...@@ -1122,7 +1129,7 @@ func transferSecret(cmd *cobra.Command, args []string) { ...@@ -1122,7 +1129,7 @@ func transferSecret(cmd *cobra.Command, args []string) {
toAddr, _ := cmd.Flags().GetString("toAddr") toAddr, _ := cmd.Flags().GetString("toAddr")
auth, _ := cmd.Flags().GetString("auth") auth, _ := cmd.Flags().GetString("auth")
returner, _ := cmd.Flags().GetString("returner") returner, _ := cmd.Flags().GetString("returner")
amount, _ := cmd.Flags().GetUint64("amount") amount, _ := cmd.Flags().GetString("amount")
inpath, _ := cmd.Flags().GetString("inpath") inpath, _ := cmd.Flags().GetString("inpath")
outpath, _ := cmd.Flags().GetString("outpath") outpath, _ := cmd.Flags().GetString("outpath")
...@@ -1130,27 +1137,21 @@ func transferSecret(cmd *cobra.Command, args []string) { ...@@ -1130,27 +1137,21 @@ func transferSecret(cmd *cobra.Command, args []string) {
assetExec, _ := cmd.Flags().GetString("exec") assetExec, _ := cmd.Flags().GetString("exec")
token, _ := cmd.Flags().GetString("token") token, _ := cmd.Flags().GetString("token")
inCircuits := &mixTy.CircuitPathInfo{
Path: inpath,
}
input := &mixTy.TransferInputTxReq{ input := &mixTy.TransferInputTxReq{
NoteHash: noteHash, NoteHashs: noteHash,
ZkPath: inCircuits, ZkPath: inpath,
} }
deposit := &mixTy.DepositInfo{ deposit := &mixTy.DepositInfo{
Addr: toAddr, ReceiverAddrs: toAddr,
ReturnAddr: returner, ReturnAddr: returner,
AuthorizeAddr: auth, AuthorizeAddr: auth,
Amount: amount, Amounts: amount,
}
outCircuits := &mixTy.CircuitPathInfo{
Path: outpath,
} }
output := &mixTy.TransferOutputTxReq{ output := &mixTy.TransferOutputTxReq{
Deposit: deposit, Deposit: deposit,
ZkPath: outCircuits, ZkPath: outpath,
} }
req := &mixTy.TransferTxReq{ req := &mixTy.TransferTxReq{
...@@ -1206,14 +1207,10 @@ func withdrawSecret(cmd *cobra.Command, args []string) { ...@@ -1206,14 +1207,10 @@ func withdrawSecret(cmd *cobra.Command, args []string) {
path, _ := cmd.Flags().GetString("path") path, _ := cmd.Flags().GetString("path")
circuits := &mixTy.CircuitPathInfo{
Path: path,
}
req := &mixTy.WithdrawTxReq{ req := &mixTy.WithdrawTxReq{
TotalAmount: amount, TotalAmount: amount,
NoteHashs: noteHashs, NoteHashs: noteHashs,
ZkPath: circuits, ZkPath: path,
} }
params := &mixTy.CreateRawTxReq{ params := &mixTy.CreateRawTxReq{
...@@ -1265,14 +1262,10 @@ func authSecret(cmd *cobra.Command, args []string) { ...@@ -1265,14 +1262,10 @@ func authSecret(cmd *cobra.Command, args []string) {
path, _ := cmd.Flags().GetString("path") path, _ := cmd.Flags().GetString("path")
circuits := &mixTy.CircuitPathInfo{
Path: path,
}
req := &mixTy.AuthTxReq{ req := &mixTy.AuthTxReq{
AuthorizeToAddr: toKey, AuthorizeToAddr: toKey,
NoteHash: noteHash, NoteHash: noteHash,
ZkPath: circuits, ZkPath: path,
} }
params := &mixTy.CreateRawTxReq{ params := &mixTy.CreateRawTxReq{
......
...@@ -95,9 +95,9 @@ func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt, ...@@ -95,9 +95,9 @@ func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt,
receipt := &types.Receipt{Ty: types.ExecOk} receipt := &types.Receipt{Ty: types.ExecOk}
var auths, authSpends []string var auths, authSpends []string
for _, in := range inputs { for _, in := range inputs {
r := makeReceipt(calcAuthorizeHashKey(in.AuthorizeHash), mixTy.TyLogAuthorizeSet, &mixTy.ExistValue{Data: true}) r := makeReceipt(calcAuthorizeHashKey(in.AuthorizeHash), mixTy.TyLogAuthorizeSet, &mixTy.ExistValue{Nullifier: in.AuthorizeHash, Exist: true})
mergeReceipt(receipt, r) mergeReceipt(receipt, r)
r = makeReceipt(calcAuthorizeSpendHashKey(in.AuthorizeSpendHash), mixTy.TyLogAuthorizeSpendSet, &mixTy.ExistValue{Data: true}) r = makeReceipt(calcAuthorizeSpendHashKey(in.AuthorizeSpendHash), mixTy.TyLogAuthorizeSpendSet, &mixTy.ExistValue{Nullifier: in.AuthorizeSpendHash, Exist: true})
mergeReceipt(receipt, r) mergeReceipt(receipt, r)
auths = append(auths, in.AuthorizeHash) auths = append(auths, in.AuthorizeHash)
authSpends = append(authSpends, in.AuthorizeSpendHash) authSpends = append(authSpends, in.AuthorizeSpendHash)
......
...@@ -83,15 +83,17 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error) ...@@ -83,15 +83,17 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error)
4. add new commits to merkle tree 4. add new commits to merkle tree
*/ */
func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error) { func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error) {
var notes []string
var sum uint64
//1. zk-proof校验 //1. zk-proof校验
noteHash, amount, err := a.depositVerify(deposit.Proof) for _, p := range deposit.Proofs {
noteHash, amount, err := a.depositVerify(p)
if err != nil { if err != nil {
return nil, err return nil, errors.Wrapf(err, "verify fail for input=%s", p.PublicInput)
}
sum += amount
notes = append(notes, noteHash)
} }
////校验存款额,目前只支持一次只存一张支票
//if val != deposit.Amount {
// return nil, errors.Wrapf(mixTy.ErrInputParaNotMatch, "deposit amount=%d not equal proof amount=%d", deposit.Amount, val)
//}
//存款 //存款
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
...@@ -101,16 +103,18 @@ func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error ...@@ -101,16 +103,18 @@ 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(amount)) receipt, err := accoutDb.ExecTransfer(a.fromaddr, execAddr, execAddr, int64(sum))
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "ExecTransfer") return nil, errors.Wrapf(err, "account save to exec")
} }
//push new commit to merkle tree //push new commit to merkle tree
var leaves [][]byte var leaves [][]byte
leaves = append(leaves, transferFr2Bytes(noteHash)) for _, n := range notes {
leaves = append(leaves, transferFr2Bytes(n))
}
rpt, err := pushTree(a.db, leaves) rpt, err := pushTree(a.db, leaves)
if err != nil { if err != nil {
return nil, err return nil, errors.Wrap(err, "pushTree")
} }
mergeReceipt(receipt, rpt) mergeReceipt(receipt, rpt)
......
...@@ -111,17 +111,23 @@ func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mix ...@@ -111,17 +111,23 @@ func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mix
var inputs []*mixTy.TransferInputPublicInput var inputs []*mixTy.TransferInputPublicInput
var outputs []*mixTy.TransferOutputPublicInput var outputs []*mixTy.TransferOutputPublicInput
in, err := transferInputVerify(db, transfer.Input) //inputs
for _, i := range transfer.Inputs {
in, err := transferInputVerify(db, i)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
inputs = append(inputs, in) inputs = append(inputs, in)
}
//output
out, err := transferOutputVerify(db, transfer.Output) out, err := transferOutputVerify(db, transfer.Output)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
outputs = append(outputs, out) outputs = append(outputs, out)
//change
change, err := transferOutputVerify(db, transfer.Change) change, err := transferOutputVerify(db, transfer.Change)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
...@@ -129,7 +135,7 @@ func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mix ...@@ -129,7 +135,7 @@ func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mix
outputs = append(outputs, change) outputs = append(outputs, change)
if !VerifyCommitValues(inputs, outputs) { if !VerifyCommitValues(inputs, outputs) {
return nil, nil, errors.Wrap(mixTy.ErrSpendInOutValueNotMatch, "verifyValue") return nil, nil, errors.Wrap(mixTy.ErrSpendInOutValueNotMatch, "verify shieldValue")
} }
return inputs, outputs, nil return inputs, outputs, nil
...@@ -148,7 +154,7 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er ...@@ -148,7 +154,7 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er
receipt := &types.Receipt{Ty: types.ExecOk} receipt := &types.Receipt{Ty: types.ExecOk}
for _, k := range inputs { for _, k := range inputs {
r := makeNullifierSetReceipt(k.NullifierHash, &mixTy.ExistValue{Data: true}) r := makeNullifierSetReceipt(k.NullifierHash, &mixTy.ExistValue{Nullifier: k.NullifierHash, Exist: true})
mergeReceipt(receipt, r) mergeReceipt(receipt, r)
} }
......
...@@ -111,7 +111,7 @@ func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, er ...@@ -111,7 +111,7 @@ func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, er
//set nullifier //set nullifier
for _, k := range nulliferSet { for _, k := range nulliferSet {
r := makeNullifierSetReceipt(k, &mixTy.ExistValue{Data: true}) r := makeNullifierSetReceipt(k, &mixTy.ExistValue{Nullifier: k, Exist: true})
mergeReceipt(receipt, r) mergeReceipt(receipt, r)
} }
return receipt, nil return receipt, nil
......
...@@ -84,12 +84,12 @@ message ZkProofInfo { ...@@ -84,12 +84,12 @@ message ZkProofInfo {
} }
message MixDepositAction { message MixDepositAction {
ZkProofInfo proof = 1; repeated ZkProofInfo proofs = 1;
} }
message MixTransferAction { message MixTransferAction {
ZkProofInfo input = 1; repeated ZkProofInfo inputs = 1;
ZkProofInfo output = 2; ZkProofInfo output = 2;
ZkProofInfo change = 3; ZkProofInfo change = 3;
...@@ -120,7 +120,6 @@ message MixAction { ...@@ -120,7 +120,6 @@ message MixAction {
} }
message DepositPublicInput { message DepositPublicInput {
string noteHash = 1; string noteHash = 1;
string amount = 2; string amount = 2;
...@@ -168,7 +167,8 @@ message VerifyProofInfo{ ...@@ -168,7 +167,8 @@ message VerifyProofInfo{
//nullifer 存在value //nullifer 存在value
message ExistValue { message ExistValue {
bool data = 1; string nullifier = 1;
bool exist = 2;
} }
message CommitTreeLeaves { message CommitTreeLeaves {
...@@ -248,22 +248,21 @@ message DecryptSecretData{ ...@@ -248,22 +248,21 @@ message DecryptSecretData{
} }
//path+filename, filename can take default
message circuitPathInfo{
string path = 1;
}
//支持同时存入多个地址,多个地址具有相同的returnAddr和AuthorizeAddr,如果不同,则单个来存
message DepositInfo{ message DepositInfo{
string addr = 1; string receiverAddrs = 1;
string returnAddr = 2; string returnAddr = 2;
string authorizeAddr = 3; string authorizeAddr = 3;
uint64 amount = 4; string amounts = 4;
} }
//钱包生成deposit tx //钱包生成deposit tx
message DepositTxReq{ message DepositTxReq{
DepositInfo deposit = 1; DepositInfo deposit = 1;
circuitPathInfo zkPath = 2; string zkPath = 2;
} }
...@@ -285,8 +284,8 @@ message TreePathProof{ ...@@ -285,8 +284,8 @@ message TreePathProof{
//可withdraw 多个note //可withdraw 多个note
message WithdrawTxReq{ message WithdrawTxReq{
uint64 totalAmount = 1; uint64 totalAmount = 1;
string noteHashs = 2; string noteHashs = 2; // seperate by ","
circuitPathInfo zkPath = 3; string zkPath = 3;
} }
...@@ -306,7 +305,7 @@ message WithdrawProofRe{ ...@@ -306,7 +305,7 @@ message WithdrawProofRe{
message AuthTxReq{ message AuthTxReq{
string noteHash = 1; string noteHash = 1;
string authorizeToAddr = 3; string authorizeToAddr = 3;
circuitPathInfo zkPath = 4; string zkPath = 4;
} }
message AuthProofRe{ message AuthProofRe{
...@@ -322,13 +321,13 @@ message AuthProofRe{ ...@@ -322,13 +321,13 @@ message AuthProofRe{
} }
message TransferInputTxReq{ message TransferInputTxReq{
string noteHash = 1; string noteHashs = 1;
circuitPathInfo zkPath = 2; string zkPath = 2;
} }
message TransferOutputTxReq{ message TransferOutputTxReq{
DepositInfo deposit = 1; DepositInfo deposit = 1;
circuitPathInfo zkPath = 2; string zkPath = 2;
} }
message TransferTxReq{ message TransferTxReq{
...@@ -371,10 +370,10 @@ message TransferProofResp{ ...@@ -371,10 +370,10 @@ message TransferProofResp{
} }
message ShieldAmountRst{ message ShieldAmountRst{
string inputRandom = 1; repeated string inputRandoms = 1;
string outputRandom = 2; string outputRandom = 2;
string changeRandom = 3; string changeRandom = 3;
ShieldAmount input = 4; repeated ShieldAmount inputs = 4;
ShieldAmount output = 5; ShieldAmount output = 5;
ShieldAmount change = 6; ShieldAmount change = 6;
...@@ -390,6 +389,12 @@ message CreateRawTxReq{ ...@@ -390,6 +389,12 @@ message CreateRawTxReq{
} }
message PaymentKeysReq{
string privKey = 1; //user wallet priv key
string addr = 2; //user addr
int32 detail = 3; //获取私钥信息
}
enum NoteStatus{ enum NoteStatus{
UNDEF = 0; UNDEF = 0;
VALID = 1; //已授权可使用 VALID = 1; //已授权可使用
......
...@@ -657,7 +657,7 @@ func (m *ZkProofInfo) GetSecrets() *DHSecretGroup { ...@@ -657,7 +657,7 @@ func (m *ZkProofInfo) GetSecrets() *DHSecretGroup {
} }
type MixDepositAction struct { type MixDepositAction struct {
Proof *ZkProofInfo `protobuf:"bytes,1,opt,name=proof,proto3" json:"proof,omitempty"` Proofs []*ZkProofInfo `protobuf:"bytes,1,rep,name=proofs,proto3" json:"proofs,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:"-"`
...@@ -688,15 +688,15 @@ func (m *MixDepositAction) XXX_DiscardUnknown() { ...@@ -688,15 +688,15 @@ func (m *MixDepositAction) XXX_DiscardUnknown() {
var xxx_messageInfo_MixDepositAction proto.InternalMessageInfo var xxx_messageInfo_MixDepositAction proto.InternalMessageInfo
func (m *MixDepositAction) GetProof() *ZkProofInfo { func (m *MixDepositAction) GetProofs() []*ZkProofInfo {
if m != nil { if m != nil {
return m.Proof return m.Proofs
} }
return nil return nil
} }
type MixTransferAction struct { type MixTransferAction struct {
Input *ZkProofInfo `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` Inputs []*ZkProofInfo `protobuf:"bytes,1,rep,name=inputs,proto3" json:"inputs,omitempty"`
Output *ZkProofInfo `protobuf:"bytes,2,opt,name=output,proto3" json:"output,omitempty"` Output *ZkProofInfo `protobuf:"bytes,2,opt,name=output,proto3" json:"output,omitempty"`
Change *ZkProofInfo `protobuf:"bytes,3,opt,name=change,proto3" json:"change,omitempty"` Change *ZkProofInfo `protobuf:"bytes,3,opt,name=change,proto3" json:"change,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
...@@ -729,9 +729,9 @@ func (m *MixTransferAction) XXX_DiscardUnknown() { ...@@ -729,9 +729,9 @@ func (m *MixTransferAction) XXX_DiscardUnknown() {
var xxx_messageInfo_MixTransferAction proto.InternalMessageInfo var xxx_messageInfo_MixTransferAction proto.InternalMessageInfo
func (m *MixTransferAction) GetInput() *ZkProofInfo { func (m *MixTransferAction) GetInputs() []*ZkProofInfo {
if m != nil { if m != nil {
return m.Input return m.Inputs
} }
return nil return nil
} }
...@@ -1317,7 +1317,8 @@ func (m *VerifyProofInfo) GetProof() *ZkProofInfo { ...@@ -1317,7 +1317,8 @@ func (m *VerifyProofInfo) GetProof() *ZkProofInfo {
//nullifer 存在value //nullifer 存在value
type ExistValue struct { type ExistValue struct {
Data bool `protobuf:"varint,1,opt,name=data,proto3" json:"data,omitempty"` Nullifier string `protobuf:"bytes,1,opt,name=nullifier,proto3" json:"nullifier,omitempty"`
Exist bool `protobuf:"varint,2,opt,name=exist,proto3" json:"exist,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:"-"`
...@@ -1348,9 +1349,16 @@ func (m *ExistValue) XXX_DiscardUnknown() { ...@@ -1348,9 +1349,16 @@ func (m *ExistValue) XXX_DiscardUnknown() {
var xxx_messageInfo_ExistValue proto.InternalMessageInfo var xxx_messageInfo_ExistValue proto.InternalMessageInfo
func (m *ExistValue) GetData() bool { func (m *ExistValue) GetNullifier() string {
if m != nil { if m != nil {
return m.Data return m.Nullifier
}
return ""
}
func (m *ExistValue) GetExist() bool {
if m != nil {
return m.Exist
} }
return false return false
} }
...@@ -1958,51 +1966,12 @@ func (m *DecryptSecretData) GetPeerKey() string { ...@@ -1958,51 +1966,12 @@ func (m *DecryptSecretData) GetPeerKey() string {
return "" return ""
} }
//path+filename, filename can take default //支持同时存入多个地址,多个地址具有相同的returnAddr和AuthorizeAddr,如果不同,则单个来存
type CircuitPathInfo struct {
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CircuitPathInfo) Reset() { *m = CircuitPathInfo{} }
func (m *CircuitPathInfo) String() string { return proto.CompactTextString(m) }
func (*CircuitPathInfo) ProtoMessage() {}
func (*CircuitPathInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{32}
}
func (m *CircuitPathInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CircuitPathInfo.Unmarshal(m, b)
}
func (m *CircuitPathInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CircuitPathInfo.Marshal(b, m, deterministic)
}
func (m *CircuitPathInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_CircuitPathInfo.Merge(m, src)
}
func (m *CircuitPathInfo) XXX_Size() int {
return xxx_messageInfo_CircuitPathInfo.Size(m)
}
func (m *CircuitPathInfo) XXX_DiscardUnknown() {
xxx_messageInfo_CircuitPathInfo.DiscardUnknown(m)
}
var xxx_messageInfo_CircuitPathInfo proto.InternalMessageInfo
func (m *CircuitPathInfo) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
type DepositInfo struct { type DepositInfo struct {
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` ReceiverAddrs string `protobuf:"bytes,1,opt,name=receiverAddrs,proto3" json:"receiverAddrs,omitempty"`
ReturnAddr string `protobuf:"bytes,2,opt,name=returnAddr,proto3" json:"returnAddr,omitempty"` ReturnAddr string `protobuf:"bytes,2,opt,name=returnAddr,proto3" json:"returnAddr,omitempty"`
AuthorizeAddr string `protobuf:"bytes,3,opt,name=authorizeAddr,proto3" json:"authorizeAddr,omitempty"` AuthorizeAddr string `protobuf:"bytes,3,opt,name=authorizeAddr,proto3" json:"authorizeAddr,omitempty"`
Amount uint64 `protobuf:"varint,4,opt,name=amount,proto3" json:"amount,omitempty"` Amounts string `protobuf:"bytes,4,opt,name=amounts,proto3" json:"amounts,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:"-"`
...@@ -2012,7 +1981,7 @@ func (m *DepositInfo) Reset() { *m = DepositInfo{} } ...@@ -2012,7 +1981,7 @@ func (m *DepositInfo) Reset() { *m = DepositInfo{} }
func (m *DepositInfo) String() string { return proto.CompactTextString(m) } func (m *DepositInfo) String() string { return proto.CompactTextString(m) }
func (*DepositInfo) ProtoMessage() {} func (*DepositInfo) ProtoMessage() {}
func (*DepositInfo) Descriptor() ([]byte, []int) { func (*DepositInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{33} return fileDescriptor_5c21d519a9be369a, []int{32}
} }
func (m *DepositInfo) XXX_Unmarshal(b []byte) error { func (m *DepositInfo) XXX_Unmarshal(b []byte) error {
...@@ -2033,9 +2002,9 @@ func (m *DepositInfo) XXX_DiscardUnknown() { ...@@ -2033,9 +2002,9 @@ func (m *DepositInfo) XXX_DiscardUnknown() {
var xxx_messageInfo_DepositInfo proto.InternalMessageInfo var xxx_messageInfo_DepositInfo proto.InternalMessageInfo
func (m *DepositInfo) GetAddr() string { func (m *DepositInfo) GetReceiverAddrs() string {
if m != nil { if m != nil {
return m.Addr return m.ReceiverAddrs
} }
return "" return ""
} }
...@@ -2054,17 +2023,17 @@ func (m *DepositInfo) GetAuthorizeAddr() string { ...@@ -2054,17 +2023,17 @@ func (m *DepositInfo) GetAuthorizeAddr() string {
return "" return ""
} }
func (m *DepositInfo) GetAmount() uint64 { func (m *DepositInfo) GetAmounts() string {
if m != nil { if m != nil {
return m.Amount return m.Amounts
} }
return 0 return ""
} }
//钱包生成deposit tx //钱包生成deposit tx
type DepositTxReq struct { type DepositTxReq struct {
Deposit *DepositInfo `protobuf:"bytes,1,opt,name=deposit,proto3" json:"deposit,omitempty"` Deposit *DepositInfo `protobuf:"bytes,1,opt,name=deposit,proto3" json:"deposit,omitempty"`
ZkPath *CircuitPathInfo `protobuf:"bytes,2,opt,name=zkPath,proto3" json:"zkPath,omitempty"` ZkPath string `protobuf:"bytes,2,opt,name=zkPath,proto3" json:"zkPath,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:"-"`
...@@ -2074,7 +2043,7 @@ func (m *DepositTxReq) Reset() { *m = DepositTxReq{} } ...@@ -2074,7 +2043,7 @@ func (m *DepositTxReq) Reset() { *m = DepositTxReq{} }
func (m *DepositTxReq) String() string { return proto.CompactTextString(m) } func (m *DepositTxReq) String() string { return proto.CompactTextString(m) }
func (*DepositTxReq) ProtoMessage() {} func (*DepositTxReq) ProtoMessage() {}
func (*DepositTxReq) Descriptor() ([]byte, []int) { func (*DepositTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{34} return fileDescriptor_5c21d519a9be369a, []int{33}
} }
func (m *DepositTxReq) XXX_Unmarshal(b []byte) error { func (m *DepositTxReq) XXX_Unmarshal(b []byte) error {
...@@ -2102,11 +2071,11 @@ func (m *DepositTxReq) GetDeposit() *DepositInfo { ...@@ -2102,11 +2071,11 @@ func (m *DepositTxReq) GetDeposit() *DepositInfo {
return nil return nil
} }
func (m *DepositTxReq) GetZkPath() *CircuitPathInfo { func (m *DepositTxReq) GetZkPath() string {
if m != nil { if m != nil {
return m.ZkPath return m.ZkPath
} }
return nil return ""
} }
type DepositProofResp struct { type DepositProofResp struct {
...@@ -2122,7 +2091,7 @@ func (m *DepositProofResp) Reset() { *m = DepositProofResp{} } ...@@ -2122,7 +2091,7 @@ func (m *DepositProofResp) Reset() { *m = DepositProofResp{} }
func (m *DepositProofResp) String() string { return proto.CompactTextString(m) } func (m *DepositProofResp) String() string { return proto.CompactTextString(m) }
func (*DepositProofResp) ProtoMessage() {} func (*DepositProofResp) ProtoMessage() {}
func (*DepositProofResp) Descriptor() ([]byte, []int) { func (*DepositProofResp) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{35} return fileDescriptor_5c21d519a9be369a, []int{34}
} }
func (m *DepositProofResp) XXX_Unmarshal(b []byte) error { func (m *DepositProofResp) XXX_Unmarshal(b []byte) error {
...@@ -2177,7 +2146,7 @@ func (m *TreePathProof) Reset() { *m = TreePathProof{} } ...@@ -2177,7 +2146,7 @@ func (m *TreePathProof) Reset() { *m = TreePathProof{} }
func (m *TreePathProof) String() string { return proto.CompactTextString(m) } func (m *TreePathProof) String() string { return proto.CompactTextString(m) }
func (*TreePathProof) ProtoMessage() {} func (*TreePathProof) ProtoMessage() {}
func (*TreePathProof) Descriptor() ([]byte, []int) { func (*TreePathProof) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{36} return fileDescriptor_5c21d519a9be369a, []int{35}
} }
func (m *TreePathProof) XXX_Unmarshal(b []byte) error { func (m *TreePathProof) XXX_Unmarshal(b []byte) error {
...@@ -2223,7 +2192,7 @@ func (m *TreePathProof) GetHelpers() []uint32 { ...@@ -2223,7 +2192,7 @@ func (m *TreePathProof) GetHelpers() []uint32 {
type WithdrawTxReq struct { type WithdrawTxReq struct {
TotalAmount uint64 `protobuf:"varint,1,opt,name=totalAmount,proto3" json:"totalAmount,omitempty"` TotalAmount uint64 `protobuf:"varint,1,opt,name=totalAmount,proto3" json:"totalAmount,omitempty"`
NoteHashs string `protobuf:"bytes,2,opt,name=noteHashs,proto3" json:"noteHashs,omitempty"` NoteHashs string `protobuf:"bytes,2,opt,name=noteHashs,proto3" json:"noteHashs,omitempty"`
ZkPath *CircuitPathInfo `protobuf:"bytes,3,opt,name=zkPath,proto3" json:"zkPath,omitempty"` ZkPath string `protobuf:"bytes,3,opt,name=zkPath,proto3" json:"zkPath,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:"-"`
...@@ -2233,7 +2202,7 @@ func (m *WithdrawTxReq) Reset() { *m = WithdrawTxReq{} } ...@@ -2233,7 +2202,7 @@ func (m *WithdrawTxReq) Reset() { *m = WithdrawTxReq{} }
func (m *WithdrawTxReq) String() string { return proto.CompactTextString(m) } func (m *WithdrawTxReq) String() string { return proto.CompactTextString(m) }
func (*WithdrawTxReq) ProtoMessage() {} func (*WithdrawTxReq) ProtoMessage() {}
func (*WithdrawTxReq) Descriptor() ([]byte, []int) { func (*WithdrawTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{37} return fileDescriptor_5c21d519a9be369a, []int{36}
} }
func (m *WithdrawTxReq) XXX_Unmarshal(b []byte) error { func (m *WithdrawTxReq) XXX_Unmarshal(b []byte) error {
...@@ -2268,11 +2237,11 @@ func (m *WithdrawTxReq) GetNoteHashs() string { ...@@ -2268,11 +2237,11 @@ func (m *WithdrawTxReq) GetNoteHashs() string {
return "" return ""
} }
func (m *WithdrawTxReq) GetZkPath() *CircuitPathInfo { func (m *WithdrawTxReq) GetZkPath() string {
if m != nil { if m != nil {
return m.ZkPath return m.ZkPath
} }
return nil return ""
} }
type WithdrawProofRe struct { type WithdrawProofRe struct {
...@@ -2293,7 +2262,7 @@ func (m *WithdrawProofRe) Reset() { *m = WithdrawProofRe{} } ...@@ -2293,7 +2262,7 @@ func (m *WithdrawProofRe) Reset() { *m = WithdrawProofRe{} }
func (m *WithdrawProofRe) String() string { return proto.CompactTextString(m) } func (m *WithdrawProofRe) String() string { return proto.CompactTextString(m) }
func (*WithdrawProofRe) ProtoMessage() {} func (*WithdrawProofRe) ProtoMessage() {}
func (*WithdrawProofRe) Descriptor() ([]byte, []int) { func (*WithdrawProofRe) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{38} return fileDescriptor_5c21d519a9be369a, []int{37}
} }
func (m *WithdrawProofRe) XXX_Unmarshal(b []byte) error { func (m *WithdrawProofRe) XXX_Unmarshal(b []byte) error {
...@@ -2374,7 +2343,7 @@ func (m *WithdrawProofRe) GetTreeProof() *TreePathProof { ...@@ -2374,7 +2343,7 @@ func (m *WithdrawProofRe) GetTreeProof() *TreePathProof {
type AuthTxReq struct { type AuthTxReq struct {
NoteHash string `protobuf:"bytes,1,opt,name=noteHash,proto3" json:"noteHash,omitempty"` NoteHash string `protobuf:"bytes,1,opt,name=noteHash,proto3" json:"noteHash,omitempty"`
AuthorizeToAddr string `protobuf:"bytes,3,opt,name=authorizeToAddr,proto3" json:"authorizeToAddr,omitempty"` AuthorizeToAddr string `protobuf:"bytes,3,opt,name=authorizeToAddr,proto3" json:"authorizeToAddr,omitempty"`
ZkPath *CircuitPathInfo `protobuf:"bytes,4,opt,name=zkPath,proto3" json:"zkPath,omitempty"` ZkPath string `protobuf:"bytes,4,opt,name=zkPath,proto3" json:"zkPath,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:"-"`
...@@ -2384,7 +2353,7 @@ func (m *AuthTxReq) Reset() { *m = AuthTxReq{} } ...@@ -2384,7 +2353,7 @@ func (m *AuthTxReq) Reset() { *m = AuthTxReq{} }
func (m *AuthTxReq) String() string { return proto.CompactTextString(m) } func (m *AuthTxReq) String() string { return proto.CompactTextString(m) }
func (*AuthTxReq) ProtoMessage() {} func (*AuthTxReq) ProtoMessage() {}
func (*AuthTxReq) Descriptor() ([]byte, []int) { func (*AuthTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{39} return fileDescriptor_5c21d519a9be369a, []int{38}
} }
func (m *AuthTxReq) XXX_Unmarshal(b []byte) error { func (m *AuthTxReq) XXX_Unmarshal(b []byte) error {
...@@ -2419,11 +2388,11 @@ func (m *AuthTxReq) GetAuthorizeToAddr() string { ...@@ -2419,11 +2388,11 @@ func (m *AuthTxReq) GetAuthorizeToAddr() string {
return "" return ""
} }
func (m *AuthTxReq) GetZkPath() *CircuitPathInfo { func (m *AuthTxReq) GetZkPath() string {
if m != nil { if m != nil {
return m.ZkPath return m.ZkPath
} }
return nil return ""
} }
type AuthProofRe struct { type AuthProofRe struct {
...@@ -2444,7 +2413,7 @@ func (m *AuthProofRe) Reset() { *m = AuthProofRe{} } ...@@ -2444,7 +2413,7 @@ func (m *AuthProofRe) Reset() { *m = AuthProofRe{} }
func (m *AuthProofRe) String() string { return proto.CompactTextString(m) } func (m *AuthProofRe) String() string { return proto.CompactTextString(m) }
func (*AuthProofRe) ProtoMessage() {} func (*AuthProofRe) ProtoMessage() {}
func (*AuthProofRe) Descriptor() ([]byte, []int) { func (*AuthProofRe) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{40} return fileDescriptor_5c21d519a9be369a, []int{39}
} }
func (m *AuthProofRe) XXX_Unmarshal(b []byte) error { func (m *AuthProofRe) XXX_Unmarshal(b []byte) error {
...@@ -2522,8 +2491,8 @@ func (m *AuthProofRe) GetTreeProof() *TreePathProof { ...@@ -2522,8 +2491,8 @@ func (m *AuthProofRe) GetTreeProof() *TreePathProof {
} }
type TransferInputTxReq struct { type TransferInputTxReq struct {
NoteHash string `protobuf:"bytes,1,opt,name=noteHash,proto3" json:"noteHash,omitempty"` NoteHashs string `protobuf:"bytes,1,opt,name=noteHashs,proto3" json:"noteHashs,omitempty"`
ZkPath *CircuitPathInfo `protobuf:"bytes,2,opt,name=zkPath,proto3" json:"zkPath,omitempty"` ZkPath string `protobuf:"bytes,2,opt,name=zkPath,proto3" json:"zkPath,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:"-"`
...@@ -2533,7 +2502,7 @@ func (m *TransferInputTxReq) Reset() { *m = TransferInputTxReq{} } ...@@ -2533,7 +2502,7 @@ func (m *TransferInputTxReq) Reset() { *m = TransferInputTxReq{} }
func (m *TransferInputTxReq) String() string { return proto.CompactTextString(m) } func (m *TransferInputTxReq) String() string { return proto.CompactTextString(m) }
func (*TransferInputTxReq) ProtoMessage() {} func (*TransferInputTxReq) ProtoMessage() {}
func (*TransferInputTxReq) Descriptor() ([]byte, []int) { func (*TransferInputTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{41} return fileDescriptor_5c21d519a9be369a, []int{40}
} }
func (m *TransferInputTxReq) XXX_Unmarshal(b []byte) error { func (m *TransferInputTxReq) XXX_Unmarshal(b []byte) error {
...@@ -2554,23 +2523,23 @@ func (m *TransferInputTxReq) XXX_DiscardUnknown() { ...@@ -2554,23 +2523,23 @@ func (m *TransferInputTxReq) XXX_DiscardUnknown() {
var xxx_messageInfo_TransferInputTxReq proto.InternalMessageInfo var xxx_messageInfo_TransferInputTxReq proto.InternalMessageInfo
func (m *TransferInputTxReq) GetNoteHash() string { func (m *TransferInputTxReq) GetNoteHashs() string {
if m != nil { if m != nil {
return m.NoteHash return m.NoteHashs
} }
return "" return ""
} }
func (m *TransferInputTxReq) GetZkPath() *CircuitPathInfo { func (m *TransferInputTxReq) GetZkPath() string {
if m != nil { if m != nil {
return m.ZkPath return m.ZkPath
} }
return nil return ""
} }
type TransferOutputTxReq struct { type TransferOutputTxReq struct {
Deposit *DepositInfo `protobuf:"bytes,1,opt,name=deposit,proto3" json:"deposit,omitempty"` Deposit *DepositInfo `protobuf:"bytes,1,opt,name=deposit,proto3" json:"deposit,omitempty"`
ZkPath *CircuitPathInfo `protobuf:"bytes,2,opt,name=zkPath,proto3" json:"zkPath,omitempty"` ZkPath string `protobuf:"bytes,2,opt,name=zkPath,proto3" json:"zkPath,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:"-"`
...@@ -2580,7 +2549,7 @@ func (m *TransferOutputTxReq) Reset() { *m = TransferOutputTxReq{} } ...@@ -2580,7 +2549,7 @@ func (m *TransferOutputTxReq) Reset() { *m = TransferOutputTxReq{} }
func (m *TransferOutputTxReq) String() string { return proto.CompactTextString(m) } func (m *TransferOutputTxReq) String() string { return proto.CompactTextString(m) }
func (*TransferOutputTxReq) ProtoMessage() {} func (*TransferOutputTxReq) ProtoMessage() {}
func (*TransferOutputTxReq) Descriptor() ([]byte, []int) { func (*TransferOutputTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{42} return fileDescriptor_5c21d519a9be369a, []int{41}
} }
func (m *TransferOutputTxReq) XXX_Unmarshal(b []byte) error { func (m *TransferOutputTxReq) XXX_Unmarshal(b []byte) error {
...@@ -2608,11 +2577,11 @@ func (m *TransferOutputTxReq) GetDeposit() *DepositInfo { ...@@ -2608,11 +2577,11 @@ func (m *TransferOutputTxReq) GetDeposit() *DepositInfo {
return nil return nil
} }
func (m *TransferOutputTxReq) GetZkPath() *CircuitPathInfo { func (m *TransferOutputTxReq) GetZkPath() string {
if m != nil { if m != nil {
return m.ZkPath return m.ZkPath
} }
return nil return ""
} }
type TransferTxReq struct { type TransferTxReq struct {
...@@ -2627,7 +2596,7 @@ func (m *TransferTxReq) Reset() { *m = TransferTxReq{} } ...@@ -2627,7 +2596,7 @@ func (m *TransferTxReq) Reset() { *m = TransferTxReq{} }
func (m *TransferTxReq) String() string { return proto.CompactTextString(m) } func (m *TransferTxReq) String() string { return proto.CompactTextString(m) }
func (*TransferTxReq) ProtoMessage() {} func (*TransferTxReq) ProtoMessage() {}
func (*TransferTxReq) Descriptor() ([]byte, []int) { func (*TransferTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{43} return fileDescriptor_5c21d519a9be369a, []int{42}
} }
func (m *TransferTxReq) XXX_Unmarshal(b []byte) error { func (m *TransferTxReq) XXX_Unmarshal(b []byte) error {
...@@ -2675,7 +2644,7 @@ func (m *ShieldAmount) Reset() { *m = ShieldAmount{} } ...@@ -2675,7 +2644,7 @@ func (m *ShieldAmount) Reset() { *m = ShieldAmount{} }
func (m *ShieldAmount) String() string { return proto.CompactTextString(m) } func (m *ShieldAmount) String() string { return proto.CompactTextString(m) }
func (*ShieldAmount) ProtoMessage() {} func (*ShieldAmount) ProtoMessage() {}
func (*ShieldAmount) Descriptor() ([]byte, []int) { func (*ShieldAmount) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{44} return fileDescriptor_5c21d519a9be369a, []int{43}
} }
func (m *ShieldAmount) XXX_Unmarshal(b []byte) error { func (m *ShieldAmount) XXX_Unmarshal(b []byte) error {
...@@ -2730,7 +2699,7 @@ func (m *TransferInputProof) Reset() { *m = TransferInputProof{} } ...@@ -2730,7 +2699,7 @@ func (m *TransferInputProof) Reset() { *m = TransferInputProof{} }
func (m *TransferInputProof) String() string { return proto.CompactTextString(m) } func (m *TransferInputProof) String() string { return proto.CompactTextString(m) }
func (*TransferInputProof) ProtoMessage() {} func (*TransferInputProof) ProtoMessage() {}
func (*TransferInputProof) Descriptor() ([]byte, []int) { func (*TransferInputProof) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{45} return fileDescriptor_5c21d519a9be369a, []int{44}
} }
func (m *TransferInputProof) XXX_Unmarshal(b []byte) error { func (m *TransferInputProof) XXX_Unmarshal(b []byte) error {
...@@ -2836,7 +2805,7 @@ func (m *TransferOutputProof) Reset() { *m = TransferOutputProof{} } ...@@ -2836,7 +2805,7 @@ func (m *TransferOutputProof) Reset() { *m = TransferOutputProof{} }
func (m *TransferOutputProof) String() string { return proto.CompactTextString(m) } func (m *TransferOutputProof) String() string { return proto.CompactTextString(m) }
func (*TransferOutputProof) ProtoMessage() {} func (*TransferOutputProof) ProtoMessage() {}
func (*TransferOutputProof) Descriptor() ([]byte, []int) { func (*TransferOutputProof) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{46} return fileDescriptor_5c21d519a9be369a, []int{45}
} }
func (m *TransferOutputProof) XXX_Unmarshal(b []byte) error { func (m *TransferOutputProof) XXX_Unmarshal(b []byte) error {
...@@ -2905,7 +2874,7 @@ func (m *TransferProofResp) Reset() { *m = TransferProofResp{} } ...@@ -2905,7 +2874,7 @@ func (m *TransferProofResp) Reset() { *m = TransferProofResp{} }
func (m *TransferProofResp) String() string { return proto.CompactTextString(m) } func (m *TransferProofResp) String() string { return proto.CompactTextString(m) }
func (*TransferProofResp) ProtoMessage() {} func (*TransferProofResp) ProtoMessage() {}
func (*TransferProofResp) Descriptor() ([]byte, []int) { func (*TransferProofResp) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{47} return fileDescriptor_5c21d519a9be369a, []int{46}
} }
func (m *TransferProofResp) XXX_Unmarshal(b []byte) error { func (m *TransferProofResp) XXX_Unmarshal(b []byte) error {
...@@ -2948,10 +2917,10 @@ func (m *TransferProofResp) GetChangeOutput() *TransferOutputProof { ...@@ -2948,10 +2917,10 @@ func (m *TransferProofResp) GetChangeOutput() *TransferOutputProof {
} }
type ShieldAmountRst struct { type ShieldAmountRst struct {
InputRandom string `protobuf:"bytes,1,opt,name=inputRandom,proto3" json:"inputRandom,omitempty"` InputRandoms []string `protobuf:"bytes,1,rep,name=inputRandoms,proto3" json:"inputRandoms,omitempty"`
OutputRandom string `protobuf:"bytes,2,opt,name=outputRandom,proto3" json:"outputRandom,omitempty"` OutputRandom string `protobuf:"bytes,2,opt,name=outputRandom,proto3" json:"outputRandom,omitempty"`
ChangeRandom string `protobuf:"bytes,3,opt,name=changeRandom,proto3" json:"changeRandom,omitempty"` ChangeRandom string `protobuf:"bytes,3,opt,name=changeRandom,proto3" json:"changeRandom,omitempty"`
Input *ShieldAmount `protobuf:"bytes,4,opt,name=input,proto3" json:"input,omitempty"` Inputs []*ShieldAmount `protobuf:"bytes,4,rep,name=inputs,proto3" json:"inputs,omitempty"`
Output *ShieldAmount `protobuf:"bytes,5,opt,name=output,proto3" json:"output,omitempty"` Output *ShieldAmount `protobuf:"bytes,5,opt,name=output,proto3" json:"output,omitempty"`
Change *ShieldAmount `protobuf:"bytes,6,opt,name=change,proto3" json:"change,omitempty"` Change *ShieldAmount `protobuf:"bytes,6,opt,name=change,proto3" json:"change,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
...@@ -2963,7 +2932,7 @@ func (m *ShieldAmountRst) Reset() { *m = ShieldAmountRst{} } ...@@ -2963,7 +2932,7 @@ func (m *ShieldAmountRst) Reset() { *m = ShieldAmountRst{} }
func (m *ShieldAmountRst) String() string { return proto.CompactTextString(m) } func (m *ShieldAmountRst) String() string { return proto.CompactTextString(m) }
func (*ShieldAmountRst) ProtoMessage() {} func (*ShieldAmountRst) ProtoMessage() {}
func (*ShieldAmountRst) Descriptor() ([]byte, []int) { func (*ShieldAmountRst) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{48} return fileDescriptor_5c21d519a9be369a, []int{47}
} }
func (m *ShieldAmountRst) XXX_Unmarshal(b []byte) error { func (m *ShieldAmountRst) XXX_Unmarshal(b []byte) error {
...@@ -2984,11 +2953,11 @@ func (m *ShieldAmountRst) XXX_DiscardUnknown() { ...@@ -2984,11 +2953,11 @@ func (m *ShieldAmountRst) XXX_DiscardUnknown() {
var xxx_messageInfo_ShieldAmountRst proto.InternalMessageInfo var xxx_messageInfo_ShieldAmountRst proto.InternalMessageInfo
func (m *ShieldAmountRst) GetInputRandom() string { func (m *ShieldAmountRst) GetInputRandoms() []string {
if m != nil { if m != nil {
return m.InputRandom return m.InputRandoms
} }
return "" return nil
} }
func (m *ShieldAmountRst) GetOutputRandom() string { func (m *ShieldAmountRst) GetOutputRandom() string {
...@@ -3005,9 +2974,9 @@ func (m *ShieldAmountRst) GetChangeRandom() string { ...@@ -3005,9 +2974,9 @@ func (m *ShieldAmountRst) GetChangeRandom() string {
return "" return ""
} }
func (m *ShieldAmountRst) GetInput() *ShieldAmount { func (m *ShieldAmountRst) GetInputs() []*ShieldAmount {
if m != nil { if m != nil {
return m.Input return m.Inputs
} }
return nil return nil
} }
...@@ -3041,7 +3010,7 @@ func (m *CreateRawTxReq) Reset() { *m = CreateRawTxReq{} } ...@@ -3041,7 +3010,7 @@ func (m *CreateRawTxReq) Reset() { *m = CreateRawTxReq{} }
func (m *CreateRawTxReq) String() string { return proto.CompactTextString(m) } func (m *CreateRawTxReq) String() string { return proto.CompactTextString(m) }
func (*CreateRawTxReq) ProtoMessage() {} func (*CreateRawTxReq) ProtoMessage() {}
func (*CreateRawTxReq) Descriptor() ([]byte, []int) { func (*CreateRawTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{49} return fileDescriptor_5c21d519a9be369a, []int{48}
} }
func (m *CreateRawTxReq) XXX_Unmarshal(b []byte) error { func (m *CreateRawTxReq) XXX_Unmarshal(b []byte) error {
...@@ -3097,6 +3066,61 @@ func (m *CreateRawTxReq) GetTitle() string { ...@@ -3097,6 +3066,61 @@ func (m *CreateRawTxReq) GetTitle() string {
return "" return ""
} }
type PaymentKeysReq struct {
PrivKey string `protobuf:"bytes,1,opt,name=privKey,proto3" json:"privKey,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
Detail int32 `protobuf:"varint,3,opt,name=detail,proto3" json:"detail,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PaymentKeysReq) Reset() { *m = PaymentKeysReq{} }
func (m *PaymentKeysReq) String() string { return proto.CompactTextString(m) }
func (*PaymentKeysReq) ProtoMessage() {}
func (*PaymentKeysReq) Descriptor() ([]byte, []int) {
return fileDescriptor_5c21d519a9be369a, []int{49}
}
func (m *PaymentKeysReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PaymentKeysReq.Unmarshal(m, b)
}
func (m *PaymentKeysReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PaymentKeysReq.Marshal(b, m, deterministic)
}
func (m *PaymentKeysReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_PaymentKeysReq.Merge(m, src)
}
func (m *PaymentKeysReq) XXX_Size() int {
return xxx_messageInfo_PaymentKeysReq.Size(m)
}
func (m *PaymentKeysReq) XXX_DiscardUnknown() {
xxx_messageInfo_PaymentKeysReq.DiscardUnknown(m)
}
var xxx_messageInfo_PaymentKeysReq proto.InternalMessageInfo
func (m *PaymentKeysReq) GetPrivKey() string {
if m != nil {
return m.PrivKey
}
return ""
}
func (m *PaymentKeysReq) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
func (m *PaymentKeysReq) GetDetail() int32 {
if m != nil {
return m.Detail
}
return 0
}
type WalletIndexInfo struct { type WalletIndexInfo struct {
NoteHash string `protobuf:"bytes,1,opt,name=noteHash,proto3" json:"noteHash,omitempty"` NoteHash string `protobuf:"bytes,1,opt,name=noteHash,proto3" json:"noteHash,omitempty"`
Nullifier string `protobuf:"bytes,2,opt,name=nullifier,proto3" json:"nullifier,omitempty"` Nullifier string `protobuf:"bytes,2,opt,name=nullifier,proto3" json:"nullifier,omitempty"`
...@@ -3796,7 +3820,6 @@ func init() { ...@@ -3796,7 +3820,6 @@ func init() {
proto.RegisterType((*SecretData)(nil), "types.SecretData") proto.RegisterType((*SecretData)(nil), "types.SecretData")
proto.RegisterType((*EncryptSecretData)(nil), "types.EncryptSecretData") proto.RegisterType((*EncryptSecretData)(nil), "types.EncryptSecretData")
proto.RegisterType((*DecryptSecretData)(nil), "types.DecryptSecretData") proto.RegisterType((*DecryptSecretData)(nil), "types.DecryptSecretData")
proto.RegisterType((*CircuitPathInfo)(nil), "types.circuitPathInfo")
proto.RegisterType((*DepositInfo)(nil), "types.DepositInfo") proto.RegisterType((*DepositInfo)(nil), "types.DepositInfo")
proto.RegisterType((*DepositTxReq)(nil), "types.DepositTxReq") proto.RegisterType((*DepositTxReq)(nil), "types.DepositTxReq")
proto.RegisterType((*DepositProofResp)(nil), "types.DepositProofResp") proto.RegisterType((*DepositProofResp)(nil), "types.DepositProofResp")
...@@ -3814,6 +3837,7 @@ func init() { ...@@ -3814,6 +3837,7 @@ func init() {
proto.RegisterType((*TransferProofResp)(nil), "types.TransferProofResp") proto.RegisterType((*TransferProofResp)(nil), "types.TransferProofResp")
proto.RegisterType((*ShieldAmountRst)(nil), "types.ShieldAmountRst") proto.RegisterType((*ShieldAmountRst)(nil), "types.ShieldAmountRst")
proto.RegisterType((*CreateRawTxReq)(nil), "types.CreateRawTxReq") proto.RegisterType((*CreateRawTxReq)(nil), "types.CreateRawTxReq")
proto.RegisterType((*PaymentKeysReq)(nil), "types.PaymentKeysReq")
proto.RegisterType((*WalletIndexInfo)(nil), "types.WalletIndexInfo") proto.RegisterType((*WalletIndexInfo)(nil), "types.WalletIndexInfo")
proto.RegisterType((*WalletDbMixInfo)(nil), "types.WalletDbMixInfo") proto.RegisterType((*WalletDbMixInfo)(nil), "types.WalletDbMixInfo")
proto.RegisterType((*WalletMixIndexReq)(nil), "types.WalletMixIndexReq") proto.RegisterType((*WalletMixIndexReq)(nil), "types.WalletMixIndexReq")
...@@ -3833,170 +3857,172 @@ func init() { ...@@ -3833,170 +3857,172 @@ func init() {
} }
var fileDescriptor_5c21d519a9be369a = []byte{ var fileDescriptor_5c21d519a9be369a = []byte{
// 2597 bytes of a gzipped FileDescriptorProto // 2625 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0x4b, 0x73, 0x1b, 0xc7, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x73, 0x23, 0x47,
0xf1, 0xe7, 0xe2, 0x8d, 0x26, 0x40, 0x82, 0x23, 0x59, 0x86, 0x59, 0xfe, 0xfb, 0xcf, 0x8c, 0x5f, 0x15, 0xf7, 0xe8, 0xd3, 0x7a, 0x96, 0x6c, 0xb9, 0x77, 0xe3, 0x28, 0xae, 0x10, 0x4c, 0x27, 0x24,
0x34, 0xed, 0x62, 0x1c, 0xc8, 0x71, 0x92, 0x2a, 0xc7, 0x2e, 0x58, 0x80, 0x44, 0x44, 0x22, 0xc8, 0xc6, 0x9b, 0x5a, 0x82, 0x36, 0x04, 0xa8, 0x82, 0x0d, 0xca, 0x4a, 0x1b, 0x2b, 0x59, 0xcb, 0xae,
0x1a, 0x80, 0xa2, 0xa4, 0x94, 0x53, 0x59, 0x01, 0x43, 0x72, 0x4b, 0x20, 0x16, 0xda, 0x1d, 0x50, 0x96, 0xbc, 0xde, 0xdd, 0x54, 0xa8, 0x9a, 0x95, 0xda, 0xf6, 0xd4, 0xca, 0x1a, 0xed, 0xcc, 0xc8,
0xa0, 0x2f, 0x4e, 0x2a, 0x87, 0x5c, 0x72, 0x4c, 0xae, 0xa9, 0xca, 0x29, 0x3e, 0xa7, 0x52, 0x39, 0x2b, 0xe7, 0x46, 0x41, 0x15, 0x17, 0x6e, 0x50, 0xc5, 0x8d, 0x2a, 0x4e, 0xe4, 0x4c, 0x51, 0x1c,
0xe4, 0x23, 0xe4, 0x9c, 0x0f, 0x90, 0xaa, 0x1c, 0x72, 0xcf, 0x27, 0x48, 0xf5, 0x3c, 0x76, 0x67, 0xf8, 0x13, 0x38, 0xf3, 0x07, 0x50, 0xc5, 0x81, 0x3b, 0x7f, 0x01, 0xf5, 0xfa, 0x63, 0xa6, 0x7b,
0x97, 0xe0, 0x4b, 0x71, 0x72, 0xca, 0x0d, 0xdd, 0xdb, 0x33, 0xd3, 0xfd, 0xeb, 0x9e, 0x9e, 0xdf, 0x2c, 0xf9, 0x63, 0x59, 0x6e, 0xdc, 0xfc, 0xde, 0xbc, 0x7e, 0xfd, 0xde, 0xef, 0x7d, 0xf4, 0xeb,
0x0c, 0x09, 0xe5, 0x63, 0x6f, 0xb6, 0x39, 0x09, 0x7c, 0xe1, 0x93, 0xbc, 0x38, 0x9d, 0xf0, 0x70, 0x96, 0xa1, 0x74, 0xe2, 0x4d, 0x6f, 0x8f, 0x03, 0x3f, 0xf2, 0x49, 0x3e, 0x3a, 0x1b, 0xf3, 0x70,
0xb5, 0x32, 0xf0, 0x8f, 0x8f, 0xfd, 0xb1, 0x52, 0xae, 0xae, 0x88, 0xc0, 0x1d, 0x87, 0xee, 0x40, 0xbd, 0xdc, 0xf7, 0x4f, 0x4e, 0xfc, 0x91, 0x64, 0xae, 0xaf, 0x46, 0x81, 0x3b, 0x0a, 0xdd, 0x7e,
0x78, 0x46, 0x45, 0x7f, 0x04, 0x8b, 0x4f, 0x9e, 0x3d, 0xe4, 0x81, 0x77, 0x70, 0x7a, 0x9f, 0x9f, 0xe4, 0x69, 0x16, 0xfd, 0x0c, 0x96, 0x9e, 0x3c, 0x7b, 0xc8, 0x03, 0xef, 0xf0, 0xec, 0x73, 0x7e,
0x92, 0xb7, 0x21, 0x87, 0x03, 0xeb, 0xce, 0x9a, 0xb3, 0xbe, 0xd4, 0x58, 0xd9, 0x94, 0xb3, 0x6c, 0x46, 0xbe, 0x0d, 0x39, 0x5c, 0x58, 0x73, 0x36, 0x9c, 0xcd, 0xe5, 0xfa, 0xea, 0x6d, 0xa1, 0xe5,
0xaa, 0xef, 0xfd, 0xd3, 0x09, 0x67, 0xf2, 0x33, 0xb9, 0x09, 0xf9, 0x13, 0x77, 0x34, 0xe5, 0xf5, 0xb6, 0xfc, 0xde, 0x3b, 0x1b, 0x73, 0x26, 0x3e, 0x93, 0x9b, 0x90, 0x3f, 0x75, 0x87, 0x13, 0x5e,
0xcc, 0x9a, 0xb3, 0x5e, 0x66, 0x4a, 0xa0, 0x1f, 0x43, 0xc5, 0x9a, 0x2b, 0x24, 0xef, 0x40, 0x6e, 0xcb, 0x6c, 0x38, 0x9b, 0x25, 0x26, 0x09, 0xfa, 0x11, 0x94, 0x0d, 0x5d, 0x21, 0x79, 0x17, 0x72,
0xe8, 0x0a, 0xb7, 0xee, 0xac, 0x65, 0xd7, 0x17, 0x1b, 0x44, 0x4f, 0x66, 0x99, 0x30, 0xf9, 0x9d, 0x03, 0x37, 0x72, 0x6b, 0xce, 0x46, 0x76, 0x73, 0xa9, 0x4e, 0x94, 0x32, 0x43, 0x84, 0x89, 0xef,
0xbe, 0x01, 0xa5, 0xe6, 0x54, 0x1c, 0xc9, 0x31, 0x04, 0x72, 0xcf, 0xf8, 0x69, 0x28, 0xc7, 0x94, 0xf4, 0x2d, 0x58, 0x6c, 0x4c, 0xa2, 0x63, 0xb1, 0x86, 0x40, 0xee, 0x19, 0x3f, 0x0b, 0xc5, 0x9a,
0x99, 0xfc, 0x4d, 0x9f, 0x02, 0xec, 0xba, 0xa7, 0xc7, 0x7c, 0x2c, 0xd0, 0x45, 0x02, 0x39, 0x77, 0x12, 0x13, 0x7f, 0xd3, 0xa7, 0x00, 0x7b, 0xee, 0xd9, 0x09, 0x1f, 0x45, 0x68, 0x22, 0x81, 0x9c,
0x38, 0x0c, 0xa4, 0x8b, 0x65, 0x26, 0x7f, 0x93, 0x35, 0x58, 0x0c, 0xf8, 0x80, 0x7b, 0x27, 0x3c, 0x3b, 0x18, 0x04, 0xc2, 0xc4, 0x12, 0x13, 0x7f, 0x93, 0x0d, 0x58, 0x0a, 0x78, 0x9f, 0x7b, 0xa7,
0xb8, 0xcf, 0x4f, 0xb5, 0x57, 0xb6, 0x8a, 0xbc, 0x01, 0xc0, 0xc7, 0x83, 0xe0, 0x74, 0x82, 0x73, 0x3c, 0xf8, 0x9c, 0x9f, 0x29, 0xab, 0x4c, 0x16, 0x79, 0x0b, 0x80, 0x8f, 0xfa, 0xc1, 0xd9, 0x18,
0xd4, 0xb3, 0xd2, 0xc0, 0xd2, 0xd0, 0x7f, 0x3a, 0xb0, 0xbc, 0xed, 0xcd, 0xee, 0xf8, 0xe3, 0x03, 0x75, 0xd4, 0xb2, 0x42, 0xc0, 0xe0, 0xd0, 0x7f, 0x3b, 0xb0, 0xb2, 0xe3, 0x4d, 0xef, 0xf9, 0xa3,
0xef, 0xb0, 0x29, 0x11, 0x22, 0x6f, 0x41, 0xa6, 0x7f, 0xaa, 0xa1, 0xb8, 0xa9, 0xbd, 0x8f, 0x6c, 0x43, 0xef, 0xa8, 0x21, 0x10, 0x22, 0xef, 0x40, 0xa6, 0x77, 0xa6, 0xa0, 0xb8, 0xa9, 0xac, 0x8f,
0x24, 0x1a, 0x99, 0xfe, 0x29, 0x79, 0x1f, 0x0a, 0xca, 0x5e, 0x2e, 0xbb, 0xd4, 0xb8, 0x91, 0xb6, 0x65, 0x04, 0x1a, 0x99, 0xde, 0x19, 0xb9, 0x05, 0x05, 0x29, 0x2f, 0xb6, 0x5d, 0xae, 0xdf, 0x48,
0x6c, 0x0e, 0x04, 0xd3, 0x26, 0xa4, 0x01, 0xe5, 0x13, 0x13, 0xbd, 0xf4, 0x62, 0x2e, 0x2e, 0x5b, 0x4b, 0x36, 0xfa, 0x11, 0x53, 0x22, 0xa4, 0x0e, 0xa5, 0x53, 0xed, 0xbd, 0xb0, 0x62, 0x26, 0x2e,
0x0b, 0x2c, 0x36, 0x23, 0xab, 0x50, 0x74, 0x15, 0x3c, 0xf5, 0x1c, 0xfa, 0xbd, 0xb5, 0xc0, 0x8c, 0xdb, 0x0b, 0x2c, 0x11, 0x23, 0xeb, 0x50, 0x74, 0x25, 0x3c, 0xb5, 0x1c, 0xda, 0xbd, 0xbd, 0xc0,
0x82, 0xdc, 0x06, 0x98, 0x44, 0xd0, 0xd4, 0xf3, 0x72, 0x42, 0x93, 0xb5, 0x18, 0xb3, 0xad, 0x05, 0x34, 0x83, 0xdc, 0x01, 0x18, 0xc7, 0xd0, 0xd4, 0xf2, 0x42, 0xa1, 0x8e, 0x5a, 0x82, 0xd9, 0xf6,
0x66, 0x99, 0x7d, 0x5e, 0xd4, 0xd9, 0xa3, 0x9f, 0x40, 0xa9, 0xb5, 0xd5, 0xe3, 0x83, 0x80, 0x0b, 0x02, 0x33, 0xc4, 0x3e, 0x29, 0xaa, 0xe8, 0xd1, 0x1f, 0xc3, 0x62, 0x73, 0xbb, 0xcb, 0xfb, 0x01,
0x52, 0x87, 0xe2, 0x84, 0x2b, 0xf8, 0x14, 0xb2, 0x46, 0x24, 0xb7, 0xa0, 0x10, 0x4a, 0x1b, 0x8d, 0x8f, 0x48, 0x0d, 0x8a, 0x63, 0x2e, 0xe1, 0x93, 0xc8, 0x6a, 0x92, 0xac, 0x41, 0x21, 0x14, 0x32,
0xab, 0x96, 0x28, 0x87, 0xaa, 0x19, 0x7d, 0x2f, 0xf0, 0xa7, 0x13, 0xb2, 0x0a, 0x25, 0x03, 0xb9, 0x0a, 0x57, 0x45, 0x51, 0x0e, 0x15, 0xbd, 0xfa, 0xd3, 0xc0, 0x9f, 0x8c, 0xc9, 0x3a, 0x2c, 0x6a,
0x9e, 0x23, 0x92, 0xd5, 0x37, 0x31, 0x0d, 0xc6, 0x3c, 0xd0, 0xd3, 0x44, 0x32, 0x79, 0x1d, 0xca, 0xc8, 0x95, 0x8e, 0x98, 0x96, 0xdf, 0xa2, 0x49, 0x30, 0xe2, 0x81, 0x52, 0x13, 0xd3, 0xe4, 0x4d,
0x18, 0x8f, 0x1f, 0x78, 0x5f, 0x72, 0x9d, 0x9a, 0x58, 0x41, 0xa7, 0x58, 0xa1, 0xbb, 0x81, 0xef, 0x28, 0xa1, 0x3f, 0x7e, 0xe0, 0x7d, 0xc5, 0x55, 0x68, 0x12, 0x06, 0x9d, 0x60, 0x86, 0xee, 0x05,
0x1f, 0x74, 0xc6, 0x07, 0x3e, 0x96, 0xde, 0x04, 0x05, 0xbd, 0x82, 0x12, 0xb0, 0x00, 0x26, 0xd3, 0xbe, 0x7f, 0xd8, 0x1e, 0x1d, 0xfa, 0x98, 0x7a, 0x63, 0x24, 0xd4, 0x0e, 0x92, 0xc0, 0x04, 0x18,
0xa7, 0x23, 0x6f, 0xd0, 0x19, 0x4f, 0xa6, 0xc6, 0x51, 0x5b, 0x45, 0x36, 0xa1, 0xa8, 0xfc, 0x0e, 0x4f, 0x9e, 0x0e, 0xbd, 0x7e, 0x7b, 0x34, 0x9e, 0x68, 0x43, 0x4d, 0x16, 0xb9, 0x0d, 0x45, 0x69,
0x35, 0xee, 0x26, 0xa3, 0x89, 0x18, 0x98, 0x31, 0xa2, 0x9f, 0x40, 0x6d, 0xdb, 0x9b, 0xb5, 0xf8, 0x77, 0xa8, 0x70, 0xd7, 0x11, 0xb5, 0x7c, 0x60, 0x5a, 0x88, 0xde, 0x85, 0xea, 0x8e, 0x37, 0x6d,
0xc4, 0x0f, 0x3d, 0xa1, 0xb3, 0xb7, 0x6e, 0xaf, 0x6d, 0x67, 0x2e, 0x72, 0x4f, 0xfb, 0x43, 0x7f, 0xf2, 0xb1, 0x1f, 0x7a, 0x91, 0x8a, 0xde, 0x16, 0x14, 0xc4, 0x76, 0xe1, 0xb9, 0x94, 0x8e, 0xed,
0xe3, 0xc0, 0xca, 0xb6, 0x37, 0xeb, 0xe3, 0x7e, 0x3b, 0xe0, 0x41, 0x3c, 0xde, 0x93, 0xfe, 0x5d, 0x63, 0x4a, 0x82, 0xfe, 0xce, 0x81, 0xd5, 0x1d, 0x6f, 0xda, 0xc3, 0x8a, 0x3b, 0xe4, 0x41, 0xa2,
0x30, 0x5e, 0x1a, 0x90, 0x0d, 0x28, 0xf8, 0x53, 0x61, 0x42, 0x99, 0x6f, 0xaa, 0x2d, 0xd0, 0x76, 0xc1, 0x43, 0x73, 0x2e, 0xd4, 0x20, 0x25, 0x50, 0xd6, 0x9f, 0x44, 0xda, 0x9d, 0x39, 0xb2, 0x52,
0x70, 0xe4, 0x8e, 0x0f, 0xf9, 0x99, 0x82, 0xb2, 0x6c, 0x95, 0x05, 0xdd, 0x97, 0x6e, 0xed, 0x7b, 0x02, 0x65, 0xfb, 0xc7, 0xee, 0xe8, 0x88, 0x9f, 0x4b, 0x2a, 0x43, 0x56, 0x4a, 0xd0, 0x03, 0x61,
0xe2, 0x68, 0x18, 0xb8, 0x2f, 0xb4, 0x5b, 0xb7, 0xa0, 0xe0, 0x1e, 0xfb, 0xd3, 0xb1, 0xf2, 0x2b, 0xd8, 0x81, 0x17, 0x1d, 0x0f, 0x02, 0xf7, 0x85, 0x32, 0x6c, 0x0d, 0x0a, 0xee, 0x89, 0x3f, 0x19,
0xc7, 0xb4, 0x84, 0x13, 0xcb, 0x68, 0xc2, 0x7a, 0x26, 0xb5, 0x83, 0xad, 0x89, 0x95, 0x05, 0xfd, 0x45, 0x02, 0xd7, 0x1c, 0x53, 0x94, 0xe1, 0x72, 0xe6, 0x52, 0x97, 0xef, 0x02, 0xd9, 0xf1, 0xa6,
0x14, 0xc8, 0xb6, 0x37, 0x6b, 0x9a, 0xac, 0x5d, 0x1b, 0xb0, 0x3f, 0x65, 0xa0, 0x8c, 0x13, 0xa8, 0x0d, 0x1d, 0x39, 0xa5, 0x79, 0xd3, 0x0c, 0xd8, 0x6c, 0x05, 0x52, 0x80, 0xfe, 0x25, 0x03, 0x25,
0x71, 0x4b, 0x90, 0x11, 0xaa, 0x0e, 0xf3, 0x2c, 0x23, 0x4e, 0xc9, 0x87, 0x50, 0x18, 0xc8, 0xbd, 0x54, 0x20, 0xd7, 0x2d, 0x43, 0x26, 0x92, 0xb9, 0x98, 0x67, 0x99, 0xe8, 0x8c, 0x7c, 0x00, 0x85,
0xa4, 0xe1, 0xb8, 0x35, 0x67, 0x8f, 0x79, 0xfe, 0x78, 0x6b, 0x81, 0x69, 0x3b, 0x72, 0x1b, 0x8a, 0xbe, 0xa8, 0x27, 0x05, 0xc7, 0xda, 0x8c, 0x3a, 0xf3, 0xfc, 0xd1, 0xf6, 0x02, 0x53, 0x72, 0xe4,
0x43, 0x95, 0x3b, 0x8d, 0xca, 0xab, 0xf1, 0x90, 0x44, 0x52, 0x71, 0x37, 0x69, 0x4b, 0xf2, 0x31, 0x0e, 0x14, 0x07, 0x32, 0x7e, 0x0a, 0x95, 0xd7, 0x93, 0x25, 0x56, 0x60, 0xb1, 0xa2, 0x94, 0x24,
0x94, 0x5e, 0x68, 0x68, 0xe4, 0x56, 0x5b, 0x6c, 0xd4, 0xe3, 0x51, 0x49, 0xd0, 0xb6, 0x16, 0x58, 0xf9, 0x08, 0x16, 0x5f, 0x28, 0x68, 0x44, 0xb9, 0x2d, 0xd5, 0x6b, 0xc9, 0x2a, 0x1b, 0xb4, 0xed,
0x64, 0x8b, 0xe3, 0x84, 0xce, 0xb4, 0xde, 0x83, 0xd6, 0xb8, 0x64, 0x0d, 0xe0, 0x38, 0x63, 0x4b, 0x05, 0x16, 0xcb, 0xe2, 0xba, 0x48, 0xc5, 0x5a, 0xd5, 0xa1, 0xb1, 0xce, 0xce, 0x02, 0x5c, 0xa7,
0x7e, 0x60, 0x17, 0x7e, 0x41, 0x0e, 0x7c, 0x2d, 0x1e, 0x98, 0x02, 0x13, 0x9b, 0x42, 0x64, 0x1d, 0x65, 0xc9, 0x8f, 0xcc, 0xe4, 0x2f, 0x88, 0x85, 0x6f, 0x24, 0x0b, 0x53, 0x60, 0x62, 0x63, 0x88,
0xef, 0xe1, 0x2d, 0x20, 0x3a, 0x9e, 0x5d, 0xab, 0xda, 0x57, 0xa1, 0x34, 0xf6, 0x05, 0xdf, 0x72, 0xa5, 0x93, 0x3a, 0xde, 0x06, 0xa2, 0xfc, 0xd9, 0x33, 0x32, 0x7e, 0x1d, 0x16, 0x47, 0x7e, 0xc4,
0xc3, 0x23, 0xb3, 0x15, 0x8d, 0x6c, 0xa5, 0x5b, 0xef, 0x67, 0x25, 0xd1, 0xdf, 0x3b, 0x70, 0xc3, 0xb7, 0xdd, 0xf0, 0x58, 0x97, 0xa3, 0xa6, 0x8d, 0x70, 0xab, 0x9a, 0x96, 0x14, 0xfd, 0xa3, 0x03,
0x04, 0x69, 0xcf, 0x45, 0xa1, 0x22, 0x02, 0xce, 0x99, 0xef, 0x0b, 0x6b, 0xbe, 0x84, 0x8e, 0xbc, 0x37, 0xb4, 0x93, 0xa6, 0x2e, 0x0a, 0xe5, 0x28, 0xe0, 0x9c, 0xf9, 0x7e, 0x64, 0xe8, 0xb3, 0x78,
0x05, 0xd5, 0xf1, 0x74, 0x34, 0xf2, 0x0e, 0x3c, 0x1e, 0x48, 0x23, 0x35, 0x75, 0x52, 0x49, 0x36, 0xe4, 0x1d, 0xa8, 0x8c, 0x26, 0xc3, 0xa1, 0x77, 0xe8, 0xf1, 0x40, 0x08, 0x49, 0xd5, 0x36, 0x93,
0x81, 0x44, 0x11, 0xf4, 0x26, 0x7c, 0x3c, 0x94, 0xa6, 0x6a, 0xc7, 0xcf, 0xf9, 0x62, 0x79, 0x9a, 0xdc, 0x06, 0x12, 0x7b, 0xd0, 0x1d, 0xf3, 0xd1, 0x40, 0x88, 0xca, 0xaa, 0x9f, 0xf1, 0xc5, 0xb0,
0x4b, 0x78, 0xfa, 0x37, 0x07, 0xea, 0x06, 0x56, 0xe9, 0xe3, 0x4b, 0xb8, 0x1b, 0x1e, 0x79, 0x7c, 0x34, 0x67, 0x59, 0xfa, 0x0f, 0x07, 0x6a, 0x1a, 0x56, 0x61, 0xe3, 0x4b, 0x98, 0x1b, 0x1e, 0x7b,
0x34, 0x6c, 0xca, 0x09, 0x1f, 0x19, 0x77, 0x13, 0xca, 0xb4, 0xd5, 0x63, 0xed, 0x69, 0x52, 0x79, 0x7c, 0x38, 0x68, 0x08, 0x85, 0x8f, 0xb4, 0xb9, 0x16, 0x33, 0x2d, 0xf5, 0x58, 0x59, 0x6a, 0x33,
0x4e, 0x50, 0xb9, 0x73, 0x83, 0x3a, 0x03, 0x55, 0x7e, 0x0e, 0x54, 0xf4, 0x17, 0x0e, 0xbc, 0x66, 0xe7, 0x38, 0x95, 0x9b, 0xeb, 0xd4, 0x39, 0xa8, 0xf2, 0x33, 0xa0, 0xa2, 0xbf, 0x70, 0xe0, 0x0d,
0x42, 0xdc, 0x91, 0xfb, 0xfc, 0xaa, 0xe9, 0xfd, 0x06, 0x63, 0xa3, 0x7f, 0x76, 0xe0, 0x66, 0x54, 0xed, 0xe2, 0xae, 0xa8, 0xf3, 0xab, 0x86, 0xf7, 0x15, 0xfa, 0x46, 0xff, 0xea, 0xc0, 0xcd, 0x38,
0x86, 0xd7, 0x05, 0x79, 0x1d, 0x96, 0x5d, 0x6b, 0x6c, 0x7c, 0x30, 0xa7, 0xd5, 0xe8, 0x4c, 0xa4, 0x0d, 0xaf, 0x0b, 0xf2, 0x26, 0xac, 0xb8, 0xc6, 0xda, 0xe4, 0x70, 0x4e, 0xb3, 0xd1, 0x98, 0x98,
0xb2, 0x4a, 0x22, 0xa9, 0xbc, 0x2e, 0xd0, 0xf4, 0x27, 0xb0, 0xac, 0x4e, 0xd4, 0xf8, 0xf0, 0xf8, 0x65, 0xa4, 0x84, 0xcd, 0xbc, 0x2e, 0xd0, 0xf4, 0x67, 0xb0, 0x22, 0x4f, 0xd5, 0xe4, 0x00, 0xf9,
0x56, 0xd4, 0x57, 0xe6, 0x92, 0x1b, 0x6c, 0x35, 0x51, 0xcb, 0xca, 0x5c, 0xd6, 0xb2, 0xd6, 0x00, 0x56, 0xdc, 0x57, 0x66, 0x0e, 0x38, 0xd8, 0x6a, 0xe2, 0x96, 0x95, 0xb9, 0xac, 0x65, 0xfd, 0x14,
0xda, 0x33, 0x2f, 0x14, 0x0f, 0x71, 0x1f, 0x22, 0x2d, 0xd1, 0x64, 0xc7, 0x59, 0x2f, 0x69, 0x62, 0xa0, 0x35, 0xf5, 0xc2, 0xe8, 0x21, 0xd6, 0x21, 0x1e, 0x64, 0x71, 0x04, 0x15, 0x1c, 0x09, 0x03,
0xb3, 0x01, 0xb5, 0x3b, 0xfe, 0xf1, 0xb1, 0x27, 0xfa, 0x01, 0xe7, 0x0f, 0xb8, 0x7b, 0xc2, 0x43, 0x4f, 0x2e, 0x8e, 0xb2, 0x42, 0xeb, 0x22, 0x93, 0x04, 0xdd, 0x82, 0xea, 0x3d, 0xff, 0xe4, 0xc4,
0xac, 0xe9, 0x91, 0xfc, 0x25, 0x29, 0x4e, 0x85, 0x69, 0x89, 0xbe, 0x0b, 0xcb, 0xb1, 0x2d, 0x62, 0x8b, 0x7a, 0x01, 0xe7, 0x0f, 0xb8, 0x7b, 0xca, 0x43, 0xcc, 0xf9, 0xa1, 0xf8, 0x4b, 0x9c, 0x12,
0x18, 0xe2, 0x51, 0x17, 0xe0, 0x0f, 0x6d, 0xa9, 0x04, 0xfa, 0x3b, 0xc7, 0xb6, 0xdc, 0x0d, 0xfc, 0x65, 0xa6, 0x28, 0xfa, 0x1e, 0xac, 0x24, 0xb2, 0x88, 0x71, 0x88, 0x4a, 0x03, 0xfc, 0x43, 0x49,
0x13, 0x2e, 0x4f, 0xd7, 0x64, 0x2a, 0x22, 0x19, 0xbf, 0x49, 0x7f, 0x7b, 0xf2, 0x00, 0x47, 0x56, 0x4a, 0x82, 0xfe, 0xc1, 0x31, 0x25, 0xf7, 0x02, 0xff, 0x94, 0x8b, 0x13, 0xd8, 0x0e, 0x55, 0x4c,
0x15, 0xc9, 0xc8, 0x8a, 0x26, 0x2a, 0xac, 0x21, 0x9f, 0x49, 0xd4, 0xab, 0xcc, 0xd2, 0xe0, 0xc9, 0xe3, 0x37, 0xe1, 0x4f, 0x57, 0x1c, 0xf2, 0x38, 0x79, 0xc5, 0x34, 0x4e, 0x4e, 0x63, 0xe9, 0xf6,
0x3c, 0x9e, 0x1e, 0x2b, 0xcf, 0x25, 0xd2, 0x55, 0x16, 0x2b, 0x90, 0x32, 0x1c, 0xf1, 0xd1, 0x84, 0x80, 0x4f, 0x45, 0x54, 0x2a, 0xcc, 0xe0, 0x48, 0xa7, 0x4f, 0xa4, 0xe5, 0x22, 0x12, 0x15, 0x96,
0x07, 0x61, 0x3d, 0xbf, 0x96, 0x5d, 0xaf, 0x32, 0x23, 0xd2, 0x36, 0x2c, 0xa2, 0x73, 0x12, 0x2d, 0x30, 0x70, 0xac, 0x38, 0xe6, 0xc3, 0x31, 0x0f, 0xc2, 0x5a, 0x7e, 0x23, 0xbb, 0x59, 0x61, 0x9a,
0xfe, 0xfc, 0x32, 0xf7, 0x46, 0xdc, 0x3d, 0xb0, 0x9a, 0x46, 0x24, 0xd3, 0x77, 0xa0, 0x22, 0x91, 0xa4, 0x2d, 0x58, 0x42, 0xe3, 0x04, 0x9a, 0xfc, 0xf9, 0x65, 0xe6, 0x0d, 0xb9, 0x7b, 0x68, 0x34,
0xf3, 0x42, 0xc1, 0x78, 0x38, 0x49, 0x61, 0x57, 0x8e, 0xb0, 0x7b, 0x00, 0x4b, 0x31, 0xd9, 0xd9, 0x95, 0x98, 0xa6, 0xef, 0x42, 0x59, 0x20, 0xe7, 0x85, 0x11, 0xe3, 0xe1, 0x38, 0x85, 0x5d, 0x29,
0x75, 0xbd, 0x00, 0x03, 0xd3, 0xd4, 0x23, 0x26, 0x34, 0x96, 0x06, 0x57, 0x0d, 0xb1, 0x50, 0xe2, 0xc6, 0xee, 0x01, 0x2c, 0x27, 0x03, 0xd1, 0x9e, 0xeb, 0x05, 0xe8, 0x98, 0x1a, 0x4f, 0x92, 0xa1,
0xa2, 0x8c, 0x64, 0xfa, 0x39, 0x2c, 0xb5, 0x23, 0x62, 0x28, 0x67, 0x43, 0x6e, 0x14, 0x78, 0x27, 0xc7, 0xe0, 0xe0, 0xae, 0x21, 0x26, 0x52, 0x92, 0xb4, 0x31, 0x4d, 0x3f, 0x81, 0xe5, 0x56, 0x3c,
0x36, 0x37, 0x52, 0x22, 0x7a, 0x34, 0xb1, 0x4b, 0x5b, 0x4b, 0xf4, 0xe7, 0x0e, 0xac, 0x34, 0x07, 0x3c, 0x0a, 0x6d, 0x38, 0x3f, 0x05, 0xde, 0xa9, 0x39, 0x3f, 0x49, 0x12, 0x2d, 0x1a, 0x9b, 0xa9,
0x03, 0xdc, 0x45, 0xbb, 0x81, 0x77, 0xe2, 0x0e, 0x24, 0x93, 0xfb, 0x6e, 0x82, 0xad, 0xa9, 0x33, 0xaf, 0x28, 0xfa, 0x73, 0x07, 0x56, 0x1b, 0xfd, 0x3e, 0x56, 0xd9, 0x5e, 0xe0, 0x9d, 0xba, 0x7d,
0xf1, 0x95, 0x33, 0x6c, 0x0d, 0x97, 0xb4, 0xf9, 0x1a, 0x0e, 0xb3, 0xb8, 0x6b, 0x26, 0x31, 0x2c, 0x31, 0xed, 0x7d, 0xdf, 0x9a, 0xe8, 0xe4, 0x99, 0xf9, 0xda, 0xb9, 0x89, 0x0e, 0xb7, 0x34, 0x67,
0xe9, 0x69, 0x82, 0xd2, 0xfe, 0x18, 0x56, 0xf6, 0xdd, 0xd1, 0x88, 0x8b, 0xe6, 0x70, 0x18, 0x68, 0x3a, 0x5c, 0x66, 0xcc, 0xb7, 0x19, 0x6b, 0x99, 0x6d, 0xa9, 0x35, 0xf6, 0x7e, 0x01, 0xab, 0x07,
0x2f, 0x48, 0x43, 0x85, 0xe2, 0x0e, 0xcc, 0xfa, 0xe6, 0xa4, 0x3a, 0xe3, 0x2d, 0x33, 0x86, 0x11, 0xee, 0x70, 0xc8, 0xa3, 0xc6, 0x60, 0x10, 0x28, 0x2b, 0x48, 0x5d, 0xba, 0xe2, 0xf6, 0xf5, 0xfe,
0xe3, 0xce, 0xc4, 0x8c, 0x9b, 0x7e, 0xed, 0x00, 0x28, 0xde, 0xd4, 0x72, 0x85, 0x9b, 0x26, 0xe0, 0xfa, 0x24, 0x3b, 0x67, 0x2d, 0xd3, 0x82, 0xf1, 0x54, 0x9e, 0x49, 0xa6, 0x72, 0xfa, 0xb5, 0x03,
0xce, 0x59, 0x02, 0xfe, 0x3a, 0x94, 0x15, 0xe1, 0x8b, 0xc1, 0x8a, 0x15, 0xd8, 0x4f, 0xa2, 0x1d, 0x20, 0x67, 0xab, 0xa6, 0x1b, 0xb9, 0xe9, 0x21, 0xdd, 0x39, 0x3f, 0xa4, 0xbf, 0x09, 0x25, 0x39,
0x1c, 0x13, 0xf4, 0x84, 0xee, 0xbc, 0xd3, 0x00, 0x73, 0x8d, 0xcd, 0x8f, 0xb9, 0xe3, 0xa1, 0x7f, 0x14, 0x26, 0x60, 0x25, 0x0c, 0xec, 0x37, 0x71, 0x85, 0x27, 0x43, 0xbc, 0xc5, 0x9b, 0x77, 0x5a,
0xac, 0xbb, 0xa9, 0xa5, 0xa1, 0x6d, 0x58, 0xd1, 0x28, 0x59, 0x0e, 0xc7, 0xa4, 0xd6, 0xb1, 0x49, 0x60, 0xac, 0xb1, 0x39, 0x32, 0x77, 0x34, 0xf0, 0x4f, 0x54, 0xb7, 0x35, 0x38, 0xb4, 0x05, 0xab,
0xad, 0x4d, 0x83, 0x33, 0x09, 0x1a, 0x4c, 0xbf, 0x80, 0x95, 0x16, 0xbf, 0xea, 0x34, 0x58, 0x17, 0x0a, 0x25, 0xc3, 0xe0, 0x64, 0xf0, 0x75, 0xcc, 0xc1, 0xd7, 0x1c, 0x95, 0x33, 0xd6, 0xa8, 0x4c,
0x81, 0x67, 0xd7, 0x85, 0x94, 0xec, 0xe9, 0xb3, 0xc9, 0xe9, 0xdf, 0x86, 0xe5, 0x81, 0x17, 0x0c, 0xbf, 0x84, 0xd5, 0x26, 0xbf, 0xaa, 0x1a, 0xcc, 0x8b, 0xc0, 0x33, 0xf3, 0x42, 0x50, 0xa6, 0xfa,
0xa6, 0x9e, 0xd8, 0x75, 0xc5, 0x91, 0xec, 0x56, 0x04, 0x72, 0x13, 0x57, 0x98, 0x2d, 0x23, 0x7f, 0xac, 0xad, 0xfe, 0x37, 0x0e, 0x2c, 0xa9, 0x83, 0x5e, 0xb4, 0xb2, 0x77, 0xa0, 0xa2, 0xe1, 0xc3,
0xd3, 0xaf, 0x60, 0x51, 0x1f, 0xf7, 0xc6, 0xe4, 0xcc, 0x65, 0x48, 0xd6, 0x3e, 0x02, 0xdb, 0x8c, 0xf8, 0x85, 0x6a, 0x03, 0x9b, 0x29, 0xf3, 0x1c, 0x41, 0x6c, 0x24, 0x01, 0x32, 0x38, 0x56, 0xe7,
0x93, 0x66, 0x69, 0x12, 0xdd, 0x56, 0x9a, 0xa4, 0xbb, 0xad, 0xb4, 0x4a, 0xa2, 0x1d, 0x91, 0x42, 0x15, 0x22, 0xe9, 0xce, 0x2b, 0xa4, 0x6a, 0x50, 0x94, 0x58, 0x86, 0x0a, 0x5a, 0x4d, 0xd2, 0x1e,
0x3a, 0x82, 0x8a, 0x76, 0xa0, 0x3f, 0xc3, 0xbd, 0xfd, 0x41, 0x4c, 0xb4, 0x92, 0x24, 0xcf, 0x72, 0x94, 0x95, 0x51, 0xbd, 0x29, 0x56, 0xf2, 0xfb, 0xc9, 0xd8, 0x65, 0x8f, 0x7c, 0x86, 0xe9, 0xc9,
0x33, 0x66, 0x58, 0x9b, 0x50, 0xf8, 0xf2, 0x19, 0x06, 0x98, 0x22, 0x72, 0xa9, 0xd0, 0x99, 0xb6, 0xbc, 0xb5, 0x06, 0x85, 0xaf, 0x9e, 0xed, 0xb9, 0x91, 0xae, 0x6c, 0x45, 0xd1, 0x5f, 0x39, 0x50,
0xa2, 0xbf, 0x74, 0xa0, 0x66, 0xe8, 0x0d, 0xb6, 0x25, 0xd9, 0x06, 0x2e, 0x3a, 0xfd, 0xde, 0x4d, 0xd5, 0x43, 0x0d, 0x36, 0x1b, 0x51, 0xdc, 0x17, 0x9d, 0x79, 0xef, 0xd9, 0x4d, 0x5b, 0xb7, 0xf6,
0xb6, 0x6f, 0xd3, 0xe4, 0xe3, 0x94, 0x99, 0x1b, 0xc3, 0x75, 0xef, 0x03, 0x1e, 0x54, 0x65, 0xbf, 0x24, 0x10, 0xfa, 0xae, 0x70, 0xdd, 0x9b, 0x80, 0x07, 0x15, 0xd1, 0x45, 0xdd, 0xe8, 0x58, 0x58,
0x75, 0xc5, 0x91, 0xf4, 0xe4, 0x4a, 0x47, 0xe0, 0x2a, 0x12, 0x43, 0x35, 0xc8, 0xf4, 0x5e, 0x23, 0x72, 0xa5, 0x83, 0x6f, 0x1d, 0xc7, 0x41, 0xb9, 0x48, 0x77, 0x54, 0x4d, 0x9b, 0x3d, 0x31, 0x6b,
0xdb, 0xdd, 0x33, 0x9b, 0xec, 0x9e, 0x5f, 0x41, 0xd5, 0xf0, 0x30, 0x85, 0xf1, 0x1a, 0x2c, 0x0a, 0xf7, 0xc4, 0x23, 0xa8, 0xe8, 0xe9, 0x4b, 0x62, 0xb9, 0x01, 0x4b, 0x91, 0x1f, 0xb9, 0xc3, 0x86,
0x5f, 0xb8, 0xa3, 0xa6, 0xcd, 0xd2, 0x6d, 0x95, 0x6c, 0xd4, 0x1a, 0x82, 0xd0, 0xec, 0xae, 0x48, 0x39, 0x9b, 0x9b, 0x2c, 0xd1, 0x7e, 0x15, 0x04, 0xa1, 0xae, 0x99, 0x98, 0x61, 0xa0, 0x9b, 0xb5,
0x61, 0xa1, 0x9e, 0xbd, 0x12, 0xea, 0x7f, 0xc9, 0xc0, 0x72, 0xc4, 0x04, 0x15, 0xec, 0xe4, 0xbd, 0xd0, 0xfd, 0x5b, 0x06, 0x56, 0xe2, 0x39, 0x4f, 0xc2, 0x4b, 0xbe, 0x63, 0xe5, 0xe9, 0x4c, 0x04,
0x44, 0xa5, 0xcf, 0x45, 0xd6, 0x14, 0xff, 0x7f, 0x86, 0x0c, 0xda, 0x59, 0xcf, 0xa5, 0xb2, 0x4e, 0x75, 0xea, 0xfe, 0x6f, 0x46, 0x3d, 0x33, 0xba, 0xb9, 0x54, 0x74, 0x29, 0x94, 0x45, 0xf3, 0xdd,
0xa1, 0x22, 0xdb, 0xf7, 0xae, 0xee, 0xd2, 0xaa, 0x09, 0x24, 0x74, 0x08, 0x91, 0x94, 0xef, 0x8e, 0x53, 0x3d, 0x56, 0x96, 0xb0, 0xc5, 0x43, 0x28, 0x04, 0x7d, 0x7f, 0xe8, 0x1e, 0x89, 0x51, 0xba,
0xdc, 0x43, 0x49, 0xb6, 0xcb, 0x2c, 0x56, 0x24, 0x36, 0x85, 0xb4, 0x28, 0xa6, 0x36, 0x85, 0xb4, 0xc4, 0x12, 0x86, 0x95, 0xe6, 0x42, 0xa2, 0x98, 0x4a, 0x73, 0x21, 0x55, 0x87, 0x52, 0x24, 0x8f,
0x6a, 0x40, 0x59, 0xa8, 0x43, 0xd7, 0x3f, 0xa8, 0x97, 0x12, 0x65, 0x93, 0x28, 0x0e, 0x16, 0x9b, 0x4c, 0xff, 0xb0, 0xb6, 0x68, 0xa5, 0x87, 0x95, 0x04, 0x2c, 0x11, 0xa3, 0x1e, 0x94, 0x70, 0x40,
0xe1, 0x51, 0x50, 0x46, 0x0e, 0xa5, 0x52, 0x79, 0x51, 0xed, 0xda, 0x84, 0xa9, 0xef, 0x5b, 0x5b, 0x92, 0x11, 0xbb, 0x28, 0x45, 0xcd, 0x69, 0xa8, 0xe7, 0x1b, 0xb5, 0x96, 0x66, 0x1b, 0x71, 0xcb,
0x33, 0xad, 0xb6, 0x12, 0x9a, 0xbb, 0x52, 0x42, 0xff, 0x90, 0x81, 0x45, 0xf4, 0xc1, 0x24, 0xf3, 0x59, 0x71, 0xfb, 0x53, 0x06, 0x96, 0x70, 0x2f, 0x1d, 0xb3, 0xf7, 0xec, 0xcb, 0xd5, 0xfc, 0xa4,
0xdd, 0xe4, 0xbd, 0xec, 0xfc, 0x5d, 0xf2, 0x06, 0x00, 0xae, 0x9d, 0xa0, 0x6f, 0x96, 0x06, 0x2b, 0x7f, 0x0b, 0x00, 0xf7, 0xb0, 0x66, 0x30, 0x83, 0x83, 0x89, 0x26, 0x28, 0x05, 0xaf, 0x34, 0xcb,
0x53, 0x4a, 0x1a, 0x77, 0xe5, 0xae, 0xad, 0xc2, 0x80, 0x51, 0xb4, 0xd3, 0x66, 0xe4, 0x73, 0x4a, 0x64, 0xa1, 0x63, 0x48, 0x9a, 0xd1, 0xd1, 0xf4, 0x9c, 0x48, 0xe7, 0xaf, 0x14, 0xe9, 0x42, 0x0a,
0x20, 0x7f, 0xa5, 0x12, 0x28, 0xa4, 0xc0, 0x4b, 0xa4, 0xb7, 0x98, 0x4e, 0xef, 0xcb, 0x24, 0xee, 0x24, 0x2b, 0x8a, 0xc5, 0x74, 0x14, 0x5f, 0x26, 0x3e, 0x9f, 0x01, 0xb1, 0x6e, 0x0a, 0x32, 0x50,
0xa7, 0x40, 0x12, 0x97, 0x8c, 0xcb, 0x13, 0x78, 0xdd, 0xee, 0x16, 0xc2, 0x8d, 0x24, 0xc7, 0xff, 0x56, 0xe1, 0x38, 0xf3, 0x0b, 0xc7, 0x6e, 0x4b, 0x5f, 0xc0, 0x0d, 0x7b, 0x24, 0x7f, 0x95, 0x3d,
0x6f, 0xb4, 0x54, 0x81, 0x8d, 0x4c, 0x2d, 0xaa, 0x96, 0xfb, 0x76, 0xf2, 0x55, 0xe2, 0xb5, 0x08, 0x2f, 0xc2, 0x4e, 0x23, 0x95, 0x4b, 0xb5, 0xdf, 0x85, 0xbc, 0x78, 0x0c, 0x50, 0x4a, 0xdf, 0x88,
0x97, 0x74, 0xec, 0xe6, 0x71, 0xa2, 0x91, 0x7a, 0x9c, 0x58, 0x4d, 0x8d, 0xb0, 0x62, 0x31, 0x8f, 0x3d, 0x4d, 0x7b, 0xc3, 0xa4, 0x1c, 0xa9, 0xa7, 0xde, 0x0c, 0xd6, 0x53, 0x2b, 0x0c, 0x9b, 0xf5,
0x14, 0x74, 0x03, 0x2a, 0x3d, 0xeb, 0x6a, 0x41, 0x2a, 0xe0, 0x3c, 0xd2, 0xf8, 0x39, 0x8f, 0x50, 0xdb, 0x01, 0xdd, 0x82, 0x72, 0xd7, 0x98, 0xf8, 0x49, 0x19, 0x9c, 0x47, 0x0a, 0x10, 0xe7, 0x11,
0x7a, 0xac, 0xab, 0xcb, 0x79, 0x4c, 0xbf, 0xce, 0xa6, 0x90, 0x57, 0x0d, 0xf7, 0xca, 0x45, 0xfb, 0x52, 0x8f, 0x95, 0x99, 0xce, 0x63, 0xfa, 0x75, 0x36, 0x85, 0xa5, 0xec, 0x88, 0x57, 0x4e, 0xc3,
0xbf, 0xfe, 0x63, 0x95, 0x31, 0xf9, 0x1e, 0x54, 0xec, 0x4b, 0x5d, 0xbd, 0x2c, 0x87, 0x99, 0x57, 0xff, 0x37, 0x0e, 0x23, 0x31, 0xc9, 0x0f, 0xa0, 0x6c, 0xde, 0xb5, 0x6a, 0x25, 0xb1, 0x4c, 0x3f,
0x4a, 0x3b, 0x29, 0x2c, 0x61, 0x28, 0x39, 0x99, 0xd2, 0x2b, 0x66, 0x05, 0x9a, 0x93, 0x59, 0x3a, 0x20, 0x9a, 0x41, 0x61, 0x96, 0xa0, 0x18, 0x85, 0x24, 0x5f, 0x0e, 0x34, 0xa0, 0x46, 0x21, 0x83,
0xfa, 0x0f, 0x27, 0x5d, 0xc2, 0xd7, 0xcc, 0x95, 0x8d, 0x6a, 0xe6, 0xcc, 0x76, 0xba, 0xd6, 0x11, 0x47, 0xff, 0xe5, 0xa4, 0x53, 0xf5, 0x9a, 0xb1, 0x32, 0x51, 0xcd, 0xa4, 0x50, 0xbd, 0xe6, 0x19,
0x7d, 0x26, 0xd2, 0xdc, 0xcb, 0x46, 0x9a, 0x9f, 0x13, 0xe9, 0x5f, 0x1d, 0x58, 0x31, 0x91, 0xc6, 0x7a, 0xce, 0xd3, 0xdc, 0xcb, 0x7a, 0x9a, 0x9f, 0xe1, 0xe9, 0xdf, 0x1d, 0x58, 0xd5, 0x9e, 0x26,
0x54, 0xe4, 0x33, 0xa8, 0x0a, 0xbb, 0x52, 0x2f, 0xda, 0x43, 0x6a, 0x54, 0xd2, 0x9e, 0x7c, 0x0a, 0xb3, 0xc2, 0xc7, 0x50, 0x89, 0xcc, 0x4c, 0xbd, 0xa8, 0x86, 0xe4, 0x2a, 0x5b, 0x9e, 0xdc, 0x85,
0x15, 0xe1, 0x06, 0x87, 0x5c, 0xec, 0x5c, 0xbe, 0xa3, 0xd4, 0x04, 0x09, 0x7b, 0x1c, 0xaf, 0x9e, 0x72, 0xe4, 0x06, 0x47, 0x3c, 0xda, 0xbd, 0xbc, 0xa2, 0xa4, 0x02, 0x4b, 0x1e, 0xd7, 0xcb, 0x17,
0xf6, 0xf4, 0xf8, 0xec, 0xe5, 0xe3, 0x6d, 0x7b, 0xfa, 0xb3, 0x0c, 0x2c, 0x27, 0x90, 0x09, 0x05, 0x37, 0xb5, 0x3e, 0x7b, 0xf9, 0x7a, 0x53, 0x9e, 0xfe, 0x32, 0x03, 0x2b, 0x16, 0x32, 0xa1, 0x80,
0x36, 0x75, 0xb9, 0xd1, 0x35, 0x1a, 0x9a, 0xcc, 0x5b, 0x2a, 0x04, 0x4c, 0xed, 0x6b, 0x6d, 0xa2, 0x43, 0x14, 0xba, 0xf4, 0x5c, 0xdf, 0x71, 0x2c, 0x1e, 0xca, 0xc8, 0xca, 0x56, 0x90, 0xc9, 0xd8,
0x32, 0x97, 0xd0, 0xa1, 0x8d, 0x5a, 0x49, 0xdb, 0x68, 0x4a, 0x6f, 0xeb, 0xc8, 0x7b, 0xa6, 0xf5, 0x59, 0x3c, 0x94, 0x91, 0x7b, 0x29, 0x19, 0x35, 0x4b, 0x9b, 0x3c, 0x72, 0x2b, 0x7e, 0xab, 0xcc,
0x5c, 0x90, 0x2a, 0xdd, 0x74, 0xde, 0x8f, 0x9a, 0x4e, 0xfe, 0x7c, 0x5b, 0xf3, 0x24, 0xfa, 0x7e, 0x89, 0xa7, 0xbf, 0x99, 0xd1, 0xd2, 0x8f, 0x95, 0xb7, 0xe2, 0xc6, 0x93, 0x9f, 0x1f, 0x5a, 0xfd,
0xf4, 0x24, 0x5a, 0xb8, 0xc0, 0x58, 0xbf, 0x89, 0xfe, 0xda, 0x81, 0xa5, 0x3b, 0x01, 0x77, 0xf1, 0x5a, 0x79, 0x2b, 0x7e, 0xad, 0x2c, 0x5c, 0x20, 0xac, 0x9e, 0x2b, 0x7f, 0xeb, 0xc0, 0xf2, 0xbd,
0xc2, 0xf0, 0x22, 0x6a, 0xf2, 0xea, 0xaf, 0x24, 0x7d, 0xf3, 0x0a, 0x19, 0xc9, 0xd1, 0x45, 0x1f, 0x80, 0xbb, 0x38, 0xab, 0xbf, 0x88, 0xcf, 0x58, 0xf9, 0x23, 0x46, 0x4f, 0x3f, 0x10, 0xc6, 0x34,
0x5d, 0xae, 0xa8, 0x8b, 0xbe, 0x7c, 0xc1, 0x0e, 0x43, 0x2e, 0xda, 0x33, 0x3e, 0x30, 0xf4, 0x2b, 0x5e, 0x44, 0xc4, 0x8f, 0x0e, 0x98, 0x61, 0x65, 0xf9, 0x03, 0x83, 0x78, 0x60, 0x0e, 0x43, 0x1e,
0x52, 0xc8, 0x43, 0x14, 0x85, 0xbe, 0xff, 0x8c, 0x8f, 0xcd, 0xdf, 0x1e, 0x62, 0x0d, 0xde, 0xf3, 0xb5, 0xa6, 0xbc, 0xaf, 0x67, 0xa4, 0x98, 0x21, 0x8e, 0x46, 0x24, 0x7a, 0xfe, 0x33, 0x3e, 0xd2,
0x85, 0x27, 0x46, 0x5c, 0x77, 0x05, 0x25, 0xd0, 0x5f, 0x21, 0x09, 0x93, 0xf7, 0x37, 0x79, 0x17, 0x3f, 0x0d, 0x24, 0x1c, 0xbc, 0x62, 0x47, 0x5e, 0x34, 0xe4, 0xaa, 0x33, 0x48, 0x82, 0x3e, 0x34,
0x97, 0x74, 0xff, 0xa2, 0xc3, 0x47, 0xde, 0xd5, 0x75, 0x83, 0x8b, 0x28, 0xa0, 0x51, 0x5c, 0xbb, 0xef, 0x93, 0x21, 0x5a, 0x35, 0xff, 0x06, 0x38, 0xe3, 0x72, 0x84, 0x67, 0xc0, 0x80, 0x47, 0xae,
0xdb, 0xfd, 0x3f, 0xe4, 0x02, 0x7f, 0xc4, 0x65, 0x94, 0x4b, 0x8d, 0x45, 0x8d, 0x1f, 0xf3, 0x47, 0x37, 0x14, 0x3b, 0xe6, 0x99, 0xa2, 0xe8, 0xaf, 0x71, 0x32, 0x13, 0x57, 0x32, 0x71, 0xbd, 0x16,
0x9c, 0xc9, 0x0f, 0x48, 0x5f, 0x5d, 0x75, 0x65, 0xd4, 0xdb, 0xc5, 0x88, 0x92, 0x29, 0x0a, 0x57, 0x73, 0xfe, 0x45, 0x33, 0x85, 0xf5, 0xe6, 0x90, 0x49, 0xbf, 0x39, 0x5c, 0xb7, 0x93, 0x7e, 0x13,
0x4c, 0x43, 0x19, 0x4f, 0xfc, 0xd0, 0xd2, 0xf5, 0x05, 0xef, 0xc9, 0x0f, 0x4c, 0x1b, 0x58, 0xa4, 0x72, 0x81, 0x3f, 0xe4, 0x02, 0xbd, 0xe5, 0xfa, 0x92, 0x8a, 0x0b, 0xf3, 0x87, 0x9c, 0x89, 0x0f,
0xb2, 0x78, 0x09, 0xa9, 0xa4, 0xfb, 0x06, 0x8d, 0xd6, 0xd3, 0x6d, 0x4f, 0xa1, 0xb1, 0x01, 0x39, 0xe2, 0x1a, 0x20, 0x6f, 0x81, 0xaa, 0x14, 0x35, 0x29, 0xc6, 0xc7, 0xc8, 0x8d, 0x26, 0xa1, 0xc0,
0x6f, 0x7c, 0xe0, 0xeb, 0x3d, 0x67, 0xce, 0xbd, 0x14, 0x66, 0x4c, 0xda, 0xa0, 0xbb, 0x62, 0xa6, 0x29, 0x79, 0x5b, 0xe9, 0xf8, 0x11, 0xef, 0x8a, 0x0f, 0x4c, 0x09, 0x18, 0x93, 0x66, 0xf1, 0x92,
0x9e, 0x39, 0xf4, 0xbd, 0x4e, 0x8b, 0xf4, 0xef, 0x8e, 0xb9, 0x27, 0xcb, 0x79, 0x87, 0xfc, 0xd2, 0x49, 0x93, 0x1e, 0x68, 0x34, 0x9a, 0x4f, 0x77, 0x3c, 0x89, 0xc6, 0x16, 0xe4, 0xbc, 0xd1, 0xa1,
0x63, 0xfe, 0x9b, 0x45, 0xfa, 0x7c, 0x20, 0x6f, 0x25, 0x80, 0xcc, 0x47, 0xa8, 0xdd, 0x84, 0xbc, 0xaf, 0xea, 0x59, 0x3f, 0x03, 0xa7, 0x30, 0x63, 0x42, 0x06, 0xcd, 0x8d, 0xa6, 0xf2, 0xe5, 0x42,
0xb2, 0x2f, 0x4a, 0xb5, 0x12, 0xd0, 0xab, 0xa1, 0x17, 0x70, 0xf5, 0xa7, 0xa8, 0x92, 0xfc, 0x12, 0x5d, 0xd5, 0x14, 0x49, 0xff, 0xe9, 0xe8, 0xab, 0xaf, 0xd0, 0x3b, 0xe0, 0x97, 0x4e, 0x6f, 0xaf,
0x2b, 0xe8, 0x67, 0x89, 0x62, 0x92, 0xbd, 0xeb, 0x03, 0xc8, 0x63, 0x48, 0xa1, 0xfe, 0xfb, 0xdc, 0x16, 0xe9, 0xf9, 0x40, 0xae, 0x59, 0x40, 0xe6, 0x63, 0xd4, 0x6e, 0x42, 0x5e, 0xca, 0x17, 0x05,
0x79, 0xf8, 0x29, 0x23, 0xfa, 0x0e, 0x2c, 0xa9, 0x2f, 0x8c, 0x3f, 0x47, 0x0e, 0x2a, 0xdd, 0xc0, 0x5b, 0x12, 0x68, 0xd5, 0xc0, 0x0b, 0xb8, 0xfc, 0x05, 0x6a, 0x51, 0x7c, 0x49, 0x18, 0xf4, 0x63,
0xfb, 0xa6, 0x79, 0x8c, 0x51, 0x02, 0x65, 0x70, 0x4b, 0xd9, 0xb5, 0xc7, 0xee, 0xd3, 0x11, 0xd7, 0x2b, 0x99, 0x44, 0x5f, 0x7c, 0x1f, 0xf2, 0xe8, 0x92, 0xfe, 0x05, 0x62, 0x1e, 0x7e, 0x52, 0x88,
0xef, 0x09, 0xd8, 0x56, 0xe6, 0xdd, 0x55, 0x09, 0xe4, 0xbc, 0x70, 0xe7, 0xbe, 0x44, 0xb1, 0xc4, 0xbe, 0x0b, 0xcb, 0xf2, 0x0b, 0xe3, 0xcf, 0xe5, 0x75, 0xf2, 0x26, 0xe4, 0x5d, 0x75, 0xd9, 0xc4,
0xe4, 0x6f, 0x52, 0x83, 0xec, 0x71, 0x78, 0xa8, 0x11, 0xc3, 0x9f, 0xb4, 0x0b, 0xaf, 0xce, 0x9b, 0xde, 0x23, 0x09, 0xca, 0x60, 0x4d, 0xca, 0xb5, 0x46, 0xee, 0xd3, 0x21, 0x57, 0x4f, 0x04, 0xd8,
0x13, 0x83, 0xb8, 0x0d, 0xf9, 0x80, 0x87, 0x13, 0x13, 0xc4, 0xff, 0x25, 0x82, 0x48, 0xbb, 0xc0, 0xb2, 0x66, 0xfd, 0x5e, 0x47, 0x20, 0xe7, 0x85, 0xbb, 0x9f, 0xab, 0x97, 0x30, 0xf1, 0x37, 0xa9,
0x94, 0x2d, 0xed, 0x02, 0x3c, 0xf0, 0x07, 0xee, 0x68, 0xdb, 0x9b, 0xf5, 0x67, 0xe8, 0xc3, 0x51, 0x42, 0xf6, 0x24, 0x3c, 0x52, 0x88, 0xe1, 0x9f, 0xb4, 0x03, 0xaf, 0xcf, 0xd2, 0x89, 0x4e, 0xdc,
0x9c, 0x66, 0xf9, 0x1b, 0xa1, 0x3f, 0xe2, 0xde, 0xe1, 0x91, 0x6a, 0xc8, 0x59, 0xa6, 0x25, 0x8c, 0x81, 0x7c, 0xc0, 0xc3, 0xb1, 0x76, 0xe2, 0x1b, 0x96, 0x13, 0x69, 0x13, 0x98, 0x94, 0xa5, 0x1d,
0xd9, 0x8b, 0xde, 0xca, 0xb2, 0x4c, 0x09, 0xf4, 0xb7, 0x0e, 0x54, 0xe4, 0x5c, 0xea, 0xa5, 0xea, 0x80, 0x07, 0x7e, 0xdf, 0x1d, 0xee, 0x78, 0xd3, 0xde, 0x14, 0x6d, 0x38, 0x4e, 0xc2, 0x2c, 0xfe,
0xb9, 0x5d, 0x6d, 0x4e, 0xa2, 0xda, 0xa2, 0xc5, 0x32, 0x73, 0x17, 0xcb, 0xce, 0x5f, 0x2c, 0x67, 0x46, 0xe8, 0x8f, 0xb9, 0x77, 0x74, 0x2c, 0x9b, 0x7d, 0x96, 0x29, 0x0a, 0x7d, 0xf6, 0xe2, 0xe7,
0x2d, 0x16, 0x67, 0x3f, 0x7f, 0x6e, 0xf6, 0x0b, 0xe9, 0xec, 0x7f, 0x04, 0x55, 0xcb, 0xbf, 0x70, 0xaf, 0x2c, 0x93, 0x04, 0xfd, 0xbd, 0x03, 0x65, 0xa1, 0x4b, 0x3e, 0x3e, 0x3d, 0x37, 0xb3, 0xcd,
0x42, 0xde, 0x84, 0xac, 0x98, 0x19, 0xd0, 0xcc, 0xae, 0x8b, 0x31, 0x61, 0xf8, 0x95, 0x6e, 0xc3, 0xb1, 0xb2, 0x2d, 0xde, 0x2c, 0x33, 0x73, 0xb3, 0xec, 0xec, 0xcd, 0x72, 0xc6, 0x66, 0x49, 0xf4,
0x8a, 0xc6, 0x0e, 0x13, 0xce, 0x78, 0x38, 0x1d, 0xfd, 0x3b, 0x59, 0xec, 0xc0, 0x0d, 0xc6, 0x9f, 0xf3, 0x73, 0xa3, 0x5f, 0x48, 0x47, 0xff, 0x43, 0xa8, 0x18, 0xf6, 0x85, 0x63, 0xf2, 0x36, 0x64,
0x9f, 0x29, 0x8b, 0x06, 0x14, 0x03, 0x39, 0xb5, 0x71, 0xc7, 0xbc, 0x48, 0x9d, 0x59, 0x9b, 0x19, 0xa3, 0xa9, 0x06, 0x4d, 0x57, 0x5d, 0x82, 0x09, 0xc3, 0xaf, 0x74, 0x07, 0x56, 0x15, 0x76, 0x18,
0xc3, 0x8d, 0x2f, 0x00, 0xe2, 0x67, 0x5b, 0xb2, 0x08, 0xc5, 0x56, 0x7b, 0x77, 0xa7, 0xd7, 0xe9, 0x70, 0xc6, 0xc3, 0xc9, 0xf0, 0xbf, 0x89, 0x62, 0x1b, 0x6e, 0x30, 0xfe, 0xfc, 0x5c, 0x5a, 0xd4,
0xd7, 0x16, 0x48, 0x05, 0x4a, 0xfb, 0x9d, 0xfe, 0x56, 0x8b, 0x35, 0xf7, 0x6b, 0x0e, 0x59, 0x81, 0xa1, 0x18, 0x08, 0xd5, 0xda, 0x1c, 0xfd, 0xc8, 0x74, 0x6e, 0x6f, 0xa6, 0x05, 0xb7, 0xbe, 0x04,
0x6a, 0x9f, 0x35, 0xbb, 0xbd, 0xbb, 0x6d, 0xd6, 0xe9, 0xee, 0xee, 0xf5, 0x6b, 0x19, 0x42, 0x60, 0x48, 0x5e, 0x6a, 0xc9, 0x12, 0x14, 0x9b, 0xad, 0xbd, 0xdd, 0x6e, 0xbb, 0x57, 0x5d, 0x20, 0x65,
0xc9, 0xa8, 0x76, 0xf6, 0xfa, 0xa8, 0xcb, 0x92, 0x2a, 0x94, 0x9b, 0x7b, 0xfd, 0xad, 0x1d, 0xd6, 0x58, 0x3c, 0x68, 0xf7, 0xb6, 0x9b, 0xac, 0x71, 0x50, 0x75, 0xc8, 0x2a, 0x54, 0x7a, 0xac, 0xd1,
0x79, 0xd2, 0xae, 0xe5, 0x36, 0x1a, 0x12, 0xae, 0xf8, 0xef, 0xbc, 0x04, 0xa0, 0xa0, 0xd6, 0xab, 0xe9, 0xde, 0x6f, 0xb1, 0x76, 0x67, 0x6f, 0xbf, 0x57, 0xcd, 0x10, 0x02, 0xcb, 0x9a, 0xb5, 0xbb,
0x2d, 0x90, 0x12, 0xe4, 0xf0, 0x2a, 0x55, 0x73, 0x70, 0x5d, 0xfd, 0x6a, 0x57, 0xcb, 0x6c, 0xbc, 0xdf, 0x43, 0x5e, 0x96, 0x54, 0xa0, 0xd4, 0xd8, 0xef, 0x6d, 0xef, 0xb2, 0xf6, 0x93, 0x56, 0x35,
0x29, 0x4b, 0x20, 0xfa, 0x6b, 0x14, 0x29, 0x42, 0xb6, 0x39, 0x1c, 0xd6, 0x16, 0x70, 0x6c, 0x8b, 0xb7, 0x55, 0x17, 0x70, 0x25, 0x3f, 0xef, 0x12, 0x80, 0x82, 0xdc, 0xaf, 0xba, 0x40, 0x16, 0x21,
0x8f, 0xb8, 0xe0, 0x35, 0x67, 0xe3, 0xfb, 0x00, 0x71, 0x17, 0x24, 0x65, 0xc8, 0xef, 0x75, 0x5b, 0x87, 0x17, 0xaf, 0xaa, 0x83, 0xfb, 0xaa, 0xce, 0x5f, 0xcd, 0x6c, 0xbd, 0x2d, 0x52, 0x20, 0xfe,
0xed, 0xbb, 0xb5, 0x05, 0xfc, 0xf9, 0xb0, 0xf9, 0xa0, 0xd3, 0xaa, 0x39, 0x68, 0x7f, 0x97, 0xed, 0x01, 0x8a, 0x14, 0x21, 0xdb, 0x18, 0x0c, 0xaa, 0x0b, 0xb8, 0xb6, 0xc9, 0x87, 0x3c, 0xe2, 0x55,
0x3c, 0x69, 0x77, 0x6b, 0x19, 0x5c, 0x6b, 0xaf, 0xd7, 0x6e, 0xd5, 0xb2, 0x1b, 0xdf, 0x81, 0x1c, 0x67, 0xeb, 0x87, 0x00, 0x49, 0x17, 0x24, 0x25, 0xc8, 0xef, 0x77, 0x9a, 0xad, 0xfb, 0xd5, 0x05,
0x36, 0x5f, 0x5c, 0xb3, 0xb7, 0xdb, 0xee, 0xb6, 0xda, 0x4c, 0xc5, 0xca, 0xda, 0xfd, 0x3d, 0xd6, 0xfc, 0xf3, 0x61, 0xe3, 0x41, 0xbb, 0x59, 0x75, 0x50, 0xfe, 0x3e, 0xdb, 0x7d, 0xd2, 0xea, 0x54,
0x6d, 0xb3, 0x9a, 0x43, 0x96, 0x00, 0xa2, 0x20, 0x58, 0x2d, 0xb3, 0xf1, 0x43, 0x78, 0x65, 0xdb, 0x33, 0xb8, 0xd7, 0x7e, 0xb7, 0xd5, 0xac, 0x66, 0xb7, 0xbe, 0x07, 0x39, 0x6c, 0xbe, 0xb8, 0x67,
0x9b, 0x99, 0x4d, 0x1b, 0x0e, 0xdc, 0xb1, 0x5e, 0xb7, 0x04, 0xb9, 0x4e, 0xeb, 0x41, 0x5b, 0x4d, 0x77, 0xaf, 0xd5, 0x69, 0xb6, 0x98, 0xf4, 0x95, 0xb5, 0x7a, 0xfb, 0xac, 0xd3, 0x62, 0x55, 0x87,
0xd0, 0xbb, 0xd3, 0xec, 0x76, 0x3b, 0xdd, 0x7b, 0x35, 0x07, 0xa5, 0xbb, 0x9d, 0x6e, 0xa7, 0xb7, 0x2c, 0x03, 0xc4, 0x4e, 0xb0, 0x6a, 0x66, 0xeb, 0x27, 0xf0, 0xda, 0x8e, 0x37, 0xd5, 0x45, 0x1b,
0xd5, 0x6e, 0xd5, 0x32, 0x8d, 0x3f, 0x3a, 0x00, 0xc7, 0xde, 0xcc, 0x3c, 0x1c, 0x7e, 0x04, 0xcb, 0xf6, 0xdd, 0x91, 0xda, 0x77, 0x11, 0x72, 0xed, 0xe6, 0x83, 0x96, 0x54, 0xd0, 0xbd, 0xd7, 0xe8,
0xf7, 0x52, 0xf3, 0x54, 0xcd, 0xa9, 0xc0, 0x9f, 0x77, 0xbd, 0xd1, 0x6a, 0x2d, 0x16, 0x7b, 0x22, 0x74, 0xda, 0x9d, 0x4f, 0xab, 0x0e, 0x52, 0xf7, 0xdb, 0x9d, 0x76, 0x77, 0xbb, 0xd5, 0xac, 0x66,
0xf0, 0xc6, 0x87, 0x74, 0x81, 0x7c, 0x08, 0x8b, 0x6a, 0x08, 0x86, 0x7d, 0xa5, 0x11, 0x9f, 0x42, 0xea, 0x7f, 0x76, 0x00, 0x4e, 0xbc, 0xa9, 0x7e, 0x0b, 0xfc, 0x10, 0x56, 0x3e, 0x4d, 0xe9, 0xa9,
0x35, 0x51, 0x22, 0x64, 0x39, 0x36, 0x92, 0x7d, 0x67, 0x75, 0x35, 0x56, 0xa4, 0x8b, 0x89, 0x2e, 0xe8, 0x53, 0x81, 0x3f, 0xef, 0x78, 0xc3, 0xf5, 0x6a, 0x42, 0x76, 0xa3, 0xc0, 0x1b, 0x1d, 0xd1,
0x3c, 0x2d, 0xc8, 0xff, 0x6b, 0xb8, 0xfd, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xed, 0xe4, 0x89, 0x05, 0xf2, 0x01, 0x2c, 0xc9, 0x25, 0xe8, 0xf6, 0x95, 0x56, 0xdc, 0x85, 0x8a, 0x95, 0x22, 0x64,
0x07, 0x0c, 0x21, 0x00, 0x00, 0x25, 0x11, 0x12, 0x7d, 0x67, 0x7d, 0x3d, 0x61, 0xa4, 0x93, 0x89, 0x2e, 0x3c, 0x2d, 0x88, 0x7f,
0x67, 0xb8, 0xf3, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x73, 0x91, 0xca, 0x02, 0x03, 0x21, 0x00,
0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
......
...@@ -74,6 +74,7 @@ func (p *MixType) GetLogMap() map[int64]*types.LogInfo { ...@@ -74,6 +74,7 @@ func (p *MixType) GetLogMap() map[int64]*types.LogInfo {
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"},
TyLogNulliferSet: {Ty: reflect.TypeOf(ExistValue{}), Name: "LogNullifierSet"},
} }
} }
...@@ -157,6 +158,17 @@ func MulCurvePointH(val string) *twistededwards.Point { ...@@ -157,6 +158,17 @@ func MulCurvePointH(val string) *twistededwards.Point {
return &pointV return &pointV
} }
func GetCurveSum(points ...*twistededwards.Point) *twistededwards.Point {
//Add之前需初始化pointSum,不能空值,不然会等于0
pointSum := twistededwards.NewPoint(points[0].X, points[0].Y)
for _, a := range points[1:] {
pointSum.Add(&pointSum, a)
}
return &pointSum
}
//A=B+C //A=B+C
func CheckSumEqual(points ...*twistededwards.Point) bool { func CheckSumEqual(points ...*twistededwards.Point) bool {
if len(points) < 2 { if len(points) < 2 {
......
...@@ -5,12 +5,42 @@ ...@@ -5,12 +5,42 @@
package wallet package wallet
import ( import (
"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"
"github.com/pkg/errors"
) )
func (policy *mixPolicy) On_ShowAccountPrivacyInfo(req *types.ReqString) (types.Message, error) { func (policy *mixPolicy) On_ShowAccountPrivacyInfo(req *mixTy.PaymentKeysReq) (types.Message, error) {
return policy.getAccountPrivacyKey(req.Data) if len(req.Addr) == 0 && len(req.PrivKey) == 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "addr or privkey need be set")
}
//通过私钥获取
if len(req.PrivKey) > 0 {
prikeybyte, err := common.FromHex(req.PrivKey)
if err != nil {
return nil, errors.Wrapf(err, "privkey fromHex error,key=%s", req.PrivKey)
}
var ret mixTy.WalletAddrPrivacy
ret.Privacy = newPrivacyKey(prikeybyte)
if req.Detail <= 0 {
ret.Privacy.EncryptKey.PrivKey = ""
ret.Privacy.PaymentKey.SpendKey = ""
}
return &ret, nil
}
//通过account 从钱包获取
keys, err := policy.getAccountPrivacyKey(req.Addr)
if err != nil {
return nil, errors.Wrapf(err, "get account =%s privacy key", req.Addr)
}
if req.Detail <= 0 {
keys.Privacy.EncryptKey.PrivKey = ""
keys.Privacy.PaymentKey.SpendKey = ""
}
return keys, nil
} }
func (policy *mixPolicy) On_ShowAccountNoteInfo(req *types.ReqAddrs) (types.Message, error) { func (policy *mixPolicy) On_ShowAccountNoteInfo(req *types.ReqAddrs) (types.Message, error) {
......
...@@ -22,21 +22,27 @@ import ( ...@@ -22,21 +22,27 @@ import (
const CECBLOCKSIZE = 32 const CECBLOCKSIZE = 32
// newPrivacyWithPrivKey create privacy from private key /*
//payment, payPrivKey=hash(privkey), payPubkey=hash(payPrivKey) 从secp256k1根私钥创建支票需要的私钥和公钥
//DH crypt key, prikey=payPrikey, pubKey=payPrikey*G payPrivKey = rootPrivKey *G_X25519 这样很难泄露rootPrivKey
func newPrivacyKey(privKey []byte) (*mixTy.AccountPrivacyKey, error) {
payPrivacyKey := mimcHashByte([][]byte{privKey}) 支票收款key: ReceiveKey= hash(payPrivKey) --或者*G的X坐标值, 看哪个电路少?
DH加解密key: encryptPubKey= payPrivKey *G_X25519, 也是很安全的,只是电路里面目前不支持x25519
*/
func newPrivacyKey(rootPrivKey []byte) *mixTy.AccountPrivacyKey {
ecdh := X25519()
key := ecdh.PublicKey(rootPrivKey)
payPrivKey := key.([32]byte)
//payPrivKey := mimcHashByte([][]byte{rootPrivKey})
paymentKey := &mixTy.PaymentKeyPair{} paymentKey := &mixTy.PaymentKeyPair{}
paymentKey.SpendKey = mixTy.Byte2Str(payPrivacyKey) paymentKey.SpendKey = mixTy.Byte2Str(payPrivKey[:])
paymentKey.ReceiveKey = mixTy.Byte2Str(mimcHashByte([][]byte{payPrivacyKey})) paymentKey.ReceiveKey = mixTy.Byte2Str(mimcHashByte([][]byte{payPrivKey[:]}))
encryptKeyPair := &mixTy.EncryptKeyPair{} encryptKeyPair := &mixTy.EncryptKeyPair{}
//ecdh := NewCurveBn256ECDH() pubkey := ecdh.PublicKey(payPrivKey)
ecdh := X25519() //需要Hex编码,不要使用fr.string, 模范围不同
pubkey := ecdh.PublicKey(payPrivacyKey) encryptKeyPair.PrivKey = hex.EncodeToString(payPrivKey[:])
//需要Hex编码,而不腻使用fr.string, 模范围不同
encryptKeyPair.PrivKey = hex.EncodeToString(payPrivacyKey)
pubData := pubkey.([32]byte) pubData := pubkey.([32]byte)
encryptKeyPair.PubKey = hex.EncodeToString(pubData[:]) encryptKeyPair.PubKey = hex.EncodeToString(pubData[:])
...@@ -44,7 +50,7 @@ func newPrivacyKey(privKey []byte) (*mixTy.AccountPrivacyKey, error) { ...@@ -44,7 +50,7 @@ func newPrivacyKey(privKey []byte) (*mixTy.AccountPrivacyKey, error) {
privacy.PaymentKey = paymentKey privacy.PaymentKey = paymentKey
privacy.EncryptKey = encryptKeyPair privacy.EncryptKey = encryptKeyPair
return privacy, nil return privacy
} }
//CEC加密需要保证明文是秘钥的倍数,如果不是,则需要填充明文,在解密时候把填充物去掉 //CEC加密需要保证明文是秘钥的倍数,如果不是,则需要填充明文,在解密时候把填充物去掉
...@@ -201,10 +207,7 @@ func (policy *mixPolicy) savePrivacyPair(addr string) (*mixTy.WalletAddrPrivacy, ...@@ -201,10 +207,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 := newPrivacyKey(priv.Bytes()) newPrivacy := newPrivacyKey(priv.Bytes())
if err != nil {
return nil, err
}
password := []byte(policy.getWalletOperate().GetPassword()) password := []byte(policy.getWalletOperate().GetPassword())
encryptered := encryptDataWithPadding(password, types.Encode(newPrivacy)) encryptered := encryptDataWithPadding(password, types.Encode(newPrivacy))
......
...@@ -91,28 +91,33 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t ...@@ -91,28 +91,33 @@ func (p *mixPolicy) processMixTx(tx *types.Transaction, height, index int64) (*t
} }
func (p *mixPolicy) processDeposit(deposit *mixTy.MixDepositAction, heightIndex string, table *table.Table) { func (p *mixPolicy) processDeposit(deposit *mixTy.MixDepositAction, heightIndex string, table *table.Table) {
data, err := mixTy.DecodePubInput(mixTy.VerifyType_DEPOSIT, deposit.Proof.PublicInput) for _, proof := range deposit.Proofs {
data, err := mixTy.DecodePubInput(mixTy.VerifyType_DEPOSIT, proof.PublicInput)
if err != nil { if err != nil {
bizlog.Error("processDeposit decode", "pubInput", deposit.Proof.PublicInput) bizlog.Error("processDeposit decode", "pubInput", proof.PublicInput)
return return
} }
input := data.(*mixTy.DepositPublicInput) input := data.(*mixTy.DepositPublicInput)
p.processSecretGroup(input.NoteHash, deposit.Proof.Secrets, heightIndex, table) p.processSecretGroup(input.NoteHash, proof.Secrets, heightIndex, table)
}
} }
func (p *mixPolicy) processTransfer(transfer *mixTy.MixTransferAction, heightIndex string, table *table.Table) { func (p *mixPolicy) processTransfer(transfer *mixTy.MixTransferAction, heightIndex string, table *table.Table) {
var nulls []string var nulls []string
data, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFERINPUT, transfer.Input.PublicInput) for _, in := range transfer.Inputs {
data, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFERINPUT, in.PublicInput)
if err != nil { if err != nil {
bizlog.Error("processTransfer.input decode", "pubInput", transfer.Input.PublicInput) bizlog.Error("processTransfer.input decode", "pubInput", in.PublicInput)
return return
} }
input := data.(*mixTy.TransferInputPublicInput) input := data.(*mixTy.TransferInputPublicInput)
nulls = append(nulls, input.NullifierHash) nulls = append(nulls, input.NullifierHash)
}
p.processNullifiers(nulls, table) p.processNullifiers(nulls, table)
//out //out
data, err = mixTy.DecodePubInput(mixTy.VerifyType_TRANSFEROUTPUT, transfer.Output.PublicInput) data, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFEROUTPUT, transfer.Output.PublicInput)
if err != nil { if err != nil {
bizlog.Error("processTransfer.output decode", "pubInput", transfer.Output.PublicInput) bizlog.Error("processTransfer.output decode", "pubInput", transfer.Output.PublicInput)
return return
......
...@@ -16,8 +16,8 @@ func TestNewPrivacyWithPrivKey(t *testing.T) { ...@@ -16,8 +16,8 @@ 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 := newPrivacyKey(keyByte) pairs := newPrivacyKey(keyByte)
assert.Equal(t, nil, err)
t.Log("payPri", pairs.PaymentKey.SpendKey, "payPub", pairs.PaymentKey.ReceiveKey) t.Log("payPri", pairs.PaymentKey.SpendKey, "payPub", pairs.PaymentKey.ReceiveKey)
t.Log("crytoPub", pairs.EncryptKey.PubKey, "crytoPri", pairs.EncryptKey.PrivKey) t.Log("crytoPub", pairs.EncryptKey.PubKey, "crytoPri", pairs.EncryptKey.PrivKey)
...@@ -87,8 +87,8 @@ func TestEncodeSecretData(t *testing.T) { ...@@ -87,8 +87,8 @@ func TestEncodeSecretData(t *testing.T) {
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 := newPrivacyKey(keyByte) privacy := newPrivacyKey(keyByte)
assert.Equal(t, nil, err)
ret := types.Encode(secret) ret := types.Encode(secret)
hexRet := hex.EncodeToString(ret) hexRet := hex.EncodeToString(ret)
//assert.Nil(t,err) //assert.Nil(t,err)
......
...@@ -132,12 +132,12 @@ func (policy *mixPolicy) createAuthTx(req *mixTy.CreateRawTxReq) (*types.Transac ...@@ -132,12 +132,12 @@ func (policy *mixPolicy) createAuthTx(req *mixTy.CreateRawTxReq) (*types.Transac
return nil, err return nil, err
} }
proofInfo, err := getZkProofKeys(auth.ZkPath.Path+mixTy.AuthCircuit, auth.ZkPath.Path+mixTy.AuthPk, *input) proofInfo, err := getZkProofKeys(auth.ZkPath+mixTy.AuthCircuit, auth.ZkPath+mixTy.AuthPk, *input)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getZkProofKeys note=%s", auth.NoteHash) return nil, errors.Wrapf(err, "getZkProofKeys note=%s", auth.NoteHash)
} }
//verify //verify
if err := policy.verifyProofOnChain(mixTy.VerifyType_AUTHORIZE, proofInfo, auth.ZkPath.Path+mixTy.AuthVk); err != nil { if err := policy.verifyProofOnChain(mixTy.VerifyType_AUTHORIZE, proofInfo, auth.ZkPath+mixTy.AuthVk); err != nil {
return nil, errors.Wrapf(err, "verifyProof fail for note=%s", auth.NoteHash) return nil, errors.Wrapf(err, "verifyProof fail for note=%s", auth.NoteHash)
} }
......
...@@ -6,8 +6,8 @@ package wallet ...@@ -6,8 +6,8 @@ package wallet
import ( import (
"encoding/hex" "encoding/hex"
"fmt"
"strconv" "strconv"
"strings" "strings"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
...@@ -32,38 +32,42 @@ type DepositInput struct { ...@@ -32,38 +32,42 @@ type DepositInput struct {
NoteRandom string `tag:"secret"` NoteRandom string `tag:"secret"`
} }
func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositProofResp, error) { func (policy *mixPolicy) depositParams(receiver, returner, auth, amount string) (*mixTy.DepositProofResp, error) {
if req == nil || len(req.Addr) <= 0 { if len(receiver) <= 0 {
return nil, errors.Wrap(types.ErrInvalidParam, "paymentAddr is nil") return nil, errors.Wrap(types.ErrInvalidParam, "receiver is nil")
} }
if req.Amount <= 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "deposit amount=%d need big than 0", req.Amount) _, e := strconv.ParseUint(amount, 0, 0)
if e != nil {
return nil, errors.Wrapf(e, "deposit amount=%s", amount)
} }
var secret mixTy.SecretData var secret mixTy.SecretData
secret.Amount = strconv.FormatUint(req.Amount, 10) secret.Amount = amount
//1. nullifier 获取随机值 //1. nullifier 获取随机值
var fr fr_bn256.Element var fr fr_bn256.Element
fr.SetRandom() fr.SetRandom()
secret.NoteRandom = fr.String() secret.NoteRandom = fr.String()
//TODO 线上检查是否随机值在nullifer里面
// 获取receiving addr对应的paymentKey // 获取receiving addr对应的paymentKey
toKey, e := policy.getPaymentKey(req.Addr) payKeys, e := policy.getPaymentKey(receiver)
if e != nil { if e != nil {
return nil, errors.Wrapf(e, "get payment key for addr = %s", req.Addr) return nil, errors.Wrapf(e, "get payment key for addr = %s", receiver)
} }
secret.ReceiverKey = toKey.ReceiverKey secret.ReceiverKey = payKeys.ReceiverKey
//获取return addr对应的key //获取return addr对应的key
var returnKey *mixTy.PaymentKey var returnKey *mixTy.PaymentKey
var err error var err error
//如果Input不填,缺省空为“0”字符串 //如果Input不填,缺省空为“0”字符串
secret.ReturnKey = "0" secret.ReturnKey = "0"
if len(req.ReturnAddr) > 0 { if len(returner) > 0 {
returnKey, err = policy.getPaymentKey(req.ReturnAddr) returnKey, err = policy.getPaymentKey(returner)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "get payment key for return addr = %s", req.ReturnAddr) return nil, errors.Wrapf(err, "get payment key for return addr = %s", returner)
} }
secret.ReturnKey = returnKey.ReceiverKey secret.ReturnKey = returnKey.ReceiverKey
} }
...@@ -71,10 +75,10 @@ func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositPr ...@@ -71,10 +75,10 @@ func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositPr
//获取auth addr对应的key //获取auth addr对应的key
var authKey *mixTy.PaymentKey var authKey *mixTy.PaymentKey
secret.AuthorizeKey = "0" secret.AuthorizeKey = "0"
if len(req.AuthorizeAddr) > 0 { if len(auth) > 0 {
authKey, err = policy.getPaymentKey(req.AuthorizeAddr) authKey, err = policy.getPaymentKey(auth)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "get payment key for authorize addr = %s", req.AuthorizeAddr) return nil, errors.Wrapf(err, "get payment key for authorize addr = %s", auth)
} }
secret.AuthorizeKey = authKey.ReceiverKey secret.AuthorizeKey = authKey.ReceiverKey
} }
...@@ -83,22 +87,22 @@ func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositPr ...@@ -83,22 +87,22 @@ func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositPr
data := types.Encode(&secret) data := types.Encode(&secret)
var group mixTy.DHSecretGroup var group mixTy.DHSecretGroup
secretData, err := encryptData(toKey.EncryptKey, data) secretData, err := encryptData(payKeys.EncryptKey, data)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", req.Addr) return nil, errors.Wrapf(err, "encryptData to addr = %s", receiver)
} }
group.Receiver = hex.EncodeToString(types.Encode(secretData)) group.Receiver = hex.EncodeToString(types.Encode(secretData))
if returnKey != nil { if returnKey != nil {
secretData, err = encryptData(returnKey.EncryptKey, data) secretData, err = encryptData(returnKey.EncryptKey, data)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", req.ReturnAddr) return nil, errors.Wrapf(err, "encryptData to addr = %s", returner)
} }
group.Returner = hex.EncodeToString(types.Encode(secretData)) group.Returner = hex.EncodeToString(types.Encode(secretData))
} }
if authKey != nil { if authKey != nil {
secretData, err = encryptData(authKey.EncryptKey, data) secretData, err = encryptData(authKey.EncryptKey, data)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "encryptData to addr = %s", req.AuthorizeAddr) return nil, errors.Wrapf(err, "encryptData to addr = %s", auth)
} }
group.Authorize = hex.EncodeToString(types.Encode(secretData)) group.Authorize = hex.EncodeToString(types.Encode(secretData))
} }
...@@ -119,14 +123,9 @@ func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositPr ...@@ -119,14 +123,9 @@ func (policy *mixPolicy) depositParams(req *mixTy.DepositInfo) (*mixTy.DepositPr
} }
func (policy *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Transaction, error) { func (policy *mixPolicy) getDepositProof(receiver, returner, auth, amount, zkPath string) (*mixTy.ZkProofInfo, 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) resp, err := policy.depositParams(receiver, returner, auth, amount)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -139,24 +138,57 @@ func (policy *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Tran ...@@ -139,24 +138,57 @@ func (policy *mixPolicy) createDepositTx(req *mixTy.CreateRawTxReq) (*types.Tran
input.ReturnPubKey = resp.Proof.ReturnKey input.ReturnPubKey = resp.Proof.ReturnKey
input.NoteRandom = resp.Proof.NoteRandom input.NoteRandom = resp.Proof.NoteRandom
proofInfo, err := getZkProofKeys(deposit.ZkPath.Path+mixTy.DepositCircuit, deposit.ZkPath.Path+mixTy.DepositPk, input) proofInfo, err := getZkProofKeys(zkPath+mixTy.DepositCircuit, zkPath+mixTy.DepositPk, input)
if err != nil { if err != nil {
return nil, err return nil, err
} }
//线上验证proof,失败的原因有可能circuit,Pk和线上vk不匹配,或不是一起产生的版本 //线上验证proof,失败的原因有可能circuit,Pk和线上vk不匹配,或不是一起产生的版本
if err := policy.verifyProofOnChain(mixTy.VerifyType_DEPOSIT, proofInfo, deposit.ZkPath.Path+mixTy.DepositVk); err != nil { if err := policy.verifyProofOnChain(mixTy.VerifyType_DEPOSIT, proofInfo, zkPath+mixTy.DepositVk); err != nil {
return nil, errors.Wrap(err, "verifyProof fail") return nil, errors.Wrap(err, "verifyProof fail")
} }
fmt.Println("createDepositTx ok")
proofInfo.Secrets = resp.Secrets proofInfo.Secrets = resp.Secrets
return policy.getDepositTx(strings.TrimSpace(req.Title+mixTy.MixX), proofInfo) return proofInfo, 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")
}
if deposit.Deposit == nil {
return nil, errors.Wrap(err, "decode deposit fail")
}
if len(deposit.ZkPath) == 0 {
deposit.ZkPath = "./"
}
//多个receiver
receivers := strings.Split(deposit.Deposit.ReceiverAddrs, ",")
amounts := strings.Split(deposit.Deposit.Amounts, ",")
if len(receivers) != len(amounts) || len(receivers) == 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "not match receivers=%s and amounts=%s", deposit.Deposit.ReceiverAddrs, deposit.Deposit.Amounts)
}
var proofs []*mixTy.ZkProofInfo
for i, rcv := range receivers {
p, err := policy.getDepositProof(rcv, deposit.Deposit.ReturnAddr, deposit.Deposit.AuthorizeAddr, amounts[i], deposit.ZkPath)
if err != nil {
return nil, errors.Wrapf(err, "get Deposit proof for=%s", rcv)
}
proofs = append(proofs, p)
}
return policy.getDepositTx(strings.TrimSpace(req.Title+mixTy.MixX), proofs)
} }
func (policy *mixPolicy) getDepositTx(execName string, proof *mixTy.ZkProofInfo) (*types.Transaction, error) { func (policy *mixPolicy) getDepositTx(execName string, proofs []*mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixDepositAction{} payload := &mixTy.MixDepositAction{}
payload.Proof = proof payload.Proofs = proofs
cfg := policy.getWalletOperate().GetAPI().GetConfig() cfg := policy.getWalletOperate().GetAPI().GetConfig()
action := &mixTy.MixAction{ action := &mixTy.MixAction{
...@@ -170,6 +202,6 @@ func (policy *mixPolicy) getDepositTx(execName string, proof *mixTy.ZkProofInfo) ...@@ -170,6 +202,6 @@ func (policy *mixPolicy) getDepositTx(execName string, proof *mixTy.ZkProofInfo)
To: address.ExecAddress(execName), To: address.ExecAddress(execName),
Expire: types.Now().Unix() + int64(300), //5 min Expire: types.Now().Unix() + int64(300), //5 min
} }
fmt.Println("createDepositTx tx")
return types.FormatTx(cfg, execName, tx) return types.FormatTx(cfg, execName, tx)
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package wallet package wallet
import ( import (
"fmt"
"strconv" "strconv"
"strings" "strings"
...@@ -17,6 +18,7 @@ import ( ...@@ -17,6 +18,7 @@ import (
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types" mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
fr_bn256 "github.com/consensys/gurvy/bn256/fr" fr_bn256 "github.com/consensys/gurvy/bn256/fr"
"github.com/consensys/gurvy/bn256/twistededwards"
) )
type TransferInput struct { type TransferInput struct {
...@@ -142,9 +144,14 @@ func (policy *mixPolicy) getTransferInputPart(note *mixTy.WalletIndexInfo) (*Tra ...@@ -142,9 +144,14 @@ func (policy *mixPolicy) getTransferInputPart(note *mixTy.WalletIndexInfo) (*Tra
} }
func (policy *mixPolicy) getTransferOutput(req *mixTy.DepositInfo) (*TransferOutput, *mixTy.DHSecretGroup, error) { func (policy *mixPolicy) getTransferOutput(req *mixTy.DepositInfo) (*TransferOutput, *mixTy.DHSecretGroup, error) {
resp, err := policy.depositParams(req) //目前只支持一个ReceiverAddr
if strings.Contains(req.ReceiverAddrs, ",") || strings.Contains(req.Amounts, ",") {
return nil, nil, errors.Wrapf(types.ErrInvalidParam, "only support one addr or amount,addrs=%s,amount=%s",
req.ReceiverAddrs, req.Amounts)
}
resp, err := policy.depositParams(req.ReceiverAddrs, req.ReturnAddr, req.AuthorizeAddr, req.Amounts)
if err != nil { if err != nil {
return nil, nil, errors.Wrapf(err, "deposit toAddr") return nil, nil, errors.Wrapf(err, "deposit toAddr=%s", req.ReceiverAddrs)
} }
var input TransferOutput var input TransferOutput
...@@ -159,60 +166,106 @@ func (policy *mixPolicy) getTransferOutput(req *mixTy.DepositInfo) (*TransferOut ...@@ -159,60 +166,106 @@ func (policy *mixPolicy) getTransferOutput(req *mixTy.DepositInfo) (*TransferOut
} }
func getShieldValue(noteAmount, transferAmount, minTxFee uint64) (*mixTy.ShieldAmountRst, error) { //input = output+找零+交易费
if noteAmount < transferAmount+minTxFee { func getShieldValue(inputAmounts []uint64, outAmount, change, minTxFee uint64) (*mixTy.ShieldAmountRst, error) {
return nil, errors.Wrapf(types.ErrInvalidParam, "transfer amount=%d big than note=%d - fee=%d", transferAmount, noteAmount, minTxFee) var sum uint64
for _, i := range inputAmounts {
sum += i
}
if sum != outAmount+change+minTxFee {
return nil, errors.Wrapf(types.ErrInvalidParam, "getShieldValue.sum error,sum=%d,out=%d,change=%d,fee=%d",
sum, outAmount, change, minTxFee)
} }
change := noteAmount - transferAmount - minTxFee
//get amount*G point //get amount*G point
//note = transfer + change + minTxFee //note = transfer + change + minTxFee
noteAmountG := mixTy.MulCurvePointG(noteAmount) var inputGPoints []*twistededwards.Point
transAmountG := mixTy.MulCurvePointG(transferAmount) for _, i := range inputAmounts {
inputGPoints = append(inputGPoints, mixTy.MulCurvePointG(i))
}
//noteAmountG := mixTy.MulCurvePointG(inputAmount)
outAmountG := mixTy.MulCurvePointG(outAmount)
changeAmountG := mixTy.MulCurvePointG(change) changeAmountG := mixTy.MulCurvePointG(change)
minTxFeeG := mixTy.MulCurvePointG(minTxFee) minTxFeeG := mixTy.MulCurvePointG(minTxFee)
if !mixTy.CheckSumEqual(noteAmountG, transAmountG, changeAmountG, minTxFeeG) { sumPointG := mixTy.GetCurveSum(inputGPoints...)
if !mixTy.CheckSumEqual(sumPointG, outAmountG, changeAmountG, minTxFeeG) {
return nil, errors.Wrapf(types.ErrInvalidParam, "amount sum fail for mul G point") return nil, errors.Wrapf(types.ErrInvalidParam, "amount sum fail for mul G point")
} }
//三个混淆随机值可以随机获取,这里noteRandom和为了Nullifier计算的NoteRandom不同。 //三个混淆随机值可以随机获取,这里noteRandom和为了Nullifier计算的NoteRandom不同。
//获取随机值,截取一半给change和transfer,和值给Note,直接用完整的random值会溢出 //获取随机值,截取一半给change和transfer,和值给Note,直接用完整的random值会溢出
var rChange, rTrans, v fr_bn256.Element var rChange, rOut, v fr_bn256.Element
random := v.SetRandom().String() random := v.SetRandom().String()
rChange.SetString(random[0 : len(random)/2]) rChange.SetString(random[0 : len(random)/2])
rTrans.SetString(random[len(random)/2:]) rOut.SetString(random[len(random)/2:])
fmt.Println("rOut", rOut.String())
fmt.Println("rChange", rChange.String())
var rSumIn, rSumOut fr_bn256.Element
rSumIn.SetZero()
rSumOut.Add(&rChange, &rOut)
var rInputs []fr_bn256.Element
rInputs = append(rInputs, rSumOut)
//len(inputAmounts)>1场景,每个input的随机值设为随机值的1/3长度,这样加起来不会超过rOut+rChange
for i := 1; i < len(inputAmounts); i++ {
var a, v fr_bn256.Element
rv := v.SetRandom().String()
a.SetString(rv[0 : len(random)/3])
rInputs = append(rInputs, a)
rSumIn.Add(&rSumIn, &a)
}
//如果len(inputAmounts)>1,则把rInputs[0]替换为rrSumOut-rSumIn,rSumIn都是1/3的随机值长度,减法应该不会溢出
if len(rInputs) > 1 {
var sub fr_bn256.Element
sub.Sub(&rSumOut, &rSumIn)
rInputs[0] = sub
}
rSumIn.Add(&rSumIn, &rInputs[0])
if !rSumIn.Equal(&rSumOut) {
var rNote fr_bn256.Element return nil, errors.Wrapf(types.ErrInvalidParam, "random sumIn=%s not equal sumOut=%s", rSumIn.String(), rSumOut.String())
rNote.Add(&rChange, &rTrans) }
noteH := mixTy.MulCurvePointH(rNote.String()) var inputHPoints []*twistededwards.Point
transferH := mixTy.MulCurvePointH(rTrans.String()) for _, i := range rInputs {
inputHPoints = append(inputHPoints, mixTy.MulCurvePointH(i.String()))
}
//noteH := mixTy.MulCurvePointH(rNote.String())
outH := mixTy.MulCurvePointH(rOut.String())
changeH := mixTy.MulCurvePointH(rChange.String()) changeH := mixTy.MulCurvePointH(rChange.String())
//fmt.Println("change",changeRandom.String()) //fmt.Println("change",changeRandom.String())
//fmt.Println("transfer",transRandom.String()) //fmt.Println("transfer",transRandom.String())
//fmt.Println("note",noteRandom.String()) //fmt.Println("note",noteRandom.String())
sumPointH := mixTy.GetCurveSum(inputHPoints...)
if !mixTy.CheckSumEqual(noteH, transferH, changeH) { if !mixTy.CheckSumEqual(sumPointH, outH, changeH) {
return nil, errors.Wrapf(types.ErrInvalidParam, "random sum error") return nil, errors.Wrapf(types.ErrInvalidParam, "random sum error")
} }
noteAmountG.Add(noteAmountG, noteH) for i, p := range inputGPoints {
transAmountG.Add(transAmountG, transferH) p.Add(p, inputHPoints[i])
}
outAmountG.Add(outAmountG, outH)
changeAmountG.Add(changeAmountG, changeH) changeAmountG.Add(changeAmountG, changeH)
sumPointG = mixTy.GetCurveSum(inputGPoints...)
if !mixTy.CheckSumEqual(noteAmountG, transAmountG, changeAmountG, minTxFeeG) { if !mixTy.CheckSumEqual(sumPointG, outAmountG, changeAmountG, minTxFeeG) {
return nil, errors.Wrapf(types.ErrInvalidParam, "amount sum fail for G+H point") return nil, errors.Wrapf(types.ErrInvalidParam, "amount sum fail for G+H point")
} }
rst := &mixTy.ShieldAmountRst{ rst := &mixTy.ShieldAmountRst{
InputRandom: rNote.String(), OutputRandom: rOut.String(),
OutputRandom: rTrans.String(),
ChangeRandom: rChange.String(), ChangeRandom: rChange.String(),
Input: &mixTy.ShieldAmount{X: noteAmountG.X.String(), Y: noteAmountG.Y.String()}, Output: &mixTy.ShieldAmount{X: outAmountG.X.String(), Y: outAmountG.Y.String()},
Output: &mixTy.ShieldAmount{X: transAmountG.X.String(), Y: transAmountG.Y.String()},
Change: &mixTy.ShieldAmount{X: changeAmountG.X.String(), Y: changeAmountG.Y.String()}, Change: &mixTy.ShieldAmount{X: changeAmountG.X.String(), Y: changeAmountG.Y.String()},
} }
for _, r := range rInputs {
rst.InputRandoms = append(rst.InputRandoms, r.String())
fmt.Println("inputRandom", r.String())
}
for _, p := range inputGPoints {
rst.Inputs = append(rst.Inputs, &mixTy.ShieldAmount{X: p.X.String(), Y: p.Y.String()})
}
return rst, nil return rst, nil
} }
...@@ -222,54 +275,83 @@ func (policy *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Tra ...@@ -222,54 +275,83 @@ func (policy *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Tra
if err != nil { if err != nil {
return nil, errors.Wrap(err, "decode req fail") return nil, errors.Wrap(err, "decode req fail")
} }
note, err := policy.getNoteInfo(transfer.GetInput().NoteHash, mixTy.NoteStatus_VALID)
noteHashs := strings.Split(transfer.GetInput().NoteHashs, ",")
var notes []*mixTy.WalletIndexInfo
for _, h := range noteHashs {
note, err := policy.getNoteInfo(h, mixTy.NoteStatus_VALID)
if err != nil { if err != nil {
return nil, err return nil, errors.Wrapf(err, "get note info for=%s", h)
}
notes = append(notes, note)
} }
//1.获取Input //1.获取Input
inputPart, err := policy.getTransferInputPart(note) var inputParts []*TransferInput
for _, n := range notes {
input, err := policy.getTransferInputPart(n)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getTransferInputPart note=%s", inputPart.NoteHash) return nil, errors.Wrapf(err, "getTransferInputPart note=%s", n.NoteHash)
}
inputParts = append(inputParts, input)
} }
bizlog.Info("transferProof get input succ", "notehash", inputPart.NoteHash) bizlog.Info("transferProof get input succ", "notehash", transfer.GetInput().NoteHashs)
noteAmount, err := strconv.ParseUint(inputPart.Amount, 10, 64) var inputAmounts []uint64
var sumInput uint64
for _, i := range inputParts {
amount, err := strconv.ParseUint(i.Amount, 10, 64)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "input part parseUint=%s", inputPart.Amount) return nil, errors.Wrapf(err, "input part parseUint=%s", i.Amount)
}
inputAmounts = append(inputAmounts, amount)
sumInput += amount
} }
//2. 获取output //2. 获取output
outAmount, err := strconv.ParseUint(transfer.Output.Deposit.Amounts, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "output part parseUint=%s", transfer.Output.Deposit.Amounts)
}
if outAmount == 0 {
return nil, errors.Wrapf(err, "output part amount=0, parseUint=%s", transfer.Output.Deposit.Amounts)
}
if sumInput < outAmount+uint64(mixTy.Privacy2PrivacyTxFee) {
return nil, errors.Wrapf(types.ErrInvalidParam, "out amount=%d big than input=%d - fee=%d", outAmount, sumInput, uint64(mixTy.Privacy2PrivacyTxFee))
}
outPart, outDHSecret, err := policy.getTransferOutput(transfer.Output.Deposit) outPart, outDHSecret, err := policy.getTransferOutput(transfer.Output.Deposit)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getTransferOutput note=%s", inputPart.NoteHash) return nil, errors.Wrap(err, "getTransferOutput for deposit")
} }
bizlog.Info("transferProof deposit to receiver succ") bizlog.Info("transferProof deposit to receiver succ")
//3. 获取找零,并扣除手续费 //3. 获取找零,并扣除手续费
//如果找零为0也需要设置,否则只有一个输入一个输出,H部分的随机数要相等,就能推测出转账值来 //如果找零为0也需要设置,否则只有一个输入一个输出,H部分的随机数要相等,就能推测出转账值来
//在transfer output 部分特殊处理,如果amount是0的值则不加进tree //在transfer output 部分特殊处理,如果amount是0的值则不加进tree
changeAmount := sumInput - outAmount - uint64(mixTy.Privacy2PrivacyTxFee)
change := &mixTy.DepositInfo{ change := &mixTy.DepositInfo{
Addr: note.Account, ReceiverAddrs: notes[0].Account,
Amount: noteAmount - transfer.Output.Deposit.Amount - uint64(mixTy.Privacy2PrivacyTxFee), Amounts: strconv.FormatUint(changeAmount, 10),
} }
changePart, changeDHSecret, err := policy.getTransferOutput(change) changePart, changeDHSecret, err := policy.getTransferOutput(change)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "change part note=%s", inputPart.NoteHash) return nil, errors.Wrap(err, "getTransferOutput change part ")
} }
bizlog.Info("transferProof deposit to change succ", "notehash", inputPart.NoteHash) bizlog.Info("transferProof deposit to change succ")
//获取shieldValue 输入输出对amount隐藏 //获取shieldValue 输入输出对amount隐藏
shieldValue, err := getShieldValue(noteAmount, transfer.Output.Deposit.Amount, uint64(mixTy.Privacy2PrivacyTxFee)) shieldValue, err := getShieldValue(inputAmounts, outAmount, changeAmount, uint64(mixTy.Privacy2PrivacyTxFee))
if err != nil { if err != nil {
return nil, err return nil, err
} }
bizlog.Info("transferProof get commit value succ", "notehash", inputPart.NoteHash) bizlog.Info("transferProof get shield value succ")
//noteCommitX, transferX, changeX //noteCommitX, transferX, changeX
inputPart.ShieldAmountX = shieldValue.Input.X for i, input := range inputParts {
inputPart.ShieldAmountY = shieldValue.Input.Y input.ShieldAmountX = shieldValue.Inputs[i].X
inputPart.AmountRandom = shieldValue.InputRandom input.ShieldAmountY = shieldValue.Inputs[i].Y
input.AmountRandom = shieldValue.InputRandoms[i]
}
outPart.ShieldAmountX = shieldValue.Output.X outPart.ShieldAmountX = shieldValue.Output.X
outPart.ShieldAmountY = shieldValue.Output.Y outPart.ShieldAmountY = shieldValue.Output.Y
...@@ -280,40 +362,44 @@ func (policy *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Tra ...@@ -280,40 +362,44 @@ func (policy *mixPolicy) createTransferTx(req *mixTy.CreateRawTxReq) (*types.Tra
changePart.AmountRandom = shieldValue.ChangeRandom changePart.AmountRandom = shieldValue.ChangeRandom
//verify input //verify input
inputProof, err := getZkProofKeys(transfer.Input.ZkPath.Path+mixTy.TransInputCircuit, transfer.Input.ZkPath.Path+mixTy.TransInputPk, *inputPart) var inputProofs []*mixTy.ZkProofInfo
for i, input := range inputParts {
inputProof, err := getZkProofKeys(transfer.Input.ZkPath+mixTy.TransInputCircuit, transfer.Input.ZkPath+mixTy.TransInputPk, *input)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "input getZkProofKeys note=%s", note) return nil, errors.Wrapf(err, "verify.input getZkProofKeys,the i=%d", i)
}
if err := policy.verifyProofOnChain(mixTy.VerifyType_TRANSFERINPUT, inputProof, transfer.Input.ZkPath+mixTy.TransInputVk); err != nil {
return nil, errors.Wrapf(err, "input verifyProof fail,the i=%d", i)
} }
if err := policy.verifyProofOnChain(mixTy.VerifyType_TRANSFERINPUT, inputProof, transfer.Input.ZkPath.Path+mixTy.TransInputVk); err != nil { inputProofs = append(inputProofs, inputProof)
return nil, errors.Wrapf(err, "input verifyProof fail for note=%s", note)
} }
//verify output //verify output
outputProof, err := getZkProofKeys(transfer.Output.ZkPath.Path+mixTy.TransOutputCircuit, transfer.Output.ZkPath.Path+mixTy.TransOutputPk, *outPart) outputProof, err := getZkProofKeys(transfer.Output.ZkPath+mixTy.TransOutputCircuit, transfer.Output.ZkPath+mixTy.TransOutputPk, *outPart)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "output getZkProofKeys note=%s", note) return nil, errors.Wrapf(err, "output getZkProofKeys")
} }
if err := policy.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, outputProof, transfer.Output.ZkPath.Path+mixTy.TransOutputVk); err != nil { if err := policy.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, outputProof, transfer.Output.ZkPath+mixTy.TransOutputVk); err != nil {
return nil, errors.Wrapf(err, "output verifyProof fail for note=%s", note) return nil, errors.Wrapf(err, "output verifyProof fail")
} }
outputProof.Secrets = outDHSecret outputProof.Secrets = outDHSecret
//verify change //verify change
changeProof, err := getZkProofKeys(transfer.Output.ZkPath.Path+mixTy.TransOutputCircuit, transfer.Output.ZkPath.Path+mixTy.TransOutputPk, *changePart) changeProof, err := getZkProofKeys(transfer.Output.ZkPath+mixTy.TransOutputCircuit, transfer.Output.ZkPath+mixTy.TransOutputPk, *changePart)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "change getZkProofKeys note=%s", note) return nil, errors.Wrapf(err, "change getZkProofKeys")
} }
if err := policy.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, changeProof, transfer.Output.ZkPath.Path+mixTy.TransOutputVk); err != nil { if err := policy.verifyProofOnChain(mixTy.VerifyType_TRANSFEROUTPUT, changeProof, transfer.Output.ZkPath+mixTy.TransOutputVk); err != nil {
return nil, errors.Wrapf(err, "change verifyProof fail for note=%s", note) return nil, errors.Wrapf(err, "change verifyProof fail")
} }
changeProof.Secrets = changeDHSecret changeProof.Secrets = changeDHSecret
return policy.getTransferTx(strings.TrimSpace(req.Title+mixTy.MixX), inputProof, outputProof, changeProof) return policy.getTransferTx(strings.TrimSpace(req.Title+mixTy.MixX), inputProofs, outputProof, changeProof)
} }
func (policy *mixPolicy) getTransferTx(execName string, proofs ...*mixTy.ZkProofInfo) (*types.Transaction, error) { func (policy *mixPolicy) getTransferTx(execName string, inputProofs []*mixTy.ZkProofInfo, proofs ...*mixTy.ZkProofInfo) (*types.Transaction, error) {
payload := &mixTy.MixTransferAction{} payload := &mixTy.MixTransferAction{}
payload.Input = proofs[0] payload.Inputs = inputProofs
payload.Output = proofs[1] payload.Output = proofs[1]
payload.Change = proofs[2] payload.Change = proofs[2]
......
...@@ -136,12 +136,12 @@ func (policy *mixPolicy) createWithdrawTx(req *mixTy.CreateRawTxReq) (*types.Tra ...@@ -136,12 +136,12 @@ func (policy *mixPolicy) createWithdrawTx(req *mixTy.CreateRawTxReq) (*types.Tra
return nil, errors.Wrapf(err, "getWithdrawParams note=%s", note) return nil, errors.Wrapf(err, "getWithdrawParams note=%s", note)
} }
proofInfo, err := getZkProofKeys(withdraw.ZkPath.Path+mixTy.WithdrawCircuit, withdraw.ZkPath.Path+mixTy.WithdrawPk, *input) proofInfo, err := getZkProofKeys(withdraw.ZkPath+mixTy.WithdrawCircuit, withdraw.ZkPath+mixTy.WithdrawPk, *input)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "getZkProofKeys note=%s", note) return nil, errors.Wrapf(err, "getZkProofKeys note=%s", note)
} }
//verify //verify
if err := policy.verifyProofOnChain(mixTy.VerifyType_WITHDRAW, proofInfo, withdraw.ZkPath.Path+mixTy.WithdrawVk); err != nil { if err := policy.verifyProofOnChain(mixTy.VerifyType_WITHDRAW, proofInfo, withdraw.ZkPath+mixTy.WithdrawVk); err != nil {
return nil, errors.Wrapf(err, "verifyProof fail for note=%s", note) return nil, errors.Wrapf(err, "verifyProof fail for note=%s", note)
} }
...@@ -153,6 +153,7 @@ func (policy *mixPolicy) createWithdrawTx(req *mixTy.CreateRawTxReq) (*types.Tra ...@@ -153,6 +153,7 @@ func (policy *mixPolicy) createWithdrawTx(req *mixTy.CreateRawTxReq) (*types.Tra
proofs = append(proofs, proofInfo) proofs = append(proofs, proofInfo)
} }
//不设计找零操作,可以全部提取回来后再存入,提取的找零一定是本账户的,不利于隐私,而且提取操作功能不够单一
if sum != withdraw.TotalAmount { if sum != withdraw.TotalAmount {
return nil, errors.Wrapf(types.ErrInvalidParam, "amount not match req=%d,note.sum=%d", withdraw.TotalAmount, sum) return nil, errors.Wrapf(types.ErrInvalidParam, "amount not match req=%d,note.sum=%d", withdraw.TotalAmount, sum)
} }
......
...@@ -13,33 +13,16 @@ import ( ...@@ -13,33 +13,16 @@ import (
) )
func TestGetCommitValue(t *testing.T) { func TestGetCommitValue(t *testing.T) {
var note, transfer, minFee uint64 var out, change, minFee, sum uint64
note = 100 var inputs []uint64
transfer = 60 inputs = []uint64{100, 80}
out = 60
minFee = 1 minFee = 1
_, err := getShieldValue(note, transfer, minFee) for _, i := range inputs {
assert.Nil(t, err) sum += i
}
//transfer > note change = sum - out - minFee
note = 100 _, err := getShieldValue(inputs, out, change, minFee)
transfer = 100
minFee = 1
_, err = getShieldValue(note, transfer, minFee)
t.Log(err)
assert.NotNil(t, err)
note = 100
transfer = 101
minFee = 0
_, err = getShieldValue(note, transfer, minFee)
t.Log(err)
assert.NotNil(t, err)
//change=0
note = 100
transfer = 99
minFee = 1
_, err = getShieldValue(note, transfer, minFee)
assert.Nil(t, err) assert.Nil(t, err)
a := "0a9c010a4d3136323433323838333039363632323833373538343930323239313730303834393836343035373630373234353332323934333436353837323033353436363930353333373131303333323139124b3238383637383239373931373237373235343930333236303134303538313534363138303135353433383231393339363836333632313634323236303434353739313434393237383237331a82033078656663333331616261616139653039353966636536356163343364626534306364646139356534356261636163613161326166626265366637323533633132326233346264323337353932343066306237623836653363343635666131343065666332636665623861653035366234323163303665353062396532646564636236383963336536656435363636373731343235663736313931653831356665666633646432393965633535386261323731343238333131623130353364376265633864646163313733393632326238666138326438373336666531623332633835376438343330643634646637336530643265326238373932396335633762366437336534383365363130303561313361376531643730636637653834656132613235343166373235363834656266613737653235313232326466313039336230313964646165623963376134393763316538653737386462313730323636323536666666363332643437363738626633366634383361373334346666326330" a := "0a9c010a4d3136323433323838333039363632323833373538343930323239313730303834393836343035373630373234353332323934333436353837323033353436363930353333373131303333323139124b3238383637383239373931373237373235343930333236303134303538313534363138303135353433383231393339363836333632313634323236303434353739313434393237383237331a82033078656663333331616261616139653039353966636536356163343364626534306364646139356534356261636163613161326166626265366637323533633132326233346264323337353932343066306237623836653363343635666131343065666332636665623861653035366234323163303665353062396532646564636236383963336536656435363636373731343235663736313931653831356665666633646432393965633535386261323731343238333131623130353364376265633864646163313733393632326238666138326438373336666531623332633835376438343330643634646637336530643265326238373932396335633762366437336534383365363130303561313361376531643730636637653834656132613235343166373235363834656266613737653235313232326466313039336230313964646165623963376134393763316538653737386462313730323636323536666666363332643437363738626633366634383361373334346666326330"
...@@ -50,7 +33,7 @@ func TestGetCommitValue(t *testing.T) { ...@@ -50,7 +33,7 @@ func TestGetCommitValue(t *testing.T) {
err = types.Decode(da, &data) err = types.Decode(da, &data)
assert.Nil(t, err) assert.Nil(t, err)
fmt.Println("data", data) //fmt.Println("data", data)
var deposit mixTy.DepositProofResp var deposit mixTy.DepositProofResp
deposit.NoteHash = "notehashstr" deposit.NoteHash = "notehashstr"
......
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