mirror of
https://github.com/logos-storage/nim-groth16.git
synced 2026-01-08 00:23:09 +00:00
add fr support files
This commit is contained in:
parent
7379bc04ae
commit
d882610744
129
example/support/calcwit.cpp
Normal file
129
example/support/calcwit.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
#include "calcwit.hpp"
|
||||
|
||||
namespace CIRCUIT_NAME {
|
||||
|
||||
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;
|
||||
|
||||
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++;
|
||||
while (pos != inipos) {
|
||||
if (circuit->InputHashMap[pos].hash==h) return pos;
|
||||
if (circuit->InputHashMap[pos].hash==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;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
73
example/support/calcwit.hpp
Normal file
73
example/support/calcwit.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
#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 12 //512
|
||||
|
||||
namespace CIRCUIT_NAME {
|
||||
|
||||
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,IODefPair> templateInsId2IOSignalInfo;
|
||||
std::string* listOfTemplateMessages;
|
||||
|
||||
// parallelism
|
||||
std::mutex numThreadMutex;
|
||||
std::condition_variable ntcvs;
|
||||
uint numThread;
|
||||
|
||||
uint 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);
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // CIRCOM_CALCWIT_H
|
||||
8799
example/support/fr.asm
Normal file
8799
example/support/fr.asm
Normal file
File diff suppressed because it is too large
Load Diff
322
example/support/fr.cpp
Normal file
322
example/support/fr.cpp
Normal file
@ -0,0 +1,322 @@
|
||||
#include "fr.hpp"
|
||||
#include <stdio.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);
|
||||
}
|
||||
|
||||
void Fr_longErr()
|
||||
{
|
||||
Fr_fail();
|
||||
}
|
||||
|
||||
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_R3.longVal);
|
||||
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;
|
||||
287
example/support/fr.hpp
Normal file
287
example/support/fr.hpp
Normal file
@ -0,0 +1,287 @@
|
||||
#ifndef __FR_H
|
||||
#define __FR_H
|
||||
|
||||
#include "fr_element.hpp"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <gmp.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/types.h> // typedef unsigned int uint;
|
||||
#endif // __APPLE__
|
||||
|
||||
extern FrElement Fr_q;
|
||||
extern FrElement Fr_R2;
|
||||
extern FrElement Fr_R3;
|
||||
extern FrRawElement Fr_rawq;
|
||||
extern FrRawElement Fr_rawR3;
|
||||
|
||||
#ifdef USE_ASM
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
|
||||
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_rawShl(FrRawElement r, FrRawElement a, uint64_t b);
|
||||
extern "C" void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b);
|
||||
|
||||
extern "C" void Fr_fail();
|
||||
|
||||
#elif defined(ARCH_ARM64)
|
||||
|
||||
void Fr_copy(PFrElement r, PFrElement a);
|
||||
void Fr_mul(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_toNormal(PFrElement r, PFrElement a);
|
||||
|
||||
void Fr_toLongNormal(PFrElement r, PFrElement a);
|
||||
int Fr_isTrue(PFrElement pE);
|
||||
void Fr_copyn(PFrElement r, PFrElement a, int n);
|
||||
void Fr_lt(PFrElement r, PFrElement a, PFrElement b);
|
||||
int Fr_toInt(PFrElement pE);
|
||||
void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_band(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_bor(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_bxor(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_bnot(PFrElement r, PFrElement a);
|
||||
void Fr_sub(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_eq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_neq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_add(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_gt(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_leq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_geq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_lor(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_lnot(PFrElement r, PFrElement a);
|
||||
void Fr_land(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_neg(PFrElement r, PFrElement a);
|
||||
void Fr_toMontgomery(PFrElement r, PFrElement a);
|
||||
void Fr_square(PFrElement r, PFrElement a);
|
||||
|
||||
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);
|
||||
void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA);
|
||||
extern "C" void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB);
|
||||
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);
|
||||
void Fr_rawZero(FrRawElement pRawResult);
|
||||
extern "C" void Fr_rawCopyS2L(FrRawElement pRawResult, int64_t val);
|
||||
extern "C" void Fr_rawAddLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
|
||||
extern "C" void Fr_rawSubSL(FrRawElement pRawResult, uint64_t rawA, FrRawElement pRawB);
|
||||
extern "C" void Fr_rawSubLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
|
||||
extern "C" void Fr_rawNegLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
|
||||
extern "C" int Fr_rawCmp(FrRawElement pRawA, FrRawElement pRawB);
|
||||
extern "C" void Fr_rawAnd(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
extern "C" void Fr_rawOr(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
extern "C" void Fr_rawXor(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
extern "C" void Fr_rawShl(FrRawElement r, FrRawElement a, uint64_t b);
|
||||
extern "C" void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b);
|
||||
extern "C" void Fr_rawNot(FrRawElement pRawResult, FrRawElement pRawA);
|
||||
extern "C" void Fr_rawSubRegular(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
|
||||
void Fr_fail();
|
||||
void Fr_longErr();
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
|
||||
void Fr_copy(PFrElement r, PFrElement a);
|
||||
void Fr_mul(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_toNormal(PFrElement r, PFrElement a);
|
||||
|
||||
void Fr_toLongNormal(PFrElement r, PFrElement a);
|
||||
int Fr_isTrue(PFrElement pE);
|
||||
void Fr_copyn(PFrElement r, PFrElement a, int n);
|
||||
void Fr_lt(PFrElement r, PFrElement a, PFrElement b);
|
||||
int Fr_toInt(PFrElement pE);
|
||||
void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_band(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_bor(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_bxor(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_bnot(PFrElement r, PFrElement a);
|
||||
void Fr_sub(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_eq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_neq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_add(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_gt(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_leq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_geq(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_lor(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_lnot(PFrElement r, PFrElement a);
|
||||
void Fr_land(PFrElement r, PFrElement a, PFrElement b);
|
||||
void Fr_neg(PFrElement r, PFrElement a);
|
||||
void Fr_toMontgomery(PFrElement r, PFrElement a);
|
||||
void Fr_square(PFrElement r, PFrElement a);
|
||||
|
||||
void Fr_rawCopy(FrRawElement pRawResult, const FrRawElement pRawA);
|
||||
void Fr_rawSwap(FrRawElement pRawResult, FrRawElement pRawA);
|
||||
void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
void Fr_rawSub(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
void Fr_rawNeg(FrRawElement pRawResult, const FrRawElement pRawA);
|
||||
void Fr_rawMMul(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA);
|
||||
void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB);
|
||||
void Fr_rawToMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
|
||||
void Fr_rawFromMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
|
||||
int Fr_rawIsEq(const FrRawElement pRawA, const FrRawElement pRawB);
|
||||
int Fr_rawIsZero(const FrRawElement pRawB);
|
||||
void Fr_rawZero(FrRawElement pRawResult);
|
||||
void Fr_rawCopyS2L(FrRawElement pRawResult, int64_t val);
|
||||
void Fr_rawAddLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
|
||||
void Fr_rawSubSL(FrRawElement pRawResult, uint64_t rawA, FrRawElement pRawB);
|
||||
void Fr_rawSubLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
|
||||
void Fr_rawNegLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
|
||||
int Fr_rawCmp(FrRawElement pRawA, FrRawElement pRawB);
|
||||
void Fr_rawAnd(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
void Fr_rawOr(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
void Fr_rawXor(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
void Fr_rawShl(FrRawElement r, FrRawElement a, uint64_t b);
|
||||
void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b);
|
||||
void Fr_rawNot(FrRawElement pRawResult, FrRawElement pRawA);
|
||||
void Fr_rawSubRegular(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
|
||||
|
||||
void Fr_fail();
|
||||
void Fr_longErr();
|
||||
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
|
||||
23
example/support/fr_element.hpp
Normal file
23
example/support/fr_element.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef FR_ELEMENT_HPP
|
||||
#define FR_ELEMENT_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#define Fr_N64 4
|
||||
#define Fr_SHORT 0x00000000
|
||||
#define Fr_MONTGOMERY 0x40000000
|
||||
#define Fr_SHORTMONTGOMERY 0x40000000
|
||||
#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;
|
||||
|
||||
#endif // FR_ELEMENT_HPP
|
||||
2389
example/support/fr_generic.cpp
Executable file
2389
example/support/fr_generic.cpp
Executable file
File diff suppressed because it is too large
Load Diff
BIN
example/support/fr_raw_arm64.o
Normal file
BIN
example/support/fr_raw_arm64.o
Normal file
Binary file not shown.
1199
example/support/fr_raw_arm64.s
Executable file
1199
example/support/fr_raw_arm64.s
Executable file
File diff suppressed because it is too large
Load Diff
364
example/support/fr_raw_generic.cpp
Normal file
364
example/support/fr_raw_generic.cpp
Normal file
@ -0,0 +1,364 @@
|
||||
#include "fr_element.hpp"
|
||||
#include <gmp.h>
|
||||
#include <cstring>
|
||||
|
||||
static uint64_t Fr_rawq[] = {0x43e1f593f0000001,0x2833e84879b97091,0xb85045b68181585d,0x30644e72e131a029, 0};
|
||||
static FrRawElement Fr_rawR2 = {0x1bb8e645ae216da7,0x53fe3ab1e35c59e3,0x8c49833d53bb8085,0x0216d0b17f4e44a5};
|
||||
static uint64_t Fr_np = {0xc2e1f593efffffff};
|
||||
static uint64_t lboMask = 0x3fffffffffffffff;
|
||||
|
||||
|
||||
void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB)
|
||||
{
|
||||
uint64_t carry = mpn_add_n(pRawResult, pRawA, pRawB, Fr_N64);
|
||||
|
||||
if(carry || mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawAddLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB)
|
||||
{
|
||||
uint64_t carry = mpn_add_1(pRawResult, pRawA, Fr_N64, rawB);
|
||||
|
||||
if(carry || mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawSub(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB)
|
||||
{
|
||||
uint64_t carry = mpn_sub_n(pRawResult, pRawA, pRawB, Fr_N64);
|
||||
|
||||
if(carry)
|
||||
{
|
||||
mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawSubRegular(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawA, pRawB, Fr_N64);
|
||||
}
|
||||
|
||||
void Fr_rawSubSL(FrRawElement pRawResult, uint64_t rawA, FrRawElement pRawB)
|
||||
{
|
||||
FrRawElement pRawA = {rawA, 0, 0, 0};
|
||||
|
||||
uint64_t carry = mpn_sub_n(pRawResult, pRawA, pRawB, Fr_N64);
|
||||
|
||||
if(carry)
|
||||
{
|
||||
mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawSubLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB)
|
||||
{
|
||||
uint64_t carry = mpn_sub_1(pRawResult, pRawA, Fr_N64, rawB);
|
||||
|
||||
if(carry)
|
||||
{
|
||||
mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawNeg(FrRawElement pRawResult, const FrRawElement pRawA)
|
||||
{
|
||||
const uint64_t zero[Fr_N64] = {0, 0, 0, 0};
|
||||
|
||||
if (mpn_cmp(pRawA, zero, Fr_N64) != 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, Fr_rawq, pRawA, Fr_N64);
|
||||
}
|
||||
else
|
||||
{
|
||||
mpn_copyi(pRawResult, zero, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
// Substracts a long element and a short element form 0
|
||||
void Fr_rawNegLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB)
|
||||
{
|
||||
uint64_t carry1 = mpn_sub_1(pRawResult, Fr_rawq, Fr_N64, rawB);
|
||||
uint64_t carry2 = mpn_sub_n(pRawResult, pRawResult, pRawA, Fr_N64);
|
||||
|
||||
if (carry1 || carry2)
|
||||
{
|
||||
mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawCopy(FrRawElement pRawResult, const FrRawElement pRawA)
|
||||
{
|
||||
pRawResult[0] = pRawA[0];
|
||||
pRawResult[1] = pRawA[1];
|
||||
pRawResult[2] = pRawA[2];
|
||||
pRawResult[3] = pRawA[3];
|
||||
}
|
||||
|
||||
int Fr_rawIsEq(const FrRawElement pRawA, const FrRawElement pRawB)
|
||||
{
|
||||
return mpn_cmp(pRawA, pRawB, Fr_N64) == 0;
|
||||
}
|
||||
|
||||
void Fr_rawMMul(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB)
|
||||
{
|
||||
const mp_size_t N = Fr_N64+1;
|
||||
const uint64_t *mq = Fr_rawq;
|
||||
|
||||
uint64_t np0;
|
||||
|
||||
uint64_t product0[N] = {0};
|
||||
uint64_t product1[N] = {0};
|
||||
uint64_t product2[N] = {0};
|
||||
uint64_t product3[N] = {0};
|
||||
|
||||
product0[4] = mpn_mul_1(product0, pRawB, Fr_N64, pRawA[0]);
|
||||
|
||||
np0 = Fr_np * product0[0];
|
||||
product1[1] = mpn_addmul_1(product0, mq, N, np0);
|
||||
|
||||
product1[4] = mpn_addmul_1(product1, pRawB, Fr_N64, pRawA[1]);
|
||||
mpn_add(product1, product1, N, product0+1, N-1);
|
||||
|
||||
np0 = Fr_np * product1[0];
|
||||
product2[1] = mpn_addmul_1(product1, mq, N, np0);
|
||||
|
||||
product2[4] = mpn_addmul_1(product2, pRawB, Fr_N64, pRawA[2]);
|
||||
mpn_add(product2, product2, N, product1+1, N-1);
|
||||
|
||||
np0 = Fr_np * product2[0];
|
||||
product3[1] = mpn_addmul_1(product2, mq, N, np0);
|
||||
|
||||
product3[4] = mpn_addmul_1(product3, pRawB, Fr_N64, pRawA[3]);
|
||||
mpn_add(product3, product3, N, product2+1, N-1);
|
||||
|
||||
np0 = Fr_np * product3[0];
|
||||
mpn_addmul_1(product3, mq, N, np0);
|
||||
|
||||
mpn_copyi(pRawResult, product3+1, Fr_N64);
|
||||
|
||||
if (mpn_cmp(pRawResult, mq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, mq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA)
|
||||
{
|
||||
Fr_rawMMul(pRawResult, pRawA, pRawA);
|
||||
}
|
||||
|
||||
void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB)
|
||||
{
|
||||
const mp_size_t N = Fr_N64+1;
|
||||
const uint64_t *mq = Fr_rawq;
|
||||
|
||||
uint64_t np0;
|
||||
|
||||
uint64_t product0[N] = {0};
|
||||
uint64_t product1[N] = {0};
|
||||
uint64_t product2[N] = {0};
|
||||
uint64_t product3[N] = {0};
|
||||
|
||||
product0[4] = mpn_mul_1(product0, pRawA, Fr_N64, pRawB);
|
||||
|
||||
np0 = Fr_np * product0[0];
|
||||
product1[1] = mpn_addmul_1(product0, mq, N, np0);
|
||||
mpn_add(product1, product1, N, product0+1, N-1);
|
||||
|
||||
np0 = Fr_np * product1[0];
|
||||
product2[1] = mpn_addmul_1(product1, mq, N, np0);
|
||||
mpn_add(product2, product2, N, product1+1, N-1);
|
||||
|
||||
np0 = Fr_np * product2[0];
|
||||
product3[1] = mpn_addmul_1(product2, mq, N, np0);
|
||||
mpn_add(product3, product3, N, product2+1, N-1);
|
||||
|
||||
np0 = Fr_np * product3[0];
|
||||
mpn_addmul_1(product3, mq, N, np0);
|
||||
|
||||
mpn_copyi(pRawResult, product3+1, Fr_N64);
|
||||
|
||||
if (mpn_cmp(pRawResult, mq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, mq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawToMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA)
|
||||
{
|
||||
Fr_rawMMul(pRawResult, pRawA, Fr_rawR2);
|
||||
}
|
||||
|
||||
void Fr_rawFromMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA)
|
||||
{
|
||||
const mp_size_t N = Fr_N64+1;
|
||||
const uint64_t *mq = Fr_rawq;
|
||||
|
||||
uint64_t np0;
|
||||
|
||||
uint64_t product0[N];
|
||||
uint64_t product1[N] = {0};
|
||||
uint64_t product2[N] = {0};
|
||||
uint64_t product3[N] = {0};
|
||||
|
||||
mpn_copyi(product0, pRawA, Fr_N64); product0[4] = 0;
|
||||
|
||||
np0 = Fr_np * product0[0];
|
||||
product1[1] = mpn_addmul_1(product0, mq, N, np0);
|
||||
mpn_add(product1, product1, N, product0+1, N-1);
|
||||
|
||||
np0 = Fr_np * product1[0];
|
||||
product2[1] = mpn_addmul_1(product1, mq, N, np0);
|
||||
mpn_add(product2, product2, N, product1+1, N-1);
|
||||
|
||||
np0 = Fr_np * product2[0];
|
||||
product3[1] = mpn_addmul_1(product2, mq, N, np0);
|
||||
mpn_add(product3, product3, N, product2+1, N-1);
|
||||
|
||||
np0 = Fr_np * product3[0];
|
||||
mpn_addmul_1(product3, mq, N, np0);
|
||||
|
||||
mpn_copyi(pRawResult, product3+1, Fr_N64);
|
||||
|
||||
if (mpn_cmp(pRawResult, mq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, mq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
int Fr_rawIsZero(const FrRawElement rawA)
|
||||
{
|
||||
return mpn_zero_p(rawA, Fr_N64) ? 1 : 0;
|
||||
}
|
||||
|
||||
int Fr_rawCmp(FrRawElement pRawA, FrRawElement pRawB)
|
||||
{
|
||||
return mpn_cmp(pRawA, pRawB, Fr_N64);
|
||||
}
|
||||
|
||||
void Fr_rawSwap(FrRawElement pRawResult, FrRawElement pRawA)
|
||||
{
|
||||
FrRawElement temp;
|
||||
|
||||
temp[0] = pRawResult[0];
|
||||
temp[1] = pRawResult[1];
|
||||
temp[2] = pRawResult[2];
|
||||
temp[3] = pRawResult[3];
|
||||
|
||||
pRawResult[0] = pRawA[0];
|
||||
pRawResult[1] = pRawA[1];
|
||||
pRawResult[2] = pRawA[2];
|
||||
pRawResult[3] = pRawA[3];
|
||||
|
||||
pRawA[0] = temp[0];
|
||||
pRawA[1] = temp[1];
|
||||
pRawA[2] = temp[2];
|
||||
pRawA[3] = temp[3];
|
||||
}
|
||||
|
||||
void Fr_rawCopyS2L(FrRawElement pRawResult, int64_t val)
|
||||
{
|
||||
pRawResult[0] = val;
|
||||
pRawResult[1] = 0;
|
||||
pRawResult[2] = 0;
|
||||
pRawResult[3] = 0;
|
||||
|
||||
if (val < 0)
|
||||
{
|
||||
pRawResult[1] = -1;
|
||||
pRawResult[2] = -1;
|
||||
pRawResult[3] = -1;
|
||||
|
||||
mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawAnd(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
|
||||
{
|
||||
mpn_and_n(pRawResult, pRawA, pRawB, Fr_N64);
|
||||
|
||||
pRawResult[3] &= lboMask;
|
||||
|
||||
if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawOr(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
|
||||
{
|
||||
mpn_ior_n(pRawResult, pRawA, pRawB, Fr_N64);
|
||||
|
||||
pRawResult[3] &= lboMask;
|
||||
|
||||
if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawXor(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
|
||||
{
|
||||
mpn_xor_n(pRawResult, pRawA, pRawB, Fr_N64);
|
||||
|
||||
pRawResult[3] &= lboMask;
|
||||
|
||||
if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawShl(FrRawElement r, FrRawElement a, uint64_t b)
|
||||
{
|
||||
uint64_t bit_shift = b % 64;
|
||||
uint64_t word_shift = b / 64;
|
||||
uint64_t word_count = Fr_N64 - word_shift;
|
||||
|
||||
mpn_copyi(r + word_shift, a, word_count);
|
||||
std::memset(r, 0, word_shift * sizeof(uint64_t));
|
||||
|
||||
if (bit_shift)
|
||||
{
|
||||
mpn_lshift(r, r, Fr_N64, bit_shift);
|
||||
}
|
||||
|
||||
r[3] &= lboMask;
|
||||
|
||||
if (mpn_cmp(r, Fr_rawq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(r, r, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b)
|
||||
{
|
||||
const uint64_t bit_shift = b % 64;
|
||||
const uint64_t word_shift = b / 64;
|
||||
const uint64_t word_count = Fr_N64 - word_shift;
|
||||
|
||||
mpn_copyi(r, a + word_shift, word_count);
|
||||
std::memset(r + word_count, 0, word_shift * sizeof(uint64_t));
|
||||
|
||||
if (bit_shift)
|
||||
{
|
||||
mpn_rshift(r, r, Fr_N64, bit_shift);
|
||||
}
|
||||
}
|
||||
|
||||
void Fr_rawNot(FrRawElement pRawResult, FrRawElement pRawA)
|
||||
{
|
||||
mpn_com(pRawResult, pRawA, Fr_N64);
|
||||
|
||||
pRawResult[3] &= lboMask;
|
||||
|
||||
if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
|
||||
{
|
||||
mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
|
||||
}
|
||||
}
|
||||
309
example/support/witnesscalc.cpp
Normal file
309
example/support/witnesscalc.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
#include "witnesscalc.h"
|
||||
#include "calcwit.hpp"
|
||||
#include "circom.hpp"
|
||||
#include "fr.hpp"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
namespace CIRCUIT_NAME {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
Circom_Circuit* loadCircuit(const void *buffer, unsigned long buffer_size) {
|
||||
if (buffer_size % sizeof(u32) != 0) {
|
||||
throw std::runtime_error("Invalid circuit file: wrong buffer_size");
|
||||
}
|
||||
|
||||
Circom_Circuit *circuit = new Circom_Circuit;
|
||||
|
||||
u8* bdata = (u8*)buffer;
|
||||
|
||||
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,IODefPair> templateInsId2IOSignalInfo1;
|
||||
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;
|
||||
if (inisize % sizeof(u32) != 0) {
|
||||
throw std::runtime_error("Invalid circuit file: wrong inisize");
|
||||
}
|
||||
u32 dataiomap[(buffer_size-inisize)/sizeof(u32)];
|
||||
memcpy((void *)dataiomap, (void *)(bdata+inisize), buffer_size-inisize);
|
||||
u32* pu32 = dataiomap;
|
||||
|
||||
for (int i = 0; i < get_size_of_io_map(); i++) {
|
||||
u32 n = *pu32;
|
||||
IODefPair p;
|
||||
p.len = n;
|
||||
IODef 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;
|
||||
}
|
||||
p.defs = (IODef*)calloc(10, sizeof(IODef));
|
||||
for (u32 j = 0; j < p.len; j++){
|
||||
p.defs[j] = defs[j];
|
||||
}
|
||||
templateInsId2IOSignalInfo1[index[i]] = p;
|
||||
}
|
||||
}
|
||||
circuit->templateInsId2IOSignalInfo = move(templateInsId2IOSignalInfo1);
|
||||
|
||||
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 {
|
||||
throw std::runtime_error("Invalid JSON type");
|
||||
}
|
||||
Fr_str2element (&v, s.c_str(), base);
|
||||
vval.push_back(v);
|
||||
} else {
|
||||
for (uint i = 0; i < val.size(); i++) {
|
||||
json2FrElements (val[i], vval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loadJson(Circom_CalcWit *ctx, const char *json_buffer, unsigned long buffer_size) {
|
||||
|
||||
json j = json::parse(json_buffer, json_buffer + buffer_size);
|
||||
|
||||
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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long getBinWitnessSize() {
|
||||
|
||||
uint Nwtns = get_size_of_witness();
|
||||
|
||||
return 44 + Fr_N64*8 * (Nwtns + 1);
|
||||
}
|
||||
|
||||
char *appendBuffer(char *buffer, const void *src, unsigned long src_size) {
|
||||
|
||||
memcpy(buffer, src, src_size);
|
||||
return buffer + src_size;
|
||||
}
|
||||
|
||||
char *appendBuffer(char *buffer, const u32 src) {
|
||||
|
||||
return appendBuffer(buffer, &src, 4);
|
||||
}
|
||||
|
||||
char *appendBuffer(char *buffer, const u64 src) {
|
||||
|
||||
return appendBuffer(buffer, &src, 8);
|
||||
}
|
||||
|
||||
char *appendBuffer(char *buffer, const FrRawElement src) {
|
||||
|
||||
return appendBuffer(buffer, src, Fr_N64*8);
|
||||
}
|
||||
|
||||
void storeBinWitness(Circom_CalcWit *ctx, char *buffer) {
|
||||
|
||||
buffer = appendBuffer(buffer, "wtns", 4);
|
||||
|
||||
u32 version = 2;
|
||||
buffer = appendBuffer(buffer, version);
|
||||
|
||||
u32 nSections = 2;
|
||||
buffer = appendBuffer(buffer, nSections);
|
||||
|
||||
// Header
|
||||
u32 idSection1 = 1;
|
||||
buffer = appendBuffer(buffer, idSection1);
|
||||
|
||||
u32 n8 = Fr_N64*8;
|
||||
|
||||
u64 idSection1length = 8 + n8;
|
||||
buffer = appendBuffer(buffer, idSection1length);
|
||||
|
||||
buffer = appendBuffer(buffer, n8);
|
||||
|
||||
buffer = appendBuffer(buffer, Fr_q.longVal);
|
||||
|
||||
uint Nwtns = get_size_of_witness();
|
||||
|
||||
u32 nVars = (u32)Nwtns;
|
||||
buffer = appendBuffer(buffer, nVars);
|
||||
|
||||
// Data
|
||||
u32 idSection2 = 2;
|
||||
buffer = appendBuffer(buffer, idSection2);
|
||||
|
||||
u64 idSection2length = (u64)n8*(u64)Nwtns;
|
||||
buffer = appendBuffer(buffer, idSection2length);
|
||||
|
||||
FrElement v;
|
||||
|
||||
for (int i=0;i<Nwtns;i++) {
|
||||
ctx->getWitness(i, &v);
|
||||
Fr_toLongNormal(&v, &v);
|
||||
buffer = appendBuffer(buffer, v.longVal);
|
||||
}
|
||||
}
|
||||
|
||||
int witnesscalc(
|
||||
const char *circuit_buffer, unsigned long circuit_size,
|
||||
const char *json_buffer, unsigned long json_size,
|
||||
char *wtns_buffer, unsigned long *wtns_size,
|
||||
char *error_msg, unsigned long error_msg_maxsize)
|
||||
{
|
||||
unsigned long witnessSize = getBinWitnessSize();
|
||||
|
||||
if (*wtns_size < witnessSize) {
|
||||
*wtns_size = witnessSize;
|
||||
return WITNESSCALC_ERROR_SHORT_BUFFER;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
std::unique_ptr<Circom_Circuit> circuit(loadCircuit(circuit_buffer, circuit_size));
|
||||
|
||||
std::unique_ptr<Circom_CalcWit> ctx(new Circom_CalcWit(circuit.get()));
|
||||
|
||||
loadJson(ctx.get(), json_buffer, json_size);
|
||||
|
||||
if (ctx.get()->getRemaingInputsToBeSet() != 0) {
|
||||
std::stringstream stream;
|
||||
stream << "Not all inputs have been set. Only "
|
||||
<< get_main_input_signal_no()-ctx.get()->getRemaingInputsToBeSet()
|
||||
<< " out of " << get_main_input_signal_no();
|
||||
|
||||
strncpy(error_msg, stream.str().c_str(), error_msg_maxsize);
|
||||
return WITNESSCALC_ERROR;
|
||||
}
|
||||
|
||||
storeBinWitness(ctx.get(), wtns_buffer);
|
||||
*wtns_size = witnessSize;
|
||||
|
||||
} catch (std::exception& e) {
|
||||
|
||||
if (error_msg) {
|
||||
strncpy(error_msg, e.what(), error_msg_maxsize);
|
||||
}
|
||||
return WITNESSCALC_ERROR;
|
||||
|
||||
} catch (std::exception *e) {
|
||||
|
||||
if (error_msg) {
|
||||
strncpy(error_msg, e->what(), error_msg_maxsize);
|
||||
}
|
||||
delete e;
|
||||
return WITNESSCALC_ERROR;
|
||||
|
||||
} catch (...) {
|
||||
if (error_msg) {
|
||||
strncpy(error_msg, "unknown error", error_msg_maxsize);
|
||||
}
|
||||
return WITNESSCALC_ERROR;
|
||||
}
|
||||
|
||||
return WITNESSCALC_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
33
example/support/witnesscalc.h
Normal file
33
example/support/witnesscalc.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef WITNESSCALC_H
|
||||
#define WITNESSCALC_H
|
||||
|
||||
namespace CIRCUIT_NAME {
|
||||
|
||||
#define WITNESSCALC_OK 0x0
|
||||
#define WITNESSCALC_ERROR 0x1
|
||||
#define WITNESSCALC_ERROR_SHORT_BUFFER 0x2
|
||||
|
||||
/**
|
||||
*
|
||||
* @return error code:
|
||||
* WITNESSCALC_OK - in case of success.
|
||||
* WITNESSCALC_ERROR - in case of an error.
|
||||
*
|
||||
* On success wtns_buffer is filled with witness data and
|
||||
* wtns_size contains the number bytes copied to wtns_buffer.
|
||||
*
|
||||
* If wtns_buffer is too small then the function returns WITNESSCALC_ERROR_SHORT_BUFFER
|
||||
* and the minimum size for wtns_buffer in wtns_size.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
witnesscalc(
|
||||
const char *circuit_buffer, unsigned long circuit_size,
|
||||
const char *json_buffer, unsigned long json_size,
|
||||
char *wtns_buffer, unsigned long *wtns_size,
|
||||
char *error_msg, unsigned long error_msg_maxsize);
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // WITNESSCALC_H
|
||||
Loading…
x
Reference in New Issue
Block a user