github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/signer/mainchain/signature/signature.go (about)

     1  package signature
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/sixexorg/magnetic-ring/account"
     6  	"github.com/sixexorg/magnetic-ring/common"
     7  	"github.com/sixexorg/magnetic-ring/core/mainchain/types"
     8  	"github.com/sixexorg/magnetic-ring/crypto"
     9  	errors2 "github.com/sixexorg/magnetic-ring/errors"
    10  )
    11  
    12  /*
    13  	check signature postion and state
    14  */
    15  func CheckSignState(sp common.SigPack, units account.MultiAccountUnits) (apprlvlIndex int, enough bool, err error) {
    16  	sigdata := sp.SigData
    17  
    18  	if sigdata == nil {
    19  		sp.SigData = make([]*common.SigMap, len(units))
    20  	}
    21  	sigdatalen := len(sigdata)
    22  
    23  	if sigdatalen > len(units) {
    24  		apprlvlIndex = -1
    25  		err = errors2.SIG_ERR_SIZE
    26  		return
    27  	}
    28  
    29  	if sigdatalen < 1 {
    30  		return 0, false, nil
    31  	}
    32  
    33  	index := 0
    34  
    35  	for index, sigmap := range sigdata {
    36  		if len(*sigmap) < int(units[index].Threshold) {
    37  			apprlvlIndex = index
    38  			return
    39  		}
    40  	}
    41  	apprlvlIndex = index
    42  	enough = true
    43  	return
    44  }
    45  
    46  func CheckAddressCanSign(units account.MultiAccountUnits, apprlvlIndex int, address common.Address) (bool, error) {
    47  	if apprlvlIndex > (len(units)-1) || apprlvlIndex < 0 {
    48  		return false, errors2.SIG_ERR_APPR_LVL
    49  	}
    50  
    51  	//unit := units[apprlvlIndex]
    52  
    53  	muldddaddr, err := units.Address()
    54  	if err != nil {
    55  		return false, err
    56  	}
    57  
    58  	if muldddaddr.ToString() == address.ToString() {
    59  		return true, nil
    60  	}
    61  
    62  	//for _, puk := range unit.Pubkeys {
    63  	//
    64  	//	pubytes := common.Sha256Ripemd160(puk.Bytes())
    65  	//
    66  	//	tempaddr := common.BytesToAddress(pubytes, common.NormalAddress)
    67  	//	if address.Equals(tempaddr) {
    68  	//		//apprlvl := *sp.SigData[apprlvlIndex]
    69  	//		//if sigbytes,ok := apprlvl[address];ok {
    70  	//		//	return sigbytes,nil
    71  	//		//}
    72  	//		return true, nil
    73  	//	}
    74  	//}
    75  
    76  	return false, errors2.SIG_ERR_UNSIGN
    77  
    78  }
    79  
    80  func SignTransaction(m *account.AccountManagerImpl, address common.Address, tx *types.Transaction, pasw string) error {
    81  	muladdr := tx.TxData.From
    82  	mulacct, err := m.GetMultipleAccount(address, muladdr)
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	impl := mulacct.(*account.MultipleAccountImpl)
    88  
    89  	addressstr := address.ToString()
    90  	fmt.Printf("addressstr=%s\n", addressstr)
    91  
    92  	key, err := m.GetNormalAccount(address, pasw)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	b := impl.ExistPubkey(key.PublicKey())
    98  
    99  	if !b {
   100  		return errors2.SIG_ERR_WRONGOWNER
   101  	}
   102  
   103  	tx.Sigs = new(common.SigPack)
   104  	err = tx.ToRaw()
   105  	if err != nil {
   106  		return err
   107  	}
   108  
   109  	sha256buf := common.Sha256(tx.Raw)
   110  	sigbuf, err := key.Sign(sha256buf)
   111  	if err != nil {
   112  		return err
   113  	}
   114  
   115  	apprindex, _, err := CheckSignState(*tx.Sigs, impl.Maus)
   116  
   117  	can, err := CheckAddressCanSign(impl.Maus, apprindex, address)
   118  
   119  	if err != nil {
   120  		return err
   121  	}
   122  
   123  	if !can {
   124  		return errors2.SIG_ERR_CANOT
   125  	}
   126  	sd := tx.Sigs.SigData
   127  
   128  	if sd == nil || len(sd) == 0 {
   129  		sd = make([]*common.SigMap, 0)
   130  		sm := make(common.SigMap, 0)
   131  		itm := common.SigMapItem{address, sigbuf}
   132  		//sm[*address] = sigbuf
   133  		sm = append(sm, &itm)
   134  		sd = append(sd, &sm)
   135  		tx.Sigs.SigData = sd
   136  	} else {
   137  		fmt.Printf("sd=%v,apprindex=%d\n", sd, apprindex)
   138  		apprlvl := sd[apprindex]
   139  		if apprlvl == nil || len(*apprlvl) == 0 {
   140  			temp := make(common.SigMap, 0)
   141  			itm := common.SigMapItem{address, sigbuf}
   142  			temp = append(temp, &itm)
   143  			sd[apprindex] = &temp
   144  		} else {
   145  			itm := common.SigMapItem{address, sigbuf}
   146  			*apprlvl = append(*apprlvl, &itm)
   147  		}
   148  	}
   149  
   150  	return nil
   151  }
   152  
   153  func VerifyTransaction(unis account.MultiAccountUnits, tx *types.Transaction) (bool, error) {
   154  
   155  	if unis == nil || len(unis) == 0 {
   156  		return false, errors2.SIG_ERR_NULL_UNITS
   157  	}
   158  
   159  	if tx.Sigs.SigData == nil || len(tx.Sigs.SigData) < 1 {
   160  		return false, errors2.SIG_ERR_NOSIG
   161  	}
   162  
   163  	if len(tx.Sigs.SigData) != len(unis) {
   164  		return false, errors2.SIG_ERR_SIGS_NOTENOUGH
   165  	}
   166  
   167  	for index, unit := range unis {
   168  		sigmaparr := tx.Sigs.SigData
   169  
   170  		sigmp := sigmaparr[index]
   171  
   172  		if len(*sigmp) < int(unit.Threshold) {
   173  			return false, errors2.SIG_ERR_APPROVE_NOT_ENOUGH
   174  		}
   175  
   176  		for _, sigitm := range *sigmp {
   177  
   178  			for _, pubk := range unit.Pubkeys {
   179  
   180  				addrhash := common.Sha256Ripemd160(pubk.Bytes())
   181  
   182  				tmpaddress := common.BytesToAddress(addrhash, common.NormalAddress)
   183  
   184  				if tmpaddress.Equals(sigitm.Key) {
   185  					bsign, err := pubk.Verify(tx.Raw, sigitm.Val)
   186  					if err != nil {
   187  						return false, err
   188  					}
   189  
   190  					if !bsign {
   191  						return false, errors2.SIG_ERR_INVALID_SIG
   192  					}
   193  				}
   194  			}
   195  		}
   196  
   197  	}
   198  
   199  	return true, nil
   200  }
   201  
   202  func SignTransactionPubk(m *account.AccountManagerImpl, pubkstr string, tx *types.Transaction, pasw string) error {
   203  	muladdr := tx.TxData.From
   204  
   205  	buf, err := common.Hex2Bytes(pubkstr)
   206  	if err != nil {
   207  		return err
   208  	}
   209  
   210  	pubk, err := crypto.UnmarshalPubkey(buf)
   211  	if err != nil {
   212  		return err
   213  	}
   214  	bytes := pubk.Bytes()
   215  	hash := common.Sha256Ripemd160(bytes)
   216  	address := common.BytesToAddress(hash, common.NormalAddress)
   217  
   218  	mulacct, err := m.GetMultipleAccount(address, muladdr)
   219  	if err != nil {
   220  		return err
   221  	}
   222  
   223  	impl := mulacct.(*account.MultipleAccountImpl)
   224  
   225  	key, err := m.GetNormalAccount(address, pasw)
   226  	if err != nil {
   227  		return err
   228  	}
   229  
   230  	b := impl.ExistPubkey(key.PublicKey())
   231  
   232  	if !b {
   233  		return errors2.SIG_ERR_WRONGOWNER
   234  	}
   235  
   236  	tx.Sigs = new(common.SigPack)
   237  	err = tx.ToRaw()
   238  	if err != nil {
   239  		return err
   240  	}
   241  
   242  	sha256buf := common.Sha256(tx.Raw)
   243  	sigbuf, err := key.Sign(sha256buf)
   244  	if err != nil {
   245  		return err
   246  	}
   247  
   248  	apprindex, _, err := CheckSignState(*tx.Sigs, impl.Maus)
   249  
   250  	can, err := CheckAddressCanSign(impl.Maus, apprindex, address)
   251  
   252  	if err != nil {
   253  		return err
   254  	}
   255  
   256  	if !can {
   257  		return errors2.SIG_ERR_CANOT
   258  	}
   259  	sd := tx.Sigs.SigData
   260  
   261  	if sd == nil || len(sd) == 0 {
   262  		sd = make([]*common.SigMap, 0)
   263  		sm := make(common.SigMap, 0)
   264  		itm := common.SigMapItem{address, sigbuf}
   265  		//sm[*address] = sigbuf
   266  		sm = append(sm, &itm)
   267  		sd = append(sd, &sm)
   268  		tx.Sigs.SigData = sd
   269  	} else {
   270  		fmt.Printf("sd=%v,apprindex=%d\n", sd, apprindex)
   271  		apprlvl := sd[apprindex]
   272  		if apprlvl == nil || len(*apprlvl) == 0 {
   273  			temp := make(common.SigMap, 0)
   274  			itm := common.SigMapItem{address, sigbuf}
   275  			temp = append(temp, &itm)
   276  			sd[apprindex] = &temp
   277  		} else {
   278  			itm := common.SigMapItem{address, sigbuf}
   279  			*apprlvl = append(*apprlvl, &itm)
   280  		}
   281  	}
   282  
   283  	return nil
   284  }
   285  
   286  func SignTransactionWithPrivk(address common.Address, tx *types.Transaction, privk string) error {
   287  
   288  	tplt := tx.Templt
   289  
   290  	impl := new(account.MultipleAccountImpl)
   291  
   292  	mulen := len(tplt.SigData)
   293  	muls := make(account.MultiAccountUnits, mulen)
   294  	for i, layer := range tplt.SigData {
   295  		var mult account.MultiAccountUnit
   296  		for _, pubdata := range *layer {
   297  			pbks := make([]crypto.PublicKey, 0)
   298  
   299  			for _, pbk := range pubdata.Pubks {
   300  				pubkey, err := crypto.UnmarshalPubkey(pbk[:])
   301  				if err != nil {
   302  					return err
   303  				}
   304  				pbks = append(pbks, pubkey)
   305  			}
   306  			mult = account.MultiAccountUnit{pubdata.M, pbks}
   307  		}
   308  		muls[i] = mult
   309  
   310  	}
   311  	impl.Maus = muls
   312  
   313  	addressstr := address.ToString()
   314  	fmt.Printf("addressstr=%s\n", addressstr)
   315  
   316  	key, err := crypto.HexToPrivateKey(privk)
   317  
   318  	//key, err := m.GetNormalAccount(address, pasw)
   319  	if err != nil {
   320  		return err
   321  	}
   322  
   323  	b := impl.ExistPubkey(key.Public())
   324  
   325  	if !b {
   326  		return errors2.SIG_ERR_WRONGOWNER
   327  	}
   328  
   329  	tx.Sigs = new(common.SigPack)
   330  	err = tx.ToRaw()
   331  	if err != nil {
   332  		return err
   333  	}
   334  
   335  	sha256buf := common.Sha256(tx.Raw)
   336  	sigbuf, err := key.Sign(sha256buf)
   337  	if err != nil {
   338  		return err
   339  	}
   340  
   341  	apprindex, _, err := CheckSignState(*tx.Sigs, impl.Maus)
   342  
   343  	can, err := CheckAddressCanSign(impl.Maus, apprindex, address)
   344  
   345  	if err != nil {
   346  		return err
   347  	}
   348  
   349  	if !can {
   350  		return errors2.SIG_ERR_CANOT
   351  	}
   352  	sd := tx.Sigs.SigData
   353  
   354  	if sd == nil || len(sd) == 0 {
   355  		sd = make([]*common.SigMap, 0)
   356  		sm := make(common.SigMap, 0)
   357  		itm := common.SigMapItem{address, sigbuf}
   358  		//sm[*address] = sigbuf
   359  		sm = append(sm, &itm)
   360  		sd = append(sd, &sm)
   361  		tx.Sigs.SigData = sd
   362  	} else {
   363  		fmt.Printf("sd=%v,apprindex=%d\n", sd, apprindex)
   364  		apprlvl := sd[apprindex]
   365  		if apprlvl == nil || len(*apprlvl) == 0 {
   366  			temp := make(common.SigMap, 0)
   367  			itm := common.SigMapItem{address, sigbuf}
   368  			temp = append(temp, &itm)
   369  			sd[apprindex] = &temp
   370  		} else {
   371  			itm := common.SigMapItem{address, sigbuf}
   372  			*apprlvl = append(*apprlvl, &itm)
   373  		}
   374  	}
   375  
   376  	return nil
   377  }