-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added latest cicuit but test failing
- Loading branch information
Showing
16 changed files
with
485 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# Notes | ||
|
||
This version of the AA is the one with just Sha256 + RSA and no nullifiers with 917,344 contraints. | ||
This is the latest version of the AA circuits with in total 1,767,153 contraints. |
111 changes: 111 additions & 0 deletions
111
mopro-core/examples/circom/anonAadhaar/aadhaar-verifier.circom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
pragma circom 2.1.6; | ||
|
||
include "./helpers/rsa.circom"; | ||
include "./helpers/sha.circom"; | ||
include "./helpers/timestamp.circom"; | ||
include "./extractor.circom"; | ||
|
||
// Circuit to verify Aadhaar signature | ||
// n: RSA pubic key size per chunk | ||
// k: Number of chunks the RSA public key is split into | ||
// maxDataLength: Maximum length of the data | ||
template AadhaarVerifier(n, k, maxDataLength) { | ||
signal input aadhaarData[maxDataLength]; // Aadhaar data padded (the data that is SHA hashed and signed) | ||
signal input aadhaarDataLength; // length of the padded data | ||
signal input signature[k]; // RSA signature | ||
signal input pubKey[k]; // RSA public key (of the government) | ||
signal input signalHash; | ||
|
||
signal output identityNullifier; // Hash of last 4 digits of Aadhaar number, name, DOB, gender and pin code | ||
signal output userNullifier; // Hash of last 4 digits of Aadhaar number and photo | ||
signal output timestamp; // Timestamp of when the data was signed - extracted and converted to Unix timestamp | ||
signal output pubkeyHash; // Poseidon hash of the RSA public key | ||
|
||
|
||
component shaHasher = Sha256Bytes(maxDataLength); | ||
shaHasher.in_padded <== aadhaarData; | ||
shaHasher.in_len_padded_bytes <== aadhaarDataLength; | ||
signal sha[256]; | ||
sha <== shaHasher.out; | ||
|
||
|
||
component rsa = RSAVerify65537(n, k); | ||
var rsaMsgLength = (256 + n) \ n; | ||
component rsaBaseMsg[rsaMsgLength]; | ||
for (var i = 0; i < rsaMsgLength; i++) { | ||
rsaBaseMsg[i] = Bits2Num(n); | ||
} | ||
for (var i = 0; i < 256; i++) { | ||
rsaBaseMsg[i \ n].in[i % n] <== sha[255 - i]; | ||
} | ||
for (var i = 256; i < n * rsaMsgLength; i++) { | ||
rsaBaseMsg[i \ n].in[i % n] <== 0; | ||
} | ||
|
||
for (var i = 0; i < rsaMsgLength; i++) { | ||
rsa.base_message[i] <== rsaBaseMsg[i].out; | ||
} | ||
for (var i = rsaMsgLength; i < k; i++) { | ||
rsa.base_message[i] <== 0; | ||
} | ||
|
||
for (var i = 0; i < k; i++) { | ||
rsa.modulus[i] <== pubKey[i]; | ||
rsa.signature[i] <== signature[i]; | ||
} | ||
|
||
|
||
component extractor = Extractor(maxDataLength); | ||
extractor.dataLen <== aadhaarDataLength; | ||
extractor.data <== aadhaarData; | ||
|
||
signal last4Digits[4] <== extractor.last4Digits; | ||
signal photoHash <== extractor.photoHash; | ||
signal basicIdentityHash <== extractor.basicIdentityHash; | ||
|
||
component poseidonHasher[2]; | ||
poseidonHasher[0] = Poseidon(5); | ||
poseidonHasher[0].inputs <== [last4Digits[0], last4Digits[1], last4Digits[2], last4Digits[3], photoHash]; | ||
|
||
poseidonHasher[1] = Poseidon(5); | ||
poseidonHasher[1].inputs <== [last4Digits[0], last4Digits[1], last4Digits[2], last4Digits[3], basicIdentityHash]; | ||
|
||
userNullifier <== poseidonHasher[0].out; | ||
identityNullifier <== poseidonHasher[1].out; | ||
|
||
|
||
// Output the timestamp rounded to nearest hour | ||
component dateToUnixTime = DateStringToTimestamp(2030, 1, 0, 0); | ||
for (var i = 0; i < 14; i++) { | ||
dateToUnixTime.in[i] <== aadhaarData[i + 6]; | ||
} | ||
timestamp <== dateToUnixTime.out - 19800; // 19800 is the offset for IST | ||
|
||
|
||
// Calculate Poseidon hash of the public key. | ||
// Poseidon component can take only 16 inputs, so we convert k chunks to k/2 chunks. | ||
// We are assuming k is > 16 and <= 32 (i.e we merge two consecutive item in array to bring down the size) | ||
var poseidonInputSize = k \ 2; | ||
if (k % 2 == 1) { | ||
poseidonInputSize++; | ||
} | ||
assert(poseidonInputSize <= 16); | ||
signal pubkeyHasherInput[poseidonInputSize]; | ||
for (var i = 0; i < poseidonInputSize; i++) { | ||
if (i == poseidonInputSize - 1 && poseidonInputSize % 2 == 1) { | ||
pubkeyHasherInput[i] <== pubKey[i * 2]; | ||
} else { | ||
pubkeyHasherInput[i] <== pubKey[i * 2] + (1 << n) * pubKey[i * 2 + 1]; | ||
} | ||
} | ||
component pubkeyHasher = Poseidon(poseidonInputSize); | ||
pubkeyHasher.inputs <== pubkeyHasherInput; | ||
pubkeyHash <== pubkeyHasher.out; | ||
|
||
|
||
signal signalHashSquare; | ||
signalHashSquare <== signalHash * signalHash; | ||
} | ||
|
||
|
||
component main { public [signalHash] } = AadhaarVerifier(64, 32, 512 * 3); |
145 changes: 145 additions & 0 deletions
145
mopro-core/examples/circom/anonAadhaar/extractor.circom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
pragma circom 2.1.6; | ||
|
||
include "./node_modules/circomlib/circuits/comparators.circom"; | ||
include "./node_modules/circomlib/circuits/poseidon.circom"; | ||
|
||
|
||
/** | ||
return 1 if left <= element <= right | ||
else return 0; | ||
**/ | ||
template InRange(n) { | ||
signal input left; | ||
signal input right; | ||
signal input element; | ||
|
||
signal output out; | ||
|
||
component l = GreaterEqThan(n); | ||
component r = GreaterEqThan(n); | ||
|
||
l.in[0] <== element; | ||
l.in[1] <== left; | ||
|
||
r.in[0] <== right; | ||
r.in[1] <== element; | ||
|
||
out <== l.out * r.out; | ||
} | ||
|
||
|
||
template PhotoPositionComputation(MAX_NUMBER_BYTES) { | ||
signal input dataLen; | ||
signal input data[MAX_NUMBER_BYTES]; | ||
signal input filter[MAX_NUMBER_BYTES]; | ||
|
||
signal output photoPosition[2]; | ||
|
||
signal numberElementLessThan16[MAX_NUMBER_BYTES]; | ||
numberElementLessThan16[0] <== 0; | ||
signal lessThan[MAX_NUMBER_BYTES - 1]; | ||
for (var i = 1; i < MAX_NUMBER_BYTES; i++) { | ||
lessThan[i - 1] <== LessThan(8)([filter[i], 16]); | ||
numberElementLessThan16[i] <== numberElementLessThan16[i - 1] + lessThan[i -1 ]; | ||
} | ||
|
||
signal totalBasicFieldsSize <== numberElementLessThan16[MAX_NUMBER_BYTES - 1]; | ||
|
||
photoPosition[0] <== totalBasicFieldsSize + 1; | ||
|
||
signal index[MAX_NUMBER_BYTES]; | ||
signal equals[MAX_NUMBER_BYTES]; | ||
signal acctualLen[MAX_NUMBER_BYTES]; | ||
signal tmp[MAX_NUMBER_BYTES - 1]; | ||
|
||
index[0] <== 0; | ||
acctualLen[0] <== 0; | ||
equals[0] <== 0; | ||
|
||
for (var i = 1; i < MAX_NUMBER_BYTES; i++) { | ||
index[i] <== index[i - 1] + 1; | ||
equals[i] <== IsEqual()([index[i], dataLen - 1]); | ||
tmp[i - 1] <== data[i - 1] * 256 + data[i]; | ||
acctualLen[i] <== (tmp[i - 1] - acctualLen[i - 1]) * equals[i] + acctualLen[i - 1]; | ||
} | ||
|
||
photoPosition[1] <== acctualLen[MAX_NUMBER_BYTES - 1]/8 - 65; | ||
|
||
} | ||
|
||
|
||
template Extractor(MAX_NUMBER_BYTES) { | ||
signal input data[MAX_NUMBER_BYTES]; | ||
signal input dataLen; | ||
|
||
signal output photoHash; | ||
signal output basicIdentityHash; | ||
signal output last4Digits[4]; | ||
|
||
signal sData[MAX_NUMBER_BYTES]; | ||
|
||
component isData255[MAX_NUMBER_BYTES - 1]; | ||
|
||
sData[0] <== 0; | ||
|
||
for (var i = 0; i < MAX_NUMBER_BYTES - 1; i++) { | ||
isData255[i] = IsEqual(); | ||
isData255[i].in[0] <== 255; | ||
isData255[i].in[1] <== data[i + 1]; | ||
sData[i + 1] <== sData[i] + isData255[i].out; | ||
} | ||
|
||
|
||
component photoPositionComputation = PhotoPositionComputation(MAX_NUMBER_BYTES); | ||
photoPositionComputation.dataLen <== dataLen; | ||
photoPositionComputation.filter <== sData; | ||
photoPositionComputation.data <== data; | ||
|
||
signal photoPosition[2] <== photoPositionComputation.photoPosition; | ||
|
||
signal photoFlag[MAX_NUMBER_BYTES]; | ||
for (var i = 0; i < MAX_NUMBER_BYTES; i++) { | ||
photoFlag[i] <== InRange(12)(photoPosition[0], photoPosition[1], i); | ||
} | ||
|
||
photoHash <== HashChain(MAX_NUMBER_BYTES)(photoFlag, data); | ||
|
||
signal basicIdentityFlag[MAX_NUMBER_BYTES]; | ||
signal pincodeFlag[MAX_NUMBER_BYTES]; | ||
signal identityFlag[MAX_NUMBER_BYTES]; | ||
|
||
for (var i = 0; i < MAX_NUMBER_BYTES; i++) { | ||
basicIdentityFlag[i] <== InRange(12)(2, 4, sData[i]); | ||
pincodeFlag[i] <== IsEqual()([10, sData[i]]); | ||
identityFlag[i] <== basicIdentityFlag[i] + pincodeFlag[i] - basicIdentityFlag[i] * pincodeFlag[i]; | ||
} | ||
|
||
basicIdentityHash <== HashChain(MAX_NUMBER_BYTES)(identityFlag, data); | ||
|
||
// extract last fordigit; | ||
for (var i = 0; i < 4; i++) { | ||
last4Digits[i] <== data[i + 2]; | ||
} | ||
} | ||
|
||
template HashChain(MAX_NUMBER_BYTES) { | ||
signal input flag[MAX_NUMBER_BYTES]; | ||
signal input data[MAX_NUMBER_BYTES]; | ||
|
||
signal output hash; | ||
|
||
signal hashChain[MAX_NUMBER_BYTES]; | ||
|
||
component hasher[MAX_NUMBER_BYTES - 1]; | ||
// We always skip the first element, since email_or_phone unnessanary when compute nullifier; | ||
hashChain[0] <== 0; | ||
|
||
for (var i = 0; i < MAX_NUMBER_BYTES - 1; i++) { | ||
hasher[i] = Poseidon(2); | ||
hasher[i].inputs[0] <== hashChain[i]; | ||
hasher[i].inputs[1] <== data[i + 1]; | ||
hashChain[i + 1] <== (hasher[i].out - hashChain[i]) * flag[i + 1] + hashChain[i]; | ||
} | ||
|
||
hash <== hashChain[MAX_NUMBER_BYTES - 1]; | ||
} |
6 changes: 3 additions & 3 deletions
6
...examples/circom/anonAadhaar/bigint.circom → .../circom/anonAadhaar/helpers/bigint.circom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
6 changes: 3 additions & 3 deletions
6
...ore/examples/circom/anonAadhaar/fp.circom → ...ples/circom/anonAadhaar/helpers/fp.circom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
...re/examples/circom/anonAadhaar/sha.circom → ...les/circom/anonAadhaar/helpers/sha.circom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
...s/circom/anonAadhaar/sha256general.circom → .../anonAadhaar/helpers/sha256general.circom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
...s/circom/anonAadhaar/sha256partial.circom → .../anonAadhaar/helpers/sha256partial.circom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.