arnaucube
arnaucube/circomlibPublic Self-hosted repository
circomlib/circuits/eddsa.circom
circuits/eddsa.circomRaw
  1include "compconstant.circom";
  2include "pointbits.circom";
  3include "pedersen.circom";
  4include "escalarmulany.circom";
  5include "escalarmulfix.circom";
  6
  7template EdDSAVerifier(n) {
  8    signal input msg[n];
  9
 10    signal input A[256];
 11    signal input R8[256];
 12    signal input S[256];
 13
 14    signal Ax;
 15    signal Ay;
 16
 17    signal R8x;
 18    signal R8y;
 19
 20    var i;
 21
 22// Ensure S<Subgroup Order
 23
 24    component  compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
 25
 26    for (i=0; i<254; i++) {
 27        S[i] ==> compConstant.in[i];
 28    }
 29    compConstant.out === 0;
 30    S[254] === 0;
 31    S[255] === 0;
 32
 33// Convert A to Field elements (And verify A)
 34
 35    component bits2pointA = Bits2Point_Strict();
 36
 37    for (i=0; i<256; i++) {
 38        bits2pointA.in[i] <== A[i];
 39    }
 40    Ax <== bits2pointA.out[0];
 41    Ay <== bits2pointA.out[1];
 42
 43// Convert R8 to Field elements (And verify R8)
 44
 45    component bits2pointR8 = Bits2Point_Strict();
 46
 47    for (i=0; i<256; i++) {
 48        bits2pointR8.in[i] <== R8[i];
 49    }
 50    R8x <== bits2pointR8.out[0];
 51    R8y <== bits2pointR8.out[1];
 52
 53// Calculate the h = H(R,A, msg)
 54
 55    component hash = Pedersen(512+n);
 56
 57    for (i=0; i<256; i++) {
 58        hash.in[i] <== R8[i];
 59        hash.in[256+i] <== A[i];
 60    }
 61    for (i=0; i<n; i++) {
 62        hash.in[512+i] <== msg[i];
 63    }
 64
 65    component point2bitsH = Point2Bits_Strict();
 66    point2bitsH.in[0] <== hash.out[0];
 67    point2bitsH.in[1] <== hash.out[1];
 68
 69// Calculate second part of the right side:  right2 = h*8*A
 70
 71    // Multiply by 8 by adding it 3 times.  This also ensure that the result is in
 72    // the subgroup.
 73    component dbl1 = BabyDbl();
 74    dbl1.x <== Ax;
 75    dbl1.y <== Ay;
 76    component dbl2 = BabyDbl();
 77    dbl2.x <== dbl1.xout;
 78    dbl2.y <== dbl1.yout;
 79    component dbl3 = BabyDbl();
 80    dbl3.x <== dbl2.xout;
 81    dbl3.y <== dbl2.yout;
 82
 83    // We check that A is not zero.
 84    component isZero = IsZero();
 85    isZero.in <== dbl3.x;
 86    isZero.out === 0;
 87
 88    component mulAny = EscalarMulAny(256);
 89    for (i=0; i<256; i++) {
 90        mulAny.e[i] <== point2bitsH.out[i];
 91    }
 92    mulAny.p[0] <== dbl3.xout;
 93    mulAny.p[1] <== dbl3.yout;
 94
 95
 96// Compute the right side: right =  R8 + right2
 97
 98    component addRight = BabyAdd();
 99    addRight.x1 <== R8x;
100    addRight.y1 <== R8y;
101    addRight.x2 <== mulAny.out[0];
102    addRight.y2 <== mulAny.out[1];
103
104// Calculate left side of equation left = S*B8
105
106    var BASE8 = [
107        17777552123799933955779906779655732241715742912184938656739573121738514868268,
108        2626589144620713026669568689430873010625803728049924121243784502389097019475
109    ];
110    component mulFix = EscalarMulFix(256, BASE8);
111    for (i=0; i<256; i++) {
112        mulFix.e[i] <== S[i];
113    }
114
115// Do the comparation left == right
116
117    mulFix.out[0] === addRight.xout;
118    mulFix.out[1] === addRight.yout;
119}