7 "golang.org/x/crypto/sha3"
9 "github.com/bytom/vapor/crypto"
10 "github.com/bytom/vapor/crypto/ed25519"
11 "github.com/bytom/vapor/math/checked"
14 func opSha256(vm *virtualMachine) error {
15 return doHash(vm, sha256.New)
18 func opSha3(vm *virtualMachine) error {
19 return doHash(vm, sha3.New256)
22 func doHash(vm *virtualMachine, hashFactory func() hash.Hash) error {
23 x, err := vm.pop(false)
31 err = vm.applyCost(cost)
40 return vm.push(h.Sum(nil), false)
43 func opCheckSig(vm *virtualMachine) error {
44 err := vm.applyCost(1024)
48 pubkeyBytes, err := vm.pop(true)
52 msg, err := vm.pop(true)
56 sig, err := vm.pop(true)
63 if len(pubkeyBytes) != ed25519.PublicKeySize {
64 return vm.pushBool(false, true)
66 return vm.pushBool(ed25519.Verify(ed25519.PublicKey(pubkeyBytes), msg, sig), true)
69 func opCheckMultiSig(vm *virtualMachine) error {
70 numPubkeys, err := vm.popInt64(true)
74 pubCost, ok := checked.MulInt64(numPubkeys, 1024)
75 if numPubkeys < 0 || !ok {
78 err = vm.applyCost(pubCost)
82 numSigs, err := vm.popInt64(true)
86 if numSigs < 0 || numSigs > numPubkeys || (numPubkeys > 0 && numSigs == 0) {
89 pubkeyByteses := make([][]byte, 0, numPubkeys)
90 for i := int64(0); i < numPubkeys; i++ {
91 pubkeyBytes, err := vm.pop(true)
95 pubkeyByteses = append(pubkeyByteses, pubkeyBytes)
97 msg, err := vm.pop(true)
104 sigs := make([][]byte, 0, numSigs)
105 for i := int64(0); i < numSigs; i++ {
106 sig, err := vm.pop(true)
110 sigs = append(sigs, sig)
113 pubkeys := make([]ed25519.PublicKey, 0, numPubkeys)
114 for _, p := range pubkeyByteses {
115 if len(p) != ed25519.PublicKeySize {
116 return vm.pushBool(false, true)
118 pubkeys = append(pubkeys, ed25519.PublicKey(p))
121 for len(sigs) > 0 && len(pubkeys) > 0 {
122 if ed25519.Verify(pubkeys[0], msg, sigs[0]) {
125 pubkeys = pubkeys[1:]
127 return vm.pushBool(len(sigs) == 0, true)
130 func opTxSigHash(vm *virtualMachine) error {
131 err := vm.applyCost(256)
135 if vm.context.TxSigHash == nil {
138 return vm.push(vm.context.TxSigHash(), false)
141 func opHash160(vm *virtualMachine) error {
142 data, err := vm.pop(false)
147 cost := int64(len(data) + 64)
148 if err = vm.applyCost(cost); err != nil {
152 return vm.push(crypto.Ripemd160(data), false)