{"id":49434046,"url":"https://github.com/reversecontrol/muchpir","last_synced_at":"2026-04-29T16:00:49.584Z","repository":{"id":47093675,"uuid":"402904526","full_name":"ReverseControl/MuchPIR","owner":"ReverseControl","description":"Homomorphic Encryption PIR Postgres C/C++ Agregate Extension.","archived":false,"fork":false,"pushed_at":"2022-11-03T01:06:18.000Z","size":1807,"stargazers_count":28,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-04-28T17:34:05.916Z","etag":null,"topics":["encryption","encryption-algorithms","homomorphic-encryption","pir","postgres","postgresql","privacy"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ReverseControl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-03T21:45:15.000Z","updated_at":"2026-01-12T08:09:31.000Z","dependencies_parsed_at":"2023-01-21T11:46:02.984Z","dependency_job_id":null,"html_url":"https://github.com/ReverseControl/MuchPIR","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ReverseControl/MuchPIR","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReverseControl%2FMuchPIR","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReverseControl%2FMuchPIR/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReverseControl%2FMuchPIR/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReverseControl%2FMuchPIR/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ReverseControl","download_url":"https://codeload.github.com/ReverseControl/MuchPIR/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReverseControl%2FMuchPIR/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32432917,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T13:34:34.882Z","status":"ssl_error","status_checked_at":"2026-04-29T13:34:29.830Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["encryption","encryption-algorithms","homomorphic-encryption","pir","postgres","postgresql","privacy"],"created_at":"2026-04-29T16:00:36.049Z","updated_at":"2026-04-29T16:00:49.569Z","avatar_url":"https://github.com/ReverseControl.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MuchPIR Demo\r\n\r\nContact The MuchPIR Team: muchpir@pm.me \r\n\r\nAuthor: Escanor Liones (Single Author)\r\n\r\n**What is PIR?** \r\n\r\nPrivate Information Retrieval refers to the ability to query a database without disclosing which item is looked up or whether that item exists at all on the database. Not only is the query kept confidential, but so is the result of the query. In particular, any observer, including the platform running the query and hosting the databse itself, cannot tell whether the data returned contains the result to our query or not, or which item was being looked up. \r\n\r\n\r\n**Who will care?**\r\n\r\n1. **Law Enforcement**: you want to look up data on bad guy A without disclosing to the company holding the data, or any third party holding or processing the query, that you are looking for data about A.\r\n2. **Stock Exchange**: aggregate data on symbol look up can disclose market interest in advance of price movement. A PIR based symbol look up would not disclose to any third parties, or the Stock Exchange itself, handling the symbol price, volume, short/long interest, etc queries any market interest in advance of price movement.\r\n\r\n**Who else will care?**\r\n\r\nApplications that require long term confidentiality guarantees may be interested in using PIR. These types of applications might need additional layers of security for a robust, secure implementation with confidentiality guarantees over long periods of time. The current implementation, even the optimized version, works when the database data itself is not encrypted. If the database data itself were to be encrypted, in addition to the queries, then the entities that will care are:\r\n\r\n3. **Banks**: customer data can be encrypted, stored in cloud services, and queried as needed for the banks daily operations. As the data itself is encrypted it matters not whether the cloud service is hacked, not trusted, or that the hardware it is running on has bugs (meltdown/specter, etc). And because the data can be operated on under encryption, the bank may do its business as usual, or at least offload a significant part of it to the cloud with security guarantees.\r\n\r\n4.  **Hospitals**: Same as banks. Offload data to the cloud encrypted and perform computations under encryption. Only the entity holding the private keys, that is the hospitals/banks, can decrypt that data and queried results on that data.\r\n \r\n\r\n**MuchPIR is Private Information Retrieval using Homomorphic Encryption implemented as a C/C++ Aggregate extension to Postgres**. This demo is good a enough implementation for folks who want to experiment with PIR on Postgres and have a working C/C++ extension.\r\n\r\n# MuchPIR Commercial\r\n\r\nThe latest version of the software this demo is based on has the following characteristics:\r\n\r\n```\r\n     Supported table size: \u003e 10 Million Rows.\r\nQuery Compute Performance: under a minute.\r\n       Network Query Size:  From about 1 MB to less than 10 MB. (Depending on configuration.)\r\n        Query Result Size:  \u003c 512 KB.\r\n            Hardware Used: x86 architecture. (Tested on AMD 2nd Gen Epyc Processor)\r\n                 Security: \u003e= 128 bits of quantum and classical security.\r\n              Integration: Just a plug in to postgres.\r\n           Encrypted data: Database/tables/schemas need no changes at all.\r\n       Cryptographic Keys: Every single query has a new private/public key pair.\r\n\r\nHighly optimized parallelized PIR query.\r\n```\r\n\r\nThe MuchPIR Team would like to point out that these parameters and performance listed are meant to encompass a wide range of use cases. If your demand for this level of privacy is for a significantly smaller databases, or requires less data bandwidth, then performance goes up and bandwidth goes down on query/response sizes. Similarly, if your databases are much larger or your bandwidth needs much bigger.\r\n\r\nWe may also speak of implementations where bandwidth and performance tradeoffs are parametrizable by the user making the query as part of the query itself. These would be implemented on a case by case basis to fit the need of your organization.\r\n\r\n\r\nThis demo targets string types on postgres, but can easily be adapted to query any type: int4, int8, float, bytea, etc.\r\n\r\n\r\n# Differential Privacy Use Cases\r\n\r\nThere are three other uses of this technology beyond PIR that we have developed concepts for:\r\n\r\n1. **Limited String Search:** small words, such as a name or last name, could be searched for instead of indexing into a particular row.\r\n2. **Exact Match Search:** within limits this could be done as well. Preferably, the search space would smaller than database size.\r\n3. **Unique ID Search:** where data could be searched based on unique ID. This would works well on columns with unique data.\r\n4. **Accumulation:** Aggregating data by addition on a given column in a way that is indistinguishable from PIR is also possible. (Same performance, same everything.)\r\n\r\nThe team is still developing  other use cases. Feel free to contact us if there is a use case of interest to you, your team or organization.\r\n\r\n\r\n# Building\r\n\r\nThis code has been ran and tested on Ubuntu 18.04 and Ubuntu 20.04. It does require:\r\n\r\n1. Microsoft SEAL Library Version 3.5.8: https://github.com/microsoft/SEAL/tree/v3.5.8\r\n2. Postgres C++ wrapper libpqxx: https://github.com/jtv/libpqxx\r\n3. Postgres Development Packages for C/C++ extensions.\r\n\r\n# Demo\r\n\r\nLet us take MuchPIR for a test run.\r\n\r\n```\r\ngit clone https://github.com/ReverseControl/MuchPIR.git\r\ncd MuchPIR\r\ndocker build -t muchpir:1.0 .\r\ndocker run -e POSTGRES_PASSWORD=pass -e POSTGRES_USER=postgres  muchpir:1.0\r\n```\r\n\r\nThis will start the container that runs the postgres server with our extension. Now we want to enter the docker container while it is running. In another terminal, we do:\r\n\r\n```\r\ndocker container ls\r\ndocker exec -u 0 -ti \u003ccontainer-name\u003e bash\r\n```\r\n\r\nBy default you will enter in the right directory to run: \r\n\r\n```\r\nsu - postgres\r\ncd /data/\r\npsql -U postgres -d testdb -f ./load_data.sql\r\nexit\r\n```\r\n\r\nThis will load data into tables that we will use for testing. The data comes from the IMDB dataset you \r\nfind here: https://datasets.imdbws.com/name.basics.tsv.gz. We took the first 69,420 lines, excluding the first \r\nline which is the header for the columns, and created several tables.\r\n\r\n```\r\nTABLE         Size   |    Signature for the tables\r\ndata_10       1024   |    table_N (\r\ndata_11       2048   |           nconst            bigint,\r\ndata_12       4096   |           primaryName       text,\r\ndata_13       8192   |           birthYear         bigint,\r\ndata_14      16384   |           deathYear         bigint,\r\ndata_15      32768   |           primaryProfession text,\r\ndata_16      65536   |           knownForTitles    text  \r\ndata_all     69420   |    ); \r\n```\r\n\r\nPostgres extensions are installed per database. Now that we have installed our extension on the system \r\n(docker container) and Postgres knows where to find it, we can now install it on our database so we \r\nmay use it.\r\n\r\n```\r\nsu - postgres\r\ncd /data/\r\npsql -U postgres -d testdb -f /git/MuchPIR/pir_select--1.0.sql\r\nexit\r\n```\r\n\r\nNow that we have the database running with the extension installed on a databse with tables and data\r\nready to go, let's build the client for testing.\r\n\r\n```\r\ncd /git/MuchPIR/client\r\ng++  -std=c++17 -march=native -I/usr/local/include/SEAL-3.5/ -L/usr/local/lib/ client_module.cpp -lpqxx -lpq -l:libseal.so.3.5\r\ntime ./a.out\r\n```\r\n\r\nYou should get an output like this:\r\n\r\n```\r\nroot@24a82b6e3437:/git/MuchPIR/client# g++  -std=c++17 -march=native -I/usr/local/include/SEAL-3.5/ -L/usr/local/lib/ client_module.cpp -lpqxx -lpq -l:libseal.so.3.5\r\nroot@24a82b6e3437:/git/MuchPIR/client# time ./a.out\r\nNote: compression is disabled. This is the maximum size for each object at this database size under current parameters.\r\n\r\n       Plain Modulus: 40961\r\n\r\n             db_size: 1024 \u003c-- Note: By default 1024 in this demo. Can be increased up to 10s of millions: requires math and code, i.e the latest version. \r\n           row_index: 0 \u003c-- Note: You can change this to any row you want in code.\r\n           hcube_dim: 1 \u003c-- Note: Hypercube dimension. This demo supports only 1 dimension. Limits DB_size to 4096 rows.\r\n          hecube_len: 1024 \u003c-- Note: An optimization. Does not affect this demo. Improves performance for high dimensional hyper cubes.\r\n\r\n    Polynomial Degree(N): 4096\r\n         Parameters size: 129 bytes.\r\n        Galois Keys size: 1659085 bytes.\r\nHypercube embedding size: 131177 bytes.\r\n             Query  Size: 1790391 bytes.\r\n             Result Size: 182362 bytes.\r\nQuery result (Polynomial): 46x^11 + 72x^10 + 65x^9 + 64x^8 + 20x^7 + 41x^6 + 73x^5 + 74x^4 + 61x^3 + 69x^2 + 72x^1 + 65\r\nQuery result (ASCII)     : Fred Astaire\r\n\r\nreal\t0m53.250s\r\nuser\t0m0.216s\r\nsys\t0m0.017s\r\n```\r\n\r\n\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freversecontrol%2Fmuchpir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freversecontrol%2Fmuchpir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freversecontrol%2Fmuchpir/lists"}