Commit 6fc4d52e authored by madengji's avatar madengji Committed by vipwzw

add transfer proof

parent 25cf36cb
......@@ -930,8 +930,7 @@ func ProofCmd() *cobra.Command {
Short: "circuit proof inputs",
}
cmd.AddCommand(DepositInputsCmd())
cmd.AddCommand(PayInInputsCmd())
cmd.AddCommand(PayOutInputsCmd())
cmd.AddCommand(TransferInputsCmd())
cmd.AddCommand(WithdrawInputsCmd())
cmd.AddCommand(AuthInputsCmd())
......@@ -957,7 +956,7 @@ func depositSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("authorize", "a", "", "authorize addr")
cmd.Flags().StringP("amount", "m", "", "amount")
cmd.Flags().Uint64P("amount", "m", 0, "amount")
cmd.MarkFlagRequired("amount")
}
......@@ -967,7 +966,7 @@ func depositSecret(cmd *cobra.Command, args []string) {
payment, _ := cmd.Flags().GetString("payment")
returnKey, _ := cmd.Flags().GetString("return")
authorize, _ := cmd.Flags().GetString("authorize")
amount, _ := cmd.Flags().GetString("amount")
amount, _ := cmd.Flags().GetUint64("amount")
req := &mixTy.DepositProofReq{
PaymentAddr: payment,
......@@ -981,89 +980,53 @@ func depositSecret(cmd *cobra.Command, args []string) {
ctx.Run()
}
// DepositInputsCmd get para chain status by height
func PayInInputsCmd() *cobra.Command {
// TransferInputsCmd get para chain status by height
func TransferInputsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "payin",
Short: "one key get pay input data",
Run: payInSecret,
Use: "transfer",
Short: "one key get transfer input output data",
Run: transferSecret,
}
payInSecretCmdFlags(cmd)
transferSecretCmdFlags(cmd)
return cmd
}
func payInSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("payment", "p", "", "payment addr")
cmd.MarkFlagRequired("payment")
cmd.Flags().StringP("return", "r", "", "return addr")
cmd.Flags().StringP("authorize", "a", "", "authorize addr")
cmd.Flags().StringP("amount", "m", "", "amount")
cmd.MarkFlagRequired("amount")
}
func payInSecret(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
payment, _ := cmd.Flags().GetString("payment")
returnKey, _ := cmd.Flags().GetString("return")
authorize, _ := cmd.Flags().GetString("authorize")
amount, _ := cmd.Flags().GetString("amount")
req := &mixTy.DepositProofReq{
PaymentAddr: payment,
ReturnAddr: returnKey,
AuthorizeAddr: authorize,
Amount: amount,
}
var res mixTy.DHSecretGroup
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.PayInProof", req, &res)
ctx.Run()
}
// DepositInputsCmd get para chain status by height
func PayOutInputsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "payout",
Short: "one key get payout input data",
Run: payOutSecret,
}
payOutSecretCmdFlags(cmd)
return cmd
}
func transferSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("noteHash", "n", "", "note hash to spend")
cmd.MarkFlagRequired("noteHash")
func payOutSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("payment", "p", "", "payment addr")
cmd.MarkFlagRequired("payment")
cmd.Flags().StringP("toAddr", "t", "", "transfer to addr")
cmd.MarkFlagRequired("toAddr")
cmd.Flags().StringP("return", "r", "", "return addr")
cmd.Flags().StringP("auth", "a", "", "transfer to auth addr")
cmd.MarkFlagRequired("auth")
cmd.Flags().StringP("authorize", "a", "", "authorize addr")
cmd.Flags().StringP("returner", "r", "", "transfer to returner addr")
cmd.MarkFlagRequired("returner")
cmd.Flags().StringP("amount", "m", "", "amount")
cmd.Flags().Uint64P("amount", "m", 0, "transfer amount")
cmd.MarkFlagRequired("amount")
}
func payOutSecret(cmd *cobra.Command, args []string) {
func transferSecret(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
payment, _ := cmd.Flags().GetString("payment")
returnKey, _ := cmd.Flags().GetString("return")
authorize, _ := cmd.Flags().GetString("authorize")
amount, _ := cmd.Flags().GetString("amount")
noteHash, _ := cmd.Flags().GetString("noteHash")
toAddr, _ := cmd.Flags().GetString("toAddr")
auth, _ := cmd.Flags().GetString("auth")
returner, _ := cmd.Flags().GetString("returner")
amount, _ := cmd.Flags().GetUint64("amount")
req := &mixTy.DepositProofReq{
PaymentAddr: payment,
ReturnAddr: returnKey,
AuthorizeAddr: authorize,
Amount: amount,
req := &mixTy.TransferProofReq{
NoteHash: noteHash,
ToAddr: toAddr,
ToAuthAddr: auth,
ReturnAddr: returner,
Amount: amount,
}
var res mixTy.DepositProofResp
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.PayOutProof", req, &res)
var res mixTy.TransferProofResp
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.TransferProof", req, &res)
ctx.Run()
}
......@@ -1109,33 +1072,24 @@ func AuthInputsCmd() *cobra.Command {
}
func authSecretCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("payment", "p", "", "payment addr")
cmd.MarkFlagRequired("payment")
cmd.Flags().StringP("return", "r", "", "return addr")
cmd.Flags().StringP("authorize", "a", "", "authorize addr")
cmd.Flags().StringP("amount", "m", "", "amount")
cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("noteHash", "n", "", "note hash to spend")
cmd.MarkFlagRequired("noteHash")
cmd.Flags().Uint32P("toReturn", "r", 0, "authorize to returner,0:to payment,1:to returner")
cmd.MarkFlagRequired("noteHash")
}
func authSecret(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
payment, _ := cmd.Flags().GetString("payment")
returnKey, _ := cmd.Flags().GetString("return")
authorize, _ := cmd.Flags().GetString("authorize")
amount, _ := cmd.Flags().GetString("amount")
noteHash, _ := cmd.Flags().GetString("noteHash")
toReturn, _ := cmd.Flags().GetUint32("toReturn")
req := &mixTy.DepositProofReq{
PaymentAddr: payment,
ReturnAddr: returnKey,
AuthorizeAddr: authorize,
Amount: amount,
req := &mixTy.AuthProofReq{
NoteHash: noteHash,
ToReturn: toReturn,
}
var res mixTy.DHSecretGroup
var res mixTy.AuthProofResp
ctx := jsonclient.NewRPCCtx(rpcLaddr, "mix.AuthProof", req, &res)
ctx.Run()
}
......@@ -62,29 +62,8 @@ func (m *Mix) CheckTx(tx *types.Transaction, index int) error {
// mix隐私交易,只私对私需要特殊签名验证
return m.DriverBase.CheckTx(tx, index)
}
_, _, err := MixTransferInfoVerify(m.GetStateDB(), action.GetTransfer())
if err != nil {
mlog.Error("checkTx", "err", err)
return err
}
return nil
}
// CheckTx check transaction
func (m *Mix) CheckTx(tx *types.Transaction, index int) error {
action := new(mixTy.MixAction)
if err := types.Decode(tx.Payload, action); err != nil {
mlog.Error("CheckTx decode", "err", err)
return err
}
if action.Ty != mixTy.MixActionTransfer {
// mix隐私交易,只私对私需要特殊签名验证
return m.DriverBase.CheckTx(tx, index)
}
_, _, err := MixTransferInfoVerify(m.GetStateDB(), action.GetTransfer())
minTxFee := m.GetAPI().GetConfig().GInt("wallet.minFee")
_, _, err := MixTransferInfoVerify(m.GetStateDB(), action.GetTransfer(), minTxFee)
if err != nil {
mlog.Error("checkTx", "err", err)
return err
......
......@@ -13,7 +13,6 @@ import (
"github.com/consensys/gurvy/bn256/twistededwards"
dbm "github.com/33cn/chain33/common/db"
"github.com/consensys/gurvy/bn256/fr"
"github.com/pkg/errors"
)
......@@ -72,18 +71,7 @@ func transferOutputVerify(db dbm.KV, proof *mixTy.ZkProofInfo) (*mixTy.TransferO
}
func getFee() *twistededwards.Point {
//手续费 可配, 缺省100000, 即0.001, point=fee*G + 0*H
var fee fr.Element
fee.SetUint64(100000).FromMont()
var pointFee twistededwards.Point
ed := twistededwards.GetEdwardsCurve()
pointFee.ScalarMul(&ed.Base, fee)
return &pointFee
}
func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mixTy.TransferOutputPublicInput) bool {
func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mixTy.TransferOutputPublicInput, minFee int64) bool {
var inputPoints, outputPoints []*twistededwards.Point
for _, in := range inputs {
var p twistededwards.Point
......@@ -99,7 +87,9 @@ func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mix
outputPoints = append(outputPoints, &p)
}
//out value add fee
outputPoints = append(outputPoints, getFee())
//对于平行链来说, 隐私交易需要一个公共账户扣主链的手续费,隐私交易只需要扣平行链执行器内的费用即可
//由于平行链的隐私交易没有实际扣平行链mix合约的手续费,平行链Mix合约会有手续费留下,平行链隐私可以考虑手续费为0
outputPoints = append(outputPoints, mixTy.MulCurvePointG(uint64(minFee)))
//sum input and output
sumInput := inputPoints[0]
......@@ -117,7 +107,7 @@ func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mix
return false
}
func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mixTy.TransferInputPublicInput, []*mixTy.TransferOutputPublicInput, error) {
func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction, minFee int64) ([]*mixTy.TransferInputPublicInput, []*mixTy.TransferOutputPublicInput, error) {
var inputs []*mixTy.TransferInputPublicInput
var outputs []*mixTy.TransferOutputPublicInput
......@@ -137,7 +127,7 @@ func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mix
outputs = append(outputs, out)
}
if !VerifyCommitValues(inputs, outputs) {
if !VerifyCommitValues(inputs, outputs, minFee) {
return nil, nil, errors.Wrap(mixTy.ErrSpendInOutValueNotMatch, "verifyValue")
}
......@@ -150,7 +140,8 @@ func MixTransferInfoVerify(db dbm.KV, transfer *mixTy.MixTransferAction) ([]*mix
3. add nullifier to pool
*/
func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, error) {
inputs, outputs, err := MixTransferInfoVerify(a.db, transfer)
minTxFee := a.api.GetConfig().GInt("wallet.minFee")
inputs, outputs, err := MixTransferInfoVerify(a.db, transfer, minTxFee)
if err != nil {
return nil, errors.Wrap(err, "Transfer.MixTransferInfoVerify")
}
......
......@@ -135,11 +135,7 @@ message WithdrawPublicInput {
}
//加密了的input/output amount
message commitAmount{
string X = 1;
string Y = 2;
}
message TransferInputPublicInput {
string treeRootHash = 1;
......@@ -264,7 +260,7 @@ message DepositProofReq{
string paymentAddr = 1;
string returnAddr = 2;
string authorizeAddr = 3;
string amount = 4;
uint64 amount = 4;
}
......@@ -301,7 +297,7 @@ message WithdrawProofResp{
message AuthProofReq{
string noteHash = 1;
uint32 authReturn = 2;
uint32 toReturn = 2;
}
message AuthProofResp{
......@@ -316,6 +312,59 @@ message AuthProofResp{
}
message TransferProofReq{
string noteHash = 1;
string toAddr = 2;
string toAuthAddr = 3;
string returnAddr = 4;
uint64 amount = 5;
}
//加密了的input/output amount
message commitValue{
string X = 1;
string Y = 2;
}
message TransferInputProof{
SecretData proof = 1;
string nullifierHash = 2;
string authSpendHash = 3;
string noteHash = 4;
string spendPrivKey = 5;
uint32 spendFlag = 6;
uint32 authFlag = 7;
TreePathProof treeProof = 8;
commitValue commitValue = 9;
string spendRandom = 10;
}
message TransferOutputProof{
SecretData proof = 1;
string noteHash = 2;
DHSecretGroup secrets = 3;
commitValue commitValue = 4;
string spendRandom = 5;
}
message TransferProofResp{
TransferInputProof transferInput = 1;
TransferOutputProof targetOutput = 2;
TransferOutputProof changeOutput = 3;
}
message CommitValueRst{
string noteRandom = 1;
string transferRandom = 2;
string changeRandom = 3;
commitValue note = 4;
commitValue transfer = 5;
commitValue change = 6;
}
enum NoteStatus{
UNDEF = 0;
......
......@@ -142,7 +142,7 @@ func (c *Jrpc) DepositProof(in *mixTy.DepositProofReq, result *json.RawMessage)
return err
}
func (c *Jrpc) AuthProof(in *mixTy.DepositProofReq, result *json.RawMessage) error {
func (c *Jrpc) AuthProof(in *mixTy.AuthProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "AuthProof", in)
if err != nil {
return err
......@@ -151,17 +151,8 @@ func (c *Jrpc) AuthProof(in *mixTy.DepositProofReq, result *json.RawMessage) err
return err
}
func (c *Jrpc) PayInProof(in *mixTy.DepositProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "PayInProof", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
func (c *Jrpc) PayOutProof(in *mixTy.DepositProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "PayOutProof", in)
func (c *Jrpc) TransferProof(in *mixTy.TransferProofReq, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "TransferProof", in)
if err != nil {
return err
}
......
......@@ -39,3 +39,9 @@ const (
MixActionTransfer
MixActionAuth
)
//curve H point
const (
PointHX = "10190477835300927557649934238820360529458681672073866116232821892325659279502"
PointHY = "7969140283216448215269095418467361784159407896899334866715345504515077887397"
)
This diff is collapsed.
......@@ -13,6 +13,8 @@ import (
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
"github.com/consensys/gurvy/bn256/fr"
"github.com/consensys/gurvy/bn256/twistededwards"
)
var (
......@@ -205,3 +207,40 @@ func DecodePubInput(ty VerifyType, input string) (interface{}, error) {
}
return nil, types.ErrInvalidParam
}
func MulCurvePointG(val interface{}) *twistededwards.Point {
v := fr.FromInterface(val)
var point twistededwards.Point
ed := twistededwards.GetEdwardsCurve()
point.ScalarMul(&ed.Base, *v.FromMont())
return &point
}
func MulCurvePointH(val string) *twistededwards.Point {
v := fr.FromInterface(val)
var pointV, pointH twistededwards.Point
pointH.X.SetString(PointHX)
pointH.Y.SetString(PointHY)
pointV.ScalarMul(&pointH, *v.FromMont())
return &pointV
}
//A=B+C
func CheckSumEqual(points ...*twistededwards.Point) bool {
if len(points) < 2 {
return false
}
//Add之前需初始化pointSum,不能空值,不然会等于0
pointSum := twistededwards.NewPoint(points[1].X, points[1].Y)
for _, a := range points[2:] {
pointSum.Add(&pointSum, a)
}
if pointSum.X.Equal(&points[0].X) && pointSum.Y.Equal(&points[0].Y) {
return true
}
return false
}
......@@ -54,3 +54,11 @@ func (policy *mixPolicy) On_DepositProof(req *mixTy.DepositProofReq) (types.Mess
func (policy *mixPolicy) On_WithdrawProof(req *mixTy.WithdrawProofReq) (types.Message, error) {
return policy.withdrawProof(req)
}
func (policy *mixPolicy) On_AuthProof(req *mixTy.AuthProofReq) (types.Message, error) {
return policy.authProof(req)
}
func (policy *mixPolicy) On_TransferProof(req *mixTy.TransferProofReq) (types.Message, error) {
return policy.transferProof(req)
}
......@@ -41,9 +41,10 @@ func TestNewPrivacyWithPrivKey(t *testing.T) {
// NoteRandom:"2824204835",
// Amount:"28242048",
//}
pub1, cryptData1, err := encryptData(pairs.ShareSecretKey.ReceivingPk, types.Encode(secret1))
data := encryptData(pairs.ShareSecretKey.ReceivingPk, types.Encode(secret1))
crypData, err := common.FromHex(data.Secret)
assert.Nil(t, err)
decryData1, err := decryptData(pairs.ShareSecretKey.PrivKey, pub1, cryptData1)
decryData1, err := decryptData(pairs.ShareSecretKey.PrivKey, data.Epk, crypData)
assert.Nil(t, err)
var val mixTy.SecretData
err = types.Decode(decryData1, &val)
......
......@@ -12,13 +12,10 @@ import (
"bytes"
"fmt"
"github.com/pkg/errors"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types"
mixExec "github.com/33cn/plugin/plugin/dapp/mix/executor"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
......@@ -102,31 +99,32 @@ func (pubkey *MixSignPublicKey) Bytes() []byte {
return pubkey.key[:]
}
func verifyCommitAmount(transfer *mixTy.MixTransferAction) error {
var inputs []*mixTy.TransferInputPublicInput
var outputs []*mixTy.TransferOutputPublicInput
for _, k := range transfer.Input {
v, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFERINPUT, k.PublicInput)
if err != nil {
return errors.Wrap(types.ErrInvalidParam, "decode transfer Input")
}
inputs = append(inputs, v.(*mixTy.TransferInputPublicInput))
}
for _, k := range transfer.Output {
v, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFEROUTPUT, k.PublicInput)
if err != nil {
return errors.Wrap(types.ErrInvalidParam, "decode transfer output")
}
outputs = append(outputs, v.(*mixTy.TransferOutputPublicInput))
}
if !mixExec.VerifyCommitValues(inputs, outputs) {
return errors.Wrap(types.ErrInvalidParam, "verify commit amount")
}
return nil
}
//
//func verifyCommitAmount(transfer *mixTy.MixTransferAction) error {
// var inputs []*mixTy.TransferInputPublicInput
// var outputs []*mixTy.TransferOutputPublicInput
//
// for _, k := range transfer.Input {
// v, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFERINPUT, k.PublicInput)
// if err != nil {
// return errors.Wrap(types.ErrInvalidParam, "decode transfer Input")
// }
// inputs = append(inputs, v.(*mixTy.TransferInputPublicInput))
// }
//
// for _, k := range transfer.Output {
// v, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFEROUTPUT, k.PublicInput)
// if err != nil {
// return errors.Wrap(types.ErrInvalidParam, "decode transfer output")
// }
// outputs = append(outputs, v.(*mixTy.TransferOutputPublicInput))
// }
//
// if !mixExec.VerifyCommitValues(inputs, outputs) {
// return errors.Wrap(types.ErrInvalidParam, "verify commit amount")
// }
// return nil
//}
// VerifyBytes verify bytes
func (pubkey *MixSignPublicKey) VerifyBytes(msg []byte, sign crypto.Signature) bool {
......@@ -157,11 +155,6 @@ func (pubkey *MixSignPublicKey) VerifyBytes(msg []byte, sign crypto.Signature) b
return false
}
if err := verifyCommitAmount(action.GetTransfer()); err != nil {
bizlog.Error("pubkey.VerifyBytes verify amount", "err", err)
return false
}
return true
}
......
This diff is collapsed.
package wallet
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetCommitValue(t *testing.T) {
var note, transfer, minFee uint64
note = 100
transfer = 60
minFee = 1
_, err := getCommitValue(note, transfer, minFee)
assert.Nil(t, err)
//transfer > note
note = 100
transfer = 100
minFee = 1
_, err = getCommitValue(note, transfer, minFee)
t.Log(err)
assert.NotNil(t, err)
note = 100
transfer = 101
minFee = 0
_, err = getCommitValue(note, transfer, minFee)
t.Log(err)
assert.NotNil(t, err)
//change=0
note = 100
transfer = 99
minFee = 1
_, err = getCommitValue(note, transfer, minFee)
assert.Nil(t, err)
}
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