github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/vm/crypto.go (about) 1 package vm 2 3 import ( 4 "crypto/ed25519" 5 "crypto/sha256" 6 "hash" 7 8 "golang.org/x/crypto/sha3" 9 10 "github.com/bytom/bytom/crypto" 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 28 cost := int64(len(x)) 29 if cost < 64 { 30 cost = 64 31 } 32 33 if err = vm.applyCost(cost); err != nil { 34 return err 35 } 36 37 h := hashFactory() 38 if _, err = h.Write(x); err != nil { 39 return err 40 } 41 return vm.pushDataStack(h.Sum(nil), false) 42 } 43 44 func opCheckSig(vm *virtualMachine) error { 45 if err := vm.applyCost(1024); err != nil { 46 return err 47 } 48 49 pubkeyBytes, err := vm.pop(true) 50 if err != nil { 51 return err 52 } 53 54 msg, err := vm.pop(true) 55 if err != nil { 56 return err 57 } 58 59 sig, err := vm.pop(true) 60 if err != nil { 61 return err 62 } 63 64 if len(msg) != 32 { 65 return ErrBadValue 66 } 67 68 if len(pubkeyBytes) != ed25519.PublicKeySize { 69 return vm.pushBool(false, true) 70 } 71 return vm.pushBool(ed25519.Verify(ed25519.PublicKey(pubkeyBytes), msg, sig), true) 72 } 73 74 func opCheckMultiSig(vm *virtualMachine) error { 75 numPubkeysBigInt, err := vm.popBigInt(true) 76 if err != nil { 77 return err 78 } 79 80 numPubkeys, err := bigIntInt64(numPubkeysBigInt) 81 if err != nil { 82 return err 83 } 84 85 pubCost, ok := checked.MulInt64(numPubkeys, 1024) 86 if numPubkeys < 0 || !ok { 87 return ErrBadValue 88 } 89 90 if err = vm.applyCost(pubCost); err != nil { 91 return err 92 } 93 94 numSigsBigInt, err := vm.popBigInt(true) 95 if err != nil { 96 return err 97 } 98 99 numSigs, err := bigIntInt64(numSigsBigInt) 100 if err != nil { 101 return err 102 } 103 104 if numSigs < 0 || numSigs > numPubkeys || (numPubkeys > 0 && numSigs == 0) { 105 return ErrBadValue 106 } 107 108 pubkeyByteses := make([][]byte, 0, numPubkeys) 109 for i := int64(0); i < numPubkeys; i++ { 110 pubkeyBytes, err := vm.pop(true) 111 if err != nil { 112 return err 113 } 114 pubkeyByteses = append(pubkeyByteses, pubkeyBytes) 115 } 116 117 msg, err := vm.pop(true) 118 if err != nil { 119 return err 120 } 121 122 if len(msg) != 32 { 123 return ErrBadValue 124 } 125 126 sigs := make([][]byte, 0, numSigs) 127 for i := int64(0); i < numSigs; i++ { 128 sig, err := vm.pop(true) 129 if err != nil { 130 return err 131 } 132 sigs = append(sigs, sig) 133 } 134 135 pubkeys := make([]ed25519.PublicKey, 0, numPubkeys) 136 for _, p := range pubkeyByteses { 137 if len(p) != ed25519.PublicKeySize { 138 return vm.pushBool(false, true) 139 } 140 pubkeys = append(pubkeys, ed25519.PublicKey(p)) 141 } 142 143 for len(sigs) > 0 && len(pubkeys) > 0 { 144 if ed25519.Verify(pubkeys[0], msg, sigs[0]) { 145 sigs = sigs[1:] 146 } 147 pubkeys = pubkeys[1:] 148 } 149 150 return vm.pushBool(len(sigs) == 0, true) 151 } 152 153 func opTxSigHash(vm *virtualMachine) error { 154 if err := vm.applyCost(256); err != nil { 155 return err 156 } 157 158 if vm.context.TxSigHash == nil { 159 return ErrContext 160 } 161 162 return vm.pushDataStack(vm.context.TxSigHash(), false) 163 } 164 165 func opHash160(vm *virtualMachine) error { 166 data, err := vm.pop(false) 167 if err != nil { 168 return err 169 } 170 171 cost := int64(len(data) + 64) 172 if err = vm.applyCost(cost); err != nil { 173 return err 174 } 175 176 return vm.pushDataStack(crypto.Ripemd160(data), false) 177 }