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