github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/vm/crypto.go (about) 1 package vm 2 3 import ( 4 "crypto/sha256" 5 "hash" 6 7 "golang.org/x/crypto/sha3" 8 9 "github.com/bytom/bytom/crypto" 10 "github.com/bytom/bytom/crypto/ed25519" 11 "github.com/bytom/bytom/math/checked" 12 ) 13 14 func opSha256(vm *virtualMachine) error { 15 return doHash(vm, sha256.New) 16 } 17 18 func opSha3(vm *virtualMachine) error { 19 return doHash(vm, sha3.New256) 20 } 21 22 func doHash(vm *virtualMachine, hashFactory func() hash.Hash) error { 23 x, err := vm.pop(false) 24 if err != nil { 25 return err 26 } 27 cost := int64(len(x)) 28 if cost < 64 { 29 cost = 64 30 } 31 err = vm.applyCost(cost) 32 if err != nil { 33 return err 34 } 35 h := hashFactory() 36 _, err = h.Write(x) 37 if err != nil { 38 return err 39 } 40 return vm.push(h.Sum(nil), false) 41 } 42 43 func opCheckSig(vm *virtualMachine) error { 44 err := vm.applyCost(1024) 45 if err != nil { 46 return err 47 } 48 pubkeyBytes, err := vm.pop(true) 49 if err != nil { 50 return err 51 } 52 msg, err := vm.pop(true) 53 if err != nil { 54 return err 55 } 56 sig, err := vm.pop(true) 57 if err != nil { 58 return err 59 } 60 if len(msg) != 32 { 61 return ErrBadValue 62 } 63 if len(pubkeyBytes) != ed25519.PublicKeySize { 64 return vm.pushBool(false, true) 65 } 66 return vm.pushBool(ed25519.Verify(ed25519.PublicKey(pubkeyBytes), msg, sig), true) 67 } 68 69 func opCheckMultiSig(vm *virtualMachine) error { 70 numPubkeys, err := vm.popInt64(true) 71 if err != nil { 72 return err 73 } 74 pubCost, ok := checked.MulInt64(numPubkeys, 1024) 75 if numPubkeys < 0 || !ok { 76 return ErrBadValue 77 } 78 err = vm.applyCost(pubCost) 79 if err != nil { 80 return err 81 } 82 numSigs, err := vm.popInt64(true) 83 if err != nil { 84 return err 85 } 86 if numSigs < 0 || numSigs > numPubkeys || (numPubkeys > 0 && numSigs == 0) { 87 return ErrBadValue 88 } 89 pubkeyByteses := make([][]byte, 0, numPubkeys) 90 for i := int64(0); i < numPubkeys; i++ { 91 pubkeyBytes, err := vm.pop(true) 92 if err != nil { 93 return err 94 } 95 pubkeyByteses = append(pubkeyByteses, pubkeyBytes) 96 } 97 msg, err := vm.pop(true) 98 if err != nil { 99 return err 100 } 101 if len(msg) != 32 { 102 return ErrBadValue 103 } 104 sigs := make([][]byte, 0, numSigs) 105 for i := int64(0); i < numSigs; i++ { 106 sig, err := vm.pop(true) 107 if err != nil { 108 return err 109 } 110 sigs = append(sigs, sig) 111 } 112 113 pubkeys := make([]ed25519.PublicKey, 0, numPubkeys) 114 for _, p := range pubkeyByteses { 115 if len(p) != ed25519.PublicKeySize { 116 return vm.pushBool(false, true) 117 } 118 pubkeys = append(pubkeys, ed25519.PublicKey(p)) 119 } 120 121 for len(sigs) > 0 && len(pubkeys) > 0 { 122 if ed25519.Verify(pubkeys[0], msg, sigs[0]) { 123 sigs = sigs[1:] 124 } 125 pubkeys = pubkeys[1:] 126 } 127 return vm.pushBool(len(sigs) == 0, true) 128 } 129 130 func opTxSigHash(vm *virtualMachine) error { 131 err := vm.applyCost(256) 132 if err != nil { 133 return err 134 } 135 if vm.context.TxSigHash == nil { 136 return ErrContext 137 } 138 return vm.push(vm.context.TxSigHash(), false) 139 } 140 141 func opHash160(vm *virtualMachine) error { 142 data, err := vm.pop(false) 143 if err != nil { 144 return err 145 } 146 147 cost := int64(len(data) + 64) 148 if err = vm.applyCost(cost); err != nil { 149 return err 150 } 151 152 return vm.push(crypto.Ripemd160(data), false) 153 }