Puncte:0

Cum se generează constrângere pe operatorul de deplasare la dreapta pe biți în Circom

drapel nz

Cum se generează constrângere pe operatorul de deplasare la dreapta pe biți în limbajul circuitului circom?

Încerc să fac următoarele:

pragma circom 2.0.0;

template MAIN() {

    semnal de intrare v;
    tipul de ieșire a semnalului;

    tip <== v >> 5;
}

component principal = MAIN();

Primesc următoarea eroare:

eroare[T3001]: Constrângerile non-patratice nu sunt permise!
   ââ "/Utilizatori/ilia/compiling/main-circom/main.circom":68:5
   â
68 â tip <== v >> 5;
   â ^^^^^^^^^^^^^^^ găsit aici
   â
   = urmărirea apelurilor:
     ->PRINCIPALA

Cred că asta are de-a face cu faptul că v >> 5 expresia nu poate fi re-exprimată ca o expresie pătratică prin compilatorul circom.

Mă străduiesc să rescriu expresia să fie pătratică. Ar putea implica scrierea atribuirii și constrângerii ca două operațiuni separate, dar nu sunt sigur ce ar fi o constrângere de validare adecvată pentru o schimbare la dreapta.

În ceea ce privește cazurile de testare, mă aștept tip a fi $5$ când v este $168$ de exemplu.

drapel kr
Întrebările de programare sunt în afara subiectului pe Crypto SE.
meshcollider avatar
drapel gb
Deplasarea la dreapta cu n biți este aceeași cu împărțirea cu 2^n, așa că o puteți folosi pentru a constrânge (înmulțiți cealaltă parte cu 2^n și utilizați o mască pentru a șterge biții inferiori). Puteți utiliza doar atribuirea cu `
drapel nz
Am fost direcționat către acest stackexchange când am pus o întrebare despre Circom pe StackOverflow... Am incercat: `tip > 5; tip * 32 === v & 0xE0;` dar acum primesc „Constrângerile non-cuadratice nu sunt permise” pe linia `type * 32 === v & 0xE0`
drapel nz
Cum pot genera constrângeri pentru un operator și pe biți? M-am uitat în circomlib, dar nu am găsit nimic care să se potrivească destul de bine, vezi doar `& 1`, dar asta nu este suficient de generic, nu cred.
drapel nz
Am încercat acest lucru pentru a genera o constrângere asupra operatorului &: `verificarea semnalului; Verifica
kelalaka avatar
drapel in
Cine a adresat această întrebare aici? Există deja întrebări și răspunsuri SageMath acolo, dar acest lucru a fost în afara subiectului?
drapel nz
Am fost direcționat către acest stackexchange aici: https://stackoverflow.com/questions/70891895/how-to-pass-function-argument-by-reference-in-circom#comment125326319_70891895 cu raționamentul că „crypto.stackexchange.com ar putea fi mai potrivit pentru întrebările legate de ZKP"
Puncte:1
drapel gb

Soluție folosind comparatorul LessThan de la circomlib:

//... import comparatori de la circomlib ...

template MAIN() {

    semnal de intrare v;
    tipul de ieșire a semnalului;
    semnal check_v;
    component lessThan = LessThan(8);

    tip <-- v >> 5;
    check_v <== tip*32;
    // folosiți circomlib LessThan pentru a verifica dacă (v - check_v) < 32
    lessThan.in[0] <== v - check_v;
    lessThan.in[1] <== 32;    
    lessThan.out === 1;
}

component principal = MAIN();
```
drapel nz
Da, a funcționat. Mulțumesc! `component lessThan = LessThan(8); // 8 biți complet lessThan.in[0]
meshcollider avatar
drapel gb
Dulce! Mi-am actualizat răspunsul cu codul final atunci. Ar trebui să curățăm aceste comentarii.
Puncte:0
drapel nz

EDIT: Acest lucru nu verifică suficient funcționarea schimburilor. Vedeți în schimb răspunsul lui @meshcollider.

Ok, nu sunt pe deplin sigur dacă acest lucru este corect, dar asta este ceea ce am venit.

pragma circom 2.0.0;

template MAIN() {

    semnal de intrare v;
    tipul de ieșire a semnalului;

    // atribuie semnalul `tip`
    // mutați 0bXXXYYYYY la 0b00000XXX
    // v este un semnal de încredere
    tip <-- v >> 5;

    // pregătește verificarea constrângerii pentru `type`
    semnal trei_biți_superiori;
    // 0b11100000 = 0xE0
    // v este un semnal de încredere
    trei_biți_superiori <-- v & 0xE0; // 3 biți superiori ai v (0bXXX00000). v poate avea doar 8 biți.

    // should_only_be_lower_bits este 0b000YYYYY
    // îl obținem cu 0bXXXYYYYY - 0bXXX00000 pentru a obține 0b000YYYYY
    var should_only_be_lower_bits = v - three_upper_bits;
    // verificăm că should_only_be_lower_bits poate fi doar MAI MAI DE 32 (0b00011111)
    // care verifică că trei_biți_superiori sunt curați și nu au fost încurcați.
    // dacă cineva s-ar încurca cu trei_biți_superiori, should_only_be_lower_bits ar conține biți mai mari
    // și să fie mai mare de 32 (0b00011111).
    // făcând asta, afirmăm criptografic că should_only_be_lower_bits este sub forma 0b000YYYYY
    semnal upper_bit_1;
    semnal upper_bit_2;
    semnal upper_bit_3;
    upper_bit_1 <-- should_only_be_lower_bits & 0x80; // 0b10000000. Acest semnal poate fi 0bX0000000
    upper_bit_2 <-- should_only_be_lower_bits & 0x40; // 0b01000000. Acest semnal poate fi 0b0X000000
    upper_bit_3 <-- should_only_be_lower_bits & 0x20; // 0b00100000. Acest semnal poate fi 0b00X00000
    upper_bit_1 === 0; // Afirmați că 0bX0000000 este 0b00000000
    upper_bit_2 === 0; // Afirmați că 0b0X000000 este 0b00000000
    upper_bit_3 === 0; // Afirmați că 0b00X00000 este 0b00000000

    // generează constrângere pentru semnal de tip
    // 2^5 = 32
    tip * 32 === trei_biți_superiori;
}

component principal = MAIN();

Comentariile îmi trec prin gândire, dar în esență verific atribuirile de semnal cu constrângeri de scădere/multiplicare.

meshcollider avatar
drapel gb
Puteți combina cele trei verificări de biți `upper_bit_` dacă utilizați 0xE0
drapel nz
Este adevărat. De asemenea, cred că trebuie să verific dacă v este doar 8 biți și nu mai mult.
meshcollider avatar
drapel gb
De asemenea, este posibil să fi ascuns problema aici: `three_upper_bits
drapel nz
@meshcollider este un punct foarte bun! Habar n-am ce fac. Încă nu sunt sigur care este modalitatea sigură de a verifica funcționarea `>> 5`.
Puncte:0
drapel nz

circomlib/circuits/sha256/shift.circom are o ShR componentă care efectuează schimbarea la dreapta.

    var InputBits = 8;
    var ResultBits = 3;

    // convertiți v în biți
    componenta n2b = Num2Bits(InputBits);
    n2b.in <== v;

    // schimb
    componenta shr = ShR(InputBits, 5); // v >> 5
    pentru (var i = 0; i < InputBits; i++) {
        shr.in[i] <== n2b.out[i];
    }

    // convertiți înapoi în număr
    componenta b2n = Bits2Num(ResultBits);
    pentru (var i = 0; i < ResultBits; i++) {
        b2n.in[i] <== shr.out[i];
    }
    tip <== b2n.out;

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.