Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
847b88d
make contract sdk simpler (#514)
motemotech Apr 17, 2025
b841f28
Revert "make contract sdk simpler (#514)" (#518)
remicolin Apr 17, 2025
1dba6d3
merge dev into main (#576)
remicolin May 29, 2025
46f6b91
feat(wip): register circuit for aadhaar
Vishalkulkarni45 Jun 3, 2025
96be955
chore: add anon aadhar circuits
Nesopie Jun 3, 2025
b750cfd
chore: remove sc and disclose selfrica test
Vishalkulkarni45 Jun 3, 2025
e4288b7
feat: extract aadhaar qr data
Vishalkulkarni45 Jun 3, 2025
67e1f7c
test: aadhaar qr data extract circuit
Vishalkulkarni45 Jun 3, 2025
69d00c7
test: aadhaar register circuit
Vishalkulkarni45 Jun 4, 2025
056a975
feat: extract pincode and ph no last 4 digit
Vishalkulkarni45 Jun 4, 2025
3ae3aaf
fix: register aadhaar nullifier and commitment
Vishalkulkarni45 Jun 5, 2025
6df7cb1
test: Verify commitment circuit of aadhaar
Vishalkulkarni45 Jun 5, 2025
f6d3703
feat: add photoHash inside commitment
Vishalkulkarni45 Jun 5, 2025
1e0e1b2
feat: build Aadhaar OFAC SMT
Vishalkulkarni45 Jun 5, 2025
0e1bd36
feat: ofac check and reveal data (test done)
Vishalkulkarni45 Jun 6, 2025
998ce57
test: qr extractor for custom data input
Vishalkulkarni45 Jun 9, 2025
dd70993
feat: add state as reveal data inside VC and disclose
Vishalkulkarni45 Jun 9, 2025
e771601
chore: add comments
Vishalkulkarni45 Jun 9, 2025
c2dcdc3
fix: num2Ceil component
Vishalkulkarni45 Jun 9, 2025
8cc2ea0
chore: review changes
Vishalkulkarni45 Jun 10, 2025
8cc5425
chore: use passport SignatureVerifier
Vishalkulkarni45 Jun 10, 2025
a1ec260
fix: signatureVerifier inputs
Vishalkulkarni45 Jun 10, 2025
98c0520
feat: extract ascii values of fields
Vishalkulkarni45 Jun 10, 2025
b247094
feat: provide users the flexibility to reveal specific characters of …
Vishalkulkarni45 Jun 11, 2025
b1ec4b3
chore: refactor
Vishalkulkarni45 Jun 11, 2025
bd7ccb7
test: register aadhaar for tampered data
Vishalkulkarni45 Jun 11, 2025
d85a186
test(wip): should return 0 if in ofac list
Vishalkulkarni45 Jun 11, 2025
462d0da
test: ofac check
Vishalkulkarni45 Jun 12, 2025
0cdfdc6
test: register aadhaar circuit for different qr data
Vishalkulkarni45 Jun 12, 2025
cb2ef91
merge dev into main (#683)
remicolin Jun 25, 2025
4140e44
fix: commitment hash
Vishalkulkarni45 Aug 10, 2025
80b1eac
fix: register aadhaar test
Vishalkulkarni45 Aug 13, 2025
8d8ba1b
chore: refactor
Vishalkulkarni45 Aug 13, 2025
6f68e7f
feat: reveal data in packed bytes
Vishalkulkarni45 Aug 13, 2025
f12b9f5
feat: add constrain on delimiterIndices
Vishalkulkarni45 Aug 15, 2025
436a200
feat: reveal timestamp
Vishalkulkarni45 Aug 15, 2025
1c1b0f0
Merge pull request #1 from Vishalkulkarni45/feat/aadhaar-int
Nesopie Aug 18, 2025
8de8e9a
merge main into feat/aadhaar
Nesopie Aug 18, 2025
b5ab8e1
merge main to feat/aadhaar
Nesopie Aug 19, 2025
22f2b52
fix: tests
Nesopie Aug 19, 2025
eb8bbe9
feat: hash pubKey
Vishalkulkarni45 Aug 19, 2025
f3a1602
feat: add registry contract
Nesopie Aug 19, 2025
611a114
feat: Update HubImplV2 (WIP)
Nesopie Aug 19, 2025
1925718
chore: merge feat/aadhaar
Nesopie Aug 19, 2025
4ff80f0
add functions to generate aadhaar data (WIP)
Nesopie Aug 20, 2025
b4e6c1c
modularize aadhaar data generation (WIP)
Nesopie Aug 20, 2025
f0c5cb8
fix(wip): register test
Vishalkulkarni45 Aug 20, 2025
db8295f
fix: test qr extractor
Nesopie Aug 20, 2025
fff34b4
fix
Nesopie Aug 20, 2025
864af0e
chore: refactor functions
Nesopie Aug 20, 2025
ee206b6
feat: add age extractor and tested
Vishalkulkarni45 Aug 21, 2025
7c5f20f
feat: add isMiniumAge check
Vishalkulkarni45 Aug 21, 2025
4cfdb71
fix: prepareAadhaarTestData func
Vishalkulkarni45 Aug 21, 2025
5eaf8d6
registry contract tests
Nesopie Aug 21, 2025
545c1d0
feat: registry contract tests
Nesopie Aug 21, 2025
15dd2a6
feat: extract fields from qr data bytes
Vishalkulkarni45 Aug 21, 2025
ea8ac1c
chore: refactor mockData
Vishalkulkarni45 Aug 22, 2025
d907a9e
feat: move minimum age to revealPackedData
Vishalkulkarni45 Aug 22, 2025
48dece3
feat: create a constant.ts to retrive fields from unpacked bytes
Vishalkulkarni45 Aug 22, 2025
ed249fe
chore: refactor
Vishalkulkarni45 Aug 22, 2025
da7b23c
fix: exports
Nesopie Aug 22, 2025
701aa9f
rebase
Nesopie Aug 22, 2025
f44dfba
rebase
Nesopie Aug 22, 2025
df28a81
feat: add public signal ,indices mapping
Vishalkulkarni45 Aug 22, 2025
0836909
chore: add public output to indices mapping
Vishalkulkarni45 Aug 22, 2025
51f7a62
fix:AADHAAR_PUBLIC_SIGNAL_INDICES
Vishalkulkarni45 Aug 22, 2025
1435569
feat: make nullifier public
Vishalkulkarni45 Aug 22, 2025
9f851a1
fix: nullifier cal for disclose circuits
Vishalkulkarni45 Aug 22, 2025
14aab02
feat: merge isMiniumAgeValid and miniumAge signal
Vishalkulkarni45 Aug 22, 2025
326b8c0
fix: disclsoe test
Vishalkulkarni45 Aug 22, 2025
8f3fbf7
feat: support for user identifier and secret
Vishalkulkarni45 Aug 22, 2025
652d935
chore :refactor
Vishalkulkarni45 Aug 22, 2025
1b746d7
feat: ofac test last name , firstname
Vishalkulkarni45 Aug 22, 2025
0647aa7
feat: add forbidden_countries_list check
Vishalkulkarni45 Aug 22, 2025
0b99a6b
feat: add tests for aadhaar (WIP)
Nesopie Aug 23, 2025
f4ac91c
Merge pull request #2 from Vishalkulkarni45/feat/ofac-forbCountry
Nesopie Aug 23, 2025
aec41fa
failing ofac tests
Nesopie Aug 23, 2025
a822731
feat: finish contract tests
Nesopie Aug 25, 2025
de6e74d
fix: merge conflicts
Nesopie Aug 25, 2025
7b6229c
merge feat/aadhaar
Nesopie Aug 25, 2025
7fcdb11
Merge pull request #3 from Vishalkulkarni45/feat/aadhaar-contracts
Nesopie Aug 25, 2025
e8f44a7
Merge remote-tracking branch 'upstream/dev' into feat/aadhaar
Nesopie Aug 25, 2025
ec914aa
update the common package to be usable in circuits and contracts
Nesopie Aug 25, 2025
ea17ea5
Merge remote-tracking branch 'upstream/dev' into feat/aadhaar
Nesopie Aug 25, 2025
5d00821
lint everything
Nesopie Aug 25, 2025
4613a8a
coderabbit fixes
Nesopie Aug 25, 2025
228da2b
merge dev
Nesopie Aug 25, 2025
837b27a
chore: update name dob,yob aadhaar ofac tree
Vishalkulkarni45 Aug 26, 2025
6fdf6df
feat: merge ofac and reverse ofac check into one
Vishalkulkarni45 Aug 26, 2025
d0f735f
test: merged ofac constrain
Vishalkulkarni45 Aug 26, 2025
385bee0
SELF-253 feat: add user email feedback (#889)
seshanthS Aug 25, 2025
fbda4f9
chore: centralize license header checks (#952)
transphorm Aug 25, 2025
5a4afbf
update unsupported passport screen (#953)
remicolin Aug 25, 2025
1a78810
feat: support new ofac trees
Nesopie Aug 27, 2025
3905a30
fix: qr extractor tests
Nesopie Sep 4, 2025
e8f8093
chore: remove unassigned age signal
Vishalkulkarni45 Sep 3, 2025
7eeccd5
chore: modify timestamp func comment
Vishalkulkarni45 Sep 3, 2025
eff1689
fix: add constrain on photo bytes delimiter
Vishalkulkarni45 Sep 4, 2025
285f0a9
fix: add range check on minimumAge within 2^7
Vishalkulkarni45 Sep 4, 2025
60501d1
fix: range check for country not in list
Vishalkulkarni45 Sep 4, 2025
3ba0ea4
chore: remove dummy constrain
Vishalkulkarni45 Sep 4, 2025
2dcb67d
fix: assert lessthan
Vishalkulkarni45 Sep 4, 2025
6a543cd
fix: check is photoEOI valid
Vishalkulkarni45 Sep 4, 2025
32e9bd2
fix: replace maxDataLength with qrPaddedLength for valid del indices
Vishalkulkarni45 Sep 4, 2025
4914074
feat: update forbidden countries in disclose and disclose id
Nesopie Sep 5, 2025
a7f69f9
feat: convert name to uppercase
Vishalkulkarni45 Sep 5, 2025
a451c80
fix: add constrain between delimiter and photoEOI
Vishalkulkarni45 Sep 8, 2025
79b0e96
feat: support for phno len 4 and 10
Vishalkulkarni45 Sep 8, 2025
0089154
chore: hard-code attestaion_ID to 3
Vishalkulkarni45 Sep 8, 2025
c751abb
feat: calculate nullifier using uppercase name
Vishalkulkarni45 Sep 8, 2025
03d8603
feat: add real id support
Nesopie Sep 8, 2025
1248a13
fix: rebase error
Vishalkulkarni45 Sep 8, 2025
a79363c
chore: refactor
Vishalkulkarni45 Sep 8, 2025
c409684
add new nullifier and commitment calc
Nesopie Sep 8, 2025
9f0e8f1
fix: reuse uppercase name from verify commitment
Vishalkulkarni45 Sep 9, 2025
4b19611
feat: add a function that will iterate though all pubkeys
Nesopie Sep 9, 2025
1a3106d
chore: skip real id test
Nesopie Sep 9, 2025
bcf5a8d
Merge pull request #4 from Vishalkulkarni45/feat/aadhaar-audit-fix
Vishalkulkarni45 Sep 9, 2025
44a5d5c
chore: merge dev
Nesopie Sep 9, 2025
1af3fbf
chore: yarn format
Nesopie Sep 9, 2025
bbd376f
chore: update yarn.lock
Nesopie Sep 9, 2025
9aade2f
chore: rm trailing / from import
Nesopie Sep 9, 2025
747b320
chore: add support for issuing state
Nesopie Sep 9, 2025
7496de2
chore: linting and types
Nesopie Sep 9, 2025
19c8b4c
chore: rm types script from circuits
Nesopie Sep 9, 2025
ff23107
chore: add license header
Nesopie Sep 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ IS_TEST_BUILD=
MIXPANEL_NFC_PROJECT_TOKEN=
SEGMENT_KEY=
SENTRY_DSN=
IS_TEST_BUILD=
3 changes: 0 additions & 3 deletions app/ios/CameraView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,18 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff
let minY = visibleRect.minY
let boxY = max(minY, min(maxY - boxHeight, maxY - boxHeight))
// let boxY = visibleRect.maxY - boxHeight

return CGRect(x: boxX, y: boxY, width: boxWidth, height: boxHeight)
}

var roiInImageCoordinates: CGRect {
guard let previewLayer = previewLayer else { return .zero }
let videoRect = previewLayer.layerRectConverted(fromMetadataOutputRect: CGRect(x: 0, y: 0, width: 1, height: 1))
let greenBox = calculateGreenBoxFrame()

// map greenBox to normalized coordinates within videoRect
let normX = (greenBox.minX - videoRect.minX) / videoRect.width
let normY = (greenBox.minY - videoRect.minY) / videoRect.height
let normWidth = greenBox.width / videoRect.width
let normHeight = greenBox.height / videoRect.height

// Ensure normalized coordinates are within [0,1] bounds as vision's max ROI is (0,0) to (1,1)
let clampedX = max(0, min(1, normX))
let clampedY = max(0, min(1, normY))
Expand Down
2 changes: 0 additions & 2 deletions app/ios/MRZScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ struct MRZScanner {
if let error = error {
print("Vision error: \(error)")
}

guard let observations = request.results as? [VNRecognizedTextObservation] else {
print("No text observations found")
completion("No text found", [])
Expand Down Expand Up @@ -47,7 +46,6 @@ struct MRZScanner {
// print("Matched MRZ pattern: \(text)")
mrzLines.append(text)
boxes.append(obs.boundingBox)

// Check if we have a complete MRZ
if (mrzLines.count == 2 && mrzLines.allSatisfy { $0.count == 44 }) || // TD3 - passport
(mrzLines.count == 3 && mrzLines.allSatisfy { $0.count == 30 }) { // TD1 - ID card
Expand Down
1 change: 0 additions & 1 deletion app/src/screens/dev/DevSettingsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ const items = [
'DocumentCameraTrouble',
'DocumentNFCTrouble',
] satisfies (keyof RootStackParamList)[];

const ScreenSelector = ({}) => {
const navigation = useNavigation();
const [open, setOpen] = useState(false);
Expand Down
23 changes: 23 additions & 0 deletions app/src/stores/databaseProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.

import React, { createContext, useEffect } from 'react';

import { useProofHistoryStore } from '@/stores/proofHistoryStore';

export const DatabaseContext = createContext(null);

export const DatabaseProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const { initDatabase } = useProofHistoryStore();

useEffect(() => {
initDatabase();
}, [initDatabase]);

return (
<DatabaseContext.Provider value={null}>{children}</DatabaseContext.Provider>
);
};
215 changes: 215 additions & 0 deletions circuits/circuits/disclose/vc_and_disclose_aadhaar.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
pragma circom 2.1.9;

include "circomlib/circuits/bitify.circom";
include "circomlib/circuits/comparators.circom";
include "../utils/aadhaar/disclose/verify_commitment.circom";
include "@openpassport/zk-email-circuits/utils/bytes.circom";
include "../utils/aadhaar/extractQrData.circom";
include "../utils/aadhaar/ofac/ofac_name_dob.circom";
include "../utils/aadhaar/ofac/ofac_name_yob.circom";
include "../utils/aadhaar/disclose/country_not_in_list.circom";

/// @title VC_AND_DISCLOSE_Aadhaar
/// @notice Verify user's commitment is part of the merkle tree and optionally disclose data from Aadhaar
/// @param nLevels Maximum number of levels in the merkle tree
/// @param namedobTreeLevels Maximum number of levels in the name-dob SMT tree
/// @param nameyobTreeLevels Maximum number of levels in the name-yob SMT tree
/// @input attestation_id Attestation ID of the credential used to generate the commitment
/// @input secret Secret of the user — used to reconstruct commitment
/// @input qrDataHash Hash of the QR data
/// @input gender Gender of the user
/// @input yob Year of birth
/// @input mob Month of birth
/// @input dob Day of birth
/// @input name[2] Name of the user (packed into 2 field elements)
/// @input aadhaar_last_4digits Last 4 digits of Aadhaar number
/// @input pincode Pincode of user's address
/// @input state State(PackedBytes) of user's address
/// @input ph_no_last_4digits Last 4 digits of phone number
/// @input photoHash Hash of user's photo
/// @input ofac_name_dob_smt_leaf_key Leaf key for name-DOB SMT verification
/// @input ofac_name_dob_smt_root Root of name-DOB SMT
/// @input ofac_name_dob_smt_siblings Siblings for name-DOB SMT proof
/// @input ofac_name_yob_smt_leaf_key Leaf key for name-YOB SMT verification
/// @input ofac_name_yob_smt_root Root of name-YOB SMT
/// @input ofac_name_yob_smt_siblings Siblings for name-YOB SMT proof
/// @input merkle_root Root of the commitment merkle tree
/// @input leaf_depth Actual size of the merkle tree
/// @input path Path of the commitment in the merkle tree
/// @input siblings Siblings of the commitment in the merkle tree
/// @input selector Bitmap indicating which fields to reveal
template VC_AND_DISCLOSE_Aadhaar(MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH,nLevels, namedobTreeLevels, nameyobTreeLevels){
signal input attestation_id;
signal input secret;
signal input qrDataHash;
signal input gender;
signal input yob[4];
signal input mob[2];
signal input dob[2];
signal input name[nameMaxLength()];
signal input aadhaar_last_4digits[4];
signal input pincode[6];
signal input state[maxFieldByteSize()];
signal input ph_no_last_4digits[4];
signal input photoHash;

signal input minimumAge;
signal input currentYear;
signal input currentMonth;
signal input currentDay;

signal input ofac_name_dob_smt_leaf_key;
signal input ofac_name_dob_smt_root;
signal input ofac_name_dob_smt_siblings[namedobTreeLevels];


signal input ofac_name_yob_smt_leaf_key;
signal input ofac_name_yob_smt_root;
signal input ofac_name_yob_smt_siblings[nameyobTreeLevels];

signal input merkle_root;
signal input leaf_depth;
signal input path[nLevels];
signal input siblings[nLevels];

signal input selector;
signal input scope;
signal input user_identifier;

signal input forbidden_countries_list[MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH * 3];
// convert selector to 119 bits which acts as a bitmap for the fields to reveal
signal sel_bits[119] <== Num2Bits(119)(selector);

signal output nullifier <== Poseidon(2)([secret, scope]);

// verify commitment is part of the merkle tree
signal uppercase_name[nameMaxLength()] <== VERIFY_COMMITMENT(nLevels)(
attestation_id,
secret,
qrDataHash,
gender,
yob,
mob,
dob,
name,
aadhaar_last_4digits,
pincode,
state,
ph_no_last_4digits,
photoHash,
merkle_root,
leaf_depth,
path,
siblings
);

signal name_packed[2] <== PackBytes(nameMaxLength())(uppercase_name);
signal yob_integer <== DigitBytesToInt(4)(yob);
signal mob_integer <== DigitBytesToInt(2)(mob);
signal dob_integer <== DigitBytesToInt(2)(dob);

// verify name-DOB in OFAC list
component ofac_name_dob = OFAC_NAME_DOB_AADHAAR(namedobTreeLevels);
ofac_name_dob.name <== name_packed;
ofac_name_dob.YOB <== yob_integer;
ofac_name_dob.MOB <== mob_integer;
ofac_name_dob.DOB <== dob_integer;
ofac_name_dob.smt_leaf_key <== ofac_name_dob_smt_leaf_key;
ofac_name_dob.smt_root <== ofac_name_dob_smt_root;
ofac_name_dob.smt_siblings <== ofac_name_dob_smt_siblings;

// verify name-YOB in OFAC list
component ofac_name_yob = OFAC_NAME_YOB_AADHAAR(nameyobTreeLevels);
ofac_name_yob.name <== name_packed;
ofac_name_yob.YOB <== yob_integer;
ofac_name_yob.smt_leaf_key <== ofac_name_yob_smt_leaf_key;
ofac_name_yob.smt_root <== ofac_name_yob_smt_root;
ofac_name_yob.smt_siblings <== ofac_name_yob_smt_siblings;

//Range-check for minimumAge
component range_check_minimumAge = Num2Bits(7);
range_check_minimumAge.in <== minimumAge;

// verify age is greater than minimum age
signal age <== AgeExtractor()(yob, mob, dob, currentYear, currentMonth, currentDay);

signal isAgeGreaterThanMinimumAge <== GreaterEqThan(7)([age, minimumAge]);

signal isMinimumAgeValid <== isAgeGreaterThanMinimumAge * minimumAge ;

// reveal fields based on selector

signal revealData[119];
revealData[0] <== gender * sel_bits[0];


for (var i = 0; i < 4; i++){
revealData[i + 1] <== yob[i] * sel_bits[i + 1];
}


for (var i = 0; i < 2; i++){
revealData[i + 5] <== mob[i] * sel_bits[i + 5];
}


for (var i = 0; i < 2; i++){
revealData[i + 7] <== dob[i] * sel_bits[i + 7];
}

for (var i = 0; i < nameMaxLength(); i++){
revealData[i + 9] <== name[i] * sel_bits[i + 9];
}

for (var i = 0; i < 4; i++){
revealData[i + 71] <== aadhaar_last_4digits[i] * sel_bits[i + 71];
}

for (var i = 0; i < 6; i++){
revealData[i + 75] <== pincode[i] * sel_bits[i + 75];
}

for (var i = 0; i < maxFieldByteSize(); i++){
revealData[i + 81] <== state[i] * sel_bits[i + 81];
}

for (var i = 0; i < 4; i++){
revealData[i + 112] <== ph_no_last_4digits[i] * sel_bits[i + 112];
}

signal output reveal_photoHash <== photoHash * sel_bits[116];

revealData[116] <== ofac_name_dob.ofacCheckResult * sel_bits[117];
revealData[117] <== ofac_name_yob.ofacCheckResult * sel_bits[118];
revealData[118] <== isMinimumAgeValid;

var revealed_data_packed_chunk_length = computeIntChunkLength(119);
signal output revealData_packed[revealed_data_packed_chunk_length] <== PackBytes(119)(revealData);

component country_not_in_list_circuit = CountryNotInList(MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH);

country_not_in_list_circuit.country[0] <== 73;
country_not_in_list_circuit.country[1] <== 78;
country_not_in_list_circuit.country[2] <== 68;

country_not_in_list_circuit.forbidden_countries_list <== forbidden_countries_list;

var chunkLength = computeIntChunkLength(MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH * 3);
signal output forbidden_countries_list_packed[chunkLength] <== country_not_in_list_circuit.forbidden_countries_list_packed;

attestation_id === 3;
}

component main { public
[
attestation_id,
currentYear,
currentMonth,
currentDay,
ofac_name_dob_smt_root,
ofac_name_yob_smt_root,
merkle_root,
scope,
user_identifier
]
} = VC_AND_DISCLOSE_Aadhaar(40, 33, 64, 64);
4 changes: 4 additions & 0 deletions circuits/circuits/register/instances/register_aadhaar.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pragma circom 2.1.9;
include "../register_aadhaar.circom";

component main = REGISTER_AADHAAR(121, 17, 512 * 3);
Loading
Loading