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

add mix sign

parent 23751000
......@@ -74,7 +74,8 @@ func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
pointGSnark := twistededwards_gadget.NewPointGadget(circuit, nil, nil)
//scalar := circuit.ALLOCATE("-1")
circuit.MUSTBE_LESS_OR_EQ(spendValue, 10000000000, 256)
//100000000*1e8 to avoid <0 values input
circuit.MUSTBE_LESS_OR_EQ(spendValue, 10000000000000000, 256)
// set point G in the circuit
pointGSnark.ScalarMulFixedBase(circuit, edgadget.BaseX, edgadget.BaseY, spendValue, edgadget)
......
......@@ -12,6 +12,7 @@ import (
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/twistededwards"
"github.com/consensys/gurvy/bn256/fr"
"github.com/pkg/errors"
)
......@@ -24,21 +25,21 @@ func (a *action) transferInputVerify(proof *mixTy.ZkProofInfo) (*mixTy.TransferI
var input mixTy.TransferInputPublicInput
data, err := hex.DecodeString(proof.PublicInput)
if err != nil {
return nil, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
return nil, errors.Wrapf(err, "transferInput verify decode string=%s", proof.PublicInput)
}
err = json.Unmarshal(data, &input)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", proof.PublicInput)
return nil, errors.Wrapf(err, "transferInput verify unmarshal string=%s", proof.PublicInput)
}
err = a.spendVerify(input.TreeRootHash, input.NullifierHash, input.AuthorizeSpendHash)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "transferInput verify spendVerify")
}
err = a.zkProofVerify(proof, mixTy.VerifyType_TRANSFERINPUT)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "transferInput verify proof verify")
}
return &input, nil
......@@ -54,23 +55,33 @@ func (a *action) transferOutputVerify(proof *mixTy.ZkProofInfo) (*mixTy.Transfer
var input mixTy.TransferOutputPublicInput
data, err := hex.DecodeString(proof.PublicInput)
if err != nil {
return nil, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
return nil, errors.Wrapf(err, "Output verify decode string=%s", proof.PublicInput)
}
err = json.Unmarshal(data, &input)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", proof.PublicInput)
return nil, errors.Wrapf(err, "Output verify unmarshal string=%s", proof.PublicInput)
}
err = a.zkProofVerify(proof, mixTy.VerifyType_TRANSFEROUTPUT)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "Output verify proof verify")
}
return &input, nil
}
func verifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mixTy.TransferOutputPublicInput) bool {
func getFee() *twistededwards.Point {
//手续费 可配, 缺省100000, 即0.001, point=fee*G + 0*H
var fee fr.Element
fee.SetUint64(100000).FromMont()
var pFee twistededwards.Point
ed := twistededwards.GetEdwardsCurve()
pFee.ScalarMul(&ed.Base, fee)
return &pFee
}
func VerifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mixTy.TransferOutputPublicInput) bool {
var inputPoints, outputPoints []*twistededwards.Point
for _, in := range inputs {
var p twistededwards.Point
......@@ -85,13 +96,17 @@ func verifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mix
p.Y.SetString(out.AmountY)
outputPoints = append(outputPoints, &p)
}
//out value add fee
outputPoints = append(outputPoints, getFee())
var sumInput, sumOutput twistededwards.Point
for _, p := range inputPoints {
sumInput.Add(&sumInput, p)
//sum input and output
sumInput := inputPoints[0]
sumOutput := outputPoints[0]
for _, p := range inputPoints[1:] {
sumInput.Add(sumInput, p)
}
for _, p := range outputPoints {
sumOutput.Add(&sumOutput, p)
for _, p := range outputPoints[1:] {
sumOutput.Add(sumOutput, p)
}
if sumInput.X.Equal(&sumOutput.X) && sumInput.Y.Equal(&sumOutput.Y) {
......@@ -125,7 +140,7 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er
outputs = append(outputs, out)
}
if !verifyCommitValues(inputs, outputs) {
if !VerifyCommitValues(inputs, outputs) {
return nil, errors.Wrap(mixTy.ErrSpendInOutValueNotMatch, "verifyValue")
}
......
......@@ -8,59 +8,127 @@ import (
"testing"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/fr"
bn256 "github.com/consensys/gurvy/bn256/twistededwards"
"github.com/stretchr/testify/assert"
)
func TestVerifyCommitValues(t *testing.T) {
input1 := &mixTy.TransferInputPublicInput{
CommitValueX: "8728367628344135467582547753719073727968275979035063555332785894244029982715",
CommitValueY: "8834462946188529904793384347374734779374831553974460136522409595751449858199",
}
const (
baseHX = "10190477835300927557649934238820360529458681672073866116232821892325659279502"
baseHY = "7969140283216448215269095418467361784159407896899334866715345504515077887397"
fee = 100000
)
func TestVerifyCommitValuesBasePoint(t *testing.T) {
var in44, out10, out34, rIn100, rOut40, rOut60 fr.Element
//calc p1=44*G+100*G, p2=10*G+30*G,p3=34*G+70*G, p1=p2+p3+fee
in44.SetUint64(4400000).FromMont()
out10.SetUint64(1000000).FromMont()
out34.SetUint64(3400000 - fee).FromMont()
rIn100.SetUint64(10000000).FromMont()
rOut40.SetUint64(3000000).FromMont()
rOut60.SetUint64(7000000).FromMont()
input2 := &mixTy.TransferInputPublicInput{
CommitValueX: "9560056125663567360314373555170485462871740364163814576088225107862234393497",
CommitValueY: "13024071698463677601393829581435828705327146000694268918451707151508990195684",
ed := bn256.GetEdwardsCurve()
var p1, p2, p3, r1, r2, r3 bn256.Point
p1.ScalarMul(&ed.Base, in44)
p2.ScalarMul(&ed.Base, out10)
p3.ScalarMul(&ed.Base, out34)
r1.ScalarMul(&ed.Base, rIn100)
r2.ScalarMul(&ed.Base, rOut40)
r3.ScalarMul(&ed.Base, rOut60)
//p1.Add(&p1,&r1)
//p2.Add(&p2,&r2)
//p3.Add(&p3,&r3)
t.Log("p1.x", p1.X.String())
t.Log("p1.y", p1.Y.String())
t.Log("p2.x", p2.X.String())
t.Log("p2.y", p2.Y.String())
t.Log("p3.x", p3.X.String())
t.Log("p3.y", p3.Y.String())
input1 := &mixTy.TransferInputPublicInput{
AmountX: p1.X.String(),
AmountY: p1.Y.String(),
}
var inputs []*mixTy.TransferInputPublicInput
inputs = append(inputs, input1)
inputs = append(inputs, input2)
output1 := &mixTy.TransferOutputPublicInput{
CommitValueX: "8728367628344135467582547753719073727968275979035063555332785894244029982715",
CommitValueY: "8834462946188529904793384347374734779374831553974460136522409595751449858199",
AmountX: p2.X.String(),
AmountY: p2.Y.String(),
}
output2 := &mixTy.TransferOutputPublicInput{
AmountX: p3.X.String(),
AmountY: p3.Y.String(),
}
var outputs []*mixTy.TransferOutputPublicInput
outputs = append(outputs, output1)
outputs = append(outputs, output2)
ret := verifyCommitValues(inputs, outputs)
ret := VerifyCommitValues(inputs, outputs)
assert.Equal(t, true, ret)
}
func TestVerifyCommitValues2(t *testing.T) {
input1 := &mixTy.TransferInputPublicInput{
CommitValueX: "10190477835300927557649934238820360529458681672073866116232821892325659279502",
CommitValueY: "7969140283216448215269095418467361784159407896899334866715345504515077887397",
}
func TestVerifyCommitValuesBaseAddHPoint(t *testing.T) {
var in44, out10, out34 fr.Element
in44.SetUint64(4400000).FromMont()
out10.SetUint64(1000000).FromMont()
out34.SetUint64(3400000 - fee).FromMont()
//random value
var rIn100, rOut40, rOut60 fr.Element
rIn100.SetUint64(10000000).FromMont()
rOut40.SetUint64(3000000).FromMont()
rOut60.SetUint64(7000000).FromMont()
var baseH bn256.Point
baseH.X.SetString(baseHX)
baseH.Y.SetString(baseHY)
ed := bn256.GetEdwardsCurve()
var p1, p2, p3, r1, r2, r3 bn256.Point
p1.ScalarMul(&ed.Base, in44)
p2.ScalarMul(&ed.Base, out10)
p3.ScalarMul(&ed.Base, out34)
r1.ScalarMul(&baseH, rIn100)
r2.ScalarMul(&baseH, rOut40)
r3.ScalarMul(&baseH, rOut60)
input2 := &mixTy.TransferInputPublicInput{
CommitValueX: "17822967620457187568904804290291537271142779717280482398091401115827760898835",
CommitValueY: "17714526567340249480661526843742175665966437069228179299143955140199226385576",
p1.Add(&p1, &r1)
p2.Add(&p2, &r2)
p3.Add(&p3, &r3)
input1 := &mixTy.TransferInputPublicInput{
AmountX: p1.X.String(),
AmountY: p1.Y.String(),
}
var inputs []*mixTy.TransferInputPublicInput
inputs = append(inputs, input1)
inputs = append(inputs, input2)
output1 := &mixTy.TransferOutputPublicInput{
CommitValueX: "14087975867275911077371231345227824611951436822132762463787130558957838320348",
CommitValueY: "15113519960384204624879642069520481336224311978035289236693658603675385299879",
AmountX: p2.X.String(),
AmountY: p2.Y.String(),
}
output2 := &mixTy.TransferOutputPublicInput{
AmountX: p3.X.String(),
AmountY: p3.Y.String(),
}
var outputs []*mixTy.TransferOutputPublicInput
outputs = append(outputs, output1)
outputs = append(outputs, output2)
ret := verifyCommitValues(inputs, outputs)
ret := VerifyCommitValues(inputs, outputs)
assert.Equal(t, true, ret)
}
......@@ -5,8 +5,13 @@
package wallet
import (
"encoding/hex"
"sync"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/log/log15"
......@@ -140,6 +145,42 @@ func (policy *mixPolicy) Call(funName string, in types.Message) (ret types.Messa
// SignTransaction 对隐私交易进行签名
func (policy *mixPolicy) SignTransaction(key crypto.PrivKey, req *types.ReqSignRawTx) (needSysSign bool, signtxhex string, err error) {
needSysSign = false
bytes, err := common.FromHex(req.GetTxHex())
if err != nil {
bizlog.Error("SignTransaction", "common.FromHex error", err)
return
}
tx := new(types.Transaction)
if err = types.Decode(bytes, tx); err != nil {
bizlog.Error("SignTransaction", "Decode Transaction error", err)
return
}
action := new(mixTy.MixAction)
if err = types.Decode(tx.Payload, action); err != nil {
bizlog.Error("SignTransaction", "Decode PrivacyAction error", err)
return
}
if action.Ty == mixTy.MixActionTransfer {
// 隐私交易的私对私、私对公需要进行特殊签名
policy.signatureTx(tx, action.GetTransfer())
} else {
tx.Sign(int32(policy.getWalletOperate().GetSignType()), key)
}
signtxhex = hex.EncodeToString(types.Encode(tx))
return
}
return true, "", types.ErrNotSupport
func (policy *mixPolicy) signatureTx(tx *types.Transaction, transfer *mixTy.MixTransferAction) error {
cfg := policy.getWalletOperate().GetAPI().GetConfig()
mixSignData := types.Encode(transfer)
tx.Signature = &types.Signature{
Ty: MixSignID,
Signature: common.BytesToHash(mixSignData).Bytes(),
// 这里填的是mix合约的公钥,让框架保持一致
Pubkey: address.ExecPubKey(cfg.ExecName(mixTy.MixX)),
}
return nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
基于框架中Crypto接口,实现签名、验证的处理
*/
package wallet
import (
"bytes"
"fmt"
"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"
)
const (
MixSignName = "mixZkSnark"
MixSignID = 6
publicKeyLen = 32
privateKeyLen = 32
)
func init() {
crypto.Register(MixSignName, &MixSignZkSnark{}, false)
crypto.RegisterType(MixSignName, MixSignID)
}
// MixSignature mix签名中对于crypto.Signature接口实现
type MixSignature struct {
sign mixTy.MixTransferAction
}
// Bytes convert to bytest
func (r *MixSignature) Bytes() []byte {
return types.Encode(&r.sign)
}
// IsZero check is zero
func (r *MixSignature) IsZero() bool {
return false
}
// String convert to string
func (r *MixSignature) String() string {
return r.sign.String()
}
// Equals check equals
func (r *MixSignature) Equals(other crypto.Signature) bool {
if _, ok := other.(*MixSignature); ok {
this := types.Encode(&r.sign)
return bytes.Equal(this, other.Bytes())
}
return false
}
// RingSignPrivateKey 环签名中对于crypto.PrivKey接口实现
type MixSignPrivateKey struct {
key [publicKeyLen]byte
}
// Bytes convert key to bytest
func (privkey *MixSignPrivateKey) Bytes() []byte {
return privkey.key[:]
}
// Sign signature trasaction
func (privkey *MixSignPrivateKey) Sign(msg []byte) crypto.Signature {
return &MixSignature{}
}
// PubKey convert to public key
func (privkey *MixSignPrivateKey) PubKey() crypto.PubKey {
publicKey := new(MixSignPublicKey)
return publicKey
}
// Equals check key equal
func (privkey *MixSignPrivateKey) Equals(other crypto.PrivKey) bool {
if otherPrivKey, ok := other.(*MixSignPrivateKey); ok {
return bytes.Equal(privkey.key[:], otherPrivKey.key[:])
}
return false
}
// RingSignPublicKey 环签名中对于crypto.PubKey接口实现
type MixSignPublicKey struct {
key [publicKeyLen]byte
}
// Bytes convert key to bytes
func (pubkey *MixSignPublicKey) Bytes() []byte {
return pubkey.key[:]
}
func verifyCommitAmount(transfer *mixTy.MixTransferAction) bool {
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 false
}
inputs = append(inputs, v.(*mixTy.TransferInputPublicInput))
}
for _, k := range transfer.Output {
v, err := mixTy.DecodePubInput(mixTy.VerifyType_TRANSFEROUTPUT, k.PublicInput)
if err != nil {
return false
}
outputs = append(outputs, v.(*mixTy.TransferOutputPublicInput))
}
if !mixExec.VerifyCommitValues(inputs, outputs) {
return false
}
return true
}
// VerifyBytes verify bytes
func (pubkey *MixSignPublicKey) VerifyBytes(msg []byte, sign crypto.Signature) bool {
if len(msg) <= 0 {
return false
}
tx := new(types.Transaction)
if err := types.Decode(msg, tx); err != nil || !bytes.Equal([]byte(mixTy.MixX), types.GetRealExecName(tx.Execer)) {
// mix特定执行器的签名
return false
}
action := new(mixTy.MixAction)
if err := types.Decode(tx.Payload, action); err != nil {
return false
}
if action.Ty != mixTy.MixActionTransfer {
// mix隐私交易,只私对私需要特殊签名验证
return false
}
//确保签名数据和tx 一致
if !bytes.Equal(sign.Bytes(), common.BytesToHash(types.Encode(action.GetTransfer())).Bytes()) {
return false
}
if !verifyCommitAmount(action.GetTransfer()) {
return false
}
return true
}
// KeyString convert key to string
func (pubkey *MixSignPublicKey) KeyString() string {
return fmt.Sprintf("%X", pubkey.key[:])
}
// Equals check key is equal
func (pubkey *MixSignPublicKey) Equals(other crypto.PubKey) bool {
if otherPubKey, ok := other.(*MixSignPublicKey); ok {
return bytes.Equal(pubkey.key[:], otherPubKey.key[:])
}
return false
}
// MixSignZkSnark 对应crypto.Crypto的接口实现
type MixSignZkSnark struct {
}
// GenKey create privacy key
func (r *MixSignZkSnark) GenKey() (crypto.PrivKey, error) {
priKey := new(MixSignPrivateKey)
return priKey, nil
}
// PrivKeyFromBytes create private key from bytes
func (r *MixSignZkSnark) PrivKeyFromBytes(b []byte) (crypto.PrivKey, error) {
if len(b) <= 0 {
return nil, types.ErrInvalidParam
}
if len(b) != privateKeyLen {
return nil, types.ErrPrivateKeyLen
}
privateKey := new(MixSignPrivateKey)
copy(privateKey.key[:], b)
return privateKey, nil
}
// PubKeyFromBytes create publick key from bytes
func (r *MixSignZkSnark) PubKeyFromBytes(b []byte) (crypto.PubKey, error) {
if len(b) <= 0 {
return nil, types.ErrInvalidParam
}
if len(b) != publicKeyLen {
return nil, types.ErrPubKeyLen
}
publicKey := new(MixSignPublicKey)
copy(publicKey.key[:], b)
return publicKey, nil
}
// SignatureFromBytes create signature from bytes
func (r *MixSignZkSnark) SignatureFromBytes(b []byte) (crypto.Signature, error) {
if len(b) <= 0 {
return nil, types.ErrInvalidParam
}
sign := new(MixSignature)
if err := types.Decode(b, &sign.sign); err != nil {
return nil, err
}
return sign, nil
}
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