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.

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