VirtualMachine.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. Copyright (c) 2018 tevador
  3. This file is part of RandomX.
  4. RandomX is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. RandomX is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with RandomX. If not, see<http://www.gnu.org/licenses/>.
  14. */
  15. #include "VirtualMachine.hpp"
  16. #include "common.hpp"
  17. #include "hashAes1Rx4.hpp"
  18. #include "blake2/blake2.h"
  19. #include <cstring>
  20. #include <iomanip>
  21. #include "intrinPortable.h"
  22. std::ostream& operator<<(std::ostream& os, const RandomX::RegisterFile& rf) {
  23. for (int i = 0; i < RandomX::RegistersCount; ++i)
  24. os << std::hex << "r" << i << " = " << rf.r[i] << std::endl << std::dec;
  25. for (int i = 0; i < 4; ++i)
  26. os << std::hex << "f" << i << " = " << *(uint64_t*)&rf.f[i].hi << " (" << rf.f[i].hi << ")" << std::endl
  27. << " = " << *(uint64_t*)&rf.f[i].lo << " (" << rf.f[i].lo << ")" << std::endl << std::dec;
  28. for (int i = 0; i < 4; ++i)
  29. os << std::hex << "e" << i << " = " << *(uint64_t*)&rf.e[i].hi << " (" << rf.e[i].hi << ")" << std::endl
  30. << " = " << *(uint64_t*)&rf.e[i].lo << " (" << rf.e[i].lo << ")" << std::endl << std::dec;
  31. for (int i = 0; i < 4; ++i)
  32. os << std::hex << "a" << i << " = " << *(uint64_t*)&rf.a[i].hi << " (" << rf.a[i].hi << ")" << std::endl
  33. << " = " << *(uint64_t*)&rf.a[i].lo << " (" << rf.a[i].lo << ")" << std::endl << std::dec;
  34. return os;
  35. }
  36. namespace RandomX {
  37. constexpr int mantissaSize = 52;
  38. constexpr int exponentSize = 11;
  39. constexpr uint64_t mantissaMask = (1ULL << mantissaSize) - 1;
  40. constexpr uint64_t exponentMask = (1ULL << exponentSize) - 1;
  41. constexpr int exponentBias = 1023;
  42. static inline uint64_t getSmallPositiveFloatBits(uint64_t entropy) {
  43. auto exponent = entropy >> 59; //0..31
  44. auto mantissa = entropy & mantissaMask;
  45. exponent += exponentBias;
  46. exponent &= exponentMask;
  47. exponent <<= mantissaSize;
  48. return exponent | mantissa;
  49. }
  50. VirtualMachine::VirtualMachine() {
  51. mem.ds.dataset = nullptr;
  52. }
  53. void VirtualMachine::resetRoundingMode() {
  54. initFpu();
  55. }
  56. void VirtualMachine::initialize() {
  57. store64(&reg.a[0].lo, getSmallPositiveFloatBits(program.getEntropy(0)));
  58. store64(&reg.a[0].hi, getSmallPositiveFloatBits(program.getEntropy(1)));
  59. store64(&reg.a[1].lo, getSmallPositiveFloatBits(program.getEntropy(2)));
  60. store64(&reg.a[1].hi, getSmallPositiveFloatBits(program.getEntropy(3)));
  61. store64(&reg.a[2].lo, getSmallPositiveFloatBits(program.getEntropy(4)));
  62. store64(&reg.a[2].hi, getSmallPositiveFloatBits(program.getEntropy(5)));
  63. store64(&reg.a[3].lo, getSmallPositiveFloatBits(program.getEntropy(6)));
  64. store64(&reg.a[3].hi, getSmallPositiveFloatBits(program.getEntropy(7)));
  65. mem.ma = program.getEntropy(8) & CacheLineAlignMask;
  66. mem.mx = program.getEntropy(10);
  67. auto addressRegisters = program.getEntropy(12);
  68. readReg0 = 0 + (addressRegisters & 1);
  69. addressRegisters >>= 1;
  70. readReg1 = 2 + (addressRegisters & 1);
  71. addressRegisters >>= 1;
  72. readReg2 = 4 + (addressRegisters & 1);
  73. addressRegisters >>= 1;
  74. readReg3 = 6 + (addressRegisters & 1);
  75. }
  76. template<bool softAes>
  77. void VirtualMachine::getResult(void* scratchpad, size_t scratchpadSize, void* outHash) {
  78. if (scratchpadSize > 0) {
  79. hashAes1Rx4<false>(scratchpad, scratchpadSize, &reg.a);
  80. }
  81. blake2b(outHash, ResultSize, &reg, sizeof(RegisterFile), nullptr, 0);
  82. }
  83. template void VirtualMachine::getResult<false>(void* scratchpad, size_t scratchpadSize, void* outHash);
  84. template void VirtualMachine::getResult<true>(void* scratchpad, size_t scratchpadSize, void* outHash);
  85. }