You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package vm
  2. import (
  3. "crypto/sha256"
  4. "github.com/tendermint/tendermint/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160"
  5. . "github.com/tendermint/tendermint/common"
  6. "github.com/tendermint/tendermint/vm/secp256k1"
  7. "github.com/tendermint/tendermint/vm/sha3"
  8. )
  9. var nativeContracts = make(map[Word256]NativeContract)
  10. func init() {
  11. nativeContracts[Int64ToWord256(1)] = ecrecoverFunc
  12. nativeContracts[Int64ToWord256(2)] = sha256Func
  13. nativeContracts[Int64ToWord256(3)] = ripemd160Func
  14. nativeContracts[Int64ToWord256(4)] = identityFunc
  15. }
  16. //-----------------------------------------------------------------------------
  17. type NativeContract func(input []byte, gas *int64) (output []byte, err error)
  18. func ecrecoverFunc(input []byte, gas *int64) (output []byte, err error) {
  19. // Deduct gas
  20. gasRequired := GasEcRecover
  21. if *gas < gasRequired {
  22. return nil, ErrInsufficientGas
  23. } else {
  24. *gas -= gasRequired
  25. }
  26. // Recover
  27. hash := input[:32]
  28. v := byte(input[32] - 27) // ignore input[33:64], v is small.
  29. sig := append(input[64:], v)
  30. recovered, err := secp256k1.RecoverPubkey(hash, sig)
  31. if err != nil {
  32. return nil, err
  33. }
  34. hashed := sha3.Sha3(recovered[1:])
  35. return LeftPadBytes(hashed, 32), nil
  36. }
  37. func sha256Func(input []byte, gas *int64) (output []byte, err error) {
  38. // Deduct gas
  39. gasRequired := int64((len(input)+31)/32)*GasSha256Word + GasSha256Base
  40. if *gas < gasRequired {
  41. return nil, ErrInsufficientGas
  42. } else {
  43. *gas -= gasRequired
  44. }
  45. // Hash
  46. hasher := sha256.New()
  47. // CONTRACT: this does not err
  48. _, err = hasher.Write(input)
  49. if err != nil {
  50. panic(err)
  51. }
  52. return hasher.Sum(nil), nil
  53. }
  54. func ripemd160Func(input []byte, gas *int64) (output []byte, err error) {
  55. // Deduct gas
  56. gasRequired := int64((len(input)+31)/32)*GasRipemd160Word + GasRipemd160Base
  57. if *gas < gasRequired {
  58. return nil, ErrInsufficientGas
  59. } else {
  60. *gas -= gasRequired
  61. }
  62. // Hash
  63. hasher := ripemd160.New()
  64. // CONTRACT: this does not err
  65. _, err = hasher.Write(input)
  66. if err != nil {
  67. panic(err)
  68. }
  69. return LeftPadBytes(hasher.Sum(nil), 32), nil
  70. }
  71. func identityFunc(input []byte, gas *int64) (output []byte, err error) {
  72. // Deduct gas
  73. gasRequired := int64((len(input)+31)/32)*GasIdentityWord + GasIdentityBase
  74. if *gas < gasRequired {
  75. return nil, ErrInsufficientGas
  76. } else {
  77. *gas -= gasRequired
  78. }
  79. // Return identity
  80. return input, nil
  81. }