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.

161 lines
5.0 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. #include <string>
  2. #include <stdexcept>
  3. #include <sstream>
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <stdlib.h>
  7. #include <gmp.h>
  8. #include "calcwit.h"
  9. #include "utils.h"
  10. Circom_CalcWit::Circom_CalcWit(Circom_Circuit *aCircuit) {
  11. circuit = aCircuit;
  12. #ifdef SANITY_CHECK
  13. signalAssigned = new bool[circuit->NSignals];
  14. signalAssigned[0] = true;
  15. #endif
  16. inputSignalsToTrigger = new int[circuit->NComponents];
  17. signalValues = new BigInt[circuit->NSignals];
  18. // Set one signal
  19. mpz_init_set_ui(signalValues[0], 1);
  20. // Initialize remaining signals
  21. for (int i=1; i<circuit->NSignals; i++) mpz_init2(signalValues[i], 256);
  22. BigInt p;
  23. mpz_init_set_str(p, circuit->P, 10);
  24. field = new ZqField(&p);
  25. mpz_clear(p);
  26. reset();
  27. }
  28. void Circom_CalcWit::reset() {
  29. #ifdef SANITY_CHECK
  30. for (int i=1; i<circuit->NComponents; i++) signalAssigned[i] = false;
  31. #endif
  32. for (int i=0; i<circuit->NComponents; i++) {
  33. inputSignalsToTrigger[i] = circuit->components[i].inputSignals;
  34. if (inputSignalsToTrigger[i] == 0) triggerComponent(i);
  35. }
  36. }
  37. Circom_CalcWit::~Circom_CalcWit() {
  38. delete field;
  39. #ifdef SANITY_CHECK
  40. delete signalAssigned;
  41. #endif
  42. for (int i=0; i<circuit->NSignals; i++) mpz_clear(signalValues[i]);
  43. delete[] signalValues;
  44. delete inputSignalsToTrigger;
  45. }
  46. int Circom_CalcWit::getSubComponentOffset(int cIdx, u64 hash) {
  47. int hIdx;
  48. for(hIdx = int(hash & 0xFF); hash!=circuit->components[cIdx].hashTable[hIdx].hash; hIdx++) {
  49. if (!circuit->components[cIdx].hashTable[hIdx].hash) throw std::runtime_error("hash not found: " + int_to_hex(hash));
  50. }
  51. int entryPos = circuit->components[cIdx].hashTable[hIdx].pos;
  52. if (circuit->components[cIdx].entries[entryPos].type != _typeComponent) {
  53. throw std::runtime_error("invalid type");
  54. }
  55. return circuit->components[cIdx].entries[entryPos].offset;
  56. }
  57. Circom_Sizes Circom_CalcWit::getSubComponentSizes(int cIdx, u64 hash) {
  58. int hIdx;
  59. for(hIdx = int(hash & 0xFF); hash!=circuit->components[cIdx].hashTable[hIdx].hash; hIdx++) {
  60. if (!circuit->components[cIdx].hashTable[hIdx].hash) throw std::runtime_error("hash not found: " + int_to_hex(hash));
  61. }
  62. int entryPos = circuit->components[cIdx].hashTable[hIdx].pos;
  63. if (circuit->components[cIdx].entries[entryPos].type != _typeComponent) {
  64. throw std::runtime_error("invalid type");
  65. }
  66. return circuit->components[cIdx].entries[entryPos].sizes;
  67. }
  68. int Circom_CalcWit::getSignalOffset(int cIdx, u64 hash) {
  69. int hIdx;
  70. for(hIdx = int(hash & 0xFF); hash!=circuit->components[cIdx].hashTable[hIdx].hash; hIdx++) {
  71. if (!circuit->components[cIdx].hashTable[hIdx].hash) throw std::runtime_error("hash not found: " + int_to_hex(hash));
  72. }
  73. int entryPos = circuit->components[cIdx].hashTable[hIdx].pos;
  74. if (circuit->components[cIdx].entries[entryPos].type != _typeSignal) {
  75. throw std::runtime_error("invalid type");
  76. }
  77. return circuit->components[cIdx].entries[entryPos].offset;
  78. }
  79. Circom_Sizes Circom_CalcWit::getSignalSizes(int cIdx, u64 hash) {
  80. int hIdx;
  81. for(hIdx = int(hash & 0xFF); hash!=circuit->components[cIdx].hashTable[hIdx].hash; hIdx++) {
  82. if (!circuit->components[cIdx].hashTable[hIdx].hash) throw std::runtime_error("hash not found: " + int_to_hex(hash));
  83. }
  84. int entryPos = circuit->components[cIdx].hashTable[hIdx].pos;
  85. if (circuit->components[cIdx].entries[entryPos].type != _typeSignal) {
  86. throw std::runtime_error("invalid type");
  87. }
  88. return circuit->components[cIdx].entries[entryPos].sizes;
  89. }
  90. PBigInt Circom_CalcWit::allocBigInts(int n) {
  91. PBigInt res = new BigInt[n];
  92. for (int i=0; i<n; i++) mpz_init2(res[i], 256);
  93. return res;
  94. }
  95. void Circom_CalcWit::freeBigInts(PBigInt bi, int n) {
  96. for (int i=0; i<n; i++) mpz_clear(bi[i]);
  97. delete[] bi;
  98. }
  99. void Circom_CalcWit::getSignal(int cIdx, int sIdx, PBigInt value) {
  100. mpz_set(*value, signalValues[sIdx]);
  101. }
  102. void Circom_CalcWit::setSignal(int cIdx, int sIdx, PBigInt value) {
  103. #ifdef SANITY_CHECK
  104. assert(signalAssigned[sIdx] == false);
  105. signalAssigned[sIdx] = true;
  106. #endif
  107. mpz_set(signalValues[sIdx], *value);
  108. if ( BITMAP_ISSET(circuit->mapIsInput, sIdx) ) {
  109. inputSignalsToTrigger[cIdx]--;
  110. if (inputSignalsToTrigger[cIdx] == 0) triggerComponent(cIdx);
  111. }
  112. }
  113. void Circom_CalcWit::checkConstraint(PBigInt value1, PBigInt value2, char const *err) {
  114. #ifdef SANITY_CHECK
  115. if (mpz_cmp(*value1, *value2) != 0) {
  116. char *pcV1 = mpz_get_str(0, 10, *value1);
  117. char *pcV2 = mpz_get_str(0, 10, *value1);
  118. std::string sV1 = std::string(pcV1);
  119. std::string sV2 = std::string(pcV2);
  120. free(pcV1);
  121. free(pcV2);
  122. throw std::runtime_error(std::string("Constraint does not match,") + err + ". " + sV1 + " != " + sV2 );
  123. }
  124. #endif
  125. }
  126. void Circom_CalcWit::triggerComponent(int newCIdx) {
  127. int oldCIdx = cIdx;
  128. cIdx = newCIdx;
  129. (*(circuit->components[newCIdx].fn))(this);
  130. cIdx = oldCIdx;
  131. }