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 }