arnaucube
arnaucube/circomlibPublic Self-hosted repository
circomlib/circuits/eddsa.circom
circuits/eddsa.circomRaw
  1/*
  2    Copyright 2018 0KIMS association.
  3
  4    This file is part of circom (Zero Knowledge Circuit Compiler).
  5
  6    circom is a free software: you can redistribute it and/or modify it
  7    under the terms of the GNU General Public License as published by
  8    the Free Software Foundation, either version 3 of the License, or
  9    (at your option) any later version.
 10
 11    circom is distributed in the hope that it will be useful, but WITHOUT
 12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 13    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
 14    License for more details.
 15
 16    You should have received a copy of the GNU General Public License
 17    along with circom. If not, see <https://www.gnu.org/licenses/>.
 18*/
 19
 20include "compconstant.circom";
 21include "pointbits.circom";
 22include "pedersen.circom";
 23include "escalarmulany.circom";
 24include "escalarmulfix.circom";
 25
 26template EdDSAVerifier(n) {
 27    signal input msg[n];
 28
 29    signal input A[256];
 30    signal input R8[256];
 31    signal input S[256];
 32
 33    signal Ax;
 34    signal Ay;
 35
 36    signal R8x;
 37    signal R8y;
 38
 39    var i;
 40
 41// Ensure S<Subgroup Order
 42
 43    component  compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
 44
 45    for (i=0; i<254; i++) {
 46        S[i] ==> compConstant.in[i];
 47    }
 48    compConstant.out === 0;
 49    S[254] === 0;
 50    S[255] === 0;
 51
 52// Convert A to Field elements (And verify A)
 53
 54    component bits2pointA = Bits2Point_Strict();
 55
 56    for (i=0; i<256; i++) {
 57        bits2pointA.in[i] <== A[i];
 58    }
 59    Ax <== bits2pointA.out[0];
 60    Ay <== bits2pointA.out[1];
 61
 62// Convert R8 to Field elements (And verify R8)
 63
 64    component bits2pointR8 = Bits2Point_Strict();
 65
 66    for (i=0; i<256; i++) {
 67        bits2pointR8.in[i] <== R8[i];
 68    }
 69    R8x <== bits2pointR8.out[0];
 70    R8y <== bits2pointR8.out[1];
 71
 72// Calculate the h = H(R,A, msg)
 73
 74    component hash = Pedersen(512+n);
 75
 76    for (i=0; i<256; i++) {
 77        hash.in[i] <== R8[i];
 78        hash.in[256+i] <== A[i];
 79    }
 80    for (i=0; i<n; i++) {
 81        hash.in[512+i] <== msg[i];
 82    }
 83
 84    component point2bitsH = Point2Bits_Strict();
 85    point2bitsH.in[0] <== hash.out[0];
 86    point2bitsH.in[1] <== hash.out[1];
 87
 88// Calculate second part of the right side:  right2 = h*8*A
 89
 90    // Multiply by 8 by adding it 3 times.  This also ensure that the result is in
 91    // the subgroup.
 92    component dbl1 = BabyDbl();
 93    dbl1.x <== Ax;
 94    dbl1.y <== Ay;
 95    component dbl2 = BabyDbl();
 96    dbl2.x <== dbl1.xout;
 97    dbl2.y <== dbl1.yout;
 98    component dbl3 = BabyDbl();
 99    dbl3.x <== dbl2.xout;
100    dbl3.y <== dbl2.yout;
101
102    // We check that A is not zero.
103    component isZero = IsZero();
104    isZero.in <== dbl3.x;
105    isZero.out === 0;
106
107    component mulAny = EscalarMulAny(256);
108    for (i=0; i<256; i++) {
109        mulAny.e[i] <== point2bitsH.out[i];
110    }
111    mulAny.p[0] <== dbl3.xout;
112    mulAny.p[1] <== dbl3.yout;
113
114
115// Compute the right side: right =  R8 + right2
116
117    component addRight = BabyAdd();
118    addRight.x1 <== R8x;
119    addRight.y1 <== R8y;
120    addRight.x2 <== mulAny.out[0];
121    addRight.y2 <== mulAny.out[1];
122
123// Calculate left side of equation left = S*B8
124
125    var BASE8 = [
126        5299619240641551281634865583518297030282874472190772894086521144482721001553,
127        16950150798460657717958625567821834550301663161624707787222815936182638968203
128    ];
129    component mulFix = EscalarMulFix(256, BASE8);
130    for (i=0; i<256; i++) {
131        mulFix.e[i] <== S[i];
132    }
133
134// Do the comparation left == right
135
136    mulFix.out[0] === addRight.xout;
137    mulFix.out[1] === addRight.yout;
138}