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