github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/signer/orgchain/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/orgchain/types"
     8  	errors2 "github.com/sixexorg/magnetic-ring/errors"
     9  )
    10  
    11  /*
    12  	check signature postion and state
    13  */
    14  func CheckSignState(sp common.SigPack, units account.MultiAccountUnits) (apprlvlIndex int, enough bool, err error) {
    15  	sigdata := sp.SigData
    16  
    17  	if sigdata == nil {
    18  		sp.SigData = make([]*common.SigMap, len(units))
    19  	}
    20  	sigdatalen := len(sigdata)
    21  
    22  	if sigdatalen > len(units) {
    23  		apprlvlIndex = -1
    24  		err = errors2.SIG_ERR_SIZE
    25  		return
    26  	}
    27  
    28  	if sigdatalen < 1 {
    29  		return 0, false, nil
    30  	}
    31  
    32  	index := 0
    33  
    34  	for index, sigmap := range sigdata {
    35  		if len(*sigmap) < int(units[index].Threshold) {
    36  			apprlvlIndex = index
    37  			return
    38  		}
    39  	}
    40  	apprlvlIndex = index
    41  	enough = true
    42  	return
    43  }
    44  
    45  func CheckAddressCanSign(units account.MultiAccountUnits, apprlvlIndex int, address common.Address) (bool, error) {
    46  	if apprlvlIndex > (len(units)-1) || apprlvlIndex < 0 {
    47  		fmt.Printf("fuckhere001\n")
    48  		return false, errors2.SIG_ERR_APPR_LVL
    49  	}
    50  
    51  	muldddaddr, err := units.Address()
    52  	if err != nil {
    53  		return false, err
    54  	}
    55  
    56  	if muldddaddr.ToString() == address.ToString() {
    57  		return true, nil
    58  	}
    59  	return false, errors2.SIG_ERR_UNSIGN
    60  
    61  }
    62  
    63  func SignTransaction(m *account.AccountManagerImpl, address common.Address, tx *types.Transaction, pasw string) error {
    64  	//fmt.Printf("sign transaction address=%s\n",address.ToString())
    65  	mulacct, err := m.GetMultipleAccount(address, address)
    66  	if err != nil {
    67  		return err
    68  	}
    69  
    70  	impl := mulacct.(*account.MultipleAccountImpl)
    71  
    72  	key, err := m.GetNormalAccount(address, pasw)
    73  	if err != nil {
    74  		return err
    75  	}
    76  
    77  	b := impl.ExistPubkey(key.PublicKey())
    78  
    79  	if !b {
    80  		return errors2.SIG_ERR_WRONGOWNER
    81  	}
    82  
    83  	tx.Sigs = new(common.SigPack)
    84  	err = tx.ToRaw()
    85  	if err != nil {
    86  		return err
    87  	}
    88  
    89  	sha256buf := common.Sha256(tx.Raw)
    90  	sigbuf, err := key.Sign(sha256buf)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	apprindex, _, err := CheckSignState(*tx.Sigs, impl.Maus)
    96  
    97  	can, err := CheckAddressCanSign(impl.Maus, apprindex, address)
    98  
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	if !can {
   104  		return errors2.SIG_ERR_CANOT
   105  	}
   106  	sd := tx.Sigs.SigData
   107  
   108  	if sd == nil || len(sd) == 0 {
   109  		sd = make([]*common.SigMap, 0)
   110  		sm := make(common.SigMap, 0)
   111  		itm := common.SigMapItem{address, sigbuf}
   112  		//sm[*address] = sigbuf
   113  		sm = append(sm, &itm)
   114  		sd = append(sd, &sm)
   115  		tx.Sigs.SigData = sd
   116  	} else {
   117  		fmt.Printf("sd=%v,apprindex=%d\n", sd, apprindex)
   118  		apprlvl := sd[apprindex]
   119  		if apprlvl == nil || len(*apprlvl) == 0 {
   120  			temp := make(common.SigMap, 0)
   121  			itm := common.SigMapItem{address, sigbuf}
   122  			temp = append(temp, &itm)
   123  			sd[apprindex] = &temp
   124  		} else {
   125  			itm := common.SigMapItem{address, sigbuf}
   126  			*apprlvl = append(*apprlvl, &itm)
   127  		}
   128  	}
   129  
   130  	return nil
   131  }
   132  
   133  func VerifyTransaction(unis account.MultiAccountUnits, tx *types.Transaction) (bool, error) {
   134  
   135  	if unis == nil || len(unis) == 0 {
   136  		return false, errors2.SIG_ERR_NULL_UNITS
   137  	}
   138  
   139  	if tx.Sigs.SigData == nil || len(tx.Sigs.SigData) < 1 {
   140  		return false, errors2.SIG_ERR_NOSIG
   141  	}
   142  
   143  	if len(tx.Sigs.SigData) != len(unis) {
   144  		return false, errors2.SIG_ERR_SIGS_NOTENOUGH
   145  	}
   146  
   147  	for index, unit := range unis {
   148  		sigmaparr := tx.Sigs.SigData
   149  
   150  		sigmp := sigmaparr[index]
   151  
   152  		if len(*sigmp) < int(unit.Threshold) {
   153  			return false, errors2.SIG_ERR_APPROVE_NOT_ENOUGH
   154  		}
   155  
   156  		for _, sigitm := range *sigmp {
   157  
   158  			for _, pubk := range unit.Pubkeys {
   159  
   160  				addrhash := common.Sha256Ripemd160(pubk.Bytes())
   161  
   162  				tmpaddress := common.BytesToAddress(addrhash, common.NormalAddress)
   163  
   164  				if tmpaddress.Equals(sigitm.Key) {
   165  					bsign, err := pubk.Verify(tx.Raw, sigitm.Val)
   166  					if err != nil {
   167  						return false, err
   168  					}
   169  
   170  					if !bsign {
   171  						return false, errors2.SIG_ERR_INVALID_SIG
   172  					}
   173  				}
   174  			}
   175  		}
   176  
   177  	}
   178  
   179  	return true, nil
   180  }