├── .env.example ├── .gitignore ├── src ├── utils.rs ├── lib.rs ├── utils │ ├── tasks.rs │ ├── templating.rs │ └── aws.rs ├── arch │ ├── mod.rs │ ├── reference.rs │ └── generic.rs ├── health_check.rs ├── rng_source.rs ├── bits │ └── all_bit_patterns_test.rs ├── config │ └── json_wrapper.rs ├── db │ └── impls.rs ├── iris_db.rs ├── config.rs ├── distance.rs ├── template.rs ├── participant.rs └── encoded_bits.rs ├── .github ├── CODEOWNERS ├── dependabot.yml ├── workflows │ ├── relyance-sci.yml │ ├── update-deployment.yaml │ └── ci.yml ├── ISSUE_TEMPLATE │ ├── feature.yml │ └── bug.yml └── PULL_REQUEST_TEMPLATE.md ├── rustfmt.toml ├── rust-toolchain.toml ├── .dockerignore ├── migrations └── 001_init.sql ├── config ├── participant.toml └── coordinator.toml ├── init-scripts └── ready.d │ └── create_sqs_queue.sh ├── bin ├── utils │ ├── generate_mock_templates.rs │ ├── sum_shares.rs │ ├── common.rs │ ├── utils.rs │ ├── sqs_query.rs │ ├── sqs_receive.rs │ ├── README.md │ ├── seed_iris_db.rs │ └── seed_mpc_db.rs ├── mpc_node.rs └── migrate-codes │ ├── mpc_db.rs │ └── migrate.rs ├── tests ├── e2e_config.toml ├── multi_match_truncated_e2e_sequence.json └── multi_match_e2e_sequence.json ├── LICENSE-MIT ├── compose_all_sides.yml ├── deny.toml ├── Dockerfile ├── Cargo.toml ├── SECURITY.md ├── CODE_OF_CONDUCT.md ├── compose.yml ├── README.md ├── benches └── rotation_comparison.rs ├── LICENSE-APACHE └── docs └── specification.ipynb /.env.example: -------------------------------------------------------------------------------- 1 | RUST_LOG=info 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .env 3 | mock_templates.json 4 | /.idea 5 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | pub mod aws; 2 | pub mod tasks; 3 | pub mod templating; 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # General code 2 | * @worldcoin/crypto @worldcoin/proof-of-personhood 3 | 4 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | group_imports = "StdExternalCrate" 2 | imports_granularity = "Module" 3 | max_width = 80 -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2024-04-27" 3 | components = ["rustc-dev", "rustc", "cargo", "rustfmt", "clippy"] 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .github/ 2 | target/ 3 | .git 4 | README.md 5 | .env 6 | .env.example 7 | compose.yml 8 | Dockerfile 9 | Dockerfile.e2e 10 | init-scripts/ 11 | config/ -------------------------------------------------------------------------------- /migrations/001_init.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE masks ( 2 | id BIGINT PRIMARY KEY, 3 | mask BYTEA NOT NULL 4 | ); 5 | 6 | CREATE TABLE shares ( 7 | id BIGINT PRIMARY KEY, 8 | share BYTEA NOT NULL 9 | ); 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "cargo" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | - package-ecosystem: "docker" 8 | directory: "/" 9 | schedule: 10 | interval: "monthly" 11 | - package-ecosystem: "github-actions" 12 | directory: "/" 13 | schedule: 14 | interval: "monthly" -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(array_chunks)] 2 | #![allow(clippy::type_complexity, clippy::comparison_chain)] 3 | 4 | pub mod arch; 5 | pub mod bits; 6 | pub mod config; 7 | pub mod coordinator; 8 | pub mod db; 9 | pub mod distance; 10 | pub mod encoded_bits; 11 | pub mod health_check; 12 | pub mod iris_db; 13 | pub mod participant; 14 | pub mod rng_source; 15 | pub mod template; 16 | pub mod utils; 17 | -------------------------------------------------------------------------------- /config/participant.toml: -------------------------------------------------------------------------------- 1 | # [service] 2 | # service_name = "mpc-participant" 3 | # metrics_host = "localhost" 4 | # metrics_port = 8125 5 | # metrics_queue_size = 5000 6 | # metrics_buffer_size = 1024 7 | # metrics_prefix = "mpc-participant" 8 | 9 | [participant] 10 | socket_addr = "127.0.0.1:8081" 11 | batch_size = 20000 12 | 13 | [participant.db] 14 | url = "postgres://localhost:5432/participant" 15 | migrate = true 16 | -------------------------------------------------------------------------------- /src/utils/tasks.rs: -------------------------------------------------------------------------------- 1 | use std::future::Future; 2 | 3 | use futures::stream::FuturesUnordered; 4 | use futures::StreamExt; 5 | use tokio::task::JoinError; 6 | 7 | pub async fn finalize_futures_unordered( 8 | mut tasks: FuturesUnordered, 9 | ) -> eyre::Result<()> 10 | where 11 | F: Future, JoinError>> + Unpin, 12 | { 13 | while let Some(result) = tasks.next().await { 14 | result??; 15 | } 16 | 17 | Ok(()) 18 | } 19 | -------------------------------------------------------------------------------- /src/arch/mod.rs: -------------------------------------------------------------------------------- 1 | mod generic; // Optimized generic implementation 2 | mod reference; // Simple generic implementations 3 | 4 | pub use generic::{denominators, distances}; 5 | 6 | //TODO: move this to the benches file 7 | #[cfg(feature = "bench")] 8 | pub mod benches { 9 | use criterion::Criterion; 10 | 11 | use super::*; 12 | 13 | pub fn group(c: &mut Criterion) { 14 | reference::benches::group(c); 15 | 16 | generic::benches::group(c); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/relyance-sci.yml: -------------------------------------------------------------------------------- 1 | name: Relyance SCI Scan 2 | 3 | on: 4 | schedule: 5 | - cron: "0 20 * * *" 6 | workflow_dispatch: 7 | 8 | jobs: 9 | execute-relyance-sci: 10 | name: Relyance SCI Job 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | 17 | - name: Pull and run SCI binary 18 | run: |- 19 | docker pull gcr.io/relyance-ext/compliance_inspector:release && \ 20 | docker run --rm -v `pwd`:/repo --env API_KEY='${{ secrets.DPP_SCI_KEY }}' gcr.io/relyance-ext/compliance_inspector:release 21 | -------------------------------------------------------------------------------- /init-scripts/ready.d/create_sqs_queue.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Create your SQS queues 4 | echo "Creating SQS queues..." 5 | awslocal sqs create-queue --queue-name coordinator-uniqueness-check.fifo --attributes "{\"FifoQueue\":\"true\", \"ContentBasedDeduplication\":\"true\"}" 6 | awslocal sqs create-queue --queue-name coordinator-results-queue.fifo --attributes "{\"FifoQueue\":\"true\", \"ContentBasedDeduplication\":\"true\"}" 7 | 8 | awslocal sqs create-queue --queue-name coordinator-db-sync-queue 9 | awslocal sqs create-queue --queue-name participant-0-db-sync-queue 10 | awslocal sqs create-queue --queue-name participant-1-db-sync-queue 11 | -------------------------------------------------------------------------------- /bin/utils/generate_mock_templates.rs: -------------------------------------------------------------------------------- 1 | use clap::Args; 2 | 3 | use crate::common::generate_templates; 4 | 5 | #[derive(Debug, Clone, Args)] 6 | pub struct GenerateMockTemplates { 7 | #[clap(short, long)] 8 | pub output: String, 9 | 10 | #[clap(short, long)] 11 | pub num_templates: usize, 12 | } 13 | 14 | pub async fn generate_mock_templates( 15 | args: &GenerateMockTemplates, 16 | ) -> eyre::Result<()> { 17 | let templates = generate_templates(args.num_templates); 18 | let json = serde_json::to_string(&templates)?; 19 | 20 | //write to file 21 | std::fs::write(&args.output, json)?; 22 | 23 | Ok(()) 24 | } 25 | -------------------------------------------------------------------------------- /bin/utils/sum_shares.rs: -------------------------------------------------------------------------------- 1 | use std::fs::read_to_string; 2 | 3 | use clap::Args; 4 | use mpc::distance::{decode, EncodedBits}; 5 | 6 | #[derive(Debug, Clone, Args)] 7 | pub struct SumShares { 8 | path: String, 9 | } 10 | 11 | pub async fn sum_shares(args: &SumShares) -> eyre::Result<()> { 12 | let shares_json = read_to_string(&args.path)?; 13 | let data = serde_json::from_str::>(&shares_json)?; 14 | 15 | let encoded: EncodedBits = data.iter().sum(); 16 | 17 | let decoded = decode(&encoded)?; 18 | 19 | println!("Code: {:?}", decoded.code); 20 | println!("Mask: {:?}", decoded.mask); 21 | 22 | Ok(()) 23 | } 24 | -------------------------------------------------------------------------------- /config/coordinator.toml: -------------------------------------------------------------------------------- 1 | # [service] 2 | # service_name = "mpc-coordinator" 3 | # metrics_host = "localhost" 4 | # metrics_port = 8125 5 | # metrics_queue_size = 5000 6 | # metrics_buffer_size = 1024 7 | # metrics_prefix = "mpc-coordinator" 8 | 9 | [coordinator] 10 | participants = '["127.0.0.1:8081"]' 11 | hamming_distance_threshold = 0.375 12 | n_closest_distances = 20 13 | 14 | [coordinator.gateway] 15 | type = "http" 16 | socket_addr = "127.0.0.1:8080" 17 | # Values below are not implemented yet 18 | distance_results_url = "" 19 | fire_and_forget = true 20 | 21 | [coordinator.db] 22 | url = "postgres://localhost:5432/coordinator" 23 | migrate = true 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest a feature 3 | labels: ["C-enhancement", "S-needs-triage"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Please ensure that the feature has not already been requested in the issue tracker. 9 | - type: textarea 10 | attributes: 11 | label: Describe the feature 12 | description: | 13 | Please describe the feature and what it is aiming to solve, if relevant. 14 | validations: 15 | required: true 16 | - type: textarea 17 | attributes: 18 | label: Additional context 19 | description: Add any other context to the feature (like screenshots, resources) -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | ## Motivation 11 | 12 | 17 | 18 | ## Solution 19 | 20 | 24 | 25 | ## PR Checklist 26 | 27 | - [ ] Added Tests 28 | - [ ] Added Documentation 29 | - [ ] Breaking changes -------------------------------------------------------------------------------- /.github/workflows/update-deployment.yaml: -------------------------------------------------------------------------------- 1 | name: Update deployment ref number 2 | 3 | on: [push] 4 | 5 | jobs: 6 | update-deployment: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Repository Dispatch 11 | uses: peter-evans/repository-dispatch@v3 12 | with: 13 | token: ${{ secrets.GIT_HUB_TOKEN }} 14 | repository: worldcoin/mpc-uniqueness-check-deploy 15 | event-type: update-ref 16 | client-payload: | 17 | { 18 | "sha": "${{ github.sha }}", 19 | "ref": "${{ github.ref }}", 20 | "ref_name": "${{ github.ref_name }}", 21 | "ref_type": "${{ github.ref_type }}", 22 | "repository": "${{ github.repository }}", 23 | "default_branch": "${{ github.event.repository.default_branch }}" 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/templating.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use serde::Serialize; 4 | use tinytemplate::TinyTemplate; 5 | 6 | const TEMPLATE_NAME: &str = "TEMPLATE"; 7 | 8 | #[derive(Serialize)] 9 | struct Context { 10 | env: HashMap, 11 | } 12 | 13 | pub fn resolve_template(s: &str) -> eyre::Result { 14 | let mut tt = TinyTemplate::new(); 15 | 16 | tt.add_template(TEMPLATE_NAME, s)?; 17 | 18 | let context = Context { 19 | env: std::env::vars().collect(), 20 | }; 21 | 22 | Ok(tt.render(TEMPLATE_NAME, &context)?) 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use super::*; 28 | 29 | #[test] 30 | fn test_resolve_template() { 31 | let template = "Hello, {env.USER}!"; 32 | let expected = format!("Hello, {}!", std::env::var("USER").unwrap()); 33 | let actual = resolve_template(template).unwrap(); 34 | 35 | assert_eq!(actual, expected); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/e2e_config.toml: -------------------------------------------------------------------------------- 1 | [coordinator] 2 | service_name = "mpc-coordinator" 3 | db.url = "postgres://postgres:postgres@localhost:8432/coordinator_db" 4 | db.migrate = true 5 | db.create = true 6 | queues.queries_queue_url = "http://localhost:4566/000000000000/coordinator-queries.fifo" 7 | queues.distances_queue_url = "http://localhost:4566/000000000000/coordinator-distances.fifo" 8 | queues.db_sync_queue_url = "http://localhost:4566/000000000000/coordinator-db-sync" 9 | participants = '["0.0.0.0:8080", "0.0.0.0:8081"]' 10 | hamming_distance_threshold = 0.375 11 | n_closest_distances = 20 12 | 13 | [[participant]] 14 | socket_addr = "0.0.0.0:8080" 15 | batch_size = 20000 16 | db.url = "postgres://postgres:postgres@localhost:8433/participant_0_db" 17 | db.migrate = true 18 | db.create = true 19 | queues.db_sync_queue_url = "http://localhost:4566/000000000000/participant-0-db-sync" 20 | 21 | [[participant]] 22 | socket_addr = "0.0.0.0:8081" 23 | batch_size = 20000 24 | db.url = "postgres://postgres:postgres@localhost:8434/participant_1_db" 25 | db.migrate = true 26 | db.create = true 27 | queues.db_sync_queue_url = "http://localhost:4566/000000000000/participant-1-db-sync" 28 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Worldcoin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /compose_all_sides.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | coordinator_left_db: 4 | image: postgres 5 | ports: 6 | - 8432:5432 7 | environment: 8 | - POSTGRES_HOST_AUTH_METHOD=trust 9 | participant_left_0_db: 10 | image: postgres 11 | ports: 12 | - 8433:5432 13 | environment: 14 | - POSTGRES_HOST_AUTH_METHOD=trust 15 | participant_left_1_db: 16 | image: postgres 17 | ports: 18 | - 8534:5432 19 | environment: 20 | - POSTGRES_HOST_AUTH_METHOD=trust 21 | coordinator_right_db: 22 | image: postgres 23 | ports: 24 | - 8532:5432 25 | environment: 26 | - POSTGRES_HOST_AUTH_METHOD=trust 27 | participant_right_0_db: 28 | image: postgres 29 | ports: 30 | - 8533:5432 31 | environment: 32 | - POSTGRES_HOST_AUTH_METHOD=trust 33 | participant_right_1_db: 34 | image: postgres 35 | ports: 36 | - 8434:5432 37 | environment: 38 | - POSTGRES_HOST_AUTH_METHOD=trust 39 | iris_db: 40 | hostname: iris_db 41 | image: mongo 42 | ports: 43 | - 27017:27017 44 | environment: 45 | - MONGO_INITDB_ROOT_USERNAME=admin 46 | - MONGO_INITDB_ROOT_PASSWORD=password 47 | -------------------------------------------------------------------------------- /bin/utils/common.rs: -------------------------------------------------------------------------------- 1 | use indicatif::{ProgressBar, ProgressStyle}; 2 | use mpc::template::Template; 3 | use rand::distributions::Alphanumeric; 4 | use rand::{thread_rng, Rng}; 5 | use rayon::iter::{IntoParallelIterator, ParallelIterator}; 6 | 7 | pub fn generate_templates(num_templates: usize) -> Vec