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