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