Update Python version requirements and fix compatibility issues
- Bump minimum Python version from 3.11 to 3.13 across all apps - Add Python 3.11-3.13 test matrix to CLI workflow - Document Python 3.11+ requirement in .env.example - Fix Starlette Broadcast removal with in-process fallback implementation - Add _InProcessBroadcast class for tests when Starlette Broadcast is unavailable - Refactor API key validators to read live settings instead of cached values - Update database models with explicit
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,153 @@
|
||||
1,1,4,main.final_parameters[0]
|
||||
2,2,4,main.final_parameters[1]
|
||||
3,3,4,main.final_parameters[2]
|
||||
4,4,4,main.final_parameters[3]
|
||||
5,5,4,main.training_complete
|
||||
6,6,4,main.initial_parameters[0]
|
||||
7,7,4,main.initial_parameters[1]
|
||||
8,8,4,main.initial_parameters[2]
|
||||
9,9,4,main.initial_parameters[3]
|
||||
10,10,4,main.learning_rate
|
||||
11,-1,4,main.current_params[0][0]
|
||||
12,-1,4,main.current_params[0][1]
|
||||
13,-1,4,main.current_params[0][2]
|
||||
14,-1,4,main.current_params[0][3]
|
||||
15,11,4,main.current_params[1][0]
|
||||
16,12,4,main.current_params[1][1]
|
||||
17,13,4,main.current_params[1][2]
|
||||
18,14,4,main.current_params[1][3]
|
||||
19,15,4,main.current_params[2][0]
|
||||
20,16,4,main.current_params[2][1]
|
||||
21,17,4,main.current_params[2][2]
|
||||
22,18,4,main.current_params[2][3]
|
||||
23,-1,4,main.current_params[3][0]
|
||||
24,-1,4,main.current_params[3][1]
|
||||
25,-1,4,main.current_params[3][2]
|
||||
26,-1,4,main.current_params[3][3]
|
||||
27,-1,3,main.epochs[0].next_epoch_params[0]
|
||||
28,-1,3,main.epochs[0].next_epoch_params[1]
|
||||
29,-1,3,main.epochs[0].next_epoch_params[2]
|
||||
30,-1,3,main.epochs[0].next_epoch_params[3]
|
||||
31,-1,3,main.epochs[0].epoch_params[0]
|
||||
32,-1,3,main.epochs[0].epoch_params[1]
|
||||
33,-1,3,main.epochs[0].epoch_params[2]
|
||||
34,-1,3,main.epochs[0].epoch_params[3]
|
||||
35,-1,3,main.epochs[0].epoch_gradients[0]
|
||||
36,-1,3,main.epochs[0].epoch_gradients[1]
|
||||
37,-1,3,main.epochs[0].epoch_gradients[2]
|
||||
38,-1,3,main.epochs[0].epoch_gradients[3]
|
||||
39,-1,3,main.epochs[0].learning_rate
|
||||
40,-1,2,main.epochs[0].param_update.new_params[0]
|
||||
41,-1,2,main.epochs[0].param_update.new_params[1]
|
||||
42,-1,2,main.epochs[0].param_update.new_params[2]
|
||||
43,-1,2,main.epochs[0].param_update.new_params[3]
|
||||
44,-1,2,main.epochs[0].param_update.current_params[0]
|
||||
45,-1,2,main.epochs[0].param_update.current_params[1]
|
||||
46,-1,2,main.epochs[0].param_update.current_params[2]
|
||||
47,-1,2,main.epochs[0].param_update.current_params[3]
|
||||
48,-1,2,main.epochs[0].param_update.gradients[0]
|
||||
49,-1,2,main.epochs[0].param_update.gradients[1]
|
||||
50,-1,2,main.epochs[0].param_update.gradients[2]
|
||||
51,-1,2,main.epochs[0].param_update.gradients[3]
|
||||
52,-1,2,main.epochs[0].param_update.learning_rate
|
||||
53,-1,1,main.epochs[0].param_update.updates[0].new_param
|
||||
54,-1,1,main.epochs[0].param_update.updates[0].current_param
|
||||
55,-1,1,main.epochs[0].param_update.updates[0].gradient
|
||||
56,-1,1,main.epochs[0].param_update.updates[0].learning_rate
|
||||
57,-1,1,main.epochs[0].param_update.updates[1].new_param
|
||||
58,-1,1,main.epochs[0].param_update.updates[1].current_param
|
||||
59,-1,1,main.epochs[0].param_update.updates[1].gradient
|
||||
60,-1,1,main.epochs[0].param_update.updates[1].learning_rate
|
||||
61,-1,1,main.epochs[0].param_update.updates[2].new_param
|
||||
62,-1,1,main.epochs[0].param_update.updates[2].current_param
|
||||
63,-1,1,main.epochs[0].param_update.updates[2].gradient
|
||||
64,-1,1,main.epochs[0].param_update.updates[2].learning_rate
|
||||
65,-1,1,main.epochs[0].param_update.updates[3].new_param
|
||||
66,-1,1,main.epochs[0].param_update.updates[3].current_param
|
||||
67,-1,1,main.epochs[0].param_update.updates[3].gradient
|
||||
68,-1,1,main.epochs[0].param_update.updates[3].learning_rate
|
||||
69,-1,3,main.epochs[1].next_epoch_params[0]
|
||||
70,-1,3,main.epochs[1].next_epoch_params[1]
|
||||
71,-1,3,main.epochs[1].next_epoch_params[2]
|
||||
72,-1,3,main.epochs[1].next_epoch_params[3]
|
||||
73,-1,3,main.epochs[1].epoch_params[0]
|
||||
74,-1,3,main.epochs[1].epoch_params[1]
|
||||
75,-1,3,main.epochs[1].epoch_params[2]
|
||||
76,-1,3,main.epochs[1].epoch_params[3]
|
||||
77,-1,3,main.epochs[1].epoch_gradients[0]
|
||||
78,-1,3,main.epochs[1].epoch_gradients[1]
|
||||
79,-1,3,main.epochs[1].epoch_gradients[2]
|
||||
80,-1,3,main.epochs[1].epoch_gradients[3]
|
||||
81,-1,3,main.epochs[1].learning_rate
|
||||
82,-1,2,main.epochs[1].param_update.new_params[0]
|
||||
83,-1,2,main.epochs[1].param_update.new_params[1]
|
||||
84,-1,2,main.epochs[1].param_update.new_params[2]
|
||||
85,-1,2,main.epochs[1].param_update.new_params[3]
|
||||
86,-1,2,main.epochs[1].param_update.current_params[0]
|
||||
87,-1,2,main.epochs[1].param_update.current_params[1]
|
||||
88,-1,2,main.epochs[1].param_update.current_params[2]
|
||||
89,-1,2,main.epochs[1].param_update.current_params[3]
|
||||
90,-1,2,main.epochs[1].param_update.gradients[0]
|
||||
91,-1,2,main.epochs[1].param_update.gradients[1]
|
||||
92,-1,2,main.epochs[1].param_update.gradients[2]
|
||||
93,-1,2,main.epochs[1].param_update.gradients[3]
|
||||
94,-1,2,main.epochs[1].param_update.learning_rate
|
||||
95,-1,1,main.epochs[1].param_update.updates[0].new_param
|
||||
96,-1,1,main.epochs[1].param_update.updates[0].current_param
|
||||
97,-1,1,main.epochs[1].param_update.updates[0].gradient
|
||||
98,-1,1,main.epochs[1].param_update.updates[0].learning_rate
|
||||
99,-1,1,main.epochs[1].param_update.updates[1].new_param
|
||||
100,-1,1,main.epochs[1].param_update.updates[1].current_param
|
||||
101,-1,1,main.epochs[1].param_update.updates[1].gradient
|
||||
102,-1,1,main.epochs[1].param_update.updates[1].learning_rate
|
||||
103,-1,1,main.epochs[1].param_update.updates[2].new_param
|
||||
104,-1,1,main.epochs[1].param_update.updates[2].current_param
|
||||
105,-1,1,main.epochs[1].param_update.updates[2].gradient
|
||||
106,-1,1,main.epochs[1].param_update.updates[2].learning_rate
|
||||
107,-1,1,main.epochs[1].param_update.updates[3].new_param
|
||||
108,-1,1,main.epochs[1].param_update.updates[3].current_param
|
||||
109,-1,1,main.epochs[1].param_update.updates[3].gradient
|
||||
110,-1,1,main.epochs[1].param_update.updates[3].learning_rate
|
||||
111,-1,3,main.epochs[2].next_epoch_params[0]
|
||||
112,-1,3,main.epochs[2].next_epoch_params[1]
|
||||
113,-1,3,main.epochs[2].next_epoch_params[2]
|
||||
114,-1,3,main.epochs[2].next_epoch_params[3]
|
||||
115,-1,3,main.epochs[2].epoch_params[0]
|
||||
116,-1,3,main.epochs[2].epoch_params[1]
|
||||
117,-1,3,main.epochs[2].epoch_params[2]
|
||||
118,-1,3,main.epochs[2].epoch_params[3]
|
||||
119,-1,3,main.epochs[2].epoch_gradients[0]
|
||||
120,-1,3,main.epochs[2].epoch_gradients[1]
|
||||
121,-1,3,main.epochs[2].epoch_gradients[2]
|
||||
122,-1,3,main.epochs[2].epoch_gradients[3]
|
||||
123,-1,3,main.epochs[2].learning_rate
|
||||
124,-1,2,main.epochs[2].param_update.new_params[0]
|
||||
125,-1,2,main.epochs[2].param_update.new_params[1]
|
||||
126,-1,2,main.epochs[2].param_update.new_params[2]
|
||||
127,-1,2,main.epochs[2].param_update.new_params[3]
|
||||
128,-1,2,main.epochs[2].param_update.current_params[0]
|
||||
129,-1,2,main.epochs[2].param_update.current_params[1]
|
||||
130,-1,2,main.epochs[2].param_update.current_params[2]
|
||||
131,-1,2,main.epochs[2].param_update.current_params[3]
|
||||
132,-1,2,main.epochs[2].param_update.gradients[0]
|
||||
133,-1,2,main.epochs[2].param_update.gradients[1]
|
||||
134,-1,2,main.epochs[2].param_update.gradients[2]
|
||||
135,-1,2,main.epochs[2].param_update.gradients[3]
|
||||
136,-1,2,main.epochs[2].param_update.learning_rate
|
||||
137,-1,1,main.epochs[2].param_update.updates[0].new_param
|
||||
138,-1,1,main.epochs[2].param_update.updates[0].current_param
|
||||
139,-1,1,main.epochs[2].param_update.updates[0].gradient
|
||||
140,-1,1,main.epochs[2].param_update.updates[0].learning_rate
|
||||
141,-1,1,main.epochs[2].param_update.updates[1].new_param
|
||||
142,-1,1,main.epochs[2].param_update.updates[1].current_param
|
||||
143,-1,1,main.epochs[2].param_update.updates[1].gradient
|
||||
144,-1,1,main.epochs[2].param_update.updates[1].learning_rate
|
||||
145,-1,1,main.epochs[2].param_update.updates[2].new_param
|
||||
146,-1,1,main.epochs[2].param_update.updates[2].current_param
|
||||
147,-1,1,main.epochs[2].param_update.updates[2].gradient
|
||||
148,-1,1,main.epochs[2].param_update.updates[2].learning_rate
|
||||
149,-1,1,main.epochs[2].param_update.updates[3].new_param
|
||||
150,-1,1,main.epochs[2].param_update.updates[3].current_param
|
||||
151,-1,1,main.epochs[2].param_update.updates[3].gradient
|
||||
152,-1,1,main.epochs[2].param_update.updates[3].learning_rate
|
||||
153,-1,0,main.lr_validator.learning_rate
|
||||
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
CC=g++
|
||||
CFLAGS=-std=c++11 -O3 -I.
|
||||
DEPS_HPP = circom.hpp calcwit.hpp fr.hpp
|
||||
DEPS_O = main.o calcwit.o fr.o fr_asm.o
|
||||
|
||||
ifeq ($(shell uname),Darwin)
|
||||
NASM=nasm -fmacho64 --prefix _
|
||||
endif
|
||||
ifeq ($(shell uname),Linux)
|
||||
NASM=nasm -felf64
|
||||
endif
|
||||
|
||||
all: modular_ml_components
|
||||
|
||||
%.o: %.cpp $(DEPS_HPP)
|
||||
$(CC) -c $< $(CFLAGS)
|
||||
|
||||
fr_asm.o: fr.asm
|
||||
$(NASM) fr.asm -o fr_asm.o
|
||||
|
||||
modular_ml_components: $(DEPS_O) modular_ml_components.o
|
||||
$(CC) -o modular_ml_components *.o -lgmp
|
||||
@@ -0,0 +1,127 @@
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
#include "calcwit.hpp"
|
||||
|
||||
extern void run(Circom_CalcWit* ctx);
|
||||
|
||||
std::string int_to_hex( u64 i )
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "0x"
|
||||
<< std::setfill ('0') << std::setw(16)
|
||||
<< std::hex << i;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
u64 fnv1a(std::string s) {
|
||||
u64 hash = 0xCBF29CE484222325LL;
|
||||
for(char& c : s) {
|
||||
hash ^= u64(c);
|
||||
hash *= 0x100000001B3LL;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
Circom_CalcWit::Circom_CalcWit (Circom_Circuit *aCircuit, uint maxTh) {
|
||||
circuit = aCircuit;
|
||||
inputSignalAssignedCounter = get_main_input_signal_no();
|
||||
inputSignalAssigned = new bool[inputSignalAssignedCounter];
|
||||
for (int i = 0; i< inputSignalAssignedCounter; i++) {
|
||||
inputSignalAssigned[i] = false;
|
||||
}
|
||||
signalValues = new FrElement[get_total_signal_no()];
|
||||
Fr_str2element(&signalValues[0], "1", 10);
|
||||
componentMemory = new Circom_Component[get_number_of_components()];
|
||||
circuitConstants = circuit ->circuitConstants;
|
||||
templateInsId2IOSignalInfo = circuit -> templateInsId2IOSignalInfo;
|
||||
busInsId2FieldInfo = circuit -> busInsId2FieldInfo;
|
||||
|
||||
maxThread = maxTh;
|
||||
|
||||
// parallelism
|
||||
numThread = 0;
|
||||
|
||||
}
|
||||
|
||||
Circom_CalcWit::~Circom_CalcWit() {
|
||||
// ...
|
||||
}
|
||||
|
||||
uint Circom_CalcWit::getInputSignalHashPosition(u64 h) {
|
||||
uint n = get_size_of_input_hashmap();
|
||||
uint pos = (uint)(h % (u64)n);
|
||||
if (circuit->InputHashMap[pos].hash!=h){
|
||||
uint inipos = pos;
|
||||
pos = (pos+1)%n;
|
||||
while (pos != inipos) {
|
||||
if (circuit->InputHashMap[pos].hash == h) return pos;
|
||||
if (circuit->InputHashMap[pos].signalid == 0) {
|
||||
fprintf(stderr, "Signal not found\n");
|
||||
assert(false);
|
||||
}
|
||||
pos = (pos+1)%n;
|
||||
}
|
||||
fprintf(stderr, "Signals not found\n");
|
||||
assert(false);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
void Circom_CalcWit::tryRunCircuit(){
|
||||
if (inputSignalAssignedCounter == 0) {
|
||||
run(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Circom_CalcWit::setInputSignal(u64 h, uint i, FrElement & val){
|
||||
if (inputSignalAssignedCounter == 0) {
|
||||
fprintf(stderr, "No more signals to be assigned\n");
|
||||
assert(false);
|
||||
}
|
||||
uint pos = getInputSignalHashPosition(h);
|
||||
if (i >= circuit->InputHashMap[pos].signalsize) {
|
||||
fprintf(stderr, "Input signal array access exceeds the size\n");
|
||||
assert(false);
|
||||
}
|
||||
|
||||
uint si = circuit->InputHashMap[pos].signalid+i;
|
||||
if (inputSignalAssigned[si-get_main_input_signal_start()]) {
|
||||
fprintf(stderr, "Signal assigned twice: %d\n", si);
|
||||
assert(false);
|
||||
}
|
||||
signalValues[si] = val;
|
||||
inputSignalAssigned[si-get_main_input_signal_start()] = true;
|
||||
inputSignalAssignedCounter--;
|
||||
tryRunCircuit();
|
||||
}
|
||||
|
||||
u64 Circom_CalcWit::getInputSignalSize(u64 h) {
|
||||
uint pos = getInputSignalHashPosition(h);
|
||||
return circuit->InputHashMap[pos].signalsize;
|
||||
}
|
||||
|
||||
std::string Circom_CalcWit::getTrace(u64 id_cmp){
|
||||
if (id_cmp == 0) return componentMemory[id_cmp].componentName;
|
||||
else{
|
||||
u64 id_father = componentMemory[id_cmp].idFather;
|
||||
std::string my_name = componentMemory[id_cmp].componentName;
|
||||
|
||||
return Circom_CalcWit::getTrace(id_father) + "." + my_name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::string Circom_CalcWit::generate_position_array(uint* dimensions, uint size_dimensions, uint index){
|
||||
std::string positions = "";
|
||||
|
||||
for (uint i = 0 ; i < size_dimensions; i++){
|
||||
uint last_pos = index % dimensions[size_dimensions -1 - i];
|
||||
index = index / dimensions[size_dimensions -1 - i];
|
||||
std::string new_pos = "[" + std::to_string(last_pos) + "]";
|
||||
positions = new_pos + positions;
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef CIRCOM_CALCWIT_H
|
||||
#define CIRCOM_CALCWIT_H
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#include "circom.hpp"
|
||||
#include "fr.hpp"
|
||||
|
||||
#define NMUTEXES 32 //512
|
||||
|
||||
u64 fnv1a(std::string s);
|
||||
|
||||
class Circom_CalcWit {
|
||||
|
||||
bool *inputSignalAssigned;
|
||||
uint inputSignalAssignedCounter;
|
||||
|
||||
Circom_Circuit *circuit;
|
||||
|
||||
public:
|
||||
|
||||
FrElement *signalValues;
|
||||
Circom_Component* componentMemory;
|
||||
FrElement* circuitConstants;
|
||||
std::map<u32,IOFieldDefPair> templateInsId2IOSignalInfo;
|
||||
IOFieldDefPair* busInsId2FieldInfo;
|
||||
std::string* listOfTemplateMessages;
|
||||
|
||||
// parallelism
|
||||
std::mutex numThreadMutex;
|
||||
std::condition_variable ntcvs;
|
||||
int numThread;
|
||||
|
||||
int maxThread;
|
||||
|
||||
// Functions called by the circuit
|
||||
Circom_CalcWit(Circom_Circuit *aCircuit, uint numTh = NMUTEXES);
|
||||
~Circom_CalcWit();
|
||||
|
||||
// Public functions
|
||||
void setInputSignal(u64 h, uint i, FrElement &val);
|
||||
void tryRunCircuit();
|
||||
|
||||
u64 getInputSignalSize(u64 h);
|
||||
|
||||
inline uint getRemaingInputsToBeSet() {
|
||||
return inputSignalAssignedCounter;
|
||||
}
|
||||
|
||||
inline void getWitness(uint idx, PFrElement val) {
|
||||
Fr_copy(val, &signalValues[circuit->witness2SignalList[idx]]);
|
||||
}
|
||||
|
||||
std::string getTrace(u64 id_cmp);
|
||||
|
||||
std::string generate_position_array(uint* dimensions, uint size_dimensions, uint index);
|
||||
|
||||
private:
|
||||
|
||||
uint getInputSignalHashPosition(u64 h);
|
||||
|
||||
};
|
||||
|
||||
typedef void (*Circom_TemplateFunction)(uint __cIdx, Circom_CalcWit* __ctx);
|
||||
|
||||
#endif // CIRCOM_CALCWIT_H
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef __CIRCOM_H
|
||||
#define __CIRCOM_H
|
||||
|
||||
#include <map>
|
||||
#include <gmp.h>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
|
||||
#include "fr.hpp"
|
||||
|
||||
typedef unsigned long long u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint8_t u8;
|
||||
|
||||
//only for the main inputs
|
||||
struct __attribute__((__packed__)) HashSignalInfo {
|
||||
u64 hash;
|
||||
u64 signalid;
|
||||
u64 signalsize;
|
||||
};
|
||||
|
||||
struct IOFieldDef {
|
||||
u32 offset;
|
||||
u32 len;
|
||||
u32 *lengths;
|
||||
u32 size;
|
||||
u32 busId;
|
||||
};
|
||||
|
||||
struct IOFieldDefPair {
|
||||
u32 len;
|
||||
IOFieldDef* defs;
|
||||
};
|
||||
|
||||
struct Circom_Circuit {
|
||||
// const char *P;
|
||||
HashSignalInfo* InputHashMap;
|
||||
u64* witness2SignalList;
|
||||
FrElement* circuitConstants;
|
||||
std::map<u32,IOFieldDefPair> templateInsId2IOSignalInfo;
|
||||
IOFieldDefPair* busInsId2FieldInfo;
|
||||
};
|
||||
|
||||
|
||||
struct Circom_Component {
|
||||
u32 templateId;
|
||||
u64 signalStart;
|
||||
u32 inputCounter;
|
||||
std::string templateName;
|
||||
std::string componentName;
|
||||
u64 idFather;
|
||||
u32* subcomponents = NULL;
|
||||
bool* subcomponentsParallel = NULL;
|
||||
bool *outputIsSet = NULL; //one for each output
|
||||
std::mutex *mutexes = NULL; //one for each output
|
||||
std::condition_variable *cvs = NULL;
|
||||
std::thread *sbct = NULL;//subcomponent threads
|
||||
};
|
||||
|
||||
/*
|
||||
For every template instantiation create two functions:
|
||||
- name_create
|
||||
- name_run
|
||||
|
||||
//PFrElement: pointer to FrElement
|
||||
|
||||
Every name_run or circom_function has:
|
||||
=====================================
|
||||
|
||||
//array of PFrElements for auxiliars in expression computation (known size);
|
||||
PFrElements expaux[];
|
||||
|
||||
//array of PFrElements for local vars (known size)
|
||||
PFrElements lvar[];
|
||||
|
||||
*/
|
||||
|
||||
uint get_main_input_signal_start();
|
||||
uint get_main_input_signal_no();
|
||||
uint get_total_signal_no();
|
||||
uint get_number_of_components();
|
||||
uint get_size_of_input_hashmap();
|
||||
uint get_size_of_witness();
|
||||
uint get_size_of_constants();
|
||||
uint get_size_of_io_map();
|
||||
uint get_size_of_bus_field_map();
|
||||
|
||||
#endif // __CIRCOM_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,321 @@
|
||||
#include "fr.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmp.h>
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
static mpz_t q;
|
||||
static mpz_t zero;
|
||||
static mpz_t one;
|
||||
static mpz_t mask;
|
||||
static size_t nBits;
|
||||
static bool initialized = false;
|
||||
|
||||
|
||||
void Fr_toMpz(mpz_t r, PFrElement pE) {
|
||||
FrElement tmp;
|
||||
Fr_toNormal(&tmp, pE);
|
||||
if (!(tmp.type & Fr_LONG)) {
|
||||
mpz_set_si(r, tmp.shortVal);
|
||||
if (tmp.shortVal<0) {
|
||||
mpz_add(r, r, q);
|
||||
}
|
||||
} else {
|
||||
mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)tmp.longVal);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_fromMpz(PFrElement pE, mpz_t v) {
|
||||
if (mpz_fits_sint_p(v)) {
|
||||
pE->type = Fr_SHORT;
|
||||
pE->shortVal = mpz_get_si(v);
|
||||
} else {
|
||||
pE->type = Fr_LONG;
|
||||
for (int i=0; i<Fr_N64; i++) pE->longVal[i] = 0;
|
||||
mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Fr_init() {
|
||||
if (initialized) return false;
|
||||
initialized = true;
|
||||
mpz_init(q);
|
||||
mpz_import(q, Fr_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
|
||||
mpz_init_set_ui(zero, 0);
|
||||
mpz_init_set_ui(one, 1);
|
||||
nBits = mpz_sizeinbase (q, 2);
|
||||
mpz_init(mask);
|
||||
mpz_mul_2exp(mask, one, nBits);
|
||||
mpz_sub(mask, mask, one);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Fr_str2element(PFrElement pE, char const *s, uint base) {
|
||||
mpz_t mr;
|
||||
mpz_init_set_str(mr, s, base);
|
||||
mpz_fdiv_r(mr, mr, q);
|
||||
Fr_fromMpz(pE, mr);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
char *Fr_element2str(PFrElement pE) {
|
||||
FrElement tmp;
|
||||
mpz_t r;
|
||||
if (!(pE->type & Fr_LONG)) {
|
||||
if (pE->shortVal>=0) {
|
||||
char *r = new char[32];
|
||||
sprintf(r, "%d", pE->shortVal);
|
||||
return r;
|
||||
} else {
|
||||
mpz_init_set_si(r, pE->shortVal);
|
||||
mpz_add(r, r, q);
|
||||
}
|
||||
} else {
|
||||
Fr_toNormal(&tmp, pE);
|
||||
mpz_init(r);
|
||||
mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)tmp.longVal);
|
||||
}
|
||||
char *res = mpz_get_str (0, 10, r);
|
||||
mpz_clear(r);
|
||||
return res;
|
||||
}
|
||||
|
||||
void Fr_idiv(PFrElement r, PFrElement a, PFrElement b) {
|
||||
mpz_t ma;
|
||||
mpz_t mb;
|
||||
mpz_t mr;
|
||||
mpz_init(ma);
|
||||
mpz_init(mb);
|
||||
mpz_init(mr);
|
||||
|
||||
Fr_toMpz(ma, a);
|
||||
// char *s1 = mpz_get_str (0, 10, ma);
|
||||
// printf("s1 %s\n", s1);
|
||||
Fr_toMpz(mb, b);
|
||||
// char *s2 = mpz_get_str (0, 10, mb);
|
||||
// printf("s2 %s\n", s2);
|
||||
mpz_fdiv_q(mr, ma, mb);
|
||||
// char *sr = mpz_get_str (0, 10, mr);
|
||||
// printf("r %s\n", sr);
|
||||
Fr_fromMpz(r, mr);
|
||||
|
||||
mpz_clear(ma);
|
||||
mpz_clear(mb);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
void Fr_mod(PFrElement r, PFrElement a, PFrElement b) {
|
||||
mpz_t ma;
|
||||
mpz_t mb;
|
||||
mpz_t mr;
|
||||
mpz_init(ma);
|
||||
mpz_init(mb);
|
||||
mpz_init(mr);
|
||||
|
||||
Fr_toMpz(ma, a);
|
||||
Fr_toMpz(mb, b);
|
||||
mpz_fdiv_r(mr, ma, mb);
|
||||
Fr_fromMpz(r, mr);
|
||||
|
||||
mpz_clear(ma);
|
||||
mpz_clear(mb);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
void Fr_pow(PFrElement r, PFrElement a, PFrElement b) {
|
||||
mpz_t ma;
|
||||
mpz_t mb;
|
||||
mpz_t mr;
|
||||
mpz_init(ma);
|
||||
mpz_init(mb);
|
||||
mpz_init(mr);
|
||||
|
||||
Fr_toMpz(ma, a);
|
||||
Fr_toMpz(mb, b);
|
||||
mpz_powm(mr, ma, mb, q);
|
||||
Fr_fromMpz(r, mr);
|
||||
|
||||
mpz_clear(ma);
|
||||
mpz_clear(mb);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
void Fr_inv(PFrElement r, PFrElement a) {
|
||||
mpz_t ma;
|
||||
mpz_t mr;
|
||||
mpz_init(ma);
|
||||
mpz_init(mr);
|
||||
|
||||
Fr_toMpz(ma, a);
|
||||
mpz_invert(mr, ma, q);
|
||||
Fr_fromMpz(r, mr);
|
||||
mpz_clear(ma);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
void Fr_div(PFrElement r, PFrElement a, PFrElement b) {
|
||||
FrElement tmp;
|
||||
Fr_inv(&tmp, b);
|
||||
Fr_mul(r, a, &tmp);
|
||||
}
|
||||
|
||||
void Fr_fail() {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
RawFr::RawFr() {
|
||||
Fr_init();
|
||||
set(fZero, 0);
|
||||
set(fOne, 1);
|
||||
neg(fNegOne, fOne);
|
||||
}
|
||||
|
||||
RawFr::~RawFr() {
|
||||
}
|
||||
|
||||
void RawFr::fromString(Element &r, const std::string &s, uint32_t radix) {
|
||||
mpz_t mr;
|
||||
mpz_init_set_str(mr, s.c_str(), radix);
|
||||
mpz_fdiv_r(mr, mr, q);
|
||||
for (int i=0; i<Fr_N64; i++) r.v[i] = 0;
|
||||
mpz_export((void *)(r.v), NULL, -1, 8, -1, 0, mr);
|
||||
Fr_rawToMontgomery(r.v,r.v);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
void RawFr::fromUI(Element &r, unsigned long int v) {
|
||||
mpz_t mr;
|
||||
mpz_init(mr);
|
||||
mpz_set_ui(mr, v);
|
||||
for (int i=0; i<Fr_N64; i++) r.v[i] = 0;
|
||||
mpz_export((void *)(r.v), NULL, -1, 8, -1, 0, mr);
|
||||
Fr_rawToMontgomery(r.v,r.v);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
RawFr::Element RawFr::set(int value) {
|
||||
Element r;
|
||||
set(r, value);
|
||||
return r;
|
||||
}
|
||||
|
||||
void RawFr::set(Element &r, int value) {
|
||||
mpz_t mr;
|
||||
mpz_init(mr);
|
||||
mpz_set_si(mr, value);
|
||||
if (value < 0) {
|
||||
mpz_add(mr, mr, q);
|
||||
}
|
||||
|
||||
mpz_export((void *)(r.v), NULL, -1, 8, -1, 0, mr);
|
||||
|
||||
for (int i=0; i<Fr_N64; i++) r.v[i] = 0;
|
||||
mpz_export((void *)(r.v), NULL, -1, 8, -1, 0, mr);
|
||||
Fr_rawToMontgomery(r.v,r.v);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
std::string RawFr::toString(const Element &a, uint32_t radix) {
|
||||
Element tmp;
|
||||
mpz_t r;
|
||||
Fr_rawFromMontgomery(tmp.v, a.v);
|
||||
mpz_init(r);
|
||||
mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)(tmp.v));
|
||||
char *res = mpz_get_str (0, radix, r);
|
||||
mpz_clear(r);
|
||||
std::string resS(res);
|
||||
free(res);
|
||||
return resS;
|
||||
}
|
||||
|
||||
void RawFr::inv(Element &r, const Element &a) {
|
||||
mpz_t mr;
|
||||
mpz_init(mr);
|
||||
mpz_import(mr, Fr_N64, -1, 8, -1, 0, (const void *)(a.v));
|
||||
mpz_invert(mr, mr, q);
|
||||
|
||||
|
||||
for (int i=0; i<Fr_N64; i++) r.v[i] = 0;
|
||||
mpz_export((void *)(r.v), NULL, -1, 8, -1, 0, mr);
|
||||
|
||||
Fr_rawMMul(r.v, r.v,Fr_rawR3);
|
||||
mpz_clear(mr);
|
||||
}
|
||||
|
||||
void RawFr::div(Element &r, const Element &a, const Element &b) {
|
||||
Element tmp;
|
||||
inv(tmp, b);
|
||||
mul(r, a, tmp);
|
||||
}
|
||||
|
||||
#define BIT_IS_SET(s, p) (s[p>>3] & (1 << (p & 0x7)))
|
||||
void RawFr::exp(Element &r, const Element &base, uint8_t* scalar, unsigned int scalarSize) {
|
||||
bool oneFound = false;
|
||||
Element copyBase;
|
||||
copy(copyBase, base);
|
||||
for (int i=scalarSize*8-1; i>=0; i--) {
|
||||
if (!oneFound) {
|
||||
if ( !BIT_IS_SET(scalar, i) ) continue;
|
||||
copy(r, copyBase);
|
||||
oneFound = true;
|
||||
continue;
|
||||
}
|
||||
square(r, r);
|
||||
if ( BIT_IS_SET(scalar, i) ) {
|
||||
mul(r, r, copyBase);
|
||||
}
|
||||
}
|
||||
if (!oneFound) {
|
||||
copy(r, fOne);
|
||||
}
|
||||
}
|
||||
|
||||
void RawFr::toMpz(mpz_t r, const Element &a) {
|
||||
Element tmp;
|
||||
Fr_rawFromMontgomery(tmp.v, a.v);
|
||||
mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)tmp.v);
|
||||
}
|
||||
|
||||
void RawFr::fromMpz(Element &r, const mpz_t a) {
|
||||
for (int i=0; i<Fr_N64; i++) r.v[i] = 0;
|
||||
mpz_export((void *)(r.v), NULL, -1, 8, -1, 0, a);
|
||||
Fr_rawToMontgomery(r.v, r.v);
|
||||
}
|
||||
|
||||
int RawFr::toRprBE(const Element &element, uint8_t *data, int bytes)
|
||||
{
|
||||
if (bytes < Fr_N64 * 8) {
|
||||
return -(Fr_N64 * 8);
|
||||
}
|
||||
|
||||
mpz_t r;
|
||||
mpz_init(r);
|
||||
|
||||
toMpz(r, element);
|
||||
|
||||
mpz_export(data, NULL, 1, 8, 1, 0, r);
|
||||
|
||||
return Fr_N64 * 8;
|
||||
}
|
||||
|
||||
int RawFr::fromRprBE(Element &element, const uint8_t *data, int bytes)
|
||||
{
|
||||
if (bytes < Fr_N64 * 8) {
|
||||
return -(Fr_N64* 8);
|
||||
}
|
||||
mpz_t r;
|
||||
mpz_init(r);
|
||||
|
||||
mpz_import(r, Fr_N64 * 8, 0, 1, 0, 0, data);
|
||||
fromMpz(element, r);
|
||||
return Fr_N64 * 8;
|
||||
}
|
||||
|
||||
static bool init = Fr_init();
|
||||
|
||||
RawFr RawFr::field;
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
#ifndef __FR_H
|
||||
#define __FR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <gmp.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/types.h> // typedef unsigned int uint;
|
||||
#endif // __APPLE__
|
||||
|
||||
#define Fr_N64 4
|
||||
#define Fr_SHORT 0x00000000
|
||||
#define Fr_LONG 0x80000000
|
||||
#define Fr_LONGMONTGOMERY 0xC0000000
|
||||
typedef uint64_t FrRawElement[Fr_N64];
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
int32_t shortVal;
|
||||
uint32_t type;
|
||||
FrRawElement longVal;
|
||||
} FrElement;
|
||||
typedef FrElement *PFrElement;
|
||||
extern FrElement Fr_q;
|
||||
extern FrElement Fr_R3;
|
||||
extern FrRawElement Fr_rawq;
|
||||
extern FrRawElement Fr_rawR3;
|
||||
|
||||
extern "C" void Fr_copy(PFrElement r, PFrElement a);
|
||||
extern "C" void Fr_copyn(PFrElement r, PFrElement a, int n);
|
||||
extern "C" void Fr_add(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_sub(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_neg(PFrElement r, PFrElement a);
|
||||
extern "C" void Fr_mul(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_square(PFrElement r, PFrElement a);
|
||||
extern "C" void Fr_band(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_bor(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_bxor(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_bnot(PFrElement r, PFrElement a);
|
||||
extern "C" void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_eq(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_neq(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_lt(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_gt(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_leq(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_geq(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_land(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_lor(PFrElement r, PFrElement a, PFrElement b);
|
||||
extern "C" void Fr_lnot(PFrElement r, PFrElement a);
|
||||
extern "C" void Fr_toNormal(PFrElement r, PFrElement a);
|
||||
extern "C" void Fr_toLongNormal(PFrElement r, PFrElement a);
|
||||
extern "C" void Fr_toMontgomery(PFrElement r, PFrElement a);
|
||||
|
||||
extern "C" int Fr_isTrue(PFrElement pE);
|
||||
extern "C" int Fr_toInt(PFrElement pE);
|
||||
|
||||
extern "C" void Fr_rawCopy(FrRawElement pRawResult, const FrRawElement pRawA);
|
||||
extern "C" void Fr_rawSwap(FrRawElement pRawResult, FrRawElement pRawA);
|
||||
extern "C" void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
extern "C" void Fr_rawSub(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
extern "C" void Fr_rawNeg(FrRawElement pRawResult, const FrRawElement pRawA);
|
||||
extern "C" void Fr_rawMMul(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
extern "C" void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA);
|
||||
extern "C" void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB);
|
||||
extern "C" void Fr_rawToMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
|
||||
extern "C" void Fr_rawFromMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
|
||||
extern "C" int Fr_rawIsEq(const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
extern "C" int Fr_rawIsZero(const FrRawElement pRawB);
|
||||
|
||||
extern "C" void Fr_fail();
|
||||
|
||||
|
||||
// Pending functions to convert
|
||||
|
||||
void Fr_str2element(PFrElement pE, char const*s, uint base);
|
||||
char *Fr_element2str(PFrElement pE);
|
||||
void Fr_idiv(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_mod(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_inv(PFrElement r, PFrElement a);
|
||||
void Fr_div(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_pow(PFrElement r, PFrElement a, PFrElement b);
|
||||
|
||||
class RawFr {
|
||||
|
||||
public:
|
||||
const static int N64 = Fr_N64;
|
||||
const static int MaxBits = 254;
|
||||
|
||||
|
||||
struct Element {
|
||||
FrRawElement v;
|
||||
};
|
||||
|
||||
private:
|
||||
Element fZero;
|
||||
Element fOne;
|
||||
Element fNegOne;
|
||||
|
||||
public:
|
||||
|
||||
RawFr();
|
||||
~RawFr();
|
||||
|
||||
const Element &zero() { return fZero; };
|
||||
const Element &one() { return fOne; };
|
||||
const Element &negOne() { return fNegOne; };
|
||||
Element set(int value);
|
||||
void set(Element &r, int value);
|
||||
|
||||
void fromString(Element &r, const std::string &n, uint32_t radix = 10);
|
||||
std::string toString(const Element &a, uint32_t radix = 10);
|
||||
|
||||
void inline copy(Element &r, const Element &a) { Fr_rawCopy(r.v, a.v); };
|
||||
void inline swap(Element &a, Element &b) { Fr_rawSwap(a.v, b.v); };
|
||||
void inline add(Element &r, const Element &a, const Element &b) { Fr_rawAdd(r.v, a.v, b.v); };
|
||||
void inline sub(Element &r, const Element &a, const Element &b) { Fr_rawSub(r.v, a.v, b.v); };
|
||||
void inline mul(Element &r, const Element &a, const Element &b) { Fr_rawMMul(r.v, a.v, b.v); };
|
||||
|
||||
Element inline add(const Element &a, const Element &b) { Element r; Fr_rawAdd(r.v, a.v, b.v); return r;};
|
||||
Element inline sub(const Element &a, const Element &b) { Element r; Fr_rawSub(r.v, a.v, b.v); return r;};
|
||||
Element inline mul(const Element &a, const Element &b) { Element r; Fr_rawMMul(r.v, a.v, b.v); return r;};
|
||||
|
||||
Element inline neg(const Element &a) { Element r; Fr_rawNeg(r.v, a.v); return r; };
|
||||
Element inline square(const Element &a) { Element r; Fr_rawMSquare(r.v, a.v); return r; };
|
||||
|
||||
Element inline add(int a, const Element &b) { return add(set(a), b);};
|
||||
Element inline sub(int a, const Element &b) { return sub(set(a), b);};
|
||||
Element inline mul(int a, const Element &b) { return mul(set(a), b);};
|
||||
|
||||
Element inline add(const Element &a, int b) { return add(a, set(b));};
|
||||
Element inline sub(const Element &a, int b) { return sub(a, set(b));};
|
||||
Element inline mul(const Element &a, int b) { return mul(a, set(b));};
|
||||
|
||||
void inline mul1(Element &r, const Element &a, uint64_t b) { Fr_rawMMul1(r.v, a.v, b); };
|
||||
void inline neg(Element &r, const Element &a) { Fr_rawNeg(r.v, a.v); };
|
||||
void inline square(Element &r, const Element &a) { Fr_rawMSquare(r.v, a.v); };
|
||||
void inv(Element &r, const Element &a);
|
||||
void div(Element &r, const Element &a, const Element &b);
|
||||
void exp(Element &r, const Element &base, uint8_t* scalar, unsigned int scalarSize);
|
||||
|
||||
void inline toMontgomery(Element &r, const Element &a) { Fr_rawToMontgomery(r.v, a.v); };
|
||||
void inline fromMontgomery(Element &r, const Element &a) { Fr_rawFromMontgomery(r.v, a.v); };
|
||||
int inline eq(const Element &a, const Element &b) { return Fr_rawIsEq(a.v, b.v); };
|
||||
int inline isZero(const Element &a) { return Fr_rawIsZero(a.v); };
|
||||
|
||||
void toMpz(mpz_t r, const Element &a);
|
||||
void fromMpz(Element &a, const mpz_t r);
|
||||
|
||||
int toRprBE(const Element &element, uint8_t *data, int bytes);
|
||||
int fromRprBE(Element &element, const uint8_t *data, int bytes);
|
||||
|
||||
int bytes ( void ) { return Fr_N64 * 8; };
|
||||
|
||||
void fromUI(Element &r, unsigned long int v);
|
||||
|
||||
static RawFr field;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __FR_H
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,374 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
#include "calcwit.hpp"
|
||||
#include "circom.hpp"
|
||||
|
||||
|
||||
#define handle_error(msg) \
|
||||
do { perror(msg); exit(EXIT_FAILURE); } while (0)
|
||||
|
||||
Circom_Circuit* loadCircuit(std::string const &datFileName) {
|
||||
Circom_Circuit *circuit = new Circom_Circuit;
|
||||
|
||||
int fd;
|
||||
struct stat sb;
|
||||
|
||||
fd = open(datFileName.c_str(), O_RDONLY);
|
||||
if (fd == -1) {
|
||||
std::cout << ".dat file not found: " << datFileName << "\n";
|
||||
throw std::system_error(errno, std::generic_category(), "open");
|
||||
}
|
||||
|
||||
if (fstat(fd, &sb) == -1) { /* To obtain file size */
|
||||
throw std::system_error(errno, std::generic_category(), "fstat");
|
||||
}
|
||||
|
||||
u8* bdata = (u8*)mmap(NULL, sb.st_size, PROT_READ , MAP_PRIVATE, fd, 0);
|
||||
close(fd);
|
||||
|
||||
circuit->InputHashMap = new HashSignalInfo[get_size_of_input_hashmap()];
|
||||
uint dsize = get_size_of_input_hashmap()*sizeof(HashSignalInfo);
|
||||
memcpy((void *)(circuit->InputHashMap), (void *)bdata, dsize);
|
||||
|
||||
circuit->witness2SignalList = new u64[get_size_of_witness()];
|
||||
uint inisize = dsize;
|
||||
dsize = get_size_of_witness()*sizeof(u64);
|
||||
memcpy((void *)(circuit->witness2SignalList), (void *)(bdata+inisize), dsize);
|
||||
|
||||
circuit->circuitConstants = new FrElement[get_size_of_constants()];
|
||||
if (get_size_of_constants()>0) {
|
||||
inisize += dsize;
|
||||
dsize = get_size_of_constants()*sizeof(FrElement);
|
||||
memcpy((void *)(circuit->circuitConstants), (void *)(bdata+inisize), dsize);
|
||||
}
|
||||
|
||||
std::map<u32,IOFieldDefPair> templateInsId2IOSignalInfo1;
|
||||
IOFieldDefPair* busInsId2FieldInfo1;
|
||||
if (get_size_of_io_map()>0) {
|
||||
u32 index[get_size_of_io_map()];
|
||||
inisize += dsize;
|
||||
dsize = get_size_of_io_map()*sizeof(u32);
|
||||
memcpy((void *)index, (void *)(bdata+inisize), dsize);
|
||||
inisize += dsize;
|
||||
assert(inisize % sizeof(u32) == 0);
|
||||
assert(sb.st_size % sizeof(u32) == 0);
|
||||
u32 dataiomap[(sb.st_size-inisize)/sizeof(u32)];
|
||||
memcpy((void *)dataiomap, (void *)(bdata+inisize), sb.st_size-inisize);
|
||||
u32* pu32 = dataiomap;
|
||||
for (int i = 0; i < get_size_of_io_map(); i++) {
|
||||
u32 n = *pu32;
|
||||
IOFieldDefPair p;
|
||||
p.len = n;
|
||||
IOFieldDef defs[n];
|
||||
pu32 += 1;
|
||||
for (u32 j = 0; j <n; j++){
|
||||
defs[j].offset=*pu32;
|
||||
u32 len = *(pu32+1);
|
||||
defs[j].len = len;
|
||||
defs[j].lengths = new u32[len];
|
||||
memcpy((void *)defs[j].lengths,(void *)(pu32+2),len*sizeof(u32));
|
||||
pu32 += len + 2;
|
||||
defs[j].size=*pu32;
|
||||
defs[j].busId=*(pu32+1);
|
||||
pu32 += 2;
|
||||
}
|
||||
p.defs = (IOFieldDef*)calloc(p.len, sizeof(IOFieldDef));
|
||||
for (u32 j = 0; j < p.len; j++){
|
||||
p.defs[j] = defs[j];
|
||||
}
|
||||
templateInsId2IOSignalInfo1[index[i]] = p;
|
||||
}
|
||||
busInsId2FieldInfo1 = (IOFieldDefPair*)calloc(get_size_of_bus_field_map(), sizeof(IOFieldDefPair));
|
||||
for (int i = 0; i < get_size_of_bus_field_map(); i++) {
|
||||
u32 n = *pu32;
|
||||
IOFieldDefPair p;
|
||||
p.len = n;
|
||||
IOFieldDef defs[n];
|
||||
pu32 += 1;
|
||||
for (u32 j = 0; j <n; j++){
|
||||
defs[j].offset=*pu32;
|
||||
u32 len = *(pu32+1);
|
||||
defs[j].len = len;
|
||||
defs[j].lengths = new u32[len];
|
||||
memcpy((void *)defs[j].lengths,(void *)(pu32+2),len*sizeof(u32));
|
||||
pu32 += len + 2;
|
||||
defs[j].size=*pu32;
|
||||
defs[j].busId=*(pu32+1);
|
||||
pu32 += 2;
|
||||
}
|
||||
p.defs = (IOFieldDef*)calloc(10, sizeof(IOFieldDef));
|
||||
for (u32 j = 0; j < p.len; j++){
|
||||
p.defs[j] = defs[j];
|
||||
}
|
||||
busInsId2FieldInfo1[i] = p;
|
||||
}
|
||||
}
|
||||
circuit->templateInsId2IOSignalInfo = move(templateInsId2IOSignalInfo1);
|
||||
circuit->busInsId2FieldInfo = busInsId2FieldInfo1;
|
||||
|
||||
munmap(bdata, sb.st_size);
|
||||
|
||||
return circuit;
|
||||
}
|
||||
|
||||
bool check_valid_number(std::string & s, uint base){
|
||||
bool is_valid = true;
|
||||
if (base == 16){
|
||||
for (uint i = 0; i < s.size(); i++){
|
||||
is_valid &= (
|
||||
('0' <= s[i] && s[i] <= '9') ||
|
||||
('a' <= s[i] && s[i] <= 'f') ||
|
||||
('A' <= s[i] && s[i] <= 'F')
|
||||
);
|
||||
}
|
||||
} else{
|
||||
for (uint i = 0; i < s.size(); i++){
|
||||
is_valid &= ('0' <= s[i] && s[i] < char(int('0') + base));
|
||||
}
|
||||
}
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
void json2FrElements (json val, std::vector<FrElement> & vval){
|
||||
if (!val.is_array()) {
|
||||
FrElement v;
|
||||
std::string s_aux, s;
|
||||
uint base;
|
||||
if (val.is_string()) {
|
||||
s_aux = val.get<std::string>();
|
||||
std::string possible_prefix = s_aux.substr(0, 2);
|
||||
if (possible_prefix == "0b" || possible_prefix == "0B"){
|
||||
s = s_aux.substr(2, s_aux.size() - 2);
|
||||
base = 2;
|
||||
} else if (possible_prefix == "0o" || possible_prefix == "0O"){
|
||||
s = s_aux.substr(2, s_aux.size() - 2);
|
||||
base = 8;
|
||||
} else if (possible_prefix == "0x" || possible_prefix == "0X"){
|
||||
s = s_aux.substr(2, s_aux.size() - 2);
|
||||
base = 16;
|
||||
} else{
|
||||
s = s_aux;
|
||||
base = 10;
|
||||
}
|
||||
if (!check_valid_number(s, base)){
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Invalid number in JSON input: " << s_aux << "\n";
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
} else if (val.is_number()) {
|
||||
double vd = val.get<double>();
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(0) << vd;
|
||||
s = stream.str();
|
||||
base = 10;
|
||||
} else {
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Invalid JSON type\n";
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
Fr_str2element (&v, s.c_str(), base);
|
||||
vval.push_back(v);
|
||||
} else {
|
||||
for (uint i = 0; i < val.size(); i++) {
|
||||
json2FrElements (val[i], vval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json::value_t check_type(std::string prefix, json in){
|
||||
if (not in.is_array()) {
|
||||
if (in.is_number_integer() || in.is_number_unsigned() || in.is_string())
|
||||
return json::value_t::number_integer;
|
||||
else return in.type();
|
||||
} else {
|
||||
if (in.size() == 0) return json::value_t::null;
|
||||
json::value_t t = check_type(prefix, in[0]);
|
||||
for (uint i = 1; i < in.size(); i++) {
|
||||
if (t != check_type(prefix, in[i])) {
|
||||
fprintf(stderr, "Types are not the same in the key %s\n",prefix.c_str());
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
void qualify_input(std::string prefix, json &in, json &in1);
|
||||
|
||||
void qualify_input_list(std::string prefix, json &in, json &in1){
|
||||
if (in.is_array()) {
|
||||
for (uint i = 0; i<in.size(); i++) {
|
||||
std::string new_prefix = prefix + "[" + std::to_string(i) + "]";
|
||||
qualify_input_list(new_prefix,in[i],in1);
|
||||
}
|
||||
} else {
|
||||
qualify_input(prefix,in,in1);
|
||||
}
|
||||
}
|
||||
|
||||
void qualify_input(std::string prefix, json &in, json &in1) {
|
||||
if (in.is_array()) {
|
||||
if (in.size() > 0) {
|
||||
json::value_t t = check_type(prefix,in);
|
||||
if (t == json::value_t::object) {
|
||||
qualify_input_list(prefix,in,in1);
|
||||
} else {
|
||||
in1[prefix] = in;
|
||||
}
|
||||
} else {
|
||||
in1[prefix] = in;
|
||||
}
|
||||
} else if (in.is_object()) {
|
||||
for (json::iterator it = in.begin(); it != in.end(); ++it) {
|
||||
std::string new_prefix = prefix.length() == 0 ? it.key() : prefix + "." + it.key();
|
||||
qualify_input(new_prefix,it.value(),in1);
|
||||
}
|
||||
} else {
|
||||
in1[prefix] = in;
|
||||
}
|
||||
}
|
||||
|
||||
void loadJson(Circom_CalcWit *ctx, std::string filename) {
|
||||
std::ifstream inStream(filename);
|
||||
json jin;
|
||||
inStream >> jin;
|
||||
json j;
|
||||
|
||||
//std::cout << jin << std::endl;
|
||||
std::string prefix = "";
|
||||
qualify_input(prefix, jin, j);
|
||||
//std::cout << j << std::endl;
|
||||
|
||||
u64 nItems = j.size();
|
||||
// printf("Items : %llu\n",nItems);
|
||||
if (nItems == 0){
|
||||
ctx->tryRunCircuit();
|
||||
}
|
||||
for (json::iterator it = j.begin(); it != j.end(); ++it) {
|
||||
// std::cout << it.key() << " => " << it.value() << '\n';
|
||||
u64 h = fnv1a(it.key());
|
||||
std::vector<FrElement> v;
|
||||
json2FrElements(it.value(),v);
|
||||
uint signalSize = ctx->getInputSignalSize(h);
|
||||
if (v.size() < signalSize) {
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Error loading signal " << it.key() << ": Not enough values\n";
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
if (v.size() > signalSize) {
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Error loading signal " << it.key() << ": Too many values\n";
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
for (uint i = 0; i<v.size(); i++){
|
||||
try {
|
||||
// std::cout << it.key() << "," << i << " => " << Fr_element2str(&(v[i])) << '\n';
|
||||
ctx->setInputSignal(h,i,v[i]);
|
||||
} catch (std::runtime_error e) {
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Error setting signal: " << it.key() << "\n" << e.what();
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeBinWitness(Circom_CalcWit *ctx, std::string wtnsFileName) {
|
||||
FILE *write_ptr;
|
||||
|
||||
write_ptr = fopen(wtnsFileName.c_str(),"wb");
|
||||
|
||||
fwrite("wtns", 4, 1, write_ptr);
|
||||
|
||||
u32 version = 2;
|
||||
fwrite(&version, 4, 1, write_ptr);
|
||||
|
||||
u32 nSections = 2;
|
||||
fwrite(&nSections, 4, 1, write_ptr);
|
||||
|
||||
// Header
|
||||
u32 idSection1 = 1;
|
||||
fwrite(&idSection1, 4, 1, write_ptr);
|
||||
|
||||
u32 n8 = Fr_N64*8;
|
||||
|
||||
u64 idSection1length = 8 + n8;
|
||||
fwrite(&idSection1length, 8, 1, write_ptr);
|
||||
|
||||
fwrite(&n8, 4, 1, write_ptr);
|
||||
|
||||
fwrite(Fr_q.longVal, Fr_N64*8, 1, write_ptr);
|
||||
|
||||
uint Nwtns = get_size_of_witness();
|
||||
|
||||
u32 nVars = (u32)Nwtns;
|
||||
fwrite(&nVars, 4, 1, write_ptr);
|
||||
|
||||
// Data
|
||||
u32 idSection2 = 2;
|
||||
fwrite(&idSection2, 4, 1, write_ptr);
|
||||
|
||||
u64 idSection2length = (u64)n8*(u64)Nwtns;
|
||||
fwrite(&idSection2length, 8, 1, write_ptr);
|
||||
|
||||
FrElement v;
|
||||
|
||||
for (int i=0;i<Nwtns;i++) {
|
||||
ctx->getWitness(i, &v);
|
||||
Fr_toLongNormal(&v, &v);
|
||||
fwrite(v.longVal, Fr_N64*8, 1, write_ptr);
|
||||
}
|
||||
fclose(write_ptr);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
std::string cl(argv[0]);
|
||||
if (argc!=3) {
|
||||
std::cout << "Usage: " << cl << " <input.json> <output.wtns>\n";
|
||||
} else {
|
||||
std::string datfile = cl + ".dat";
|
||||
std::string jsonfile(argv[1]);
|
||||
std::string wtnsfile(argv[2]);
|
||||
|
||||
// auto t_start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
Circom_Circuit *circuit = loadCircuit(datfile);
|
||||
|
||||
Circom_CalcWit *ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
loadJson(ctx, jsonfile);
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
std::cerr << "Not all inputs have been set. Only " << get_main_input_signal_no()-ctx->getRemaingInputsToBeSet() << " out of " << get_main_input_signal_no() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
/*
|
||||
for (uint i = 0; i<get_size_of_witness(); i++){
|
||||
FrElement x;
|
||||
ctx->getWitness(i, &x);
|
||||
std::cout << i << ": " << Fr_element2str(&x) << std::endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//auto t_mid = std::chrono::high_resolution_clock::now();
|
||||
//std::cout << std::chrono::duration<double, std::milli>(t_mid-t_start).count()<<std::endl;
|
||||
|
||||
writeBinWitness(ctx,wtnsfile);
|
||||
|
||||
//auto t_end = std::chrono::high_resolution_clock::now();
|
||||
//std::cout << std::chrono::duration<double, std::milli>(t_end-t_mid).count()<<std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,618 @@
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include "circom.hpp"
|
||||
#include "calcwit.hpp"
|
||||
void LearningRateValidation_0_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather);
|
||||
void LearningRateValidation_0_run(uint ctx_index,Circom_CalcWit* ctx);
|
||||
void ParameterUpdate_1_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather);
|
||||
void ParameterUpdate_1_run(uint ctx_index,Circom_CalcWit* ctx);
|
||||
void VectorParameterUpdate_2_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather);
|
||||
void VectorParameterUpdate_2_run(uint ctx_index,Circom_CalcWit* ctx);
|
||||
void TrainingEpoch_3_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather);
|
||||
void TrainingEpoch_3_run(uint ctx_index,Circom_CalcWit* ctx);
|
||||
void ModularTrainingVerification_4_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather);
|
||||
void ModularTrainingVerification_4_run(uint ctx_index,Circom_CalcWit* ctx);
|
||||
Circom_TemplateFunction _functionTable[5] = {
|
||||
LearningRateValidation_0_run,
|
||||
ParameterUpdate_1_run,
|
||||
VectorParameterUpdate_2_run,
|
||||
TrainingEpoch_3_run,
|
||||
ModularTrainingVerification_4_run };
|
||||
Circom_TemplateFunction _functionTableParallel[5] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL };
|
||||
uint get_main_input_signal_start() {return 6;}
|
||||
|
||||
uint get_main_input_signal_no() {return 5;}
|
||||
|
||||
uint get_total_signal_no() {return 154;}
|
||||
|
||||
uint get_number_of_components() {return 20;}
|
||||
|
||||
uint get_size_of_input_hashmap() {return 256;}
|
||||
|
||||
uint get_size_of_witness() {return 19;}
|
||||
|
||||
uint get_size_of_constants() {return 4;}
|
||||
|
||||
uint get_size_of_io_map() {return 0;}
|
||||
|
||||
uint get_size_of_bus_field_map() {return 0;}
|
||||
|
||||
void release_memory_component(Circom_CalcWit* ctx, uint pos) {{
|
||||
|
||||
if (pos != 0){{
|
||||
|
||||
if(ctx->componentMemory[pos].subcomponents)
|
||||
delete []ctx->componentMemory[pos].subcomponents;
|
||||
|
||||
if(ctx->componentMemory[pos].subcomponentsParallel)
|
||||
delete []ctx->componentMemory[pos].subcomponentsParallel;
|
||||
|
||||
if(ctx->componentMemory[pos].outputIsSet)
|
||||
delete []ctx->componentMemory[pos].outputIsSet;
|
||||
|
||||
if(ctx->componentMemory[pos].mutexes)
|
||||
delete []ctx->componentMemory[pos].mutexes;
|
||||
|
||||
if(ctx->componentMemory[pos].cvs)
|
||||
delete []ctx->componentMemory[pos].cvs;
|
||||
|
||||
if(ctx->componentMemory[pos].sbct)
|
||||
delete []ctx->componentMemory[pos].sbct;
|
||||
|
||||
}}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
||||
// function declarations
|
||||
// template declarations
|
||||
void LearningRateValidation_0_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather){
|
||||
ctx->componentMemory[coffset].templateId = 0;
|
||||
ctx->componentMemory[coffset].templateName = "LearningRateValidation";
|
||||
ctx->componentMemory[coffset].signalStart = soffset;
|
||||
ctx->componentMemory[coffset].inputCounter = 1;
|
||||
ctx->componentMemory[coffset].componentName = componentName;
|
||||
ctx->componentMemory[coffset].idFather = componentFather;
|
||||
ctx->componentMemory[coffset].subcomponents = new uint[0];
|
||||
}
|
||||
|
||||
void LearningRateValidation_0_run(uint ctx_index,Circom_CalcWit* ctx){
|
||||
FrElement* circuitConstants = ctx->circuitConstants;
|
||||
FrElement* signalValues = ctx->signalValues;
|
||||
FrElement expaux[0];
|
||||
FrElement lvar[0];
|
||||
u64 mySignalStart = ctx->componentMemory[ctx_index].signalStart;
|
||||
std::string myTemplateName = ctx->componentMemory[ctx_index].templateName;
|
||||
std::string myComponentName = ctx->componentMemory[ctx_index].componentName;
|
||||
u64 myFather = ctx->componentMemory[ctx_index].idFather;
|
||||
u64 myId = ctx_index;
|
||||
u32* mySubcomponents = ctx->componentMemory[ctx_index].subcomponents;
|
||||
bool* mySubcomponentsParallel = ctx->componentMemory[ctx_index].subcomponentsParallel;
|
||||
std::string* listOfTemplateMessages = ctx->listOfTemplateMessages;
|
||||
uint sub_component_aux;
|
||||
uint index_multiple_eq;
|
||||
int cmp_index_ref_load = -1;
|
||||
for (uint i = 0; i < 0; i++){
|
||||
uint index_subc = ctx->componentMemory[ctx_index].subcomponents[i];
|
||||
if (index_subc != 0){
|
||||
assert(!(ctx->componentMemory[index_subc].inputCounter));
|
||||
release_memory_component(ctx,index_subc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterUpdate_1_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather){
|
||||
ctx->componentMemory[coffset].templateId = 1;
|
||||
ctx->componentMemory[coffset].templateName = "ParameterUpdate";
|
||||
ctx->componentMemory[coffset].signalStart = soffset;
|
||||
ctx->componentMemory[coffset].inputCounter = 3;
|
||||
ctx->componentMemory[coffset].componentName = componentName;
|
||||
ctx->componentMemory[coffset].idFather = componentFather;
|
||||
ctx->componentMemory[coffset].subcomponents = new uint[0];
|
||||
}
|
||||
|
||||
void ParameterUpdate_1_run(uint ctx_index,Circom_CalcWit* ctx){
|
||||
FrElement* circuitConstants = ctx->circuitConstants;
|
||||
FrElement* signalValues = ctx->signalValues;
|
||||
FrElement expaux[2];
|
||||
FrElement lvar[0];
|
||||
u64 mySignalStart = ctx->componentMemory[ctx_index].signalStart;
|
||||
std::string myTemplateName = ctx->componentMemory[ctx_index].templateName;
|
||||
std::string myComponentName = ctx->componentMemory[ctx_index].componentName;
|
||||
u64 myFather = ctx->componentMemory[ctx_index].idFather;
|
||||
u64 myId = ctx_index;
|
||||
u32* mySubcomponents = ctx->componentMemory[ctx_index].subcomponents;
|
||||
bool* mySubcomponentsParallel = ctx->componentMemory[ctx_index].subcomponentsParallel;
|
||||
std::string* listOfTemplateMessages = ctx->listOfTemplateMessages;
|
||||
uint sub_component_aux;
|
||||
uint index_multiple_eq;
|
||||
int cmp_index_ref_load = -1;
|
||||
{
|
||||
PFrElement aux_dest = &signalValues[mySignalStart + 0];
|
||||
// load src
|
||||
Fr_mul(&expaux[1],&signalValues[mySignalStart + 3],&signalValues[mySignalStart + 2]); // line circom 18
|
||||
Fr_sub(&expaux[0],&signalValues[mySignalStart + 1],&expaux[1]); // line circom 18
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
for (uint i = 0; i < 0; i++){
|
||||
uint index_subc = ctx->componentMemory[ctx_index].subcomponents[i];
|
||||
if (index_subc != 0){
|
||||
assert(!(ctx->componentMemory[index_subc].inputCounter));
|
||||
release_memory_component(ctx,index_subc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VectorParameterUpdate_2_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather){
|
||||
ctx->componentMemory[coffset].templateId = 2;
|
||||
ctx->componentMemory[coffset].templateName = "VectorParameterUpdate";
|
||||
ctx->componentMemory[coffset].signalStart = soffset;
|
||||
ctx->componentMemory[coffset].inputCounter = 9;
|
||||
ctx->componentMemory[coffset].componentName = componentName;
|
||||
ctx->componentMemory[coffset].idFather = componentFather;
|
||||
ctx->componentMemory[coffset].subcomponents = new uint[4]{0};
|
||||
}
|
||||
|
||||
void VectorParameterUpdate_2_run(uint ctx_index,Circom_CalcWit* ctx){
|
||||
FrElement* circuitConstants = ctx->circuitConstants;
|
||||
FrElement* signalValues = ctx->signalValues;
|
||||
FrElement expaux[2];
|
||||
FrElement lvar[2];
|
||||
u64 mySignalStart = ctx->componentMemory[ctx_index].signalStart;
|
||||
std::string myTemplateName = ctx->componentMemory[ctx_index].templateName;
|
||||
std::string myComponentName = ctx->componentMemory[ctx_index].componentName;
|
||||
u64 myFather = ctx->componentMemory[ctx_index].idFather;
|
||||
u64 myId = ctx_index;
|
||||
u32* mySubcomponents = ctx->componentMemory[ctx_index].subcomponents;
|
||||
bool* mySubcomponentsParallel = ctx->componentMemory[ctx_index].subcomponentsParallel;
|
||||
std::string* listOfTemplateMessages = ctx->listOfTemplateMessages;
|
||||
uint sub_component_aux;
|
||||
uint index_multiple_eq;
|
||||
int cmp_index_ref_load = -1;
|
||||
{
|
||||
PFrElement aux_dest = &lvar[0];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[0]);
|
||||
}
|
||||
{
|
||||
uint aux_create = 0;
|
||||
int aux_cmp_num = 0+ctx_index+1;
|
||||
uint csoffset = mySignalStart+13;
|
||||
uint aux_dimensions[1] = {4};
|
||||
for (uint i = 0; i < 4; i++) {
|
||||
std::string new_cmp_name = "updates"+ctx->generate_position_array(aux_dimensions, 1, i);
|
||||
ParameterUpdate_1_create(csoffset,aux_cmp_num,ctx,new_cmp_name,myId);
|
||||
mySubcomponents[aux_create+ i] = aux_cmp_num;
|
||||
csoffset += 4 ;
|
||||
aux_cmp_num += 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[1];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[1]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[1],&circuitConstants[0]); // line circom 31
|
||||
while(Fr_isTrue(&expaux[0])){
|
||||
{
|
||||
uint cmp_index_ref = ((1 * Fr_toInt(&lvar[1])) + 0);
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 1];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + ((1 * Fr_toInt(&lvar[1])) + 4)]);
|
||||
}
|
||||
// run sub component if needed
|
||||
if(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1)){
|
||||
ParameterUpdate_1_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
uint cmp_index_ref = ((1 * Fr_toInt(&lvar[1])) + 0);
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 2];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + ((1 * Fr_toInt(&lvar[1])) + 8)]);
|
||||
}
|
||||
// run sub component if needed
|
||||
if(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1)){
|
||||
ParameterUpdate_1_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
uint cmp_index_ref = ((1 * Fr_toInt(&lvar[1])) + 0);
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 3];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + 12]);
|
||||
}
|
||||
// run sub component if needed
|
||||
if(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1)){
|
||||
ParameterUpdate_1_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &signalValues[mySignalStart + ((1 * Fr_toInt(&lvar[1])) + 0)];
|
||||
// load src
|
||||
cmp_index_ref_load = ((1 * Fr_toInt(&lvar[1])) + 0);
|
||||
cmp_index_ref_load = ((1 * Fr_toInt(&lvar[1])) + 0);
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&ctx->signalValues[ctx->componentMemory[mySubcomponents[((1 * Fr_toInt(&lvar[1])) + 0)]].signalStart + 0]);
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[1];
|
||||
// load src
|
||||
Fr_add(&expaux[0],&lvar[1],&circuitConstants[2]); // line circom 31
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[1],&circuitConstants[0]); // line circom 31
|
||||
}
|
||||
for (uint i = 0; i < 4; i++){
|
||||
uint index_subc = ctx->componentMemory[ctx_index].subcomponents[i];
|
||||
if (index_subc != 0){
|
||||
assert(!(ctx->componentMemory[index_subc].inputCounter));
|
||||
release_memory_component(ctx,index_subc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrainingEpoch_3_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather){
|
||||
ctx->componentMemory[coffset].templateId = 3;
|
||||
ctx->componentMemory[coffset].templateName = "TrainingEpoch";
|
||||
ctx->componentMemory[coffset].signalStart = soffset;
|
||||
ctx->componentMemory[coffset].inputCounter = 9;
|
||||
ctx->componentMemory[coffset].componentName = componentName;
|
||||
ctx->componentMemory[coffset].idFather = componentFather;
|
||||
ctx->componentMemory[coffset].subcomponents = new uint[1]{0};
|
||||
}
|
||||
|
||||
void TrainingEpoch_3_run(uint ctx_index,Circom_CalcWit* ctx){
|
||||
FrElement* circuitConstants = ctx->circuitConstants;
|
||||
FrElement* signalValues = ctx->signalValues;
|
||||
FrElement expaux[1];
|
||||
FrElement lvar[1];
|
||||
u64 mySignalStart = ctx->componentMemory[ctx_index].signalStart;
|
||||
std::string myTemplateName = ctx->componentMemory[ctx_index].templateName;
|
||||
std::string myComponentName = ctx->componentMemory[ctx_index].componentName;
|
||||
u64 myFather = ctx->componentMemory[ctx_index].idFather;
|
||||
u64 myId = ctx_index;
|
||||
u32* mySubcomponents = ctx->componentMemory[ctx_index].subcomponents;
|
||||
bool* mySubcomponentsParallel = ctx->componentMemory[ctx_index].subcomponentsParallel;
|
||||
std::string* listOfTemplateMessages = ctx->listOfTemplateMessages;
|
||||
uint sub_component_aux;
|
||||
uint index_multiple_eq;
|
||||
int cmp_index_ref_load = -1;
|
||||
{
|
||||
PFrElement aux_dest = &lvar[0];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[0]);
|
||||
}
|
||||
{
|
||||
std::string new_cmp_name = "param_update";
|
||||
VectorParameterUpdate_2_create(mySignalStart+13,0+ctx_index+1,ctx,new_cmp_name,myId);
|
||||
mySubcomponents[0] = 0+ctx_index+1;
|
||||
}
|
||||
{
|
||||
uint cmp_index_ref = 0;
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 4];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copyn(aux_dest,&signalValues[mySignalStart + 4],4);
|
||||
}
|
||||
// no need to run sub component
|
||||
ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 4;
|
||||
assert(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter > 0);
|
||||
}
|
||||
{
|
||||
uint cmp_index_ref = 0;
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 8];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copyn(aux_dest,&signalValues[mySignalStart + 8],4);
|
||||
}
|
||||
// no need to run sub component
|
||||
ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 4;
|
||||
assert(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter > 0);
|
||||
}
|
||||
{
|
||||
uint cmp_index_ref = 0;
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 12];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + 12]);
|
||||
}
|
||||
// need to run sub component
|
||||
ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1;
|
||||
assert(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter));
|
||||
VectorParameterUpdate_2_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &signalValues[mySignalStart + 0];
|
||||
// load src
|
||||
cmp_index_ref_load = 0;
|
||||
cmp_index_ref_load = 0;
|
||||
// end load src
|
||||
Fr_copyn(aux_dest,&ctx->signalValues[ctx->componentMemory[mySubcomponents[0]].signalStart + 0],4);
|
||||
}
|
||||
for (uint i = 0; i < 1; i++){
|
||||
uint index_subc = ctx->componentMemory[ctx_index].subcomponents[i];
|
||||
if (index_subc != 0){
|
||||
assert(!(ctx->componentMemory[index_subc].inputCounter));
|
||||
release_memory_component(ctx,index_subc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModularTrainingVerification_4_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather){
|
||||
ctx->componentMemory[coffset].templateId = 4;
|
||||
ctx->componentMemory[coffset].templateName = "ModularTrainingVerification";
|
||||
ctx->componentMemory[coffset].signalStart = soffset;
|
||||
ctx->componentMemory[coffset].inputCounter = 5;
|
||||
ctx->componentMemory[coffset].componentName = componentName;
|
||||
ctx->componentMemory[coffset].idFather = componentFather;
|
||||
ctx->componentMemory[coffset].subcomponents = new uint[4]{0};
|
||||
}
|
||||
|
||||
void ModularTrainingVerification_4_run(uint ctx_index,Circom_CalcWit* ctx){
|
||||
FrElement* circuitConstants = ctx->circuitConstants;
|
||||
FrElement* signalValues = ctx->signalValues;
|
||||
FrElement expaux[2];
|
||||
FrElement lvar[4];
|
||||
u64 mySignalStart = ctx->componentMemory[ctx_index].signalStart;
|
||||
std::string myTemplateName = ctx->componentMemory[ctx_index].templateName;
|
||||
std::string myComponentName = ctx->componentMemory[ctx_index].componentName;
|
||||
u64 myFather = ctx->componentMemory[ctx_index].idFather;
|
||||
u64 myId = ctx_index;
|
||||
u32* mySubcomponents = ctx->componentMemory[ctx_index].subcomponents;
|
||||
bool* mySubcomponentsParallel = ctx->componentMemory[ctx_index].subcomponentsParallel;
|
||||
std::string* listOfTemplateMessages = ctx->listOfTemplateMessages;
|
||||
uint sub_component_aux;
|
||||
uint index_multiple_eq;
|
||||
int cmp_index_ref_load = -1;
|
||||
{
|
||||
PFrElement aux_dest = &lvar[0];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[3]);
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[1];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[0]);
|
||||
}
|
||||
{
|
||||
std::string new_cmp_name = "lr_validator";
|
||||
LearningRateValidation_0_create(mySignalStart+152,18+ctx_index+1,ctx,new_cmp_name,myId);
|
||||
mySubcomponents[0] = 18+ctx_index+1;
|
||||
}
|
||||
{
|
||||
uint aux_create = 1;
|
||||
int aux_cmp_num = 0+ctx_index+1;
|
||||
uint csoffset = mySignalStart+26;
|
||||
uint aux_dimensions[1] = {3};
|
||||
for (uint i = 0; i < 3; i++) {
|
||||
std::string new_cmp_name = "epochs"+ctx->generate_position_array(aux_dimensions, 1, i);
|
||||
TrainingEpoch_3_create(csoffset,aux_cmp_num,ctx,new_cmp_name,myId);
|
||||
mySubcomponents[aux_create+ i] = aux_cmp_num;
|
||||
csoffset += 42 ;
|
||||
aux_cmp_num += 6;
|
||||
}
|
||||
}
|
||||
{
|
||||
uint cmp_index_ref = 0;
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 0];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + 9]);
|
||||
}
|
||||
// need to run sub component
|
||||
ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1;
|
||||
assert(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter));
|
||||
LearningRateValidation_0_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[2];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[1]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[2],&circuitConstants[0]); // line circom 100
|
||||
while(Fr_isTrue(&expaux[0])){
|
||||
{
|
||||
PFrElement aux_dest = &signalValues[mySignalStart + ((0 + (1 * Fr_toInt(&lvar[2]))) + 10)];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + ((1 * Fr_toInt(&lvar[2])) + 5)]);
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[2];
|
||||
// load src
|
||||
Fr_add(&expaux[0],&lvar[2],&circuitConstants[2]); // line circom 100
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[2],&circuitConstants[0]); // line circom 100
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[2];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[1]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[2],&circuitConstants[3]); // line circom 106
|
||||
while(Fr_isTrue(&expaux[0])){
|
||||
{
|
||||
PFrElement aux_dest = &lvar[3];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[1]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[3],&circuitConstants[0]); // line circom 110
|
||||
while(Fr_isTrue(&expaux[0])){
|
||||
{
|
||||
uint cmp_index_ref = ((1 * Fr_toInt(&lvar[2])) + 1);
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + ((1 * Fr_toInt(&lvar[3])) + 4)];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + (((4 * Fr_toInt(&lvar[2])) + (1 * Fr_toInt(&lvar[3]))) + 10)]);
|
||||
}
|
||||
// run sub component if needed
|
||||
if(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1)){
|
||||
TrainingEpoch_3_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[3];
|
||||
// load src
|
||||
Fr_add(&expaux[0],&lvar[3],&circuitConstants[2]); // line circom 110
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[3],&circuitConstants[0]); // line circom 110
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[3];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[1]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[3],&circuitConstants[0]); // line circom 115
|
||||
while(Fr_isTrue(&expaux[0])){
|
||||
{
|
||||
uint cmp_index_ref = ((1 * Fr_toInt(&lvar[2])) + 1);
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + ((1 * Fr_toInt(&lvar[3])) + 8)];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[2]);
|
||||
}
|
||||
// run sub component if needed
|
||||
if(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1)){
|
||||
TrainingEpoch_3_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[3];
|
||||
// load src
|
||||
Fr_add(&expaux[0],&lvar[3],&circuitConstants[2]); // line circom 115
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[3],&circuitConstants[0]); // line circom 115
|
||||
}
|
||||
{
|
||||
uint cmp_index_ref = ((1 * Fr_toInt(&lvar[2])) + 1);
|
||||
{
|
||||
PFrElement aux_dest = &ctx->signalValues[ctx->componentMemory[mySubcomponents[cmp_index_ref]].signalStart + 12];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + 9]);
|
||||
}
|
||||
// run sub component if needed
|
||||
if(!(ctx->componentMemory[mySubcomponents[cmp_index_ref]].inputCounter -= 1)){
|
||||
TrainingEpoch_3_run(mySubcomponents[cmp_index_ref],ctx);
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[3];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[1]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[3],&circuitConstants[0]); // line circom 122
|
||||
while(Fr_isTrue(&expaux[0])){
|
||||
{
|
||||
PFrElement aux_dest = &signalValues[mySignalStart + (((4 * (Fr_toInt(&lvar[2]) + 1)) + (1 * Fr_toInt(&lvar[3]))) + 10)];
|
||||
// load src
|
||||
cmp_index_ref_load = ((1 * Fr_toInt(&lvar[2])) + 1);
|
||||
cmp_index_ref_load = ((1 * Fr_toInt(&lvar[2])) + 1);
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&ctx->signalValues[ctx->componentMemory[mySubcomponents[((1 * Fr_toInt(&lvar[2])) + 1)]].signalStart + ((1 * Fr_toInt(&lvar[3])) + 0)]);
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[3];
|
||||
// load src
|
||||
Fr_add(&expaux[0],&lvar[3],&circuitConstants[2]); // line circom 122
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[3],&circuitConstants[0]); // line circom 122
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[2];
|
||||
// load src
|
||||
Fr_add(&expaux[0],&lvar[2],&circuitConstants[2]); // line circom 106
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[2],&circuitConstants[3]); // line circom 106
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[2];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[1]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[2],&circuitConstants[0]); // line circom 128
|
||||
while(Fr_isTrue(&expaux[0])){
|
||||
{
|
||||
PFrElement aux_dest = &signalValues[mySignalStart + ((1 * Fr_toInt(&lvar[2])) + 0)];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&signalValues[mySignalStart + ((12 + (1 * Fr_toInt(&lvar[2]))) + 10)]);
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &lvar[2];
|
||||
// load src
|
||||
Fr_add(&expaux[0],&lvar[2],&circuitConstants[2]); // line circom 128
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&expaux[0]);
|
||||
}
|
||||
Fr_lt(&expaux[0],&lvar[2],&circuitConstants[0]); // line circom 128
|
||||
}
|
||||
{
|
||||
PFrElement aux_dest = &signalValues[mySignalStart + 4];
|
||||
// load src
|
||||
// end load src
|
||||
Fr_copy(aux_dest,&circuitConstants[2]);
|
||||
}
|
||||
for (uint i = 0; i < 4; i++){
|
||||
uint index_subc = ctx->componentMemory[ctx_index].subcomponents[i];
|
||||
if (index_subc != 0){
|
||||
assert(!(ctx->componentMemory[index_subc].inputCounter));
|
||||
release_memory_component(ctx,index_subc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run(Circom_CalcWit* ctx){
|
||||
ModularTrainingVerification_4_create(1,0,ctx,"main",0);
|
||||
ModularTrainingVerification_4_run(0,ctx);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
const wc = require("./witness_calculator.js");
|
||||
const { readFileSync, writeFile } = require("fs");
|
||||
|
||||
if (process.argv.length != 5) {
|
||||
console.log("Usage: node generate_witness.js <file.wasm> <input.json> <output.wtns>");
|
||||
} else {
|
||||
const input = JSON.parse(readFileSync(process.argv[3], "utf8"));
|
||||
|
||||
const buffer = readFileSync(process.argv[2]);
|
||||
wc(buffer).then(async witnessCalculator => {
|
||||
/*
|
||||
const w= await witnessCalculator.calculateWitness(input,0);
|
||||
for (let i=0; i< w.length; i++){
|
||||
console.log(w[i]);
|
||||
}*/
|
||||
const buff= await witnessCalculator.calculateWTNSBin(input,0);
|
||||
writeFile(process.argv[4], buff, function(err) {
|
||||
if (err) throw err;
|
||||
});
|
||||
});
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,381 @@
|
||||
module.exports = async function builder(code, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
let wasmModule;
|
||||
try {
|
||||
wasmModule = await WebAssembly.compile(code);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.log("\nTry to run circom --c in order to generate c++ code instead\n");
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
let wc;
|
||||
|
||||
let errStr = "";
|
||||
let msgStr = "";
|
||||
|
||||
const instance = await WebAssembly.instantiate(wasmModule, {
|
||||
runtime: {
|
||||
exceptionHandler : function(code) {
|
||||
let err;
|
||||
if (code == 1) {
|
||||
err = "Signal not found.\n";
|
||||
} else if (code == 2) {
|
||||
err = "Too many signals set.\n";
|
||||
} else if (code == 3) {
|
||||
err = "Signal already set.\n";
|
||||
} else if (code == 4) {
|
||||
err = "Assert Failed.\n";
|
||||
} else if (code == 5) {
|
||||
err = "Not enough memory.\n";
|
||||
} else if (code == 6) {
|
||||
err = "Input signal array access exceeds the size.\n";
|
||||
} else {
|
||||
err = "Unknown error.\n";
|
||||
}
|
||||
throw new Error(err + errStr);
|
||||
},
|
||||
printErrorMessage : function() {
|
||||
errStr += getMessage() + "\n";
|
||||
// console.error(getMessage());
|
||||
},
|
||||
writeBufferMessage : function() {
|
||||
const msg = getMessage();
|
||||
// Any calls to `log()` will always end with a `\n`, so that's when we print and reset
|
||||
if (msg === "\n") {
|
||||
console.log(msgStr);
|
||||
msgStr = "";
|
||||
} else {
|
||||
// If we've buffered other content, put a space in between the items
|
||||
if (msgStr !== "") {
|
||||
msgStr += " "
|
||||
}
|
||||
// Then append the message to the message we are creating
|
||||
msgStr += msg;
|
||||
}
|
||||
},
|
||||
showSharedRWMemory : function() {
|
||||
printSharedRWMemory ();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
const sanityCheck =
|
||||
options
|
||||
// options &&
|
||||
// (
|
||||
// options.sanityCheck ||
|
||||
// options.logGetSignal ||
|
||||
// options.logSetSignal ||
|
||||
// options.logStartComponent ||
|
||||
// options.logFinishComponent
|
||||
// );
|
||||
|
||||
|
||||
wc = new WitnessCalculator(instance, sanityCheck);
|
||||
return wc;
|
||||
|
||||
function getMessage() {
|
||||
var message = "";
|
||||
var c = instance.exports.getMessageChar();
|
||||
while ( c != 0 ) {
|
||||
message += String.fromCharCode(c);
|
||||
c = instance.exports.getMessageChar();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function printSharedRWMemory () {
|
||||
const shared_rw_memory_size = instance.exports.getFieldNumLen32();
|
||||
const arr = new Uint32Array(shared_rw_memory_size);
|
||||
for (let j=0; j<shared_rw_memory_size; j++) {
|
||||
arr[shared_rw_memory_size-1-j] = instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
|
||||
// If we've buffered other content, put a space in between the items
|
||||
if (msgStr !== "") {
|
||||
msgStr += " "
|
||||
}
|
||||
// Then append the value to the message we are creating
|
||||
msgStr += (fromArray32(arr).toString());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class WitnessCalculator {
|
||||
constructor(instance, sanityCheck) {
|
||||
this.instance = instance;
|
||||
|
||||
this.version = this.instance.exports.getVersion();
|
||||
this.n32 = this.instance.exports.getFieldNumLen32();
|
||||
|
||||
this.instance.exports.getRawPrime();
|
||||
const arr = new Uint32Array(this.n32);
|
||||
for (let i=0; i<this.n32; i++) {
|
||||
arr[this.n32-1-i] = this.instance.exports.readSharedRWMemory(i);
|
||||
}
|
||||
this.prime = fromArray32(arr);
|
||||
|
||||
this.witnessSize = this.instance.exports.getWitnessSize();
|
||||
|
||||
this.sanityCheck = sanityCheck;
|
||||
}
|
||||
|
||||
circom_version() {
|
||||
return this.instance.exports.getVersion();
|
||||
}
|
||||
|
||||
async _doCalculateWitness(input_orig, sanityCheck) {
|
||||
//input is assumed to be a map from signals to arrays of bigints
|
||||
this.instance.exports.init((this.sanityCheck || sanityCheck) ? 1 : 0);
|
||||
let prefix = "";
|
||||
var input = new Object();
|
||||
//console.log("Input: ", input_orig);
|
||||
qualify_input(prefix,input_orig,input);
|
||||
//console.log("Input after: ",input);
|
||||
const keys = Object.keys(input);
|
||||
var input_counter = 0;
|
||||
keys.forEach( (k) => {
|
||||
const h = fnvHash(k);
|
||||
const hMSB = parseInt(h.slice(0,8), 16);
|
||||
const hLSB = parseInt(h.slice(8,16), 16);
|
||||
const fArr = flatArray(input[k]);
|
||||
let signalSize = this.instance.exports.getInputSignalSize(hMSB, hLSB);
|
||||
if (signalSize < 0){
|
||||
throw new Error(`Signal ${k} not found\n`);
|
||||
}
|
||||
if (fArr.length < signalSize) {
|
||||
throw new Error(`Not enough values for input signal ${k}\n`);
|
||||
}
|
||||
if (fArr.length > signalSize) {
|
||||
throw new Error(`Too many values for input signal ${k}\n`);
|
||||
}
|
||||
for (let i=0; i<fArr.length; i++) {
|
||||
const arrFr = toArray32(normalize(fArr[i],this.prime),this.n32)
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
this.instance.exports.writeSharedRWMemory(j,arrFr[this.n32-1-j]);
|
||||
}
|
||||
try {
|
||||
this.instance.exports.setInputSignal(hMSB, hLSB,i);
|
||||
input_counter++;
|
||||
} catch (err) {
|
||||
// console.log(`After adding signal ${i} of ${k}`)
|
||||
throw new Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
if (input_counter < this.instance.exports.getInputSize()) {
|
||||
throw new Error(`Not all inputs have been set. Only ${input_counter} out of ${this.instance.exports.getInputSize()}`);
|
||||
}
|
||||
}
|
||||
|
||||
async calculateWitness(input, sanityCheck) {
|
||||
|
||||
const w = [];
|
||||
await this._doCalculateWitness(input, sanityCheck);
|
||||
|
||||
for (let i=0; i<this.witnessSize; i++) {
|
||||
this.instance.exports.getWitness(i);
|
||||
const arr = new Uint32Array(this.n32);
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
arr[this.n32-1-j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
w.push(fromArray32(arr));
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
async calculateBinWitness(input, sanityCheck) {
|
||||
|
||||
const buff32 = new Uint32Array(this.witnessSize*this.n32);
|
||||
const buff = new Uint8Array( buff32.buffer);
|
||||
await this._doCalculateWitness(input, sanityCheck);
|
||||
|
||||
for (let i=0; i<this.witnessSize; i++) {
|
||||
this.instance.exports.getWitness(i);
|
||||
const pos = i*this.n32;
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
buff32[pos+j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
|
||||
async calculateWTNSBin(input, sanityCheck) {
|
||||
|
||||
const buff32 = new Uint32Array(this.witnessSize*this.n32+this.n32+11);
|
||||
const buff = new Uint8Array( buff32.buffer);
|
||||
await this._doCalculateWitness(input, sanityCheck);
|
||||
|
||||
//"wtns"
|
||||
buff[0] = "w".charCodeAt(0)
|
||||
buff[1] = "t".charCodeAt(0)
|
||||
buff[2] = "n".charCodeAt(0)
|
||||
buff[3] = "s".charCodeAt(0)
|
||||
|
||||
//version 2
|
||||
buff32[1] = 2;
|
||||
|
||||
//number of sections: 2
|
||||
buff32[2] = 2;
|
||||
|
||||
//id section 1
|
||||
buff32[3] = 1;
|
||||
|
||||
const n8 = this.n32*4;
|
||||
//id section 1 length in 64bytes
|
||||
const idSection1length = 8 + n8;
|
||||
const idSection1lengthHex = idSection1length.toString(16);
|
||||
buff32[4] = parseInt(idSection1lengthHex.slice(0,8), 16);
|
||||
buff32[5] = parseInt(idSection1lengthHex.slice(8,16), 16);
|
||||
|
||||
//this.n32
|
||||
buff32[6] = n8;
|
||||
|
||||
//prime number
|
||||
this.instance.exports.getRawPrime();
|
||||
|
||||
var pos = 7;
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
buff32[pos+j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
pos += this.n32;
|
||||
|
||||
// witness size
|
||||
buff32[pos] = this.witnessSize;
|
||||
pos++;
|
||||
|
||||
//id section 2
|
||||
buff32[pos] = 2;
|
||||
pos++;
|
||||
|
||||
// section 2 length
|
||||
const idSection2length = n8*this.witnessSize;
|
||||
const idSection2lengthHex = idSection2length.toString(16);
|
||||
buff32[pos] = parseInt(idSection2lengthHex.slice(0,8), 16);
|
||||
buff32[pos+1] = parseInt(idSection2lengthHex.slice(8,16), 16);
|
||||
|
||||
pos += 2;
|
||||
for (let i=0; i<this.witnessSize; i++) {
|
||||
this.instance.exports.getWitness(i);
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
buff32[pos+j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
pos += this.n32;
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function qualify_input_list(prefix,input,input1){
|
||||
if (Array.isArray(input)) {
|
||||
for (let i = 0; i<input.length; i++) {
|
||||
let new_prefix = prefix + "[" + i + "]";
|
||||
qualify_input_list(new_prefix,input[i],input1);
|
||||
}
|
||||
} else {
|
||||
qualify_input(prefix,input,input1);
|
||||
}
|
||||
}
|
||||
|
||||
function qualify_input(prefix,input,input1) {
|
||||
if (Array.isArray(input)) {
|
||||
a = flatArray(input);
|
||||
if (a.length > 0) {
|
||||
let t = typeof a[0];
|
||||
for (let i = 1; i<a.length; i++) {
|
||||
if (typeof a[i] != t){
|
||||
throw new Error(`Types are not the same in the key ${prefix}`);
|
||||
}
|
||||
}
|
||||
if (t == "object") {
|
||||
qualify_input_list(prefix,input,input1);
|
||||
} else {
|
||||
input1[prefix] = input;
|
||||
}
|
||||
} else {
|
||||
input1[prefix] = input;
|
||||
}
|
||||
} else if (typeof input == "object") {
|
||||
const keys = Object.keys(input);
|
||||
keys.forEach( (k) => {
|
||||
let new_prefix = prefix == ""? k : prefix + "." + k;
|
||||
qualify_input(new_prefix,input[k],input1);
|
||||
});
|
||||
} else {
|
||||
input1[prefix] = input;
|
||||
}
|
||||
}
|
||||
|
||||
function toArray32(rem,size) {
|
||||
const res = []; //new Uint32Array(size); //has no unshift
|
||||
const radix = BigInt(0x100000000);
|
||||
while (rem) {
|
||||
res.unshift( Number(rem % radix));
|
||||
rem = rem / radix;
|
||||
}
|
||||
if (size) {
|
||||
var i = size - res.length;
|
||||
while (i>0) {
|
||||
res.unshift(0);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function fromArray32(arr) { //returns a BigInt
|
||||
var res = BigInt(0);
|
||||
const radix = BigInt(0x100000000);
|
||||
for (let i = 0; i<arr.length; i++) {
|
||||
res = res*radix + BigInt(arr[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function flatArray(a) {
|
||||
var res = [];
|
||||
fillArray(res, a);
|
||||
return res;
|
||||
|
||||
function fillArray(res, a) {
|
||||
if (Array.isArray(a)) {
|
||||
for (let i=0; i<a.length; i++) {
|
||||
fillArray(res, a[i]);
|
||||
}
|
||||
} else {
|
||||
res.push(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function normalize(n, prime) {
|
||||
let res = BigInt(n) % prime
|
||||
if (res < 0) res += prime
|
||||
return res
|
||||
}
|
||||
|
||||
function fnvHash(str) {
|
||||
const uint64_max = BigInt(2) ** BigInt(64);
|
||||
let hash = BigInt("0xCBF29CE484222325");
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
hash ^= BigInt(str[i].charCodeAt());
|
||||
hash *= BigInt(0x100000001B3);
|
||||
hash %= uint64_max;
|
||||
}
|
||||
let shash = hash.toString(16);
|
||||
let n = 16 - shash.length;
|
||||
shash = '0'.repeat(n).concat(shash);
|
||||
return shash;
|
||||
}
|
||||
Reference in New Issue
Block a user