From b4b1bb56e6e163110e82a9d2df5e8d100f0e4ae8 Mon Sep 17 00:00:00 2001 From: Kalidou Diagne Date: Fri, 13 Jun 2025 22:05:23 +0400 Subject: [PATCH] migrate project data from .ts to Markdown files (#453) * migrate project data from .ts to Markdown files --- .github/auto_assign.yml | 2 +- README.md | 6 +- app/(pages)/blog/[slug]/page.tsx | 2 +- app/(pages)/blog/page.tsx | 20 +- app/(pages)/blog/tags/[tag]/page.tsx | 42 +- app/(pages)/blog/tags/page.tsx | 49 +- .../devcon-7/sections/Devcon7Booths.tsx | 2 +- .../devcon-7/sections/Devcon7Section.tsx | 2 +- app/(pages)/layout.tsx | 52 -- app/(pages)/programs/index.tsx | 16 +- app/(pages)/projects/[id]/page.tsx | 15 +- .../projects/sections/ProjectContent.tsx | 162 ++----- app/(pages)/resources/page.tsx | 2 +- app/api/articles/route.ts | 2 +- app/api/projects/route.ts | 26 + app/labels.ts | 71 +++ app/layout.tsx | 63 ++- app/providers/GlobalProvider.tsx | 68 +++ app/providers/ProjectsProvider.tsx | 451 ++++++++++++++++++ components/blog/article-in-evidance-card.tsx | 2 +- components/blog/article-list-card.tsx | 2 +- .../{ArticlesList.tsx => articles-list.tsx} | 26 +- components/blog/blog-article-card.tsx | 2 +- .../blog/blog-article-related-projects.tsx | 14 +- components/blog/blog-articles.tsx | 2 +- components/blog/blog-content.tsx | 2 +- components/blog/blog-recent-articles.tsx | 2 +- components/blog/project-blog-articles.tsx | 2 +- components/layouts/GlobalProviderLayout.tsx | 18 + components/layouts/QueryProviderLayout.tsx | 15 - components/project/discover-more-projects.tsx | 35 +- components/project/project-card.tsx | 11 +- components/project/project-detail-tags.tsx | 85 ++-- components/project/project-filters-bar.tsx | 52 +- components/project/project-list.tsx | 24 +- components/project/project-result-bar.tsx | 55 +-- components/research/research-card.tsx | 22 +- components/research/research-list.tsx | 80 ++-- {articles => content/articles}/README.md | 6 +- .../articles}/_article-template.md | 2 +- ...oduction-to-arbitrums-optimistic-rollup.md | 0 ...to-maci-10-privacy-scaling-explorations.md | 0 ...dvancing-anon-aadhaar-whats-new-in-v100.md | 0 .../articles}/announcing-anon-aadhaar.md | 0 .../articles}/announcing-maci-v111.md | 0 ...journey-in-privacy-preserving-solutions.md | 0 ...going-to-survive-the-quantum-apocalypse.md | 0 .../articles}/bandada-is-live.md | 0 ...whats-next-in-programmable-cryptography.md | 0 ...ng-up-data-privacy-scaling-explorations.md | 0 ...ertificate-transparency-using-newtonpir.md | 0 .../circom-mpc-tldr-and-retrospective.md | 0 ...-landscape-of-post-quantum-cryptography.md | 0 .../continuing-the-zero-gravity-journey.md | 0 .../articles}/devcon-vi-recap.md | 0 .../efficient-client-side-proving-for-zkid.md | 0 .../from-cex-to-ccex-with-summa-part-1.md | 0 .../from-cex-to-ccex-with-summa-part-2.md | 0 ...o-world-the-first-signs-of-practical-io.md | 0 .../interep-on-ramp-for-reputaion.md | 0 ...ment-l2-from-plasma-and-validity-proofs.md | 0 .../articles}/introducing-trinity.md | 0 .../articles}/lattice-based-proof-systems.md | 0 .../learnings-from-the-kzg-ceremony.md | 0 .../meet-coco-privacy-scaling-explorations.md | 0 .../mopro-comparison-of-circom-provers.md | 0 .../articles}/mopro-native-packages.md | 0 .../articles}/mpc-retrospective.md | 11 +- .../articles}/p0tion-v10-release.md | 0 ...re-aggregation-with-falcon-and-LaBRADOR.md | 17 +- .../articles}/pse-may-2025-newsletter.md | 0 .../articles}/pse-security-what-is-new.md | 0 ...on-mechanism-for-anonymous-environments.md | 0 .../articles}/rate-limiting-nullifier-rln.md | 0 .../articles}/reflecting-on-maci-platform.md | 0 ...nt-maci-10-privacy-scaling-explorations.md | 0 .../articles}/retrospective-summa.md | 0 ...ctive-trusted-setups-and-p0tion-project.md | 0 ...n-circuit-in-halo2-and-its-applications.md | 0 .../secure-multi-party-computation.md | 0 ...grammable-cryptography-challenges-ahead.md | 0 ...phore-community-grants-awarded-projects.md | 0 .../articles}/semaphore-community-grants.md | 0 ...v2-is-live-privacy-scaling-explorations.md | 0 .../articles}/semaphore-v3-announcement.md | 0 .../articles}/summon-major-update.md | 0 .../articles}/tee-based-ppd.md | 122 +++-- ...ext-chapter-for-zkevm-community-edition.md | 0 ...tract-security-for-l2-scaling-solutions.md | 0 .../articles}/the-zk-ecdsa-landscape.md | 0 .../articles}/tlsnotary-updates.md | 0 ...towards_a_quantum-safe_p2p_for_ethereum.md | 0 ...te-and-non-repudiable-reputation-system.md | 2 +- ...ion-to-the-celestial-call-and-unirep-v2.md | 0 .../articles}/unirep-protocol.md | 0 ...ential-introducing-the-pse-core-program.md | 0 .../articles}/web2-nullifiers-using-voprf.md | 0 ...tly-secure-multi-party-applications-yet.md | 0 ...fully-homomorphic-encryption-fhe-part-1.md | 0 ...fully-homomorphic-encryption-fhe-part-2.md | 0 ...m-community-edition-part-1-introduction.md | 0 ...evm-community-edition-part-2-components.md | 0 ...nity-edition-part-3-logic-and-structure.md | 0 ...zkitter-an-anon-friendly-social-network.md | 0 ...iml-and-web3-with-zero-knowledge-proofs.md | 0 ...ony-final-call-and-failed-contributions.md | 0 ...on-testnet-privacy-scaling-explorations.md | 0 .../zkopru-trusted-setup-ceremony.md | 0 ...-completed-privacy-scaling-explorations.md | 0 ...-wat-y-wen-privacy-scaling-explorations.md | 0 .../zkpdf-unlocking-verifiable-data.md | 0 {data => content}/events/devcon-7.ts | 0 content/projects/README.md | 210 ++++++++ content/projects/_project-template.md | 89 ++++ .../projects/anon-aadhaar.md | 74 ++- content/projects/anon-klub.md | 30 ++ .../bandada.ts => content/projects/bandada.md | 156 +++--- content/projects/channel-4.md | 20 + content/projects/chiquito.md | 27 ++ .../projects/circom-mpc.md | 58 +-- content/projects/client-side-proving.md | 70 +++ content/projects/coco.md | 24 + content/projects/cryptkeeper.md | 18 + .../cursive.ts => content/projects/cursive.md | 76 ++- content/projects/discreetly.md | 19 + content/projects/dsl-working-group.md | 18 + content/projects/ecip-halo2.md | 19 + content/projects/eigen-trust.md | 18 + .../projects/excubiae.md | 101 ++-- content/projects/interep.md | 21 + content/projects/jubmoji.md | 31 ++ .../projects/machina-iO.md | 82 ++-- content/projects/maci-platform.md | 33 ++ .../maci.ts => content/projects/maci.md | 54 +-- .../mopro.ts => content/projects/mopro.md | 92 ++-- .../projects/mpc-framework.md | 137 ++---- .../projects/mpc-stats.md | 48 +- content/projects/mpz.md | 27 ++ .../projects/openpassport.md | 57 +-- .../p0tion.ts => content/projects/p0tion.md | 54 +-- content/projects/p256.md | 27 ++ .../projects/pir-scaling-semaphore.md | 150 +++--- .../projects/plasma-fold.md | 68 +-- content/projects/pod2.md | 42 ++ content/projects/pollen-labs.md | 34 ++ .../projects/post-quantum-cryptography.md | 43 +- .../projects/powers-of-tau.md | 58 +-- .../projects/private-proof-delegation.md | 65 +-- content/projects/pse-halo2.md | 28 ++ content/projects/pse-security.md | 19 + .../publicly-verifiable-garbled-circuit.md | 18 + .../rln.ts => content/projects/rln.md | 50 +- content/projects/scaling-semaphore.md | 49 ++ .../projects/semaphore.md | 153 +++--- content/projects/sonobe.md | 42 ++ content/projects/summa.md | 22 + content/projects/tlsn.md | 32 ++ .../projects/trusted-setups.md | 50 +- .../projects/unirep-protocol.md | 85 ++-- .../vOPRF.ts => content/projects/vOPRF.md | 51 +- content/projects/voice-deck.md | 20 + content/projects/wax.md | 26 + content/projects/zk-email.md | 20 + .../zk-id.ts => content/projects/zk-id.md | 99 ++-- .../zk-kit.ts => content/projects/zk-kit.md | 88 ++-- content/projects/zkevm-community.md | 18 + .../zkitter.ts => content/projects/zkitter.md | 54 +-- content/projects/zkml.md | 18 + .../zkopru.ts => content/projects/zkopru.md | 91 ++-- content/projects/zkp2p.md | 20 + {app/(pages)/content => content}/resources.md | 0 data/programs/accelerationProgramFaq.tsx | 51 -- data/programs/coreProgramFaq.tsx | 34 -- data/projects.ts | 120 ----- data/projects/README.md | 150 ------ data/projects/anon-klub.ts | 49 -- data/projects/channel-4.ts | 35 -- data/projects/chiquito.ts | 41 -- data/projects/client-side-proving.ts | 89 ---- data/projects/coco.ts | 49 -- data/projects/cryptkeeper.ts | 33 -- data/projects/discreetly.ts | 34 -- data/projects/dsl-working-group.ts | 34 -- data/projects/ecip-halo2.ts | 41 -- data/projects/eigen-trust.ts | 33 -- data/projects/interep.ts | 40 -- data/projects/jubmoji.ts | 46 -- data/projects/maci-platform.ts | 47 -- data/projects/mpz.ts | 45 -- data/projects/p256.ts | 41 -- data/projects/pod2.ts | 82 ---- data/projects/pollen-labs.ts | 48 -- data/projects/pse-halo2.ts | 44 -- data/projects/pse-security.ts | 39 -- .../publicly-verifiable-garbled-circuit.ts | 33 -- data/projects/sonobe.ts | 57 --- data/projects/summa.ts | 41 -- data/projects/tlsn.ts | 63 --- data/projects/voice-deck.ts | 35 -- data/projects/wax.ts | 43 -- data/projects/zk-email.ts | 35 -- data/projects/zkevm-community.ts | 33 -- data/projects/zkml.ts | 33 -- data/projects/zkp2p.ts | 35 -- hooks/useGetProjectRelatedArticles.ts | 2 +- lib/blog.ts | 158 ------ lib/content.ts | 239 ++++++++++ lib/projectsUtils.ts | 18 - lib/types.ts | 1 + locales/en/devcon-7.json | 3 - state/useProjectFiltersState.ts | 351 -------------- styles/globals.css | 35 +- tailwind.config.js | 11 +- 213 files changed, 3345 insertions(+), 3973 deletions(-) delete mode 100644 app/(pages)/layout.tsx create mode 100644 app/api/projects/route.ts create mode 100644 app/providers/GlobalProvider.tsx create mode 100644 app/providers/ProjectsProvider.tsx rename components/blog/{ArticlesList.tsx => articles-list.tsx} (91%) create mode 100644 components/layouts/GlobalProviderLayout.tsx delete mode 100644 components/layouts/QueryProviderLayout.tsx rename {articles => content/articles}/README.md (92%) rename {articles => content/articles}/_article-template.md (99%) rename {articles => content/articles}/a-technical-introduction-to-arbitrums-optimistic-rollup.md (100%) rename {articles => content/articles}/a-technical-introduction-to-maci-10-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/advancing-anon-aadhaar-whats-new-in-v100.md (100%) rename {articles => content/articles}/announcing-anon-aadhaar.md (100%) rename {articles => content/articles}/announcing-maci-v111.md (100%) rename {articles => content/articles}/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions.md (100%) rename {articles => content/articles}/are-elliptic-curves-going-to-survive-the-quantum-apocalypse.md (100%) rename {articles => content/articles}/bandada-is-live.md (100%) rename {articles => content/articles}/beyond-zero-knowledge-whats-next-in-programmable-cryptography.md (100%) rename {articles => content/articles}/bls-wallet-bundling-up-data-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/certificate-transparency-using-newtonpir.md (100%) rename {articles => content/articles}/circom-mpc-tldr-and-retrospective.md (100%) rename {articles => content/articles}/code-optimizations-in-the-landscape-of-post-quantum-cryptography.md (100%) rename {articles => content/articles}/continuing-the-zero-gravity-journey.md (100%) rename {articles => content/articles}/devcon-vi-recap.md (100%) rename {articles => content/articles}/efficient-client-side-proving-for-zkid.md (100%) rename {articles => content/articles}/from-cex-to-ccex-with-summa-part-1.md (100%) rename {articles => content/articles}/from-cex-to-ccex-with-summa-part-2.md (100%) rename {articles => content/articles}/hello-world-the-first-signs-of-practical-io.md (100%) rename {articles => content/articles}/interep-on-ramp-for-reputaion.md (100%) rename {articles => content/articles}/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs.md (100%) rename {articles => content/articles}/introducing-trinity.md (100%) rename {articles => content/articles}/lattice-based-proof-systems.md (100%) rename {articles => content/articles}/learnings-from-the-kzg-ceremony.md (100%) rename {articles => content/articles}/meet-coco-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/mopro-comparison-of-circom-provers.md (100%) rename {articles => content/articles}/mopro-native-packages.md (100%) rename {articles => content/articles}/mpc-retrospective.md (91%) rename {articles => content/articles}/p0tion-v10-release.md (100%) rename {articles => content/articles}/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR.md (70%) rename {articles => content/articles}/pse-may-2025-newsletter.md (100%) rename {articles => content/articles}/pse-security-what-is-new.md (100%) rename {articles => content/articles}/rate-limiting-nullifier-a-spam-protection-mechanism-for-anonymous-environments.md (100%) rename {articles => content/articles}/rate-limiting-nullifier-rln.md (100%) rename {articles => content/articles}/reflecting-on-maci-platform.md (100%) rename {articles => content/articles}/release-announcement-maci-10-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/retrospective-summa.md (100%) rename {articles => content/articles}/retrospective-trusted-setups-and-p0tion-project.md (100%) rename {articles => content/articles}/rsa-verification-circuit-in-halo2-and-its-applications.md (100%) rename {articles => content/articles}/secure-multi-party-computation.md (100%) rename {articles => content/articles}/self-sovereign-identity-programmable-cryptography-challenges-ahead.md (100%) rename {articles => content/articles}/semaphore-community-grants-awarded-projects.md (100%) rename {articles => content/articles}/semaphore-community-grants.md (100%) rename {articles => content/articles}/semaphore-v2-is-live-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/semaphore-v3-announcement.md (100%) rename {articles => content/articles}/summon-major-update.md (100%) rename {articles => content/articles}/tee-based-ppd.md (92%) rename {articles => content/articles}/the-next-chapter-for-zkevm-community-edition.md (100%) rename {articles => content/articles}/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions.md (100%) rename {articles => content/articles}/the-zk-ecdsa-landscape.md (100%) rename {articles => content/articles}/tlsnotary-updates.md (100%) rename {articles => content/articles}/towards_a_quantum-safe_p2p_for_ethereum.md (100%) rename {articles => content/articles}/unirep-a-private-and-non-repudiable-reputation-system.md (99%) rename {articles => content/articles}/unirep-ceremony-an-invitation-to-the-celestial-call-and-unirep-v2.md (100%) rename {articles => content/articles}/unirep-protocol.md (100%) rename {articles => content/articles}/unleashing-potential-introducing-the-pse-core-program.md (100%) rename {articles => content/articles}/web2-nullifiers-using-voprf.md (100%) rename {articles => content/articles}/why-we-cant-build-perfectly-secure-multi-party-applications-yet.md (100%) rename {articles => content/articles}/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1.md (100%) rename {articles => content/articles}/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2.md (100%) rename {articles => content/articles}/zkevm-community-edition-part-1-introduction.md (100%) rename {articles => content/articles}/zkevm-community-edition-part-2-components.md (100%) rename {articles => content/articles}/zkevm-community-edition-part-3-logic-and-structure.md (100%) rename {articles => content/articles}/zkitter-an-anon-friendly-social-network.md (100%) rename {articles => content/articles}/zkml-bridging-aiml-and-web3-with-zero-knowledge-proofs.md (100%) rename {articles => content/articles}/zkopru-ceremony-final-call-and-failed-contributions.md (100%) rename {articles => content/articles}/zkopru-on-testnet-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/zkopru-trusted-setup-ceremony.md (100%) rename {articles => content/articles}/zkopru-trusted-setup-completed-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/zkopru-wat-y-wen-privacy-scaling-explorations.md (100%) rename {articles => content/articles}/zkpdf-unlocking-verifiable-data.md (100%) rename {data => content}/events/devcon-7.ts (100%) create mode 100644 content/projects/README.md create mode 100644 content/projects/_project-template.md rename data/projects/anon-aadhaar.ts => content/projects/anon-aadhaar.md (57%) create mode 100644 content/projects/anon-klub.md rename data/projects/bandada.ts => content/projects/bandada.md (62%) create mode 100644 content/projects/channel-4.md create mode 100644 content/projects/chiquito.md rename data/projects/circom-mpc.ts => content/projects/circom-mpc.md (58%) create mode 100644 content/projects/client-side-proving.md create mode 100644 content/projects/coco.md create mode 100644 content/projects/cryptkeeper.md rename data/projects/cursive.ts => content/projects/cursive.md (67%) create mode 100644 content/projects/discreetly.md create mode 100644 content/projects/dsl-working-group.md create mode 100644 content/projects/ecip-halo2.md create mode 100644 content/projects/eigen-trust.md rename data/projects/excubiae.ts => content/projects/excubiae.md (61%) create mode 100644 content/projects/interep.md create mode 100644 content/projects/jubmoji.md rename data/projects/machina-iO.ts => content/projects/machina-iO.md (73%) create mode 100644 content/projects/maci-platform.md rename data/projects/maci.ts => content/projects/maci.md (53%) rename data/projects/mopro.ts => content/projects/mopro.md (56%) rename data/projects/mpc-framework.ts => content/projects/mpc-framework.md (54%) rename data/projects/mpc-stats.ts => content/projects/mpc-stats.md (64%) create mode 100644 content/projects/mpz.md rename data/projects/openpassport.ts => content/projects/openpassport.md (62%) rename data/projects/p0tion.ts => content/projects/p0tion.md (54%) create mode 100644 content/projects/p256.md rename data/projects/pir-scaling-semaphore.ts => content/projects/pir-scaling-semaphore.md (52%) rename data/projects/plasma-fold.ts => content/projects/plasma-fold.md (67%) create mode 100644 content/projects/pod2.md create mode 100644 content/projects/pollen-labs.md rename data/projects/post-quantum-cryptography.ts => content/projects/post-quantum-cryptography.md (78%) rename data/projects/powers-of-tau.ts => content/projects/powers-of-tau.md (50%) rename data/projects/private-proof-delegation.ts => content/projects/private-proof-delegation.md (74%) create mode 100644 content/projects/pse-halo2.md create mode 100644 content/projects/pse-security.md create mode 100644 content/projects/publicly-verifiable-garbled-circuit.md rename data/projects/rln.ts => content/projects/rln.md (50%) create mode 100644 content/projects/scaling-semaphore.md rename data/projects/semaphore.ts => content/projects/semaphore.md (55%) create mode 100644 content/projects/sonobe.md create mode 100644 content/projects/summa.md create mode 100644 content/projects/tlsn.md rename data/projects/trusted-setups.ts => content/projects/trusted-setups.md (72%) rename data/projects/unirep-protocol.ts => content/projects/unirep-protocol.md (66%) rename data/projects/vOPRF.ts => content/projects/vOPRF.md (72%) create mode 100644 content/projects/voice-deck.md create mode 100644 content/projects/wax.md create mode 100644 content/projects/zk-email.md rename data/projects/zk-id.ts => content/projects/zk-id.md (67%) rename data/projects/zk-kit.ts => content/projects/zk-kit.md (53%) create mode 100644 content/projects/zkevm-community.md rename data/projects/zkitter.ts => content/projects/zkitter.md (58%) create mode 100644 content/projects/zkml.md rename data/projects/zkopru.ts => content/projects/zkopru.md (52%) create mode 100644 content/projects/zkp2p.md rename {app/(pages)/content => content}/resources.md (100%) delete mode 100644 data/programs/accelerationProgramFaq.tsx delete mode 100644 data/programs/coreProgramFaq.tsx delete mode 100644 data/projects.ts delete mode 100644 data/projects/README.md delete mode 100644 data/projects/anon-klub.ts delete mode 100644 data/projects/channel-4.ts delete mode 100644 data/projects/chiquito.ts delete mode 100644 data/projects/client-side-proving.ts delete mode 100644 data/projects/coco.ts delete mode 100644 data/projects/cryptkeeper.ts delete mode 100644 data/projects/discreetly.ts delete mode 100644 data/projects/dsl-working-group.ts delete mode 100644 data/projects/ecip-halo2.ts delete mode 100644 data/projects/eigen-trust.ts delete mode 100644 data/projects/interep.ts delete mode 100644 data/projects/jubmoji.ts delete mode 100644 data/projects/maci-platform.ts delete mode 100644 data/projects/mpz.ts delete mode 100644 data/projects/p256.ts delete mode 100644 data/projects/pod2.ts delete mode 100644 data/projects/pollen-labs.ts delete mode 100644 data/projects/pse-halo2.ts delete mode 100644 data/projects/pse-security.ts delete mode 100644 data/projects/publicly-verifiable-garbled-circuit.ts delete mode 100644 data/projects/sonobe.ts delete mode 100644 data/projects/summa.ts delete mode 100644 data/projects/tlsn.ts delete mode 100644 data/projects/voice-deck.ts delete mode 100644 data/projects/wax.ts delete mode 100644 data/projects/zk-email.ts delete mode 100644 data/projects/zkevm-community.ts delete mode 100644 data/projects/zkml.ts delete mode 100644 data/projects/zkp2p.ts delete mode 100644 lib/blog.ts create mode 100644 lib/content.ts delete mode 100644 lib/projectsUtils.ts delete mode 100644 locales/en/devcon-7.json delete mode 100644 state/useProjectFiltersState.ts diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml index 92de517..e6157db 100644 --- a/.github/auto_assign.yml +++ b/.github/auto_assign.yml @@ -1,5 +1,5 @@ addReviewers: true addAssignees: author -reviewers: [thebeyondr, AtHeartEngineer, ChialiT, heeckhau, kalidiagne] +reviewers: [kalidiagne, psedesign] skipKeywords: [wip] runOnDraft: false diff --git a/README.md b/README.md index 116daec..63048d6 100644 --- a/README.md +++ b/README.md @@ -11,17 +11,17 @@ Enhancing Ethereum through cryptographic research and collective experimentation ### Add/Edit article -- For updating/adding a new article [you can follow this guide](https://github.com/privacy-scaling-explorations/pse.dev/blob/main/articles/README.md) +- For updating/adding a new article [you can follow this guide](content/articles/README.md) ### Add/Edit project list -- For updating/adding project detail [you can follow this guide](https://github.com/privacy-scaling-explorations/pse.dev/blob/main/data/projects/README.md) +- For updating/adding project detail [you can follow this guide](content/projects/README.md) ## PR Review process #### For internal, PSE member: -- Suggest to tag: @kalidiagne, @psedesign, @AtHeartEngineer for PR review. +- Suggest to tag: @kalidiagne, @psedesign for PR review. - If question, please reach out in discord channel #website-pse #### For external: diff --git a/app/(pages)/blog/[slug]/page.tsx b/app/(pages)/blog/[slug]/page.tsx index 2e47b61..4fb842b 100644 --- a/app/(pages)/blog/[slug]/page.tsx +++ b/app/(pages)/blog/[slug]/page.tsx @@ -4,7 +4,7 @@ import { AppContent } from "@/components/ui/app-content" import { Button } from "@/components/ui/button" import { Label } from "@/components/ui/label" import { Markdown } from "@/components/ui/markdown" -import { getArticles, getArticleById } from "@/lib/blog" +import { getArticles, getArticleById } from "@/lib/content" import { cn, getBackgroundImage } from "@/lib/utils" import { Metadata } from "next" import Link from "next/link" diff --git a/app/(pages)/blog/page.tsx b/app/(pages)/blog/page.tsx index dd935f8..2d02a52 100644 --- a/app/(pages)/blog/page.tsx +++ b/app/(pages)/blog/page.tsx @@ -8,9 +8,9 @@ import { QueryClient, dehydrate, } from "@tanstack/react-query" -import ArticlesList from "@/components/blog/ArticlesList" import { Skeleton } from "@/components/skeleton" -import { getArticles } from "@/lib/blog" +import { getArticles } from "@/lib/content" +import { ArticlesList } from "@/components/blog/articles-list" export const dynamic = "force-dynamic" @@ -79,21 +79,7 @@ const BlogPage = async ({ searchParams }: BlogPageProps) => { return (
-
- - - {tag && ( -

- {`Filtered by tag: "${tag}"`} -

- )} -
- {LABELS.BLOG_PAGE.SUBTITLE} -
-
-
- - + }> diff --git a/app/(pages)/blog/tags/[tag]/page.tsx b/app/(pages)/blog/tags/[tag]/page.tsx index b5b3dc3..ff25329 100644 --- a/app/(pages)/blog/tags/[tag]/page.tsx +++ b/app/(pages)/blog/tags/[tag]/page.tsx @@ -2,7 +2,7 @@ import { LABELS } from "@/app/labels" import { ArticleListCard } from "@/components/blog/article-list-card" import { AppContent } from "@/components/ui/app-content" import { Label } from "@/components/ui/label" -import { getArticles, Article, getArticleTags } from "@/lib/blog" +import { getArticles, Article, getArticleTags, ArticleTag } from "@/lib/content" import { interpolate } from "@/lib/utils" import { HydrationBoundary, @@ -23,22 +23,43 @@ export async function generateMetadata({ params, }: BlogTagPageProps): Promise { const { tag } = params + const tags = await getArticleTags() + const tagInfo = tags.find((t) => t.id === tag) return { - title: interpolate(LABELS.BLOG_TAGS_PAGE.TAG_TITLE, { tag }), + title: interpolate(LABELS.BLOG_TAGS_PAGE.TAG_TITLE, { + tag: tagInfo?.name ?? tag, + }), description: LABELS.BLOG_TAGS_PAGE.SUBTITLE, } } export const generateStaticParams = async () => { const tags = await getArticleTags() - return tags.map((tag) => ({ tag })) + return tags.map((tag) => ({ tag: tag.id })) } const BlogTagPage = async ({ params }: BlogTagPageProps) => { const { tag } = params const queryClient = new QueryClient() + // First get all tags to find the display name + await queryClient.prefetchQuery({ + queryKey: ["get-articles-tags"], + queryFn: async () => { + try { + const tags = getArticleTags() + return tags + } catch (error) { + console.error("Error fetching article tags:", error) + return [] + } + }, + }) + + const tags = queryClient.getQueryData(["get-articles-tags"]) as ArticleTag[] + const tagInfo = tags.find((t) => t.id === tag) + await queryClient.prefetchQuery({ queryKey: ["get-articles-by-tag", tag], queryFn: async () => { @@ -59,8 +80,8 @@ const BlogTagPage = async ({ params }: BlogTagPageProps) => { return (
-
- + +
{ {LABELS.BLOG_TAGS_PAGE.BACK_TO_ARTICLES} - - -
- - +
}>
@@ -87,7 +105,7 @@ const BlogTagPage = async ({ params }: BlogTagPageProps) => { ))} {articles?.length === 0 && (

- No articles found for tag "{tag}" + No articles found for tag "{tagInfo?.name ?? tag}"

)}
diff --git a/app/(pages)/blog/tags/page.tsx b/app/(pages)/blog/tags/page.tsx index 88947de..025923f 100644 --- a/app/(pages)/blog/tags/page.tsx +++ b/app/(pages)/blog/tags/page.tsx @@ -2,7 +2,7 @@ import { LABELS } from "@/app/labels" import { Icons } from "@/components/icons" import { AppContent } from "@/components/ui/app-content" import { Label } from "@/components/ui/label" -import { getArticleTags } from "@/lib/blog" +import { getArticleTags, ArticleTag } from "@/lib/content" import { HydrationBoundary, QueryClient } from "@tanstack/react-query" import Link from "next/link" import { Suspense } from "react" @@ -20,21 +20,21 @@ const BlogTagsPage = async () => { queryKey: ["get-articles-tags"], queryFn: async () => { try { - const articles = getArticleTags() - return articles + const tags = getArticleTags() + return tags } catch (error) { - console.error("Error fetching articles:", error) + console.error("Error fetching article tags:", error) return [] } }, }) - const tags = queryClient.getQueryData(["get-articles-tags"]) as string[] + const tags = queryClient.getQueryData(["get-articles-tags"]) as ArticleTag[] return ( -
-
- +
+ +
{ - -
- - - - - {tags?.map((tag) => ( - - {tag} - - ))} - - +
+
+ + + {tags?.map((tag) => ( + + {tag.name} + + ))} + + +
) diff --git a/app/(pages)/devcon-7/sections/Devcon7Booths.tsx b/app/(pages)/devcon-7/sections/Devcon7Booths.tsx index fe5a452..5713582 100644 --- a/app/(pages)/devcon-7/sections/Devcon7Booths.tsx +++ b/app/(pages)/devcon-7/sections/Devcon7Booths.tsx @@ -1,9 +1,9 @@ import Image from "next/image" import Link from "next/link" -import { booths } from "@/data/events/devcon-7" import { AppContent } from "@/components/ui/app-content" import { Icons } from "@/components/icons" +import { booths } from "@/content/events/devcon-7" export const Devcon7Booths = () => { return ( diff --git a/app/(pages)/devcon-7/sections/Devcon7Section.tsx b/app/(pages)/devcon-7/sections/Devcon7Section.tsx index e2e41e6..770f2bc 100644 --- a/app/(pages)/devcon-7/sections/Devcon7Section.tsx +++ b/app/(pages)/devcon-7/sections/Devcon7Section.tsx @@ -2,11 +2,11 @@ import { useState } from "react" import Link from "next/link" -import { events } from "@/data/events/devcon-7" import { cva } from "class-variance-authority" import { cn } from "@/lib/utils" import { Icons } from "@/components/icons" +import { events } from "@/content/events/devcon-7" const tableSection = cva("lg:grid lg:grid-cols-[200px_1fr_160px_20px] lg:gap-8") const tableSectionTitle = cva( diff --git a/app/(pages)/layout.tsx b/app/(pages)/layout.tsx deleted file mode 100644 index feb8cbe..0000000 --- a/app/(pages)/layout.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import "@/styles/globals.css" -import Script from "next/script" - -import { fontDisplay, fontSans } from "@/lib/fonts" -import { SiteFooter } from "@/components/site-footer" -import { SiteHeader } from "@/components/site-header" -import { TailwindIndicator } from "@/components/tailwind-indicator" - -interface RootLayoutProps { - children: React.ReactNode - params: any -} - -export default function RootLayout({ children }: RootLayoutProps) { - return ( - <> - - - - -
- -
{children}
- -
- - - - - ) -} diff --git a/app/(pages)/programs/index.tsx b/app/(pages)/programs/index.tsx index 1988c92..912b36f 100644 --- a/app/(pages)/programs/index.tsx +++ b/app/(pages)/programs/index.tsx @@ -3,8 +3,6 @@ import { useCallback, useEffect, useRef, useState } from "react" import Image from "next/image" import Link from "next/link" -import { accelerationProgramFaq } from "@/data/programs/accelerationProgramFaq" -import { coreProgramFaq } from "@/data/programs/coreProgramFaq" import { ReactNode } from "react-markdown/lib/ast-to-react" import { twMerge } from "tailwind-merge" @@ -299,8 +297,8 @@ export const ProgramPageContent = () => { id="faq" className="!border-anakiwa-300" size="xs" - items={coreProgramFaq.map( - ({ question: label, answer }, index) => { + items={LABELS.CORE_PROGRAM_FAQ.map( + ({ QUESTION: label, ANSWER: answer }, index) => { return { label, value: index.toString(), @@ -441,14 +439,18 @@ export const ProgramPageContent = () => { { + items={LABELS.ACCELERATION_PROGRAM_FAQ.map( + ({ QUESTION: label, ANSWER: answer }, index) => { return { label, value: index.toString(), children: ( - {answer} + {typeof answer === "string" + ? answer + : answer.map((item, index) => { + return {item} + })} ), } diff --git a/app/(pages)/projects/[id]/page.tsx b/app/(pages)/projects/[id]/page.tsx index 5a48b0e..0ac0a85 100644 --- a/app/(pages)/projects/[id]/page.tsx +++ b/app/(pages)/projects/[id]/page.tsx @@ -1,8 +1,6 @@ import { Metadata } from "next" -import { getProjectById } from "@/lib/projectsUtils" import { ProjectInterface } from "@/lib/types" - import { ProjectContent } from "../sections/ProjectContent" type PageProps = { @@ -14,10 +12,19 @@ export interface ProjectProps { project: ProjectInterface } +/* export async function generateMetadata({ params, }: PageProps): Promise { - const { project, content } = getProjectById(params.id) + const response = await fetch("/api/projects") + const projects = await response.json() + + const project = projects.find( + (p: ProjectInterface) => + String(p.id?.toLowerCase()) === params.id.toString().toLowerCase() + ) + + const content = project?.content const imageUrl = (project?.image ?? "")?.length > 0 ? `/project-banners/${project?.image}` @@ -36,7 +43,7 @@ export async function generateMetadata({ ], }, } -} +}*/ export default async function ProjectDetailPage({ params }: PageProps) { return diff --git a/app/(pages)/projects/sections/ProjectContent.tsx b/app/(pages)/projects/sections/ProjectContent.tsx index 25e10d8..86dd546 100644 --- a/app/(pages)/projects/sections/ProjectContent.tsx +++ b/app/(pages)/projects/sections/ProjectContent.tsx @@ -1,9 +1,7 @@ "use client" import Link from "next/link" -import { useRouter } from "next/navigation" import { siteConfig } from "@/config/site" -import { getProjectById } from "@/lib/projectsUtils" import { ProjectCategory, ProjectStatus } from "@/lib/types" import { cn } from "@/lib/utils" @@ -21,14 +19,52 @@ import { WikiCard } from "@/components/cards/wiki-card" import { ProjectTeamMembers } from "@/components/project/project-team" import { ProjectBlogArticles } from "@/components/blog/project-blog-articles" import { ProjectYouTubeVideos } from "@/components/sections/ProjectYouTubeVideos" +import { useProjects } from "@/app/providers/ProjectsProvider" + +const markdownComponents = { + h1: ({ ...props }) => + createMarkdownElement("h1", { + className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", + ...props, + }), + h2: ({ ...props }) => + createMarkdownElement("h2", { + className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", + ...props, + }), + h3: ({ ...props }) => + createMarkdownElement("h3", { + className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", + ...props, + }), + h4: ({ ...props }) => + createMarkdownElement("h4", { + className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", + ...props, + }), + h5: ({ ...props }) => + createMarkdownElement("h5", { + className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", + ...props, + }), + h6: ({ ...props }) => + createMarkdownElement("h6", { + className: "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", + ...props, + }), + p: ({ ...props }) => + createMarkdownElement("p", { + className: "py-2 leading-[150%] text-base text-slate-600", + ...props, + }), +} export const ProjectContent = ({ id }: { id: string }) => { - const router = useRouter() - const { project, content } = getProjectById(id) ?? {} + const { getProjectById } = useProjects() + const { project } = getProjectById(id) ?? {} const hasSocialLinks = Object.keys(project?.links ?? {}).length > 0 - - const editPageURL = siteConfig?.editProjectPage(project?.id) + const editPageURL = siteConfig?.editProjectPage(project?.id as string) const ProjectStatusMessageMap: Record = { [ProjectStatus.ACTIVE]: "", @@ -41,14 +77,12 @@ export const ProjectContent = ({ id }: { id: string }) => { const isResearchProject = project?.category === ProjectCategory.RESEARCH - if (!project?.id) { - router.push("/404") - } - if (!project?.id) { return null } + console.log(" rest", project) + return (
@@ -57,16 +91,16 @@ export const ProjectContent = ({ id }: { id: string }) => {
0 + (project?.content as any)?.length > 0 ? "lg:grid-cols-[140px_1fr_290px]" : "lg:grid-cols-[1fr_290px]" )} > - {content?.description?.length > 0 && ( + {(project?.content as any)?.length > 0 && ( )} @@ -87,54 +121,9 @@ export const ProjectContent = ({ id }: { id: string }) => {

{project?.name}

- {content?.tldr && ( - - createMarkdownElement("h1", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h2: ({ ...props }) => - createMarkdownElement("h2", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h3: ({ ...props }) => - createMarkdownElement("h3", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h4: ({ ...props }) => - createMarkdownElement("h4", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h5: ({ ...props }) => - createMarkdownElement("h5", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h6: ({ ...props }) => - createMarkdownElement("h6", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - p: ({ ...props }) => - createMarkdownElement("p", { - className: - "py-2 leading-[150%] text-base text-slate-600", - ...props, - }), - }} - > - {content?.tldr} + {project?.tldr && ( + + {project?.tldr} )}
@@ -176,54 +165,9 @@ export const ProjectContent = ({ id }: { id: string }) => { )}
- {content?.description && ( - - createMarkdownElement("h1", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h2: ({ ...props }) => - createMarkdownElement("h2", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h3: ({ ...props }) => - createMarkdownElement("h3", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h4: ({ ...props }) => - createMarkdownElement("h4", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h5: ({ ...props }) => - createMarkdownElement("h5", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - h6: ({ ...props }) => - createMarkdownElement("h6", { - className: - "text-neutral-700 text-[22px] leading-6 font-bold pt-10 pb-4", - ...props, - }), - p: ({ ...props }) => - createMarkdownElement("p", { - className: - "text-tuatara-700 font-sans text-base font-normal peer mt-4 first:mt-0", - ...props, - }), - }} - > - {content?.description} + {(project?.content as any) && ( + + {project?.content as any} )} diff --git a/app/(pages)/resources/page.tsx b/app/(pages)/resources/page.tsx index 58a78ae..a32b96e 100644 --- a/app/(pages)/resources/page.tsx +++ b/app/(pages)/resources/page.tsx @@ -14,7 +14,7 @@ import { AppContent } from "@/components/ui/app-content" import { Button } from "@/components/ui/button" import { Label } from "@/components/ui/label" -import ResourcesContent from "../content/resources.md" +import ResourcesContent from "@/content/resources.md" interface ResourceItemProps { label: string diff --git a/app/api/articles/route.ts b/app/api/articles/route.ts index 3dca471..4711165 100644 --- a/app/api/articles/route.ts +++ b/app/api/articles/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from "next/server" -import { getArticles } from "@/lib/blog" +import { getArticles } from "@/lib/content" // Cache control export const revalidate = 60 // Revalidate cache after 60 seconds diff --git a/app/api/projects/route.ts b/app/api/projects/route.ts new file mode 100644 index 0000000..c76923e --- /dev/null +++ b/app/api/projects/route.ts @@ -0,0 +1,26 @@ +import { NextRequest, NextResponse } from "next/server" +import { getProjects } from "@/lib/content" + +// Cache control +export const revalidate = 60 // Revalidate cache after 60 seconds +export const dynamic = "force-dynamic" // Ensure the route is always evaluated + +export async function GET(request: NextRequest) { + const { searchParams } = new URL(request.url) + const tag = searchParams.get("tag") || undefined + const limit = searchParams.get("limit") + ? parseInt(searchParams.get("limit") as string, 10) + : undefined + const status = searchParams.get("status") || undefined + + try { + const projects = getProjects({ tag, limit, status }) + return NextResponse.json(projects ?? []) + } catch (error) { + console.error("Error fetching projects:", error) + return NextResponse.json( + { error: "Failed to fetch projects", success: false }, + { status: 500 } + ) + } +} diff --git a/app/labels.ts b/app/labels.ts index 951c1ec..ff521ba 100644 --- a/app/labels.ts +++ b/app/labels.ts @@ -343,4 +343,75 @@ export const LABELS = { "We are mapping the emerging zero knowledge ecosystem through collective experimentation. We collaborate, share what we learn, and welcome contributions from around the world.", }, }, + CORE_PROGRAM_FAQ: [ + { + QUESTION: "Who can apply?", + ANSWER: + "The Core Program is open to university students based in Japan, South Korea, Taiwan, Costa Rica, Ecuador and Argentina with a basic understanding of programming. If you're currently enrolled in a mathematics or computer science program, you're likely an excellent fit.", + }, + { + QUESTION: "What is the structure of the program?", + ANSWER: + "We use a hybrid learning model with the majority of learning happening online and weekly in-person meetings for discussions and problem-solving. The program consists of three stages: 1) self-driven exploration & guidance, 2) hands-on circuit writing, and 3) open-source project contribution.", + }, + { + QUESTION: "How much time will I need to commit?", + ANSWER: + "We're looking for dedicated students who can commit 40 hours a week from mid-July to September. You will be required to attend in-person meetups once a week and make presentations.", + }, + { + QUESTION: "Can I participate remotely?", + ANSWER: + "Unfortunately no, the weekly in-person sessions are required for in-depth discussions and collaborative problem-solving.", + }, + { + QUESTION: "What will I gain from this program?", + ANSWER: + "Upon completing the program, you'll have comprehensive knowledge about programmable cryptography, a bolstered GitHub portfolio, and opportunities to apply for grants for further research and contributions.", + }, + { + QUESTION: "What if I have more questions?", + ANSWER: + "For any further questions or additional information, you can join our Telegram group!", + }, + ], + ACCELERATION_PROGRAM_FAQ: [ + { + QUESTION: "Who can apply?", + ANSWER: + "The Acceleration program is open to alumni of our entry level programs (e.g. Launch Program, ZK Playground) and other applicants at beginner to intermediate levels with programmable cryptography.", + }, + { + QUESTION: "What platform does the program use?", + ANSWER: + "We will primarily utilize a Github repository for managing documents and staging of the grant proposals, grantees, and their progress. Stakeholders involved can utilize Github issues and pull requests to comment and collaborate.", + }, + { + QUESTION: "How does the grant funding work?", + ANSWER: [ + "While the core funding this program comes through PSE via the Ethereum Ecosystem Support Program (ESP), some bounties are supported by specific teams.", + "Selected grantees will receive a small amount of funding after the completion of the first milestone. Following milestones will be awarded larger amounts.", + ], + }, + { + QUESTION: "How many proposals are accepted per open task?", + ANSWER: + "Generally one proposal will be accepted. However, it is possible for applicants to form a team and work collaboratively.", + }, + { + QUESTION: "How long will I have to tackle the open tasks?", + ANSWER: + "Though our rounds are run in three month periods, the duration of your grant may be shorter or longer depending on task details.", + }, + { + QUESTION: "Can I propose an open task?", + ANSWER: + "If you have an interesting idea, you can submit it as an self proposed open task. Just to make sure you clearly credit to the original idea and clearly state if that idea is also funded by someone else.", + }, + { + QUESTION: "What if I have more questions?", + ANSWER: + "For any further questions or additional information, you can join our Telegram group!", + }, + ], } diff --git a/app/layout.tsx b/app/layout.tsx index ec43447..70c9e90 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,8 +1,13 @@ import "@/styles/globals.css" +import Script from "next/script" import { Metadata, Viewport } from "next" +import { GlobalProviderLayout } from "@/components/layouts/GlobalProviderLayout" +import { SiteFooter } from "@/components/site-footer" +import { SiteHeader } from "@/components/site-header" +import { TailwindIndicator } from "@/components/tailwind-indicator" import { siteConfig } from "@/config/site" -import { QueryClientProviderLayout } from "@/components/layouts/QueryProviderLayout" +import { cn } from "@/lib/utils" import { DM_Sans, Inter, Space_Grotesk } from "next/font/google" @@ -38,6 +43,13 @@ const sans = DM_Sans({ const fonts = [inter, display, sans] +export const viewport: Viewport = { + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "white" }, + { media: "(prefers-color-scheme: dark)", color: "black" }, + ], +} + export const metadata: Metadata = { title: { default: siteConfig.name, @@ -99,25 +111,46 @@ export const metadata: Metadata = { }, } -export const viewport: Viewport = { - themeColor: [ - { media: "(prefers-color-scheme: light)", color: "white" }, - { media: "(prefers-color-scheme: dark)", color: "black" }, - ], -} - interface RootLayoutProps { children: React.ReactNode } export default function RootLayout({ children }: RootLayoutProps) { return ( - - font.className).join(" ")}> - - {children} - - - + + + + + +
+ +
{children}
+ +
+ +
+ + ) } diff --git a/app/providers/GlobalProvider.tsx b/app/providers/GlobalProvider.tsx new file mode 100644 index 0000000..53b5d1b --- /dev/null +++ b/app/providers/GlobalProvider.tsx @@ -0,0 +1,68 @@ +"use client" + +import { + createContext, + useContext, + ReactNode, + useState, + useEffect, +} from "react" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" +import { ProjectsProvider } from "./ProjectsProvider" + +interface GlobalContextType { + children?: ReactNode + isDarkMode: boolean + setIsDarkMode: (value: boolean) => void +} + +const GlobalContext = createContext(undefined) + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + retry: false, + }, + }, +}) + +export function GlobalProvider({ children }: { children: ReactNode }) { + const [isDarkMode, setIsDarkMode] = useState(false) + + // Initialize dark mode from system preference + useEffect(() => { + const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)") + setIsDarkMode(mediaQuery.matches) + + const handleChange = (e: MediaQueryListEvent) => { + setIsDarkMode(e.matches) + } + + mediaQuery.addEventListener("change", handleChange) + return () => mediaQuery.removeEventListener("change", handleChange) + }, []) + + const value = { + isDarkMode, + setIsDarkMode, + } + + return ( + + + + {children} + + + + ) +} + +export function useGlobalProvider() { + const context = useContext(GlobalContext) + if (context === undefined) { + throw new Error("useGlobalContext must be used within a GlobalProvider") + } + return context +} diff --git a/app/providers/ProjectsProvider.tsx b/app/providers/ProjectsProvider.tsx new file mode 100644 index 0000000..9d997c5 --- /dev/null +++ b/app/providers/ProjectsProvider.tsx @@ -0,0 +1,451 @@ +"use client" + +import { + createContext, + useContext, + ReactNode, + useState, + useMemo, + useCallback, +} from "react" +import { useQuery } from "@tanstack/react-query" +import Fuse from "fuse.js" +import { ProjectCategory, ProjectInterface } from "@/lib/types" +import { uniq } from "@/lib/utils" +import { LABELS } from "@/app/labels" + +export type ProjectSortBy = "random" | "asc" | "desc" | "relevance" +export type ProjectFilter = + | "keywords" + | "builtWith" + | "themes" + | "fundingSource" +export type FiltersProps = Record +export const DEFAULT_PROJECT_SORT_BY: ProjectSortBy = "asc" + +interface ProjectInterfaceScore extends ProjectInterface { + score: number +} + +export const SortByFnMapping: Record< + ProjectSortBy, + (a: ProjectInterfaceScore, b: ProjectInterfaceScore) => number +> = { + random: () => Math.random() - 0.5, + asc: (a, b) => a.name.localeCompare(b.name), + desc: (a, b) => b.name.localeCompare(a.name), + relevance: (a, b) => b?.score - a?.score, +} + +export const FilterLabelMapping: Record = { + keywords: LABELS.COMMON.FILTER_LABELS.KEYWORDS, + builtWith: LABELS.COMMON.FILTER_LABELS.BUILT_WITH, + themes: LABELS.COMMON.FILTER_LABELS.THEMES, + fundingSource: LABELS.COMMON.FILTER_LABELS.FUNDING_SOURCE, +} + +interface ProjectsContextType { + projects: ProjectInterface[] + researchs: ProjectInterface[] + isLoading: boolean + isError: boolean + error: Error | null + filters: FiltersProps + activeFilters: Partial + queryString: string + searchQuery: string + sortBy: ProjectSortBy + getProjectById: (id: string | number) => { project: ProjectInterface } + toggleFilter: (params: { + tag: ProjectFilter + value: string + searchQuery?: string + }) => void + setFilterFromQueryString: (filters: Partial) => void + onFilterProject: (searchPattern: string) => void + onSelectTheme: (theme: string, searchPattern?: string) => void + sortProjectBy: (sortBy: ProjectSortBy) => void + refetch: () => Promise +} + +const ProjectsContext = createContext( + undefined +) + +const createURLQueryString = (params: Partial): string => { + if (Object.keys(params)?.length === 0) return "" + return Object.keys(params) + .map((key: any) => `${key}=${encodeURIComponent((params as any)[key])}`) + .join("&") +} + +const filterProjects = ({ + searchPattern = "", + activeFilters = {}, + findAnyMatch = false, + projects: projectListItems = [], +}: { + searchPattern?: string + activeFilters?: Partial + findAnyMatch?: boolean + projects?: ProjectInterface[] +}) => { + const projectList = projectListItems.map((project: any) => ({ + ...project, + id: project?.id?.toLowerCase(), + })) + + const keys = [ + "name", + "tldr", + "tags.themes", + "tags.keywords", + "tags.builtWith", + "projectStatus", + ] + + const tagsFiltersQuery: Record[] = [] + + Object.entries(activeFilters).forEach(([key, values]) => { + values.forEach((value) => { + if (!value) return + tagsFiltersQuery.push({ + [`tags.${key}`]: value, + }) + }) + }) + + const noActiveFilters = + tagsFiltersQuery.length === 0 && searchPattern.length === 0 + if (noActiveFilters) return projectList + + let query: any = {} + + if (findAnyMatch) { + query = { + $or: [...tagsFiltersQuery, { name: searchPattern }], + } + } else if (searchPattern?.length === 0) { + query = { + $and: [...tagsFiltersQuery], + } + } else if (tagsFiltersQuery.length === 0) { + query = { + name: searchPattern, + } + } else { + query = { + $and: [ + { + $and: [...tagsFiltersQuery], + }, + { name: searchPattern }, + ], + } + } + + const fuse = new Fuse(projectList, { + threshold: 0.3, + useExtendedSearch: true, + includeScore: true, + findAllMatches: true, + distance: 200, + keys, + }) + + const result = fuse.search(query)?.map(({ item, score }) => ({ + ...item, + score, + })) + return result ?? [] +} + +const sortProjectByFn = ({ + projects = [], + sortBy = DEFAULT_PROJECT_SORT_BY, + category = null, + ignoreCategories = [ProjectCategory.RESEARCH], +}: { + projects: ProjectInterface[] + sortBy?: ProjectSortBy + category?: ProjectCategory | null + ignoreCategories?: ProjectCategory[] +}) => { + const sortedProjectList: ProjectInterface[] = [ + ...(projects as ProjectInterfaceScore[]), + ] + .sort(SortByFnMapping[sortBy]) + .filter( + (project) => + !ignoreCategories + ?.map((category) => category?.toLowerCase()) + .includes(project.category?.toLowerCase() as any) + ) + + if (category) { + return sortedProjectList.filter( + (project) => project.category?.toLowerCase() === category?.toLowerCase() + ) + } + + return sortedProjectList.map((project: any) => ({ + id: project?.id?.toLowerCase(), + ...project, + })) +} + +const getProjectFilters = (projects: ProjectInterface[]): FiltersProps => { + const filters: FiltersProps = { + themes: ["play", "build", "research"], + keywords: [], + builtWith: [], + fundingSource: [], + } + + projects.forEach((project) => { + if (project?.tags?.builtWith) { + filters.builtWith.push( + ...project.tags.builtWith.map((tag) => { + if (typeof tag === "string") { + return tag.toLowerCase() + } + return "" + }) + ) + } + + if (project?.tags?.keywords) { + filters.keywords.push( + ...project.tags.keywords.map((keyword) => + typeof keyword === "string" ? keyword.toLowerCase() : "" + ) + ) + } + }) + + Object.entries(filters).forEach(([key, entries]) => { + filters[key as ProjectFilter] = uniq(entries) + }) + + return filters +} + +async function fetchProjects(tag?: string) { + try { + const params = new URLSearchParams() + if (tag) params.append("tag", tag) + + const response = await fetch(`/api/projects?${params.toString()}`, { + cache: "default", + }) + + if (!response.ok) { + throw new Error(`Failed to fetch projects: ${response.status}`) + } + + const projects = await response.json() + return projects || [] + } catch (error) { + console.error("Error fetching projects:", error) + throw error + } +} + +interface ProjectsProviderProps { + children: ReactNode + tag?: string +} + +export function ProjectsProvider({ children, tag }: ProjectsProviderProps) { + const [sortBy, setSortBy] = useState(DEFAULT_PROJECT_SORT_BY) + const [activeFilters, setActiveFilters] = useState>({}) + const [queryString, setQueryString] = useState("") + const [searchQuery, setSearchQuery] = useState("") + + const { + data: fetchedProjects = [], + isLoading, + isError, + error, + refetch, + } = useQuery({ + queryKey: ["projects", tag], + queryFn: () => fetchProjects(tag), + }) + + const getProjectById = useCallback( + (id: string | number) => { + const project: ProjectInterface = + fetchedProjects.filter( + (project: ProjectInterface) => + String(project.id?.toLowerCase()) === id.toString().toLowerCase() + )[0] ?? {} + + const content = project?.content + + return { + project, + content, + } + }, + [fetchedProjects] + ) + + const filters = useMemo( + () => getProjectFilters(fetchedProjects), + [fetchedProjects] + ) + + const filteredProjects = useMemo( + () => + filterProjects({ + searchPattern: searchQuery, + activeFilters, + projects: fetchedProjects, + }), + [searchQuery, activeFilters, fetchedProjects] + ) + + const projects = useMemo( + () => + sortProjectByFn({ + projects: filteredProjects, + sortBy, + ignoreCategories: [ProjectCategory.RESEARCH], + }), + [filteredProjects, sortBy] + ) + + const researchs = useMemo( + () => + sortProjectByFn({ + projects: filteredProjects, + sortBy, + category: ProjectCategory.RESEARCH, + ignoreCategories: [ + ProjectCategory.DEVTOOLS, + ProjectCategory.APPLICATION, + ], + }), + [filteredProjects, sortBy] + ) + + const toggleFilter = useCallback( + ({ + tag: filterKey, + value, + searchQuery: search, + }: { + tag: ProjectFilter + value: string + searchQuery?: string + }) => { + if (!filterKey) return + setActiveFilters((prevFilters) => { + const values: string[] = prevFilters?.[filterKey] ?? [] + const index = values?.indexOf(value) + const newValues = [...values] + + if (index > -1) { + newValues.splice(index, 1) + } else { + newValues.push(value) + } + + const activeFiltersNormalized = newValues.filter(Boolean) + const newActiveFilters = { + ...prevFilters, + [filterKey]: activeFiltersNormalized, + } + + setQueryString(createURLQueryString(newActiveFilters)) + if (search !== undefined) setSearchQuery(search) + return newActiveFilters + }) + }, + [] + ) + + const onSelectTheme = useCallback((theme: string, searchPattern = "") => { + setActiveFilters((prevFilters) => { + const themes = prevFilters?.themes?.includes(theme) ? [] : [theme] + const newActiveFilters = { + ...prevFilters, + themes, + } + setSearchQuery(searchPattern) + return newActiveFilters + }) + }, []) + + const onFilterProject = useCallback((searchPattern: string) => { + setSearchQuery(searchPattern) + }, []) + + const setFilterFromQueryString = useCallback( + (filters: Partial) => { + setActiveFilters(filters) + setQueryString(createURLQueryString(filters)) + }, + [] + ) + + const sortProjectBy = useCallback((newSortBy: ProjectSortBy) => { + setSortBy(newSortBy) + }, []) + + const contextValue = useMemo( + () => ({ + projects, + researchs, + isLoading, + isError, + error: error as Error | null, + filters, + activeFilters, + queryString, + searchQuery, + sortBy, + getProjectById, + toggleFilter, + setFilterFromQueryString, + onFilterProject, + onSelectTheme, + sortProjectBy, + refetch, + }), + [ + projects, + researchs, + isLoading, + isError, + error, + filters, + activeFilters, + queryString, + searchQuery, + sortBy, + getProjectById, + toggleFilter, + setFilterFromQueryString, + onFilterProject, + onSelectTheme, + sortProjectBy, + refetch, + ] + ) + + return ( + + {children} + + ) +} + +export function useProjects() { + const context = useContext(ProjectsContext) + if (context === undefined) { + throw new Error("useProjects must be used within a ProjectsProvider") + } + return context +} diff --git a/components/blog/article-in-evidance-card.tsx b/components/blog/article-in-evidance-card.tsx index 96fb010..2c9b8f2 100644 --- a/components/blog/article-in-evidance-card.tsx +++ b/components/blog/article-in-evidance-card.tsx @@ -2,7 +2,7 @@ import { Icons } from "../icons" import { Button } from "../ui/button" -import { Article } from "@/lib/blog" +import { Article } from "@/lib/content" import { cn } from "@/lib/utils" import Link from "next/link" import { LABELS } from "@/app/labels" diff --git a/components/blog/article-list-card.tsx b/components/blog/article-list-card.tsx index 721fcaf..7baea37 100644 --- a/components/blog/article-list-card.tsx +++ b/components/blog/article-list-card.tsx @@ -1,7 +1,7 @@ "use client" import Link from "next/link" import { Markdown } from "../ui/markdown" -import { Article } from "@/lib/blog" +import { Article } from "@/lib/content" import { getBackgroundImage } from "@/lib/utils" export const ArticleListCard = ({ diff --git a/components/blog/ArticlesList.tsx b/components/blog/articles-list.tsx similarity index 91% rename from components/blog/ArticlesList.tsx rename to components/blog/articles-list.tsx index 4dd271d..ed8b9ec 100644 --- a/components/blog/ArticlesList.tsx +++ b/components/blog/articles-list.tsx @@ -1,7 +1,7 @@ "use client" import { useQuery } from "@tanstack/react-query" -import { Article } from "@/lib/blog" +import { Article } from "@/lib/content" import { ArticleListCard } from "./article-list-card" import { cn, getBackgroundImage } from "@/lib/utils" import Link from "next/link" @@ -161,7 +161,7 @@ interface ArticlesListProps { tag?: string } -const ArticlesList: React.FC = ({ +export const ArticlesList: React.FC = ({ tag, }: ArticlesListProps) => { const { @@ -186,21 +186,23 @@ const ArticlesList: React.FC = ({ } const lastArticle = articles[0] - const featuredArticles = !tag ? articles.slice(1, 5) : [] - const otherArticles = !tag ? articles.slice(5) : articles + const featuredArticles = !tag ? articles.slice(1, 3) : [] + const otherArticles = !tag ? articles.slice(3) : articles const hasTag = tag !== undefined return (
{!hasTag && ( -
- +
+
+ +
{featuredArticles?.map((article: Article) => { return ( @@ -225,5 +227,3 @@ const ArticlesList: React.FC = ({
) } - -export default ArticlesList diff --git a/components/blog/blog-article-card.tsx b/components/blog/blog-article-card.tsx index 2b3c7e1..63337a0 100644 --- a/components/blog/blog-article-card.tsx +++ b/components/blog/blog-article-card.tsx @@ -1,4 +1,4 @@ -import { Article } from "@/lib/blog" +import { Article } from "@/lib/content" import { cn } from "@/lib/utils" import { cva } from "class-variance-authority" import Image from "next/image" diff --git a/components/blog/blog-article-related-projects.tsx b/components/blog/blog-article-related-projects.tsx index f5d7ecc..5413874 100644 --- a/components/blog/blog-article-related-projects.tsx +++ b/components/blog/blog-article-related-projects.tsx @@ -1,6 +1,7 @@ "use client" -import { useProjectFiltersState } from "@/state/useProjectFiltersState" +import { useMemo } from "react" +import { useProjects } from "@/app/providers/ProjectsProvider" import ProjectCard from "../project/project-card" interface BlogArticleRelatedProjectsProps { @@ -10,12 +11,13 @@ interface BlogArticleRelatedProjectsProps { export const BlogArticleRelatedProjects = ({ projectsIds, }: BlogArticleRelatedProjectsProps) => { - const { projects: allProjects, researchs: allResearchs } = - useProjectFiltersState((state) => state) + const { projects: allProjects, researchs: allResearchs } = useProjects() - const projects = [...allProjects, ...allResearchs].filter((project) => - projectsIds.includes(project.id) - ) + const projects = useMemo(() => { + return [...allProjects, ...allResearchs].filter((project) => + projectsIds.includes(project.id) + ) + }, [allProjects, allResearchs, projectsIds]) if (projects.length === 0) return null diff --git a/components/blog/blog-articles.tsx b/components/blog/blog-articles.tsx index 11b2428..3175acd 100644 --- a/components/blog/blog-articles.tsx +++ b/components/blog/blog-articles.tsx @@ -1,4 +1,4 @@ -import { Article, getArticles } from "@/lib/blog" +import { Article, getArticles } from "@/lib/content" import Link from "next/link" import { BlogArticleCard } from "./blog-article-card" diff --git a/components/blog/blog-content.tsx b/components/blog/blog-content.tsx index 49f6415..4800d85 100644 --- a/components/blog/blog-content.tsx +++ b/components/blog/blog-content.tsx @@ -1,4 +1,4 @@ -import { Article, getArticles } from "@/lib/blog" +import { Article, getArticles } from "@/lib/content" import Link from "next/link" import { AppContent } from "../ui/app-content" import { Markdown } from "../ui/markdown" diff --git a/components/blog/blog-recent-articles.tsx b/components/blog/blog-recent-articles.tsx index 2d488cb..3592dee 100644 --- a/components/blog/blog-recent-articles.tsx +++ b/components/blog/blog-recent-articles.tsx @@ -1,6 +1,6 @@ import { LABELS } from "@/app/labels" import { AppContent } from "../ui/app-content" -import { getArticles, Article } from "@/lib/blog" +import { getArticles, Article } from "@/lib/content" import Link from "next/link" import { cn } from "@/lib/utils" import { Button } from "../ui/button" diff --git a/components/blog/project-blog-articles.tsx b/components/blog/project-blog-articles.tsx index 07b078a..d8f481c 100644 --- a/components/blog/project-blog-articles.tsx +++ b/components/blog/project-blog-articles.tsx @@ -2,7 +2,7 @@ import { ProjectInterface } from "@/lib/types" import { AppContent } from "../ui/app-content" -import { Article } from "@/lib/blog" +import { Article } from "@/lib/content" import { ArticleListCard } from "./article-list-card" import { useGetProjectRelatedArticles } from "@/hooks/useGetProjectRelatedArticles" diff --git a/components/layouts/GlobalProviderLayout.tsx b/components/layouts/GlobalProviderLayout.tsx new file mode 100644 index 0000000..8ca38fb --- /dev/null +++ b/components/layouts/GlobalProviderLayout.tsx @@ -0,0 +1,18 @@ +"use client" + +import { GlobalProvider } from "@/app/providers/GlobalProvider" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" + +const queryClient = new QueryClient() + +export const GlobalProviderLayout = ({ + children, +}: { + children: React.ReactNode +}) => { + return ( + + {children} + + ) +} diff --git a/components/layouts/QueryProviderLayout.tsx b/components/layouts/QueryProviderLayout.tsx deleted file mode 100644 index 42e09f5..0000000 --- a/components/layouts/QueryProviderLayout.tsx +++ /dev/null @@ -1,15 +0,0 @@ -"use client" - -import { QueryClient, QueryClientProvider } from "@tanstack/react-query" - -const queryClient = new QueryClient() - -export const QueryClientProviderLayout = ({ - children, -}: { - children: React.ReactNode -}) => { - return ( - {children} - ) -} diff --git a/components/project/discover-more-projects.tsx b/components/project/discover-more-projects.tsx index 4f63c01..8eccfdd 100644 --- a/components/project/discover-more-projects.tsx +++ b/components/project/discover-more-projects.tsx @@ -1,8 +1,8 @@ "use client" +import { useMemo } from "react" import Link from "next/link" -import { projects } from "@/data/projects" -import { filterProjects } from "@/state/useProjectFiltersState" +import { useProjects } from "@/app/providers/ProjectsProvider" import { ProjectInterface } from "@/lib/types" import { shuffleArray } from "@/lib/utils" @@ -13,25 +13,28 @@ import ProjectCard from "./project-card" import { ProjectProps } from "@/app/(pages)/projects/[id]/page" export default function DiscoverMoreProjects({ project }: ProjectProps) { - const getSuggestedProjects = () => { - const projectList = projects.filter((p) => p.id !== project.id) + const { projects: allProjects, onFilterProject } = useProjects() - const suggestedProject = filterProjects({ - searchPattern: "", - activeFilters: project?.tags, - findAnyMatch: true, - projects: projectList, + const suggestedProject = useMemo(() => { + const projectList = allProjects.filter( + (p: ProjectInterface) => p.id !== project.id + ) + + // Filter projects by tags + onFilterProject("") + const suggestedProjects = projectList.filter((p) => { + const projectThemes = project.tags?.themes ?? [] + const pThemes = p.tags?.themes ?? [] + return projectThemes.some((tag) => pThemes.includes(tag)) }) // No match return random projects - if (suggestedProject?.length < 2) { + if (suggestedProjects?.length < 2) { return shuffleArray(projectList).slice(0, 2) } - return suggestedProject.slice(0, 2) - } - - const suggestedProject = getSuggestedProjects() + return suggestedProjects.slice(0, 2) + }, [allProjects, project.id, project.tags?.themes, onFilterProject]) return (
@@ -40,8 +43,8 @@ export default function DiscoverMoreProjects({ project }: ProjectProps) { {LABELS.COMMON.DISCOVER_MORE}
- {suggestedProject?.map((project: ProjectInterface, index: number) => ( - + {suggestedProject?.map((project: ProjectInterface) => ( + ))}
- {projectContent?.tldr && ( + {(tldr ?? "")?.length > 0 && (
-

- {projectContent?.tldr} -

+

{tldr}

)}
diff --git a/components/project/project-detail-tags.tsx b/components/project/project-detail-tags.tsx index be97ba9..a06cb87 100644 --- a/components/project/project-detail-tags.tsx +++ b/components/project/project-detail-tags.tsx @@ -1,11 +1,11 @@ "use client" -import { HtmlHTMLAttributes } from "react" +import { HtmlHTMLAttributes, useMemo } from "react" import Link from "next/link" import { FilterLabelMapping, ProjectFilter, -} from "@/state/useProjectFiltersState" +} from "@/app/providers/ProjectsProvider" import { ProjectInterface } from "@/lib/types" import { LABELS } from "@/app/labels" @@ -16,6 +16,12 @@ interface TagsProps extends HtmlHTMLAttributes { label: string } +interface TagGroup { + key: string + label: string + tags: string[] +} + const TagsWrapper = ({ label, children }: TagsProps) => { return (
@@ -30,42 +36,53 @@ type IProjectTags = { } export function ProjectTags({ project }: IProjectTags) { - const FilterKeyMapping: Record = { - keywords: LABELS.COMMON.FILTER_LABELS.KEYWORDS, - builtWith: LABELS.COMMON.FILTER_LABELS.BUILT_WITH, - themes: LABELS.COMMON.FILTER_LABELS.THEMES, - fundingSource: LABELS.COMMON.FILTER_LABELS.FUNDING_SOURCE, - } + const FilterKeyMapping = useMemo( + () => ({ + keywords: LABELS.COMMON.FILTER_LABELS.KEYWORDS, + builtWith: LABELS.COMMON.FILTER_LABELS.BUILT_WITH, + themes: LABELS.COMMON.FILTER_LABELS.THEMES, + fundingSource: LABELS.COMMON.FILTER_LABELS.FUNDING_SOURCE, + }), + [] + ) + + const filteredTags = useMemo( + () => + Object.entries(FilterLabelMapping) + .filter(([key]) => !["themes", "builtWith"].includes(key)) + .map(([key]) => { + const keyTags = project?.tags?.[key as ProjectFilter] + const hasItems = keyTags && keyTags?.length > 0 + + if (!hasItems) return null + + return { + key, + label: FilterKeyMapping[key as ProjectFilter] || key, + tags: keyTags, + } + }) + .filter((item): item is TagGroup => item !== null), + [project?.tags, FilterKeyMapping] + ) return (
- {Object.entries(FilterLabelMapping).map(([key]) => { - const keyTags = project?.tags?.[key as ProjectFilter] - const hasItems = keyTags && keyTags?.length > 0 - - if (["themes", "builtWith"].includes(key)) return null // keys to ignore - return ( - hasItems && ( -
- -
- {keyTags?.map((tag, index) => { - return ( - - - {tag} - - - ) - })} -
-
+ {filteredTags.map((tagGroup) => ( +
+ +
+ {tagGroup.tags?.map((tag, index) => ( + + + {tag} + + + ))}
- ) - ) - })} +
+
+ ))}
) } diff --git a/components/project/project-filters-bar.tsx b/components/project/project-filters-bar.tsx index ab51b67..847307f 100644 --- a/components/project/project-filters-bar.tsx +++ b/components/project/project-filters-bar.tsx @@ -3,16 +3,8 @@ import React, { ChangeEvent, ReactNode, useEffect, useState } from "react" import Image from "next/image" import { useRouter, useSearchParams } from "next/navigation" -import { projects } from "@/data/projects" import FiltersIcon from "@/public/icons/filters.svg" -import { - FilterLabelMapping, - FilterTypeMapping, - ProjectFilter, - useProjectFiltersState, -} from "@/state/useProjectFiltersState" import { useDebounce } from "react-use" - import { IThemeStatus, IThemesButton } from "@/types/common" import { ProjectCategories, @@ -24,7 +16,11 @@ import { } from "@/lib/types" import { cn, queryStringToObject } from "@/lib/utils" import { LABELS } from "@/app/labels" - +import { + useProjects, + ProjectFilter, + FilterLabelMapping, +} from "@/app/providers/ProjectsProvider" import { Icons } from "../icons" import Badge from "../ui/badge" import { Button } from "../ui/button" @@ -33,6 +29,14 @@ import { Checkbox } from "../ui/checkbox" import { Input } from "../ui/input" import { Modal } from "../ui/modal" +// Define the mapping for filter types +const FilterTypeMapping: Record = { + keywords: "checkbox", + builtWith: "checkbox", + themes: "button", + fundingSource: "checkbox", +} + interface FilterWrapperProps { label: string children?: ReactNode @@ -42,7 +46,9 @@ interface FilterWrapperProps { const FilterWrapper = ({ label, children, className }: FilterWrapperProps) => { return (
- {label} + + {label} + {children}
) @@ -81,8 +87,14 @@ export default function ProjectFiltersBar() { const [searchQuery, setSearchQuery] = useState("") const [filterCount, setFilterCount] = useState(0) - const { filters, toggleFilter, queryString, activeFilters, onFilterProject } = - useProjectFiltersState((state) => state) + const { + filters, + toggleFilter, + queryString, + activeFilters, + onFilterProject, + setFilterFromQueryString, + } = useProjects() useEffect(() => { if (!queryString) return @@ -91,10 +103,8 @@ export default function ProjectFiltersBar() { useEffect(() => { // set active filters from url - useProjectFiltersState.setState({ - activeFilters: queryStringToObject(searchParams), - }) - }, [searchParams]) + setFilterFromQueryString(queryStringToObject(searchParams)) + }, [searchParams, setFilterFromQueryString]) useEffect(() => { const count = Object.values(activeFilters).reduce((acc, curr) => { @@ -104,11 +114,7 @@ export default function ProjectFiltersBar() { }, [activeFilters]) const clearAllFilters = () => { - useProjectFiltersState.setState({ - activeFilters: {}, - queryString: "", - projects, - }) + setFilterFromQueryString({}) setSearchQuery("") // clear input router.push("/projects") } @@ -255,9 +261,7 @@ export default function ProjectFiltersBar() { ) => { setSearchQuery(e?.target?.value) - useProjectFiltersState.setState({ - searchQuery: e?.target?.value, - }) + onFilterProject(e?.target?.value) }} value={searchQuery} placeholder={LABELS.COMMON.SEARCH_PROJECT_PLACEHOLDER} diff --git a/components/project/project-list.tsx b/components/project/project-list.tsx index 4ad0ceb..dd5a8e7 100644 --- a/components/project/project-list.tsx +++ b/components/project/project-list.tsx @@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useRef, useState } from "react" import Image from "next/image" import NoResultIcon from "@/public/icons/no-result.svg" -import { useProjectFiltersState } from "@/state/useProjectFiltersState" import { cva } from "class-variance-authority" import { @@ -18,6 +17,7 @@ import { cn } from "@/lib/utils" import { LABELS } from "@/app/labels" import ProjectCard from "./project-card" +import { useProjects } from "@/app/providers/ProjectsProvider" const sectionTitleClass = cva( "relative font-sans text-base font-bold uppercase tracking-[3.36px] text-anakiwa-950 after:ml-8 after:absolute after:top-1/2 after:h-[1px] after:w-full after:translate-y-1/2 after:bg-anakiwa-300 after:content-['']" @@ -47,9 +47,14 @@ export const ProjectList = () => { const [isManualScroll, setIsManualScroll] = useState(false) const [isMounted, setIsMounted] = useState(false) - const { projects, searchQuery, queryString } = useProjectFiltersState( - (state) => state - ) + const { projects, searchQuery, activeFilters } = useProjects() + const hasSearchParams = + searchQuery?.length > 0 || + Object.values({ + keywords: activeFilters?.keywords ?? [], + builtWith: activeFilters?.builtWith ?? [], + themes: activeFilters?.themes ?? [], + }).some((arr) => arr.length > 0) const noItems = projects?.length === 0 @@ -94,8 +99,6 @@ export const ProjectList = () => { } }, []) - const hasActiveFilters = searchQuery !== "" || queryString !== "" - // loading state skeleton if (!isMounted) { return ( @@ -129,11 +132,10 @@ export const ProjectList = () => { {} as Record ) - // show all projects without sections if there are active filters - if (hasActiveFilters) { + if (hasSearchParams) { return (
- {projects.map((project) => ( + {projects?.map((project: any) => ( { className="flex justify-between gap-10" >
- {!hasActiveFilters && ( + {!hasSearchParams && (

{status}

@@ -174,7 +176,7 @@ export const ProjectList = () => {
)}
- {projects.map((project) => ( + {projects.map((project: any) => ( { const { activeFilters, toggleFilter, projects, sortProjectBy, sortBy } = - useProjectFiltersState((state) => state) + useProjects() const haveActiveFilters = Object.entries(activeFilters).some( ([, values]) => values?.length > 0 @@ -61,7 +60,7 @@ export const ProjectResultBar = () => { {resultLabel} sortProjectBy(sortBy as ProjectSortBy)} disabled={!projects?.length} @@ -69,31 +68,29 @@ export const ProjectResultBar = () => {
{haveActiveFilters && (
- {Object.entries(activeFilters).map(([key, filters], index) => { - return ( - <> - {filters?.map((filter) => { - if (filter?.length === 0) return null - - return ( - - toggleFilter({ - tag: key as ProjectFilter, - value: filter, - }) - } - key={`${index}-${filter}`} - > - {filter} - - ) - })} - + {Object.entries(activeFilters) + .flatMap(([key, filters]) => + (filters ?? []).map((filter) => ({ + key, + filter, + })) ) - })} + .filter(({ filter }) => filter?.length > 0) + .map(({ key, filter }, index) => ( + + toggleFilter({ + tag: key as ProjectFilter, + value: filter, + }) + } + > + {filter} + + ))}
)}
diff --git a/components/research/research-card.tsx b/components/research/research-card.tsx index 7b3860a..5468249 100644 --- a/components/research/research-card.tsx +++ b/components/research/research-card.tsx @@ -3,7 +3,7 @@ import Image from "next/image" import { useRouter } from "next/navigation" import { VariantProps, cva } from "class-variance-authority" -import { getProjectById } from "@/lib/projectsUtils" +import { useProjects } from "@/app/providers/ProjectsProvider" import { ProjectInterface, ProjectLinkWebsite, @@ -70,10 +70,16 @@ export default function ProjectCard({ }: ProjectCardProps) { const router = useRouter() - const { id, image, links, name, imageAlt, projectStatus, cardTags } = - project ?? {} - - const { content: projectContent } = getProjectById(id) + const { + id, + image, + links, + name, + imageAlt, + projectStatus, + cardTags, + tldr = "", + } = project ?? {} return ( {name} - {projectContent?.tldr && ( + {(tldr ?? "")?.length > 0 && (
-

- {projectContent?.tldr} -

+

{tldr}

)}
diff --git a/components/research/research-list.tsx b/components/research/research-list.tsx index f0a3412..3653f96 100644 --- a/components/research/research-list.tsx +++ b/components/research/research-list.tsx @@ -1,17 +1,18 @@ "use client" -import React, { useEffect, useState } from "react" +import React, { useEffect, useState, useMemo } from "react" import Image from "next/image" import NoResultIcon from "@/public/icons/no-result.svg" -import { useProjectFiltersState } from "@/state/useProjectFiltersState" import { cva } from "class-variance-authority" -import { ProjectStatus } from "@/lib/types" +import { ProjectInterface, ProjectStatus } from "@/lib/types" import { cn } from "@/lib/utils" import { LABELS } from "@/app/labels" +import { useProjects } from "@/app/providers/ProjectsProvider" import ResearchCard from "./research-card" import Link from "next/link" + const sectionTitleClass = cva( "relative font-sans text-base font-bold uppercase tracking-[3.36px] text-anakiwa-950 after:ml-8 after:absolute after:top-1/2 after:h-[1px] after:w-full after:translate-y-1/2 after:bg-anakiwa-300 after:content-['']" ) @@ -37,17 +38,28 @@ const ProjectStatusOrderList = ["active", "maintained", "inactive"] export const ResearchList = () => { const [isMounted, setIsMounted] = useState(false) - const { researchs, searchQuery, queryString } = useProjectFiltersState( - (state) => state - ) + const { researchs, searchQuery, queryString } = useProjects() const noItems = researchs?.length === 0 + const hasActiveFilters = searchQuery !== "" || queryString !== "" useEffect(() => { setIsMounted(true) }, []) - const hasActiveFilters = searchQuery !== "" || queryString !== "" + const { activeResearchs, pastResearchs } = useMemo(() => { + const active = researchs.filter( + (research: ProjectInterface) => + research.projectStatus === ProjectStatus.ACTIVE + ) + + const past = researchs.filter( + (research: ProjectInterface) => + research.projectStatus !== ProjectStatus.ACTIVE + ) + + return { activeResearchs: active, pastResearchs: past } + }, [researchs]) if (!isMounted) { return ( @@ -74,14 +86,6 @@ export const ResearchList = () => { if (noItems) return - const activeResearchs = researchs.filter( - (research) => research.projectStatus === ProjectStatus.ACTIVE - ) - - const pastResearchs = researchs.filter( - (research) => research.projectStatus !== ProjectStatus.ACTIVE - ) - return (
{
)}
- {activeResearchs.map((project) => { - return ( - - ) - })} + {activeResearchs.map((project: ProjectInterface) => ( + + ))}
@@ -120,17 +122,15 @@ export const ResearchList = () => {
- {pastResearchs.map((project) => { - return ( - - {project.name} - - ) - })} + {pastResearchs.map((project: ProjectInterface) => ( + + {project.name} + + ))}
diff --git a/articles/README.md b/content/articles/README.md similarity index 92% rename from articles/README.md rename to content/articles/README.md index 5bdd699..8967cf0 100644 --- a/articles/README.md +++ b/content/articles/README.md @@ -4,7 +4,7 @@ This document explains how to add new articles to into pse.dev blog section. ## Step 1: Create the Article File -1. Duplicate the `_article-template.md` file in the `articles` directory +1. Duplicate the `_article-template.md` file in the `content/articles` directory 2. Rename it to match your article's title using kebab-case (e.g., `my-new-article.md`) ## Step 2: Fill in the Article Information @@ -20,7 +20,7 @@ tldr: "A brief summary of your article" #Short summary date: "YYYY-MM-DD" # Publication date in ISO format canonical: "mirror.xyz/my-new-article" # (Optional) The original source URL, this tells search engines the primary version of the content tags: ["tag1", "tag2"] # (Optional) Add relevant tags as an array of strings to categorize the article -projects: ["project-1"] +projects: ["project-1"] # (Optional) Link to related projects by their id --- ``` @@ -63,7 +63,7 @@ Before submitting, make sure to: Open Pull request following the previews step and for any help -- Suggest to tag: @kalidiagne, @psedesign, @AtHeartEngineer for PR review. +- Suggest to tag: @kalidiagne, @psedesign for PR review. - If question, please reach out in discord channel #website-pse ## Important Notes diff --git a/articles/_article-template.md b/content/articles/_article-template.md similarity index 99% rename from articles/_article-template.md rename to content/articles/_article-template.md index 0bf8cb3..493cdf8 100644 --- a/articles/_article-template.md +++ b/content/articles/_article-template.md @@ -7,4 +7,4 @@ date: "YYYY-MM-DD" # Publication date in ISO format canonical: "mirror.xyz/my-new-article" # (Optional) The original source URL, this tells search engines the primary version of the content tags: ["tag1", "tag2"] # (Optional) Add relevant tags as an array of strings to categorize the article projects: ["project-1"] ---- \ No newline at end of file +--- diff --git a/articles/a-technical-introduction-to-arbitrums-optimistic-rollup.md b/content/articles/a-technical-introduction-to-arbitrums-optimistic-rollup.md similarity index 100% rename from articles/a-technical-introduction-to-arbitrums-optimistic-rollup.md rename to content/articles/a-technical-introduction-to-arbitrums-optimistic-rollup.md diff --git a/articles/a-technical-introduction-to-maci-10-privacy-scaling-explorations.md b/content/articles/a-technical-introduction-to-maci-10-privacy-scaling-explorations.md similarity index 100% rename from articles/a-technical-introduction-to-maci-10-privacy-scaling-explorations.md rename to content/articles/a-technical-introduction-to-maci-10-privacy-scaling-explorations.md diff --git a/articles/advancing-anon-aadhaar-whats-new-in-v100.md b/content/articles/advancing-anon-aadhaar-whats-new-in-v100.md similarity index 100% rename from articles/advancing-anon-aadhaar-whats-new-in-v100.md rename to content/articles/advancing-anon-aadhaar-whats-new-in-v100.md diff --git a/articles/announcing-anon-aadhaar.md b/content/articles/announcing-anon-aadhaar.md similarity index 100% rename from articles/announcing-anon-aadhaar.md rename to content/articles/announcing-anon-aadhaar.md diff --git a/articles/announcing-maci-v111.md b/content/articles/announcing-maci-v111.md similarity index 100% rename from articles/announcing-maci-v111.md rename to content/articles/announcing-maci-v111.md diff --git a/articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions.md b/content/articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions.md similarity index 100% rename from articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions.md rename to content/articles/anonklub-reflections-on-our-journey-in-privacy-preserving-solutions.md diff --git a/articles/are-elliptic-curves-going-to-survive-the-quantum-apocalypse.md b/content/articles/are-elliptic-curves-going-to-survive-the-quantum-apocalypse.md similarity index 100% rename from articles/are-elliptic-curves-going-to-survive-the-quantum-apocalypse.md rename to content/articles/are-elliptic-curves-going-to-survive-the-quantum-apocalypse.md diff --git a/articles/bandada-is-live.md b/content/articles/bandada-is-live.md similarity index 100% rename from articles/bandada-is-live.md rename to content/articles/bandada-is-live.md diff --git a/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography.md b/content/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography.md similarity index 100% rename from articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography.md rename to content/articles/beyond-zero-knowledge-whats-next-in-programmable-cryptography.md diff --git a/articles/bls-wallet-bundling-up-data-privacy-scaling-explorations.md b/content/articles/bls-wallet-bundling-up-data-privacy-scaling-explorations.md similarity index 100% rename from articles/bls-wallet-bundling-up-data-privacy-scaling-explorations.md rename to content/articles/bls-wallet-bundling-up-data-privacy-scaling-explorations.md diff --git a/articles/certificate-transparency-using-newtonpir.md b/content/articles/certificate-transparency-using-newtonpir.md similarity index 100% rename from articles/certificate-transparency-using-newtonpir.md rename to content/articles/certificate-transparency-using-newtonpir.md diff --git a/articles/circom-mpc-tldr-and-retrospective.md b/content/articles/circom-mpc-tldr-and-retrospective.md similarity index 100% rename from articles/circom-mpc-tldr-and-retrospective.md rename to content/articles/circom-mpc-tldr-and-retrospective.md diff --git a/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography.md b/content/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography.md similarity index 100% rename from articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography.md rename to content/articles/code-optimizations-in-the-landscape-of-post-quantum-cryptography.md diff --git a/articles/continuing-the-zero-gravity-journey.md b/content/articles/continuing-the-zero-gravity-journey.md similarity index 100% rename from articles/continuing-the-zero-gravity-journey.md rename to content/articles/continuing-the-zero-gravity-journey.md diff --git a/articles/devcon-vi-recap.md b/content/articles/devcon-vi-recap.md similarity index 100% rename from articles/devcon-vi-recap.md rename to content/articles/devcon-vi-recap.md diff --git a/articles/efficient-client-side-proving-for-zkid.md b/content/articles/efficient-client-side-proving-for-zkid.md similarity index 100% rename from articles/efficient-client-side-proving-for-zkid.md rename to content/articles/efficient-client-side-proving-for-zkid.md diff --git a/articles/from-cex-to-ccex-with-summa-part-1.md b/content/articles/from-cex-to-ccex-with-summa-part-1.md similarity index 100% rename from articles/from-cex-to-ccex-with-summa-part-1.md rename to content/articles/from-cex-to-ccex-with-summa-part-1.md diff --git a/articles/from-cex-to-ccex-with-summa-part-2.md b/content/articles/from-cex-to-ccex-with-summa-part-2.md similarity index 100% rename from articles/from-cex-to-ccex-with-summa-part-2.md rename to content/articles/from-cex-to-ccex-with-summa-part-2.md diff --git a/articles/hello-world-the-first-signs-of-practical-io.md b/content/articles/hello-world-the-first-signs-of-practical-io.md similarity index 100% rename from articles/hello-world-the-first-signs-of-practical-io.md rename to content/articles/hello-world-the-first-signs-of-practical-io.md diff --git a/articles/interep-on-ramp-for-reputaion.md b/content/articles/interep-on-ramp-for-reputaion.md similarity index 100% rename from articles/interep-on-ramp-for-reputaion.md rename to content/articles/interep-on-ramp-for-reputaion.md diff --git a/articles/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs.md b/content/articles/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs.md similarity index 100% rename from articles/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs.md rename to content/articles/intmax-a-scalable-payment-l2-from-plasma-and-validity-proofs.md diff --git a/articles/introducing-trinity.md b/content/articles/introducing-trinity.md similarity index 100% rename from articles/introducing-trinity.md rename to content/articles/introducing-trinity.md diff --git a/articles/lattice-based-proof-systems.md b/content/articles/lattice-based-proof-systems.md similarity index 100% rename from articles/lattice-based-proof-systems.md rename to content/articles/lattice-based-proof-systems.md diff --git a/articles/learnings-from-the-kzg-ceremony.md b/content/articles/learnings-from-the-kzg-ceremony.md similarity index 100% rename from articles/learnings-from-the-kzg-ceremony.md rename to content/articles/learnings-from-the-kzg-ceremony.md diff --git a/articles/meet-coco-privacy-scaling-explorations.md b/content/articles/meet-coco-privacy-scaling-explorations.md similarity index 100% rename from articles/meet-coco-privacy-scaling-explorations.md rename to content/articles/meet-coco-privacy-scaling-explorations.md diff --git a/articles/mopro-comparison-of-circom-provers.md b/content/articles/mopro-comparison-of-circom-provers.md similarity index 100% rename from articles/mopro-comparison-of-circom-provers.md rename to content/articles/mopro-comparison-of-circom-provers.md diff --git a/articles/mopro-native-packages.md b/content/articles/mopro-native-packages.md similarity index 100% rename from articles/mopro-native-packages.md rename to content/articles/mopro-native-packages.md diff --git a/articles/mpc-retrospective.md b/content/articles/mpc-retrospective.md similarity index 91% rename from articles/mpc-retrospective.md rename to content/articles/mpc-retrospective.md index 11ea2a3..6085ecb 100644 --- a/articles/mpc-retrospective.md +++ b/content/articles/mpc-retrospective.md @@ -1,5 +1,5 @@ --- -authors: ["Kevin Chia","Jern Kun","Kazumune Masaki"] # Add your name or multiple authors in an array +authors: ["Kevin Chia", "Jern Kun", "Kazumune Masaki"] # Add your name or multiple authors in an array title: "MPCStats Retrospective: Lessons from a Privacy-Preserving Stats Platform" # The title of your article image: "/articles/mpcstats-retrospective/cover.png" # Image used as cover, Keep in mind the image size, where possible use .webp format, possibly images less then 200/300kb tldr: "A retrospective on the MPCStats project—exploring our goals, technical challenges, demo at Devcon 2024, and the decision to sunset the platform." @@ -20,13 +20,12 @@ We got valuable feedback after the demo, and we recognized that identifying impa ![mpcstats-demo](/articles/mpcstats-retrospective/mpcstats-demo.png) - ### What was achieved - Successfully delivered an [interactive demo at Devcon 2024](https://www.youtube.com/watch?v=wCp7Zsjou7w), where participants submitted their ETH balance from Binance and queried aggregated statistics like the Gini coefficient, mean, median, and max. - - Computations were performed using MPC, with data authenticity verified by [TLSNotary](https://tlsnotary.org/) and execution delegated to three servers for smoother UX. - - The system completed most computations within 1 minute and was secure against up to 1 out of 3 malicious parties. Full details are available in our [demo report](https://www.notion.so/3055bb69afd24d60bf8ee8d4fa5f774c?pvs=21). - - The same demo was also presented at **Taipei Blockchain Week**, with a total of 19 participants across both events. + - Computations were performed using MPC, with data authenticity verified by [TLSNotary](https://tlsnotary.org/) and execution delegated to three servers for smoother UX. + - The system completed most computations within 1 minute and was secure against up to 1 out of 3 malicious parties. Full details are available in our [demo report](https://www.notion.so/3055bb69afd24d60bf8ee8d4fa5f774c?pvs=21). + - The same demo was also presented at **Taipei Blockchain Week**, with a total of 19 participants across both events. - Developed a reusable [infrastructure for MPC demos](https://github.com/MPCStats/mpc-demo-infra), allowing other teams to adapt for different data sources and statistical functions, using the statistics library we built with [MP-SPDZ](https://github.com/data61/MP-SPDZ). - Built an earlier [ZK-based version of the statistics library](https://github.com/MPCStats/zk-stats-lib) using [EZKL](https://github.com/zkonduit/ezkl), enabling single-party computations and helping explore privacy-preserving techniques beyond MPC. @@ -64,4 +63,4 @@ And write-ups: We hope these components can serve as a reference or starting point for teams exploring privacy-preserving statistics, MPC applications, and input authentication using TLSNotary. -No active maintenance will be guaranteed going forward. However, the code and write-ups will remain publicly accessible for anyone who finds them useful. \ No newline at end of file +No active maintenance will be guaranteed going forward. However, the code and write-ups will remain publicly accessible for anyone who finds them useful. diff --git a/articles/p0tion-v10-release.md b/content/articles/p0tion-v10-release.md similarity index 100% rename from articles/p0tion-v10-release.md rename to content/articles/p0tion-v10-release.md diff --git a/articles/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR.md b/content/articles/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR.md similarity index 70% rename from articles/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR.md rename to content/articles/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR.md index 8b414a8..80b9614 100644 --- a/articles/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR.md +++ b/content/articles/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR.md @@ -1,13 +1,11 @@ --- - -title: 'Post-Quantum Signature Aggregation with Falcon + LaBRADOR' +title: "Post-Quantum Signature Aggregation with Falcon + LaBRADOR" date: 2025-05-19 author: PSE Research image: "/articles/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR/cover.webp" -tagline: 'Compact lattice-based proofs for Ethereum' -description: 'Introducing our work on aggregating Falcon signatures using LaBRADOR, a lattice-based proof system optimized for Ethereum.' -canonical: 'https://ethresear.ch/t/lattice-based-signature-aggregation/22282' - +tagline: "Compact lattice-based proofs for Ethereum" +description: "Introducing our work on aggregating Falcon signatures using LaBRADOR, a lattice-based proof system optimized for Ethereum." +canonical: "https://ethresear.ch/t/lattice-based-signature-aggregation/22282" --- We demonstrate efficient aggregation of Falcon signatures using LaBRADOR, achieving compact, quantum-resistant proofs. Read the full technical breakdown on [ethresear.ch](https://ethresear.ch/t/lattice-based-signature-aggregation/22282). @@ -18,13 +16,12 @@ Ethereum currently uses BLS signatures, but these are vulnerable to future quant Key highlights: -* **Compact proofs:** Aggregate 10,000 Falcon-512 signatures into a 74 KB proof. -* **Efficient generation:** Proofs generated in \~6 seconds on commodity hardware. -* **Verification optimization:** Current verification time (\~2.6 seconds) identified as a primary bottleneck, with active work to reduce it further. +- **Compact proofs:** Aggregate 10,000 Falcon-512 signatures into a 74 KB proof. +- **Efficient generation:** Proofs generated in \~6 seconds on commodity hardware. +- **Verification optimization:** Current verification time (\~2.6 seconds) identified as a primary bottleneck, with active work to reduce it further. This work is part of our broader post-quantum initiative at PSE, focusing on securing Ethereum's core infrastructure. --- 🔗 **Full technical details and discussions:** [Lattice-based signature aggregation on ethresear.ch](https://ethresear.ch/t/lattice-based-signature-aggregation/22282) - diff --git a/articles/pse-may-2025-newsletter.md b/content/articles/pse-may-2025-newsletter.md similarity index 100% rename from articles/pse-may-2025-newsletter.md rename to content/articles/pse-may-2025-newsletter.md diff --git a/articles/pse-security-what-is-new.md b/content/articles/pse-security-what-is-new.md similarity index 100% rename from articles/pse-security-what-is-new.md rename to content/articles/pse-security-what-is-new.md diff --git a/articles/rate-limiting-nullifier-a-spam-protection-mechanism-for-anonymous-environments.md b/content/articles/rate-limiting-nullifier-a-spam-protection-mechanism-for-anonymous-environments.md similarity index 100% rename from articles/rate-limiting-nullifier-a-spam-protection-mechanism-for-anonymous-environments.md rename to content/articles/rate-limiting-nullifier-a-spam-protection-mechanism-for-anonymous-environments.md diff --git a/articles/rate-limiting-nullifier-rln.md b/content/articles/rate-limiting-nullifier-rln.md similarity index 100% rename from articles/rate-limiting-nullifier-rln.md rename to content/articles/rate-limiting-nullifier-rln.md diff --git a/articles/reflecting-on-maci-platform.md b/content/articles/reflecting-on-maci-platform.md similarity index 100% rename from articles/reflecting-on-maci-platform.md rename to content/articles/reflecting-on-maci-platform.md diff --git a/articles/release-announcement-maci-10-privacy-scaling-explorations.md b/content/articles/release-announcement-maci-10-privacy-scaling-explorations.md similarity index 100% rename from articles/release-announcement-maci-10-privacy-scaling-explorations.md rename to content/articles/release-announcement-maci-10-privacy-scaling-explorations.md diff --git a/articles/retrospective-summa.md b/content/articles/retrospective-summa.md similarity index 100% rename from articles/retrospective-summa.md rename to content/articles/retrospective-summa.md diff --git a/articles/retrospective-trusted-setups-and-p0tion-project.md b/content/articles/retrospective-trusted-setups-and-p0tion-project.md similarity index 100% rename from articles/retrospective-trusted-setups-and-p0tion-project.md rename to content/articles/retrospective-trusted-setups-and-p0tion-project.md diff --git a/articles/rsa-verification-circuit-in-halo2-and-its-applications.md b/content/articles/rsa-verification-circuit-in-halo2-and-its-applications.md similarity index 100% rename from articles/rsa-verification-circuit-in-halo2-and-its-applications.md rename to content/articles/rsa-verification-circuit-in-halo2-and-its-applications.md diff --git a/articles/secure-multi-party-computation.md b/content/articles/secure-multi-party-computation.md similarity index 100% rename from articles/secure-multi-party-computation.md rename to content/articles/secure-multi-party-computation.md diff --git a/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead.md b/content/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead.md similarity index 100% rename from articles/self-sovereign-identity-programmable-cryptography-challenges-ahead.md rename to content/articles/self-sovereign-identity-programmable-cryptography-challenges-ahead.md diff --git a/articles/semaphore-community-grants-awarded-projects.md b/content/articles/semaphore-community-grants-awarded-projects.md similarity index 100% rename from articles/semaphore-community-grants-awarded-projects.md rename to content/articles/semaphore-community-grants-awarded-projects.md diff --git a/articles/semaphore-community-grants.md b/content/articles/semaphore-community-grants.md similarity index 100% rename from articles/semaphore-community-grants.md rename to content/articles/semaphore-community-grants.md diff --git a/articles/semaphore-v2-is-live-privacy-scaling-explorations.md b/content/articles/semaphore-v2-is-live-privacy-scaling-explorations.md similarity index 100% rename from articles/semaphore-v2-is-live-privacy-scaling-explorations.md rename to content/articles/semaphore-v2-is-live-privacy-scaling-explorations.md diff --git a/articles/semaphore-v3-announcement.md b/content/articles/semaphore-v3-announcement.md similarity index 100% rename from articles/semaphore-v3-announcement.md rename to content/articles/semaphore-v3-announcement.md diff --git a/articles/summon-major-update.md b/content/articles/summon-major-update.md similarity index 100% rename from articles/summon-major-update.md rename to content/articles/summon-major-update.md diff --git a/articles/tee-based-ppd.md b/content/articles/tee-based-ppd.md similarity index 92% rename from articles/tee-based-ppd.md rename to content/articles/tee-based-ppd.md index 51db72b..279600f 100644 --- a/articles/tee-based-ppd.md +++ b/content/articles/tee-based-ppd.md @@ -8,23 +8,27 @@ projects: ["private-proof-delegation"] --- ## tl;dr + We built a TEE-based system for secure zero-knowledge proof delegation using Intel TDX. It allows clients to privately outsource large proving tasks without leaking inputs. Unlike mobile-native proving, which is constrained by hardware limits, TEE-based proving can scale to larger statements today — and continue to scale as proof systems improve. As a hardware-backed solution, TEE remains compatible with future advancements in software (e.g., faster proof systems, better engineering) and won't be invalidated by them, as long as the trust model is acceptable. ➡️ [Jump to Benchmarking section](#Benchmarking) to see how it performs in practice. # Introduction + ## Background and motivation + Typically, zk applications let consumer devices such as mobile phones or web browsers generate SNARK proofs. In such cases, the secret inputs from the clients never leave the device; therefore, the privacy of the inputs is protected. However, the complexity of the statements that weak hardware can prove is fairly limited. This means that proving more complex statements requires stronger hardware—something most users do not have access to in their daily lives. One approach to address this issue is to **delegate the proof generation** to external servers with powerful hardware. This technique is called proof delegation. By using this technique, clients with weak devices can offload heavy computation to an external server and still obtain proof about their private data. ![Proof delegation image](/articles/tee-based-ppd/proof-delegation.png) -*How naive proof delegation works* +_How naive proof delegation works_ In naive proof delegation, the client sends their raw inputs directly to the proving server, which then generates the proof. This approach works well for non-sensitive computations (e.g., public blockchain state transitions), but it fails to preserve the zero-knowledge property when the inputs are private. The server learns the data as is, so there is no privacy guarantee. ## Private proof delegation (PPD) + **Private proof delegation** (PPD) enhances this model by ensuring the private input remains hidden from the server. This is achieved by introducing a cryptographic layer between the client and the proving server. Instead of sending raw data, the client encrypts the private input before transmission. ![Private proof delegation image](/articles/tee-based-ppd/private-proof-delegation.png) -*Private proof delegation* +_Private proof delegation_ The cryptographic techniques that we can possibly use include @@ -35,6 +39,7 @@ The cryptographic techniques that we can possibly use include In this article, we focus on the TEE-based approach, which we believe is practical and well-supported in today's cloud environments. # TEE Primer: What and Why + ## What is Trusted Execution Environment (TEE)? A **Trusted Execution Environment (TEE)** is a **secure and isolated processing environment** that runs alongside the main operating system on a machine. It provides: @@ -48,7 +53,9 @@ TEEs are critically important for scenarios where sensitive data or computations Different TEE implementations exist today, such as [Intel SGX](https://www.intel.com/content/www/us/en/products/docs/accelerator-engines/software-guard-extensions.html), [ARM TrustZone](https://www.arm.com/technologies/trustzone-for-cortex-a), [AMD SEV](https://www.amd.com/en/developer/sev.html), and [Intel TDX](https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html). Each offers varying degrees of isolation, threat models, and usability. ## Key components + There are several key components of TEE: + - Hardware isolation - Memory encryption - Remote attestation @@ -57,6 +64,7 @@ There are several key components of TEE: We will take a closer look into each of the items. ### Hardware isolation + At the heart of any Trusted Execution Environment (TEE) is the concept of hardware-enforced isolation. Hardware isolation refers to the physical and logical mechanisms built directly into the CPU and platform architecture that create a boundary between the execution environment inside the TEE and the rest of the system (Rich Execution Environment, REE)—including the operating system, hypervisor, firmware, and other software running outside the TEE. Rather than relying on software controls (which can be bypassed by privileged attackers), hardware isolation ensures that: @@ -71,8 +79,8 @@ This isolation is enforced by mechanisms such as - Dedicated secure memory regions (e.g., Enclave Page Cache in Intel SGX, Secure EPT in Intel TDX) - CPU privilege separation between "trusted" and "untrusted" execution modes - ### Memory encryption + While hardware isolation protects the logical boundaries of the Trusted Execution Environment (TEE), it does not by itself prevent physical attacks targeting the system’s memory. For example, if the attacker has access to the physical hardware, it is possible to dump the memory to see the data inside. Memory encryption addresses this gap by ensuring that all data stored outside the CPU boundary — particularly in RAM — remains cryptographically protected by encryption schemes against unauthorized access, even in the face of direct hardware attacks. The data stored inside the memory is always encrypted with a key secured in the chip (only TEE can access the key). For example, in Intel TDX, AES-XTS with ephemeral 128-bit memory-encryption keys (TDX) are used for encrypting the data, and the integrity of the data inside memory is guaranteed by SHA-3-based MAC so that malicious data tampering can be detected. This ensures that @@ -82,6 +90,7 @@ This ensures that - Side-channel leakage through unprotected memory reads/writes is minimized. ### Remote attestation + Even with hardware isolation and memory encryption, a crucial question remains: **"How can a remote party trust that the TEE is running the intended code on a genuine, uncompromised platform?"** @@ -93,7 +102,6 @@ Even with hardware isolation and memory encryption, a crucial question remains: This proof enables remote clients to establish trust before transmitting sensitive data or initiating private computations. - - The booted TD image exactly as expected (secure boot). - The measurements created/extended during runtime are as expected. - The TEE is executed on a certified hardware platform. @@ -122,6 +130,7 @@ In Intel TDX and similar TEEs, the root of trust is composed of Importantly, the security of the entire TEE — including attestation, isolation, and encryption — ultimately depends on the integrity and authenticity of this Root of Trust. ## What is the trust assumption of TEE? + In traditional cryptography, security relies on mathematical hardness assumptions — for example, the difficulty of solving the Discrete Logarithm Problem (DLP) or the intractability of Learning With Errors (LWE). These assumptions are well-studied and allow cryptographic protocols to provide strong, quantifiable security guarantees. In contrast, when relying on a Trusted Execution Environment (TEE), security instead depends on a different class of assumptions: trust in hardware, firmware, and system integrity. @@ -131,20 +140,20 @@ While TEEs dramatically reduce the size of the trusted computing base compared t In this section, we detail what specific components and entities must be trusted when building on a TEE. - ### Trust in the Hardware Manufacturer + A fundamental trust anchor when using a TEE is the **hardware manufacturer**. In the case of Intel TDX, this is Intel Corporation, which designs and produces the processors and microcode that enforce TDX protections. When trusting the hardware manufacturer, the following assumptions are made: - **Correct Implementation**: -The manufacturer has correctly implemented the TEE architecture as specified, including hardware isolation, memory encryption, key management, and the attestation mechanism. Errors or backdoors in the hardware implementation could trivially undermine the TEE’s guarantees. + The manufacturer has correctly implemented the TEE architecture as specified, including hardware isolation, memory encryption, key management, and the attestation mechanism. Errors or backdoors in the hardware implementation could trivially undermine the TEE’s guarantees. - **Secure Key Provisioning**: -Attestation keys (used to sign attestation quotes) are provisioned securely during the manufacturing process and cannot be extracted, replaced, or misused. + Attestation keys (used to sign attestation quotes) are provisioned securely during the manufacturing process and cannot be extracted, replaced, or misused. - **Supply Chain Integrity**: -The physical chip that arrives at the cloud datacenter is authentic and has not been tampered with or replaced during production or delivery. + The physical chip that arrives at the cloud datacenter is authentic and has not been tampered with or replaced during production or delivery. - **Prompt Security Response**: -If vulnerabilities are discovered (e.g., speculative execution side-channels), the manufacturer acts responsibly to issue patches, microcode updates, or mitigations. + If vulnerabilities are discovered (e.g., speculative execution side-channels), the manufacturer acts responsibly to issue patches, microcode updates, or mitigations. **What if Broken** If the hardware manufacturer is dishonest, coerced, or negligent, the entire security model of the TEE collapses. The TEE could leak secrets, forge attestation quotes, or fail to enforce isolation — without any detectable signals to the user. @@ -152,6 +161,7 @@ If the hardware manufacturer is dishonest, coerced, or negligent, the entire sec This trust assumption is not cryptographic in the traditional sense; it is institutional and engineering-based. ### Trust in the Attestation Service + The attestation process is what enables remote parties (such as clients) to verify the trustworthiness of a TEE before entrusting it with sensitive data. However, the correctness of attestation relies on the integrity of the attestation service infrastructure. Typically, there are two main parties involved: @@ -162,17 +172,14 @@ Typically, there are two main parties involved: When trusting the attestation service, the following assumptions are made: - **Authenticity of Device Identity**: -The attestation key bound to the physical device is genuine and was issued by the manufacturer’s trusted key hierarchy. + The attestation key bound to the physical device is genuine and was issued by the manufacturer’s trusted key hierarchy. - **Correct Verification and Validation**: -The attestation service correctly verifies the quotes it receives, checking that: - - Measurements match an expected secure configuration. - - Firmware and security versions meet minimum patch levels. - - No security policy violations have occurred. + The attestation service correctly verifies the quotes it receives, checking that: - Measurements match an expected secure configuration. - Firmware and security versions meet minimum patch levels. - No security policy violations have occurred. - **Impartial and Secure Operation**: -The attestation service must behave honestly, not issuing approvals for devices that are compromised, outdated, or misconfigured. + The attestation service must behave honestly, not issuing approvals for devices that are compromised, outdated, or misconfigured. - **Resistance to Collusion or Coercion**: -The attestation service must resist external pressures (e.g., nation-state coercion) that might lead it to falsely attestation to an insecure environment. + The attestation service must resist external pressures (e.g., nation-state coercion) that might lead it to falsely attestation to an insecure environment. **What if Broken** If the attestation service incorrectly verifies a compromised TEE — or worse, issues fabricated attestation results — remote users would falsely believe they are communicating with a secure environment. @@ -181,14 +188,16 @@ This would completely undermine the remote trust model that TEEs are designed to --- # TEE-based private proof delegation + ## Construction of TEE-based private proof delegation + TEE-based private proof delegation system involves a few additional components compared to naive PPD system. In this section, we describe how to construct a TEE-based private proof delegation system. - ![TEE based PPD architecture](/articles/tee-based-ppd/tee-ppd.png) -*Architecture diagram* +_Architecture diagram_ In the architecture diagram above, we can see several components, including + - Client - TD Host - TD Guest (Prover) @@ -206,28 +215,33 @@ In the architecture diagram above, we can see several components, including **Verifier** is anyone who verifies the generated proof. ## Execution flow -### Remote Attestation -We start the whole process with remote attestation. In this step, the client ensures that the prover VM is running on legitimate hardware and firmware, OS, and program. +### Remote Attestation + +We start the whole process with remote attestation. In this step, the client ensures that the prover VM is running on legitimate hardware and firmware, OS, and program. ### What Happens 1. The **TEE environment** (such as a confidential VM or enclave) begins by measuring its **initial state** at launch time. These measurements include: + - The code and data loaded into the TEE at startup - Configuration values (e.g., enabled security features, TEE attributes) 2. These measurements are securely recorded in **platform-protected registers**, such as: + - Platform Configuration Registers (PCRs) in a TPM - Runtime Measurement Registers (RTMRs) or equivalent TEE-specific structures 3. The TEE then generates an **attestation report** — a structured message that includes: + - The recorded measurements - TEE metadata (such as the identity of the code, runtime version, and security configuration) - Optional application-specific data (e.g., a nonce or public key from the client) -4. This attestation report is sent to a trusted component inside the platform known as the **attestation signing agent** (e.g., a *quoting enclave*, *firmware-based attestation module*, or *secure co-processor*). +4. This attestation report is sent to a trusted component inside the platform known as the **attestation signing agent** (e.g., a _quoting enclave_, _firmware-based attestation module_, or _secure co-processor_). 5. The attestation signing agent signs the report using a **manufacturer-provisioned attestation key**. This key is + - Cryptographically tied to the device - Certified by the TEE vendor (e.g., Intel, AMD, ARM) - Stored and used in a protected environment inaccessible to untrusted software @@ -235,6 +249,7 @@ We start the whole process with remote attestation. In this step, the client ens 6. The resulting **attestation quote** is returned to the TEE and passed to the **client** (or relying party) that requested attestation. 7. The client forwards the quote to a **remote attestation service**, which: + - Verifies the signature on the quote using the manufacturer’s root certificate - Validates the integrity and freshness of the TEE’s measurements - Confirms that the platform is genuine, up-to-date, and securely configured @@ -252,7 +267,7 @@ Only once this trust is established does the client proceed to send sensitive da ### Runtime Attestation with Linux IMA and Keylime -While launch-time attestation provides assurance that a Trusted Execution Environment (TEE) **starts in a known-good state**, it does not cover what happens *after* boot. A malicious actor could, for example, replace a binary or tamper with configuration files post-launch without affecting the original attestation quote. +While launch-time attestation provides assurance that a Trusted Execution Environment (TEE) **starts in a known-good state**, it does not cover what happens _after_ boot. A malicious actor could, for example, replace a binary or tamper with configuration files post-launch without affecting the original attestation quote. To address this, we incorporate **runtime attestation** using the **[Linux Integrity Measurement Architecture (IMA)](https://www.redhat.com/en/blog/how-use-linux-kernels-integrity-measurement-architecture)** and the **[Keylime](https://keylime.dev/)** framework. @@ -260,9 +275,10 @@ To address this, we incorporate **runtime attestation** using the **[Linux Integ #### What Is Linux IMA? -**IMA** is a Linux kernel subsystem that measures files — such as executables, libraries, scripts, and configuration files — *at the time they are accessed*. It maintains a **measurement log**, which contains cryptographic hashes of all accessed files. These hashes are extended into a **Platform Configuration Register (PCR)** (typically **PCR10** in TPM-backed systems). +**IMA** is a Linux kernel subsystem that measures files — such as executables, libraries, scripts, and configuration files — _at the time they are accessed_. It maintains a **measurement log**, which contains cryptographic hashes of all accessed files. These hashes are extended into a **Platform Configuration Register (PCR)** (typically **PCR10** in TPM-backed systems). This allows the system to: + - Detect if any critical file has been changed or tampered with. - Compare runtime measurements against a reference "good" state. - Bind application behavior to expected code and configuration. @@ -274,6 +290,7 @@ This allows the system to: **Keylime** is an open-source remote attestation framework designed to work with IMA. It allows a **remote verifier** (e.g., a client) to continuously monitor the integrity of a **running system**, including a TEE-based confidential VM. Keylime components include: + - **Agent (inside the TEE guest)**: Reports IMA measurements and TPM quotes - **Verifier (outside the TEE)**: Validates measurements against a policy - **Registrar**: Manages key provisioning and trust setup @@ -282,17 +299,17 @@ Keylime components include: #### How Runtime Attestation Complements Launch-Time Attestation -| Launch-Time Attestation | Runtime Attestation (IMA + Keylime) | -|--------------------------------------------------|----------------------------------------------------| -| Validates integrity at the point of TD creation | Monitors integrity throughout execution | -| Covers bootloader, kernel, early OS state | Covers binaries, libraries, config files, scripts | -| Performed once at startup | Ongoing or on-demand validation | -| Bound to hardware measurement registers (e.g., RTMRs) | Bound to TPM PCRs (e.g., PCR10) | - +| Launch-Time Attestation | Runtime Attestation (IMA + Keylime) | +| ----------------------------------------------------- | ------------------------------------------------- | +| Validates integrity at the point of TD creation | Monitors integrity throughout execution | +| Covers bootloader, kernel, early OS state | Covers binaries, libraries, config files, scripts | +| Performed once at startup | Ongoing or on-demand validation | +| Bound to hardware measurement registers (e.g., RTMRs) | Bound to TPM PCRs (e.g., PCR10) | #### Benefits in a ZK Proving Context In delegated proving, runtime attestation can ensure that: + - The ZK prover binary running inside the TEE has not been modified or replaced. - The proving key and parameters are untampered. - The system hasn’t silently switched to an insecure configuration. @@ -320,10 +337,12 @@ This provides **stronger guarantees to the client** — not only is the environm ### Trust Model Enhancement By combining + - **Launch-time attestation** (via TEE quote + attestation service), and - **Runtime attestation** (via IMA + Keylime + TPM), We create a **two-layer trust model** where the client can verify: + 1. The TEE starts securely and is properly configured. 2. The integrity of the prover binary and environment is continuously enforced. @@ -354,15 +373,18 @@ Once attestation confirms that the TEE is in a trusted state, the client needs a 4. The proving process begins using the securely provisioned input. ## Proof generation and verification + Once all the data needed to compute the zk proof, the TD guest can now compute the proof. This part is pretty much the same as normal computation because we can run exactly the same binaries as in the normal server. When proof is computed, TD guest sends the proof back to the client or any third party who wants to verify the proof. # Benchmarking + We took benchmarks of the system architecture described in the previous section. The benchmark targets are **[semaphore](https://semaphore.pse.dev/)** and [proof-of-twitter](https://github.com/zkemail/proof-of-twitter/tree/main) from **[zkemail](https://prove.email/)**. Both are important client applications that utilize zk proof for privacy. The results help assess whether modern TEEs offer a viable foundation for private proof delegation in practice. The first thing we did was to take benchmarks of the semaphore circuit using [this repo](https://github.com/vplasencia/semaphore-benchmarks). For the semaphore we ran three benchmarking settings. + 1. Benchmark for proof generation inside TEE VM 2. Benchmark for proof generation inside normal VM 3. Benchmark for E2E TEE-based private proof delegation setting @@ -372,14 +394,15 @@ For 1 and 3, we use the Azure VM Standard_EC16eds_v5 series; for 2, we use the A For zkemail, we used proof-of-twitter circuit to measure the number. For this, we only took E2E benchmarks to see if the whole system can provide an acceptable number. ## Semaphore benchmarks -1. Benchmark for proof generation inside TEE VM -![Benchmark1](/articles/tee-based-ppd/benchmark1.png) -2. Proof generation inside normal VM -![Benchmark2](/articles/tee-based-ppd/benchmark2.png) +1. Benchmark for proof generation inside TEE VM + ![Benchmark1](/articles/tee-based-ppd/benchmark1.png) +2. Proof generation inside normal VM + ![Benchmark2](/articles/tee-based-ppd/benchmark2.png) E2E benchmarks In our scenario, we measure the E2E performance, including + - Keylime runtime attestation - TDX attestation - Proof generation @@ -393,6 +416,7 @@ In our scenario, we measure the E2E performance, including | Total | 3166ms | 2803ms | 2809ms | 2926ms | ## zk-email benchmarks + We use the proof-of-twitter circuit as our benchmark target. This demonstrates a real-world use case for TEE-based private proof delegation. The benchmark was taken for the E2E setting, as in the semaphore benchmark. | | 1 | 2 | 3 | Avg. | @@ -402,19 +426,20 @@ We use the proof-of-twitter circuit as our benchmark target. This demonstrates a | Proving | 87213ms | 57185ms | 56976ms | 67124ms | | Total | 89224ms | 59216ms | 59462ms | 69300ms | - ## Discussions -See Table 2—the ~67s proving time dominates E2E latency, so in this case, TEE overhead becomes <5 %. Our benchmarks show that TEE-based delegated proving is both **feasible and practically performant** for real-world zero-knowledge applications — with varying trade-offs depending on the circuit size and security assumptions. +See Table 2—the ~67s proving time dominates E2E latency, so in this case, TEE overhead becomes <5 %. Our benchmarks show that TEE-based delegated proving is both **feasible and practically performant** for real-world zero-knowledge applications — with varying trade-offs depending on the circuit size and security assumptions. ### Attestation Overhead Is Modest Both **Keylime runtime attestation** and **TDX launch attestation** contribute **1.74 s total (696 ms + 1 048 ms)** in both cases. In the Semaphore benchmark, their combined overhead accounts for less than 25% of the total latency. This indicates that + - **Launch-time and runtime attestation are fast enough** to be included in every proving session. - They can be embedded into interactive or on-demand proving scenarios without causing significant delay. However, it's important to note that our benchmarks used a **simple attestation policy** that only performs **signature verification** on the attestation quote. In a production setting, policies may include + - Validation of **RTMR (Runtime Measurement Register)** values - Checks for **specific file measurements** via IMA - Enforcement of secure configuration (e.g., Secure Boot, kernel version) @@ -424,10 +449,12 @@ Such policies would add additional verification steps, which could modestly incr ### Input Transfer Cost Not Accounted Our current benchmark **skips the actual transfer of secret input data** (e.g., witness values, proving keys if needed). In real deployments, this step involves + - Transmitting encrypted payloads over a secure channel (e.g., via mTLS) - Decrypting and loading the data inside the TEE The cost of this step depends on + - **Payload size** (some proving inputs may be tens or hundreds of megabytes) - **Network conditions**, including latency and bandwidth - **Disk I/O**, if data is staged or stored before proving @@ -439,6 +466,7 @@ While not captured here, this cost should be considered for systems with large o The **zkEmail circuit** (based on proof-of-Twitter) demonstrates a **much larger proving time** — averaging over 67 seconds — due to higher circuit complexity. In contrast, the **Semaphore proof** completes in just over 1.1 seconds on average. This reinforces a key insight: + - The performance bottleneck shifts from attestation to proving as circuit size grows. - TEE-induced overhead is amortized in large proofs, making the TEE setup cost relatively negligible in long-running sessions. @@ -450,6 +478,7 @@ One advantage of using a **VM-based TEE like Intel TDX** is the ability to **sca - This enables faster proof generation for large circuits without modifying the security model or proving logic. Furthermore, although we have not explored it in this benchmark, **[GPU acceleration is becoming increasingly feasible](https://developer.nvidia.com/blog/confidential-computing-on-h100-gpus-for-secure-and-trustworthy-ai/)** within TEE environments. Some confidential computing frameworks are beginning to support + - GPU passthrough into confidential VMs - Secure offloading of compute-intensive workloads (like FFTs, MSMs) into trusted GPU regions @@ -493,18 +522,15 @@ For context, the typical hardware specs used in these mobile benchmarks are These constraints illustrate the challenge of using mobile-native proving for larger circuits. - - --- ## Relative Comparison (based on our benchmarks) -| Approach | Semaphore Circuit | Notes | -| ---------------------- | ---------------------------- | ------------------------------------------- | +| Approach | Semaphore Circuit | Notes | +| ---------------------- | ----------------------------- | ------------------------------------------- | | TEE | ~210ms (proving), ~2.9s (E2E) | Fast, attested, scalable | -| Collaborative zkSNARKs | ~ 700ms (proving) | Needs coordination; performance varies | -| MoPro | 165 ~ 1267ms (proving) | Local execution; limited by mobile hardware | - +| Collaborative zkSNARKs | ~ 700ms (proving) | Needs coordination; performance varies | +| MoPro | 165 ~ 1267ms (proving) | Local execution; limited by mobile hardware | # Conclusion @@ -522,20 +548,20 @@ TEE-based proving is ready for real deployment — especially in cloud-based pri - Bind attestation results directly to ZK proof outputs. - Extend runtime integrity policies for broader trust coverage. - --- ## Appendix ## Our choice of TEE + Trusted Execution Environments (TEEs) come in multiple forms, distinguished primarily by the granularity of isolation they provide. The two most prominent architectures are process-based TEEs and VM-based TEEs. - ![Trust boundary image](/articles/tee-based-ppd/trust-boundary.png) -*Trust boundary of different types of TEEs* +_Trust boundary of different types of TEEs_ #### **Process-Based TEEs** + Examples: Intel SGX, ARM TrustZone Characteristics: @@ -558,6 +584,7 @@ Limitations: - Harder scalability: Managing large applications inside small enclaves can be extremely difficult. #### **VM-Based TEEs** + Examples: Intel TDX, AMD SEV-SNP Characteristics: @@ -579,6 +606,7 @@ Limitations: - Slightly higher performance overhead compared to native execution (due to memory encryption and virtualization). #### Why VM-Based TEE Is Better for Our Purpose + In our private proof delegation use case — where we generate zero-knowledge proofs inside the TEE — the requirements favor VM-based TEE designs for several reasons: **Large Memory Requirements**: @@ -597,4 +625,4 @@ Azure Confidential VMs (ECedsv5 series) allow seamless deployment, scaling, and VM-based TEEs like TDX provide attestation mechanisms that cover the entire VM, enabling strong guarantees about the full execution environment — not just a single process. ![Azure CVM](/articles/tee-based-ppd/cvm-availability.png) -*Confidential VM availability on Azure* +_Confidential VM availability on Azure_ diff --git a/articles/the-next-chapter-for-zkevm-community-edition.md b/content/articles/the-next-chapter-for-zkevm-community-edition.md similarity index 100% rename from articles/the-next-chapter-for-zkevm-community-edition.md rename to content/articles/the-next-chapter-for-zkevm-community-edition.md diff --git a/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions.md b/content/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions.md similarity index 100% rename from articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions.md rename to content/articles/the-power-of-crowdsourcing-smart-contract-security-for-l2-scaling-solutions.md diff --git a/articles/the-zk-ecdsa-landscape.md b/content/articles/the-zk-ecdsa-landscape.md similarity index 100% rename from articles/the-zk-ecdsa-landscape.md rename to content/articles/the-zk-ecdsa-landscape.md diff --git a/articles/tlsnotary-updates.md b/content/articles/tlsnotary-updates.md similarity index 100% rename from articles/tlsnotary-updates.md rename to content/articles/tlsnotary-updates.md diff --git a/articles/towards_a_quantum-safe_p2p_for_ethereum.md b/content/articles/towards_a_quantum-safe_p2p_for_ethereum.md similarity index 100% rename from articles/towards_a_quantum-safe_p2p_for_ethereum.md rename to content/articles/towards_a_quantum-safe_p2p_for_ethereum.md diff --git a/articles/unirep-a-private-and-non-repudiable-reputation-system.md b/content/articles/unirep-a-private-and-non-repudiable-reputation-system.md similarity index 99% rename from articles/unirep-a-private-and-non-repudiable-reputation-system.md rename to content/articles/unirep-a-private-and-non-repudiable-reputation-system.md index 7214e44..41bebc4 100644 --- a/articles/unirep-a-private-and-non-repudiable-reputation-system.md +++ b/content/articles/unirep-a-private-and-non-repudiable-reputation-system.md @@ -21,7 +21,7 @@ tags: projects: ["unirep", "semaphore"] --- -*Originally published on Aug 26, 2021* +_Originally published on Aug 26, 2021_ ![](https://miro.medium.com/max/1106/0*nr6Aia8myVXSIZ2R) diff --git a/articles/unirep-ceremony-an-invitation-to-the-celestial-call-and-unirep-v2.md b/content/articles/unirep-ceremony-an-invitation-to-the-celestial-call-and-unirep-v2.md similarity index 100% rename from articles/unirep-ceremony-an-invitation-to-the-celestial-call-and-unirep-v2.md rename to content/articles/unirep-ceremony-an-invitation-to-the-celestial-call-and-unirep-v2.md diff --git a/articles/unirep-protocol.md b/content/articles/unirep-protocol.md similarity index 100% rename from articles/unirep-protocol.md rename to content/articles/unirep-protocol.md diff --git a/articles/unleashing-potential-introducing-the-pse-core-program.md b/content/articles/unleashing-potential-introducing-the-pse-core-program.md similarity index 100% rename from articles/unleashing-potential-introducing-the-pse-core-program.md rename to content/articles/unleashing-potential-introducing-the-pse-core-program.md diff --git a/articles/web2-nullifiers-using-voprf.md b/content/articles/web2-nullifiers-using-voprf.md similarity index 100% rename from articles/web2-nullifiers-using-voprf.md rename to content/articles/web2-nullifiers-using-voprf.md diff --git a/articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet.md b/content/articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet.md similarity index 100% rename from articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet.md rename to content/articles/why-we-cant-build-perfectly-secure-multi-party-applications-yet.md diff --git a/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1.md b/content/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1.md similarity index 100% rename from articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1.md rename to content/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-1.md diff --git a/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2.md b/content/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2.md similarity index 100% rename from articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2.md rename to content/articles/zero-to-start-applied-fully-homomorphic-encryption-fhe-part-2.md diff --git a/articles/zkevm-community-edition-part-1-introduction.md b/content/articles/zkevm-community-edition-part-1-introduction.md similarity index 100% rename from articles/zkevm-community-edition-part-1-introduction.md rename to content/articles/zkevm-community-edition-part-1-introduction.md diff --git a/articles/zkevm-community-edition-part-2-components.md b/content/articles/zkevm-community-edition-part-2-components.md similarity index 100% rename from articles/zkevm-community-edition-part-2-components.md rename to content/articles/zkevm-community-edition-part-2-components.md diff --git a/articles/zkevm-community-edition-part-3-logic-and-structure.md b/content/articles/zkevm-community-edition-part-3-logic-and-structure.md similarity index 100% rename from articles/zkevm-community-edition-part-3-logic-and-structure.md rename to content/articles/zkevm-community-edition-part-3-logic-and-structure.md diff --git a/articles/zkitter-an-anon-friendly-social-network.md b/content/articles/zkitter-an-anon-friendly-social-network.md similarity index 100% rename from articles/zkitter-an-anon-friendly-social-network.md rename to content/articles/zkitter-an-anon-friendly-social-network.md diff --git a/articles/zkml-bridging-aiml-and-web3-with-zero-knowledge-proofs.md b/content/articles/zkml-bridging-aiml-and-web3-with-zero-knowledge-proofs.md similarity index 100% rename from articles/zkml-bridging-aiml-and-web3-with-zero-knowledge-proofs.md rename to content/articles/zkml-bridging-aiml-and-web3-with-zero-knowledge-proofs.md diff --git a/articles/zkopru-ceremony-final-call-and-failed-contributions.md b/content/articles/zkopru-ceremony-final-call-and-failed-contributions.md similarity index 100% rename from articles/zkopru-ceremony-final-call-and-failed-contributions.md rename to content/articles/zkopru-ceremony-final-call-and-failed-contributions.md diff --git a/articles/zkopru-on-testnet-privacy-scaling-explorations.md b/content/articles/zkopru-on-testnet-privacy-scaling-explorations.md similarity index 100% rename from articles/zkopru-on-testnet-privacy-scaling-explorations.md rename to content/articles/zkopru-on-testnet-privacy-scaling-explorations.md diff --git a/articles/zkopru-trusted-setup-ceremony.md b/content/articles/zkopru-trusted-setup-ceremony.md similarity index 100% rename from articles/zkopru-trusted-setup-ceremony.md rename to content/articles/zkopru-trusted-setup-ceremony.md diff --git a/articles/zkopru-trusted-setup-completed-privacy-scaling-explorations.md b/content/articles/zkopru-trusted-setup-completed-privacy-scaling-explorations.md similarity index 100% rename from articles/zkopru-trusted-setup-completed-privacy-scaling-explorations.md rename to content/articles/zkopru-trusted-setup-completed-privacy-scaling-explorations.md diff --git a/articles/zkopru-wat-y-wen-privacy-scaling-explorations.md b/content/articles/zkopru-wat-y-wen-privacy-scaling-explorations.md similarity index 100% rename from articles/zkopru-wat-y-wen-privacy-scaling-explorations.md rename to content/articles/zkopru-wat-y-wen-privacy-scaling-explorations.md diff --git a/articles/zkpdf-unlocking-verifiable-data.md b/content/articles/zkpdf-unlocking-verifiable-data.md similarity index 100% rename from articles/zkpdf-unlocking-verifiable-data.md rename to content/articles/zkpdf-unlocking-verifiable-data.md diff --git a/data/events/devcon-7.ts b/content/events/devcon-7.ts similarity index 100% rename from data/events/devcon-7.ts rename to content/events/devcon-7.ts diff --git a/content/projects/README.md b/content/projects/README.md new file mode 100644 index 0000000..c1a2a4b --- /dev/null +++ b/content/projects/README.md @@ -0,0 +1,210 @@ +# How to Add a New Project to the Projects List + +## 1. Create a New Project Markdown File: + +- Go to the `/content/projects` folder in your project. +- Create a new file named `[project-name].md` +- Use the `_project-template.md` file as your starting point + +## 2. Add Project Frontmatter: + +- Open the newly created `[project-name].md` file. +- Copy the frontmatter from `_project-template.md` and customize it with your project details: + +```markdown +--- +# ======================================== +# REQUIRED PROPERTIES +# ======================================== +id: "your-project-id" # Unique project identifier (string) +name: "Your Project Name" # Project display name (string) +image: "/projects/your-project/cover.webp" # Project cover image path (string) +section: "pse" # Project section: "pse" | "grant" | "collaboration" | "archived" +projectStatus: "active" # Project status: "active" | "inactive" | "maintained" +tldr: "Brief project summary" # Short description of the project + +# ======================================== +# OPTIONAL PROPERTIES - Remove if not needed +# ======================================== +category: "research" # Project category: "research" | "devtools" | "application" +license: "MIT" # Project license +tags: # Project tags + keywords: ["tag1", "tag2", "tag3"] # Relevant keywords + themes: ["privacy", "scalability"] # Project themes + types: ["research", "development"] # Project types + builtWith: ["typescript", "react"] # Technologies used +links: # Project links + github: "https://github.com/org/repo" + website: "https://project-website.com" + discord: "https://discord.gg/invite" +team: # Project team members + - name: "Team Member Name" + role: "Developer" # (Optional) + email: "member@example.com" # (Optional) + image: "/team/member.webp" # (Optional) + links: # Team member links + github: "https://github.com/member" + twitter: "https://twitter.com/member" +--- + +# Your Project Title + +Your project content goes here using **Markdown** formatting. +``` + +**Note**: All properties in the frontmatter use YAML syntax. Remove any optional properties you don't need. The content below the frontmatter uses standard Markdown formatting. + +#### 3. Project Sections and Properties: + +**Required Properties:** + +- `id`: Unique project identifier (kebab-case) +- `name`: Display name of the project +- `image`: Path to project cover image +- `section`: Project category ("pse", "grant", "collaboration", "archived") +- `projectStatus`: Current status ("active", "inactive", "maintained") +- `tldr`: Brief one-line description + +**Optional Properties:** + +- `category`: Project type ("research", "devtools", "application") +- `license`: Project license (e.g., "MIT", "Apache-2.0") +- `hasWiki`: Boolean for wiki page template +- `youtubeLinks`: Array of YouTube video URLs +- `tags`: Object with keywords, themes, types, builtWith, fundingSource arrays +- `links`: Object with social/project links (github, website, discord, etc.) +- `extraLinks`: Categorized action links (buildWith, play, research, learn) +- `team`: Array of team member objects with name, role, email, image, links + +That's it! Your new project will now be visible in the projects list. + +## Project Status Values + +- `active`: Currently being developed +- `inactive`: Not actively maintained +- `maintained`: Stable, receiving updates as needed + +## Project Categories + +- `research`: Research-focused projects +- `devtools`: Developer tools and utilities +- `application`: Application projects + +## Project Sections + +- `pse`: Privacy & Scaling Explorations projects +- `grant`: Grant-funded projects +- `collaboration`: Collaborative projects +- `archived`: Archived/historical projects + +## Adding Extra Links to Project Pages + +To add action links to your project page, use the `extraLinks` property in your frontmatter: + +```yaml +extraLinks: + buildWith: + - label: "Get Started Building" + url: "https://github.com/org/repo#quick-start" + - label: "API Documentation" + url: "https://docs.example.com" + play: + - label: "Try the Demo" + url: "https://demo.example.com" + - label: "Interactive Tutorial" + url: "https://tutorial.example.com" + research: + - label: "Read the Paper" + url: "https://papers.example.com" + - label: "Technical Specifications" + url: "https://specs.example.com" + learn: + - label: "Documentation" + url: "https://docs.example.com" + - label: "Video Tutorials" + url: "https://youtube.com/playlist" +``` + +This creates themed link sections on your project detail page: + +![Project links](/public/project/example-project-detail.jpg) + +## Adding YouTube Videos to a Project + +Add YouTube videos to your project by including a `youtubeLinks` array in the frontmatter: + +```yaml +youtubeLinks: + - "https://www.youtube.com/watch?v=XXXXXXXXXXX" + - "https://youtu.be/XXXXXXXXXXX" + - "XXXXXXXXXXX" # Just the YouTube video ID +``` + +The videos will appear as clickable thumbnails with titles on the project page: + +![YouTube Videos](/public/project/example-project-video.png) + +## Adding Team Members to a Project + +Add team members to your project using the `team` array in the frontmatter: + +```yaml +team: + - name: "John Doe" + role: "Lead Developer" # Optional + image: "/team/john-doe.jpg" # Optional + email: "john.doe@example.com" # Optional + links: # Optional + github: "https://github.com/johndoe" + twitter: "https://twitter.com/johndoe" + website: "https://johndoe.dev" + discord: "johndoe#1234" +``` + +Supported link types: `github`, `website`, `discord`, `twitter`, `youtube`, `telegram` + +![Project Team Members](/public/project/example-project-team.png) + +## Tags and Themes + +The `tags` object supports several categories: + +- `keywords`: Technical keywords and concepts +- `themes`: High-level project themes (privacy, scalability, etc.) +- `types`: Project types (research, application, protocol, etc.) +- `builtWith`: Technologies and tools used +- `fundingSource`: Funding sources (pse, grants, etc.) + +```yaml +tags: + keywords: ["MPC", "TypeScript", "privacy", "Garbled Circuits"] + themes: ["privacy", "buildWith", "play", "research"] + types: ["protocol", "toolkit"] + builtWith: ["TypeScript", "Node.js", "React"] + fundingSource: ["pse"] +``` + +## Content Formatting + +The content below the frontmatter supports full **Markdown** formatting including: + +- Headers (`#`, `##`, `###`) +- **Bold** and _italic_ text +- [Links](https://example.com) +- Lists (bulleted and numbered) +- Code blocks with syntax highlighting +- Tables +- Images + +### Project Detail Page Features + +Your markdown project file now supports: + +- Rich markdown content formatting +- Embedded YouTube videos +- Team member profiles with social links +- Categorized action links +- Responsive image handling +- SEO-optimized metadata + +**Note**: Keywords and themes are curated by the communications & design team. If you wish to add new ones, please create a PR for review. diff --git a/content/projects/_project-template.md b/content/projects/_project-template.md new file mode 100644 index 0000000..1fb884a --- /dev/null +++ b/content/projects/_project-template.md @@ -0,0 +1,89 @@ +--- +# ======================================== +# REQUIRED PROPERTIES +# ======================================== +id: "project-id" # Unique project identifier (string) +name: "Project Name" # Project display name (string) +image: "/projects/project-folder/cover.webp" # Project cover image path (string) +section: "pse" # Project section: "pse" | "grant" | "collaboration" | "archived" +projectStatus: "active" # Project status: "active" | "inactive" | "maintained" +tldr: "Brief project summary" # Short description of the project + +# ======================================== +# OPTIONAL PROPERTIES - Remove if not needed +# ======================================== +imageAlt: "Alt text for the image" # Alt text for the image +previousBrandImage: "/projects/project-folder/old-cover.webp" # Previous brand image +category: "research" # Project category: "research" | "applications" | "devtools" +license: "MIT" # Project license +hasWiki: false # Whether project has wiki page template +youtubeLinks: # Array of YouTube links + - "https://www.youtube.com/watch?v=example" +tags: # Project tags + keywords: ["tag1", "tag2", "tag3"] # Relevant keywords + themes: ["privacy", "scalability"] # Project themes + types: ["research", "development"] # Project types + builtWith: ["typescript", "react"] # Technologies used + fundingSource: ["pse", "grants"] # Funding sources +links: # Project links + github: "https://github.com/org/repo" + website: "https://project-website.com" + discord: "https://discord.gg/invite" + twitter: "https://twitter.com/project" + youtube: "https://youtube.com/@project" + telegram: "https://t.me/project" +extraLinks: # Extra action links + buildWith: + - label: "Build with this" + url: "https://example.com/build" + play: + - label: "Try it out" + url: "https://example.com/demo" + research: + - label: "Read the paper" + url: "https://example.com/paper" + learn: + - label: "Learn more" + url: "https://example.com/docs" +cardTags: # Tags displayed on project cards + primary: "Primary Tag" + secondary: "Secondary Tag" +team: # Project team members + - name: "Team Member Name" + role: "Developer" # (Optional) + email: "member@example.com" # (Optional) + image: "/team/member.webp" # (Optional) + links: # Team member links + github: "https://github.com/member" + twitter: "https://twitter.com/member" +--- + +# Project Title + +## Overview + +Brief overview of what the project does and why it matters. + +## Key Features + +- Feature 1 +- Feature 2 +- Feature 3 + +## Technical Details + +Detailed technical information about the project implementation. + +## Getting Started + +Instructions on how to use or contribute to the project. + +## Resources + +- [Documentation](https://example.com/docs) +- [GitHub Repository](https://github.com/org/repo) +- [Research Paper](https://example.com/paper) + +## Contact + +For questions or contributions, reach out to the team members listed above. diff --git a/data/projects/anon-aadhaar.ts b/content/projects/anon-aadhaar.md similarity index 57% rename from data/projects/anon-aadhaar.ts rename to content/projects/anon-aadhaar.md index b22975a..fceca7b 100644 --- a/data/projects/anon-aadhaar.ts +++ b/content/projects/anon-aadhaar.md @@ -1,14 +1,28 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "anon-aadhaar" +name: "Anon Aadhaar" +image: "anon-aadhaar.svg" +section: "pse" +projectStatus: "active" +category: "application" +tldr: "Tools for building build privacy-preserving applications using government ID cards, specifically Aadhaar cards in India." +license: "MIT" +tags: + keywords: ["Anonymity/privacy", "Social", "Identity", "Voting/governance"] + themes: ["build", "play"] + types: ["Legos/dev tools", "Lego sets/toolkits", "Proof of concept"] + builtWith: ["circom", "rsa", "TypeScript", "Solidity"] +links: + website: "https://anon-aadhaar.pse.dev/" + github: "https://github.com/privacy-scaling-explorations/anon-aadhaar" + telegram: "https://t.me/anon_aadhaar" + twitter: "https://twitter.com/AnonAadhaar" +extraLinks: + play: + - label: "Try it out: On-Chain Voting App" + url: "https://boilerplate.anon-aadhaar.pse.dev/" +--- -const content: ProjectContent = { - en: { - tldr: "Tools for building build privacy-preserving applications using government ID cards, specifically Aadhaar cards in India.", - description: ` ### Overview Anon Aadhaar is a project that allows Aadhaar ID holders to prove their Indian residency, optionally revealing some aspects of their identity while hiding the others. The project provides ZK Circuits, SDK for Javascript and Solidity, a demo application, and integrates with the PCD framework for a better developer experience. @@ -17,55 +31,25 @@ Anon Aadhaar is a project that allows Aadhaar ID holders to prove their Indian r Anon Aadhaar is a zero knowledge protocol that let Aadhaar owners prove their identity in a privacy preserving way. Key features include: -- **Selective Disclosure**: If your app request to reveal one of the field from the identity the circuit will reveal it in its output. There only four fields that could be revealed (Age > 18, Gender, State, Pincode). Note that by default the Prover will reveal nothing from the ID. + +- **Selective Disclosure**: If your app request to reveal one of the field from the identity the circuit will reveal it in its output. There only four fields that could be revealed (Age > 18, Gender, State, Pincode). Note that by default the Prover will reveal nothing from the ID. - **Nullifier**: Nullifier is a unique identifiers derived from data fields, used to prevent double-spending or duplicate proofs without revealing the actual data. - **Timestamp**: The timestamp of the signature associated with the data is converted into a UNIX UTC format, enabling Timebased One Time Password verification at the verifier level. The protocol is served through an SDK containing: + - TypeScript Library: [@anon-aadhaar/core](https://www.npmjs.com/package/@anon-aadhaar/core) - Solidity Library: [@anon-aadhaar/contracts](https://www.npmjs.com/package/@anon-aadhaar/contracts) - React Library: [@anon-aadhaar/react](https://www.npmjs.com/package/@anon-aadhaar/react) You can play with our **mobile prover**, which offer a faster proving time: + - [Anon Aadhaar React Native](https://github.com/anon-aadhaar/anon-aadhaar-react-native) We developed a prover for [Digilocker](https://www.digilocker.gov.in/), that let you generate ZKPs from official documents stored in the Digolocker App, enabling use cases with proof of degrees, UPI, driver license and more. ### Applications: + - Quick Setup - [Website](https://anon-aadhaar-quick-setup.vercel.app/) | [GitHub](https://github.com/anon-aadhaar/quick-setup) - Boilerplate On-Chain Voting App - [Website](https://boilerplate.anon-aadhaar.pse.dev/) | [GitHub](https://github.com/anon-aadhaar/boilerplate) - Anon Digilocker - [Website](https://anon-digilocker.vercel.app/) | [GitHub](https://github.com/anon-aadhaar/anon-digilocker) -`, - }, -} - -export const anonAadhaar: ProjectInterface = { - id: "anon-aadhaar", - category: ProjectCategory.APPLICATION, - section: "pse", - content, - projectStatus: ProjectStatus.ACTIVE, - image: "anon-aadhaar.svg", - license: "MIT", - name: "Anon Aadhaar", - links: { - website: "https://anon-aadhaar.pse.dev/", - github: "https://github.com/privacy-scaling-explorations/anon-aadhaar", - telegram: "https://t.me/anon_aadhaar", - twitter: "https://twitter.com/AnonAadhaar", - }, - tags: { - keywords: ["Anonymity/privacy", "Social", "Identity", "Voting/governance"], - themes: ["build", "play"], - types: ["Legos/dev tools", "Lego sets/toolkits", "Proof of concept"], - builtWith: ["circom", "rsa", "TypeScript", "Solidity"], - }, - extraLinks: { - play: [ - { - label: "Try it out: On-Chain Voting App", - url: "https://boilerplate.anon-aadhaar.pse.dev/", - }, - ], - }, -} diff --git a/content/projects/anon-klub.md b/content/projects/anon-klub.md new file mode 100644 index 0000000..57c32dd --- /dev/null +++ b/content/projects/anon-klub.md @@ -0,0 +1,30 @@ +--- +id: "anon-klub" +name: "AnonKlub" +image: "anonklub.svg" +section: "archived" +projectStatus: "inactive" +category: "application" +tldr: "A mechanism for anonymous proof of Ethereum address ownership." +tags: + keywords: + [ + "Transaction privacy", + "Anonymity/privacy", + "Social", + "Identity", + "Voting/governance", + ] + themes: ["build", "play"] + types: ["Infrastructure/protocol", "Prototype", "Proof of concept"] + builtWith: ["circom", "snarkjs", "halo2"] +links: + github: "https://github.com/anonklub" + website: "https://anonklub.github.io" +extraLinks: + learn: + - label: "Sunsetting Blog Post: Reflections on Our Journey in Privacy-Preserving Solutions" + url: "https://mirror.xyz/privacy-scaling-explorations.eth/7VTKFVR4PM75WtNnBzuQSBZW-UYoJOsnzBBQmB9MWbY" +--- + +AnonKlub is a tool designed for Ethereum developers that allows for anonymous proof of Ethereum address ownership. It doesn't directly address the public observability of Ethereum transactions but provides a workaround for privacy. Users can prepare a list of Ethereum addresses, sign a message from an address they own, and use that signature to generate a zero-knowledge proof. This proof enables users to perform actions anonymously that would typically require ownership of an address from the initial list. Use cases include anonymous NFT minting and Discord verification for DAOs without disclosing the public address. diff --git a/data/projects/bandada.ts b/content/projects/bandada.md similarity index 62% rename from data/projects/bandada.ts rename to content/projects/bandada.md index 5e75fc0..b52cdfa 100644 --- a/data/projects/bandada.ts +++ b/content/projects/bandada.md @@ -1,14 +1,63 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "bandada" +name: "Bandada" +image: "bandada.webp" +section: "pse" +projectStatus: "maintained" +category: "application" +tldr: "An open-source tool for managing privacy-preserving groups of anonymous individuals." +tags: + keywords: + [ + "Anonymity/privacy", + "Social", + "Identity", + "Transaction privacy", + "Voting/governance", + "Reputation", + "Education", + "Scaling", + "Key management", + ] + types: + [ + "Legos/dev tools", + "Lego sets/toolkits", + "Prototype", + "Proof of concept", + "Infrastructure/protocol", + "Plugin", + "Application", + ] + builtWith: ["semaphore", "zk-kit"] + themes: ["build", "play"] +links: + github: "https://github.com/bandada-infra/bandada" + website: "https://bandada.pse.dev" + twitter: "https://twitter.com/BandadaDevs" +extraLinks: + buildWith: + - label: "Bandada API" + url: "https://api.bandada.pse.dev/" + - label: "Bandada API SDK" + url: "https://github.com/bandada-infra/bandada/tree/main/libs/api-sdk" + - label: "Bandada Boilerplate" + url: "https://github.com/bandada-infra/boilerplate" + play: + - label: "Bandada Dashboard" + url: "https://app.bandada.pse.dev/" + - label: "Bandada Boilerplate Live App" + url: "https://demo.bandada.pse.dev/" + learn: + - label: "Bandada Website" + url: "https://bandada.pse.dev/" + - label: "Bandada Documentation" + url: "https://docs.bandada.pse.dev/" + - label: "Bandada Board" + url: "https://github.com/orgs/bandada-infra/projects/1" +--- -const content: ProjectContent = { - en: { - tldr: "An open-source tool for managing privacy-preserving groups of anonymous individuals.", - description: `### Overview +### Overview [Bandada](https://bandada.pse.dev/) is a project designed to simplify the management of privacy-preserving groups. It is aimed at developers who want to build privacy-based applications and integrate anonymity sets, as well as non-developers working in DAOs, governments, international institutions, non-profit organizations, and associations that want to create and manage anonymous groups. @@ -26,7 +75,7 @@ Bandada offers a plug-and-play infrastructure, reducing the time and complexity ### Background -In Spanish, "Bandada" means "flock" or "group” of birds or animals moving together in a coordinated manner. Groups are an important concept when we speak about privacy and zero-knowledge technologies, they can be thought of as anonymity sets. Credentials are a way to establish necessary trust between a set of participants while letting users keep control over how their identities are stored and used. +In Spanish, "Bandada" means "flock" or "group" of birds or animals moving together in a coordinated manner. Groups are an important concept when we speak about privacy and zero-knowledge technologies, they can be thought of as anonymity sets. Credentials are a way to establish necessary trust between a set of participants while letting users keep control over how their identities are stored and used. Bandada allows you to create groups and establish trust within the participants by ensuring that everyone who joins the group must meet the credential requirements. @@ -44,7 +93,7 @@ Bandada also provides a preset of credential validators that can be extended wit - Group with members who have contributed to a specific GitHub repository. -- “Whitelist” a group of GitHub devs who have contributed to top DAOs' repositories. +- "Whitelist" a group of GitHub devs who have contributed to top DAOs' repositories. - Group of people with more than X followers on Twitter. @@ -57,86 +106,3 @@ Bandada also provides a preset of credential validators that can be extended wit - Groups of wallets holding a specific NFT. - Token-gated access to content. - -`, - }, -} - -export const bandada: ProjectInterface = { - id: "bandada", - category: ProjectCategory.APPLICATION, - section: "pse", - content, - projectStatus: ProjectStatus.MAINTAINED, - image: "bandada.webp", - name: "Bandada", - links: { - github: "https://github.com/bandada-infra/bandada", - website: "https://bandada.pse.dev", - twitter: "https://twitter.com/BandadaDevs", - }, - tags: { - keywords: [ - "Anonymity/privacy", - "Social", - "Identity", - "Transaction privacy", - "Voting/governance", - "Reputation", - "Education", - "Scaling", - "Key management", - ], - types: [ - "Legos/dev tools", - "Lego sets/toolkits", - "Prototype", - "Proof of concept", - "Infrastructure/protocol", - "Plugin", - "Application", - ], - builtWith: ["semaphore", "zk-kit"], - themes: ["build", "play"], - }, - extraLinks: { - buildWith: [ - { - label: "Bandada API", - url: "https://api.bandada.pse.dev/", - }, - { - label: "Bandada API SDK", - url: "https://github.com/bandada-infra/bandada/tree/main/libs/api-sdk", - }, - { - label: "Bandada Boilerplate", - url: "https://github.com/bandada-infra/boilerplate", - }, - ], - play: [ - { - label: "Bandada Dashboard", - url: "https://app.bandada.pse.dev/", - }, - { - label: "Bandada Boilerplate Live App", - url: "https://demo.bandada.pse.dev/", - }, - ], - learn: [ - { - label: "Bandada Website", - url: "https://bandada.pse.dev/", - }, - { - label: "Bandada Documentation", - url: "https://docs.bandada.pse.dev/", - }, - { - label: "Bandada Board", - url: "https://github.com/orgs/bandada-infra/projects/1", - }, - ], - }, -} diff --git a/content/projects/channel-4.md b/content/projects/channel-4.md new file mode 100644 index 0000000..91ce848 --- /dev/null +++ b/content/projects/channel-4.md @@ -0,0 +1,20 @@ +--- +id: "channel-4" +name: "Channel 4" +image: "channel4.svg" +section: "archived" +projectStatus: "inactive" +category: "application" +tldr: "Content discovery through community contributions, using state channels to reward users for popular posts." +tags: + keywords: ["Scaling"] + themes: ["play"] + types: ["Application"] + builtWith: ["state channel", "smart contract"] +links: + github: "https://github.com/State-Channel-4" + website: "https://channel4.wtf/" + discord: "https://discord.gg/76UrYgVyEx" +--- + +Channel 4 is a community-driven platform where users can submit and discover content. It uses state channels to incentivize user engagement. When a user likes the content you've submitted, a state channel closes and rewards are dropped into their wallet. This approach combines entertainment with the power of state channels, enabling community members to earn while they engage. diff --git a/content/projects/chiquito.md b/content/projects/chiquito.md new file mode 100644 index 0000000..f752020 --- /dev/null +++ b/content/projects/chiquito.md @@ -0,0 +1,27 @@ +--- +id: "chiquito" +name: "chiquito" +image: "" +section: "pse" +projectStatus: "inactive" +category: "devtools" +tldr: "A modern ZKP language and compiler for plonkish and AIR arithmetizations" +tags: + themes: ["build"] + types: + [ + "Legos/dev tools", + "Lego sets/toolkits", + "Proof of concept", + "language", + "dsl", + ] + keywords: ["DSL", "language", "rust", "python", "halo2"] + builtWith: ["halo2", "rust"] +links: + github: "https://github.com/privacy-scaling-explorations/chiquito" + website: "https://docs.pecadorplonkish.xyz/" + twitter: "" +--- + +Chiquito is a high-level structured language for implementing zero knowledge proof circuits, currently being implemented in the DSL Working Group of PSE. It is a state machine zk-language that provides better syntax and abstraction. It can automatically compiler arbitrary boolean expressions for state machine transitions. It can optimise the resulting arithmetization. Chiquito has a Halo2 backend, which is a low level zkDSL that writes circuits using the PLONKish arithmetization and is working on supporting additional backends. Chiquito circuits can be written using both Python and Rust. diff --git a/data/projects/circom-mpc.ts b/content/projects/circom-mpc.md similarity index 58% rename from data/projects/circom-mpc.ts rename to content/projects/circom-mpc.md index 02552eb..580a1a3 100644 --- a/data/projects/circom-mpc.ts +++ b/content/projects/circom-mpc.md @@ -1,46 +1,32 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "circom-mpc" +name: "Circom-MPC" +image: "" +section: "pse" +projectStatus: "inactive" +category: "research" +tldr: "PSE Research project that enables the use of the Circom language to develop MPC applications." +tags: + keywords: ["mpc", "circom", "mp-spdz"] + themes: ["research"] +links: + github: "https://github.com/namnc/circom-2-arithc" +--- -const content: ProjectContent = { - en: { - tldr: "PSE Research project that enables the use of the Circom language to develop MPC applications.", - description: `Circom-MPC is a set of projects designed to compile and run arithmetic and boolean MPC circuits written in Circom. +Circom-MPC is a set of projects designed to compile and run arithmetic and boolean MPC circuits written in Circom. In this project, we envisioned MPC as a broader paradigm, where MPC serves as an umbrella for generic techniques such as Zero-Knowledge Proof, Garbled Circuit, Secret-Sharing, or Fully Homomorphic Encryption. Throughout this research the team produced some valuable resources and insights, including: + - Implementation of [circom-2-arithc](https://github.com/namnc/circom-2-arithc), a fork of the Circom compiler that targets arithmetic circuits, which can be fed into any MPC backend -- Example integration of circom-2-arithc with the popular Secret-Sharing based backend MP-SPDZ in [circom-MP-SPDZ](https://github.com/namnc/circom-mp-spdz). -- Proof of concept application using [MPC-ML](https://hackmd.io/YsWhryEtQ0WwKyerSL8oCw#Circomlib-ML-Patches-and-Benchmarks) with [keras-2-circom-MP-SPDZ](https://github.com/namnc/circom-mp-spdz/blob/main/ML-TESTS.md) which extends keras-2-circom-ZK to [keras-2-circom-MPC](https://github.com/namnc/keras2circom). +- Example integration of circom-2-arithc with the popular Secret-Sharing based backend MP-SPDZ in [circom-MP-SPDZ](https://github.com/namnc/circom-mp-spdz). +- Proof of concept application using [MPC-ML](https://hackmd.io/YsWhryEtQ0WwKyerSL8oCw#Circomlib-ML-Patches-and-Benchmarks) with [keras-2-circom-MP-SPDZ](https://github.com/namnc/circom-mp-spdz/blob/main/ML-TESTS.md) which extends keras-2-circom-ZK to [keras-2-circom-MPC](https://github.com/namnc/keras2circom). - [Modular Layer benchmarks](https://github.com/namnc/circom-mp-spdz/blob/main/BENCHMARK.md) for the keras model. -We decided to sunset the project for a few reasons: -- The overwhelming amount of effort to fully implement it. +We decided to sunset the project for a few reasons: + +- The overwhelming amount of effort to fully implement it. - The low current traction of users (could be due to Circom). Hence an [MPC-Framework](https://pse.dev/en/projects/mpc-framework) variant may be of more public interest. -- The existence of competitors such as [Sharemind MPC into Carbyne Stack](https://cyber.ee/uploads/Sharemind_MPC_CS_integration_a01ca476a7.pdf). +- The existence of competitors such as [Sharemind MPC into Carbyne Stack](https://cyber.ee/uploads/Sharemind_MPC_CS_integration_a01ca476a7.pdf). Therefore, we will leave it as a paradigm, and hope that any interested party will pick it up and continue its development. - `, - }, -} - -export const circomMpc: ProjectInterface = { - id: "circom-mpc", - category: ProjectCategory.RESEARCH, - projectStatus: ProjectStatus.INACTIVE, - section: "pse", - content, - image: "", - imageAlt: "Circom-MPC", - name: "Circom-MPC", - links: { - github: "https://github.com/namnc/circom-2-arithc", - }, - tags: { - keywords: ["mpc", "circom", "mp-spdz"], - themes: ["research"], - }, -} diff --git a/content/projects/client-side-proving.md b/content/projects/client-side-proving.md new file mode 100644 index 0000000..e457d0c --- /dev/null +++ b/content/projects/client-side-proving.md @@ -0,0 +1,70 @@ +--- +id: "client-side-proving" +name: "Client-Side Proving" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "Developing efficient zero-knowledge proving systems for mobile devices, enabling private digital ID and secure communication with minimal resources." +license: "MIT" +tags: + keywords: ["Zero Knowledge", "Mobile", "Privacy", "Digital Identity"] + themes: ["build", "research"] + types: ["Legos/dev tools", "Benchmarking", "Proof systems"] +team: + - name: "Alex Kuzmin" + email: "alex.kuzmin@pse.dev" + - name: "Guorong Du" + email: "dgr009@pse.dev" +--- + +### Project Overview + +The Client-Side Proving project aims to develop practical and efficient zero-knowledge (ZK) proving systems tailored specifically for mobile devices. By exploring various proving systems - including Binius, Spartan, Plonky2, Scribe, and WHIR - we provide benchmarks, insights, and optimized implementations that enable performant client-side applications. + +### Objective + +Our primary objective is to identify and optimize ZK proof systems that require minimal resources, have no trusted setup, and maintain post-quantum security. These efforts are particularly focused on supporting applications in digital identity, secure communications, and privacy-preserving credential management. + +### Project Status + +- **Stage:** MVP Development +- **Status:** Active +- **Team Lead:** Alex Kuzmin +- **Team Members:** Guorong Du + +### Technical Approach + +The project rigorously benchmarks mobile-friendly ZK proving systems based on critical criteria including computational complexity, RAM efficiency and proof size. Key innovations and strategies include: + +- **Benchmarking Binius, Spartan, Plonky2, and Scribe** for mobile usability. +- **Optimizing RAM usage** through streaming techniques. +- **Evaluation and integration of lookups** to enhance proving efficiency in computationally intensive ZK circuits. + +### Milestones + +- **April 2025:** Established baseline benchmarks for common mobile hardware. +- **May 2025 (planned):** Comprehensive benchmarking results published for selected ZK proving systems. +- **June 2025 (planned):** Optimization of Spartan using WHIR PCS and/or Scribe's read-write streaming techniques. +- **Q3 2025 (planned):** Collaboration with an Identity initiative, integrating optimized proving systems. + +### Applications + +Client-Side Proving enables numerous privacy-focused mobile applications, including: + +- Mobile Digital ID wallets ensuring user privacy. +- Anonymous online communication and collaboration tools. + +### How to get in touch + +- Join the [PSE Discord](https://discord.com/invite/sF5CT5rzrR) +- Reach out via email Alex: alex.kuzmin@pse.dev or Guorong Du: dgr009@pse.dev + +### Publications + +- [Benchmarks for Digital ID Wallet](https://hackmd.io/@clientsideproving/S1wiUc0n1e) +- [Mobile Hardware Survey](https://hackmd.io/@clientsideproving/ByqafXAv1e) +- [Plonky2 Sha256 Benchmarks](https://hackmd.io/@clientsideproving/B1xLCuJL5yg) +- [Proof Systems Survey](https://hackmd.io/@clientsideproving/HyKBkz7jye) + +Benchmark findings and technical write-ups will be released regularly, highlighting the project's research outcomes and performance evaluations. diff --git a/content/projects/coco.md b/content/projects/coco.md new file mode 100644 index 0000000..c8e22a3 --- /dev/null +++ b/content/projects/coco.md @@ -0,0 +1,24 @@ +--- +id: "coco" +name: "COCO" +image: "coco.svg" +section: "archived" +projectStatus: "inactive" +category: "application" +tldr: "Integrating Nova into the EVM involves wrapping Liam Eagen's theoretical ECIP argument in Halo 2" +tags: + keywords: ["prediction market", "scaling"] +extraLinks: + learn: + - label: "Meet COCO!" + url: "https://mirror.xyz/privacy-scaling-explorations.eth/tEf7iYa8l7ECZwN2T57yyiws7h9Uchip30CQvx-JBBQ" + buildWith: + - label: "Smart contracts" + url: "https://github.com/Janmajayamall/coco-contracts" + - label: "Frontend" + url: "https://github.com/Janmajayamall/coco-frontend" + - label: "Frontend (General)" + url: "https://github.com/Janmajayamall/coco-frontend-general" +--- + +With Coco, groups can collaborate to curate feeds of any topic they're interested in. As you scroll through your Coco feed, rather than upvoting or downvoting posts, you'll spend WETH to predict what other group members and the group's moderators will want to see. When you're right, you'll get back your original WETH and more — but if you're wrong, you'll lose what you put in. Through this process, you help Coco filter value from noise to make sure group feeds only consist of posts that the group cares about.With Coco, groups can collaborate to curate feeds of any topic they're interested in. As you scroll through your Coco feed, rather than upvoting or downvoting posts, you'll spend WETH to predict what other group members and the group's moderators will want to see. When you're right, you'll get back your original WETH and more — but if you're wrong, you'll lose what you put in. Through this process, you help Coco filter value from noise to make sure group feeds only consist of posts that the group cares about. diff --git a/content/projects/cryptkeeper.md b/content/projects/cryptkeeper.md new file mode 100644 index 0000000..f853f30 --- /dev/null +++ b/content/projects/cryptkeeper.md @@ -0,0 +1,18 @@ +--- +id: "cryptkeeper" +name: "CryptKeeper" +image: "cryptkeeper.webp" +section: "archived" +projectStatus: "inactive" +category: "application" +tldr: "A browser extension for secure, portable anonymous identity management across applications." +tags: + keywords: ["Anonymity/privacy", "Social", "Identity"] + themes: ["build"] + types: ["Application", "Infrastructure/protocol", "Lego sets/toolkits"] + builtWith: ["semaphore", "rln"] +links: + github: "https://github.com/CryptKeeperZK" +--- + +CryptKeeper is a browser extension that generates Semaphore and RLN proofs for websites, providing a secure and portable solution for managing anonymous identity secrets across different applications. It simplifies the integration of zero-knowledge (ZK) identities and proofs into applications, allowing developers to focus on building the front-end and logic of their applications. By handling complex aspects of cryptography, circuits, caching, and storage, CryptKeeper enables users to interact with decentralized applications (dapps) without revealing their private identity secrets. It is aimed at building secure community standards for the growing ZK ecosystem. diff --git a/data/projects/cursive.ts b/content/projects/cursive.md similarity index 67% rename from data/projects/cursive.ts rename to content/projects/cursive.md index 17612a3..68080ad 100644 --- a/data/projects/cursive.ts +++ b/content/projects/cursive.md @@ -1,43 +1,14 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A research lab & design studio exploring how cryptography like MPC and ZK can be used to discover and deepen human connection.", - description: ` -What began as an experimental initiative to transform PSE's theoretical cryptography research into tangible applications has evolved into a dedicated lab that incubates practical ways to connect people through applied cryptography. - -Cursive's work creates essential feedback loops between researchers and developers, continuously improving a variety of open source codebases. They also experiment with new interfaces to experience cryptography, finding particular success with NFC technology. They have used a variety of form factors like cards, stickers, and bracelets to enable users to securely collect private data for cryptographic computations. - -While initial experiments focused on creating engaging ways for users to gather data for zero-knowledge proofs, Cursive is now expanding into developing meaningful multiparty computation (MPC) interactions that put cutting-edge cryptographic research directly into users' hands. - -Here are some product + research highlights: -- Client-side Nova folding to provide a "Spotify Wrapped" summary of your ZKSummit11 experience: https://github.com/cursive-team/zk-summit -- Private set intersection using multi-party FHE: https://github.com/cursive-team/2P-PSI -- Private hiring matcher using phantom-zone, a full multi-party FHE circuit builder: https://github.com/cursive-team/pz-hiring -- Trinity, a new 2PC scheme with optimal DevX and UX: https://github.com/cursive-team/trinity-v0 -`, - }, -} - -export const nfctap: ProjectInterface = { - id: "cursive", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.APPLICATION, - section: "grant", - content, - image: "cursive.webp", - name: "Cursive", - links: { - github: "https://github.com/cursive-team", - website: "https://www.cursive.team/", - }, - tags: { - keywords: [ +--- +id: "cursive" +name: "Cursive" +image: "cursive.webp" +section: "grant" +projectStatus: "active" +category: "application" +tldr: "A research lab & design studio exploring how cryptography like MPC and ZK can be used to discover and deepen human connection." +tags: + keywords: + [ "anonymity/privacy", "education", "data portability", @@ -47,8 +18,23 @@ export const nfctap: ProjectInterface = { "key management", "reputation", "toolkits", - ], - builtWith: [], - themes: ["build", "play"], - }, -} + ] + builtWith: [] + themes: ["build", "play"] +links: + github: "https://github.com/cursive-team" + website: "https://www.cursive.team/" +--- + +What began as an experimental initiative to transform PSE's theoretical cryptography research into tangible applications has evolved into a dedicated lab that incubates practical ways to connect people through applied cryptography. + +Cursive's work creates essential feedback loops between researchers and developers, continuously improving a variety of open source codebases. They also experiment with new interfaces to experience cryptography, finding particular success with NFC technology. They have used a variety of form factors like cards, stickers, and bracelets to enable users to securely collect private data for cryptographic computations. + +While initial experiments focused on creating engaging ways for users to gather data for zero-knowledge proofs, Cursive is now expanding into developing meaningful multiparty computation (MPC) interactions that put cutting-edge cryptographic research directly into users' hands. + +Here are some product + research highlights: + +- Client-side Nova folding to provide a "Spotify Wrapped" summary of your ZKSummit11 experience: https://github.com/cursive-team/zk-summit +- Private set intersection using multi-party FHE: https://github.com/cursive-team/2P-PSI +- Private hiring matcher using phantom-zone, a full multi-party FHE circuit builder: https://github.com/cursive-team/pz-hiring +- Trinity, a new 2PC scheme with optimal DevX and UX: https://github.com/cursive-team/trinity-v0 diff --git a/content/projects/discreetly.md b/content/projects/discreetly.md new file mode 100644 index 0000000..20d8bab --- /dev/null +++ b/content/projects/discreetly.md @@ -0,0 +1,19 @@ +--- +id: "discreetly" +name: "Discreetly" +image: "discreetly.svg" +section: "pse" +projectStatus: "inactive" +category: "applications" +tldr: "An anonymous, federated, chat application using ZK." +tags: + keywords: ["Anonymity/privacy", "Social"] + themes: ["play"] + types: ["Legos/dev tools", "Proof of concept", "Application"] + builtWith: ["rln", "semaphore"] +links: + github: "https://github.com/Discreetly" + website: "https://app.discreetly.chat/" +--- + +An anonymous, federated, chat application that uses Rate-Limiting Nullifier for spam prevention. diff --git a/content/projects/dsl-working-group.md b/content/projects/dsl-working-group.md new file mode 100644 index 0000000..723aeeb --- /dev/null +++ b/content/projects/dsl-working-group.md @@ -0,0 +1,18 @@ +--- +id: "dsl-working-group" +name: "DSL Working Group" +image: "" +section: "pse" +projectStatus: "inactive" +category: "research" +tldr: "Exploration of languages for writing zk circuits" +tags: + types: ["Legos/dev tools", "Proof of concept", "Developer tooling"] + keywords: [] + themes: ["research"] + builtWith: [] +links: + github: "https://github.com/privacy-scaling-explorations/chiquito/" +--- + +The DSL Working Group is focused on the exploration and improvement of languages used to write zero-knowledge circuits. The group's primary goal is to enhance the state of zk circuit languages, making them easier to write and review by offering the right abstractions. They also aim to make it harder to write unsound circuits by implementing static analysis and enforcing safer patterns. Additionally, they are working to support next-generation (Incrementally Verifiable Computation or IVC) proving systems. The group is currently working on Chiquito, a high-level Domain-Specific Language (DSL) for Halo2 circuits that lowers the entry barrier to write zk circuits with a state-machine abstraction API. diff --git a/content/projects/ecip-halo2.md b/content/projects/ecip-halo2.md new file mode 100644 index 0000000..03e18a1 --- /dev/null +++ b/content/projects/ecip-halo2.md @@ -0,0 +1,19 @@ +--- +id: "ecip-halo2" +name: "ECIP (Elliptic Curve Inner Products) Halo 2 Implementation" +image: "" +section: "pse" +projectStatus: "inactive" +category: "devtools" +tldr: "Integrating Nova into the EVM involves wrapping Liam Eagen's theoretical ECIP argument in Halo 2" +links: + github: "https://github.com/levs57/sage-circuits/" +extraLinks: + learn: + - label: "Designing a plonk circuit for Liam Eagen's protocol" + url: "https://hackmd.io/@levs57/r1n77YvP3" + - label: "ZKPs of Elliptic Curve Inner Products from Principal Divisors and Weil Reciprocity" + url: "https://eprint.iacr.org/2022/596" +--- + +Liam Eagen has developed a ZK proof for Elliptic Curve Inner Products (ECIPs) to overcome a significant bottle neck in recursive proof composition over elliptic curve cycles. The process of integrating Nova into the EVM requires an efficient method or "argument" for handling large elliptic Multi-Scalar Multiplications (MSMs). The final step in this integration process involves wrapping this argument Halo 2. diff --git a/content/projects/eigen-trust.md b/content/projects/eigen-trust.md new file mode 100644 index 0000000..e0b5e62 --- /dev/null +++ b/content/projects/eigen-trust.md @@ -0,0 +1,18 @@ +--- +id: "eigen-trust" +name: "EigenTrust" +image: "" +section: "archived" +projectStatus: "inactive" +category: "research" +tldr: "A distributed reputation system with zero-knowledge features." +tags: + keywords: ["Reputation", "Identity"] + themes: ["build"] + types: ["Infrastructure/protocol"] + builtWith: ["ethereum attestation service", "halo2", "ethers.rs"] +links: + github: "https://github.com/eigen-trust/protocol" +--- + +EigenTrust is a library designed to manage trust within a distributed network, incorporating zero-knowledge features. It serves as a reputation bank for the Ethereum ecosystem, providing an interoperable layer for managing reputation and trust. The protocol creates zero-knowledge proofs of reputation scores based on ratings given by network participants. This allows for the creation of a reputation system for peer-to-peer marketplaces and exchanges, reputation-weighted voting, and community gatekeeping. diff --git a/data/projects/excubiae.ts b/content/projects/excubiae.md similarity index 61% rename from data/projects/excubiae.ts rename to content/projects/excubiae.md index 17d7666..cf3272a 100644 --- a/data/projects/excubiae.ts +++ b/content/projects/excubiae.md @@ -1,77 +1,68 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "excubiae" +name: "Excubiae" +image: "" +section: "pse" +projectStatus: "maintained" +category: "devtools" +tldr: "an on-chain flexible & composable framework to create, reuse and customize gatekeepers." +license: "MIT" +tags: + keywords: ["Gatekeeper", "Access Control", "Policy", "Checker"] + themes: ["build"] + types: ["Legos/dev tools", "Lego sets/frameworks"] + builtWith: ["TypeScript", "Solidity"] +links: + github: "https://github.com/privacy-scaling-explorations/excubiae" + discord: "https://discord.com/channels/943612659163602974/1332087370065117260" +--- -const content: ProjectContent = { - en: { - tldr: "an on-chain flexible & composable framework to create, reuse and customize gatekeepers.", - description: `### Overview -Excubiae is a composable framework for implementing custom, attribute-based access control policies on EVM-compatible networks. It separates policy definition (*what rules to enforce*) from policy checking (*how to validate those rules*), enabling flexible and reusable access control patterns. +### Overview + +Excubiae is a composable framework for implementing custom, attribute-based access control policies on EVM-compatible networks. It separates policy definition (_what rules to enforce_) from policy checking (_how to validate those rules_), enabling flexible and reusable access control patterns. The framework enforces access through two core components: Policy, which defines the enforcement of rules and, Checker which defines the validation of submitted evidence based on the rules. -Designed with modularity, customizability and reusability in mind, Excubiae provides protocol developers with the building blocks to implement robust access control systems. +Designed with modularity, customizability and reusability in mind, Excubiae provides protocol developers with the building blocks to implement robust access control systems. The name "Excubiae" comes from the ancient Roman guards who stood watch and enforced access control—a fitting metaphor for a system that secures smart contract access through configurable policies. -### Vision -As blockchain protocols evolve, they generate new forms of verifiable evidence and proofs. While these proofs are critical for access control, integrating them into on-chain systems outside their native environments (e.g., APIs, apps, libraries) remains a challenge. +### Vision + +As blockchain protocols evolve, they generate new forms of verifiable evidence and proofs. While these proofs are critical for access control, integrating them into on-chain systems outside their native environments (e.g., APIs, apps, libraries) remains a challenge. Excubiae bridges this gap by providing a universal framework for composing and enforcing interoperable on-chain access policies, serving as a foundational layer for secure, evidence-based authentication across the ecosystem. -### Features -- **Composable Access Control** – A modular and reusable framework for attribute-based access control on EVM-compatible networks. Excubiae separates policy logic from validation logic, enabling independent audits and cross-protocol composability. -- **Gas-Efficient Minimal Proxy Pattern** – Uses a minimal proxy pattern with immutable arguments to reduce gas costs. Factory contracts can efficiently deploy Policies and Checkers while ensuring proper initialization. -- **Multi-Stage Validation System** – Supports three validation stages to support layered access control for use cases such as voting, governance, and staged authentication. - - **PRE** – Initial conditions (e.g., token ownership). - - **MAIN** – Ongoing validation (e.g., governance approval). - - **POST** – Follow-up actions (e.g., logging, permission updates). +### Features -### Status -🚀 Version [v0.3.2](https://github.com/privacy-scaling-explorations/excubiae/releases/tag/v0.3.2) has been officially released! Excubiae has reached a fully-fledged MVP, and the focus is now on adoption and integration. +- **Composable Access Control** – A modular and reusable framework for attribute-based access control on EVM-compatible networks. Excubiae separates policy logic from validation logic, enabling independent audits and cross-protocol composability. +- **Gas-Efficient Minimal Proxy Pattern** – Uses a minimal proxy pattern with immutable arguments to reduce gas costs. Factory contracts can efficiently deploy Policies and Checkers while ensuring proper initialization. +- **Multi-Stage Validation System** – Supports three validation stages to support layered access control for use cases such as voting, governance, and staged authentication. + - **PRE** – Initial conditions (e.g., token ownership). + - **MAIN** – Ongoing validation (e.g., governance approval). + - **POST** – Follow-up actions (e.g., logging, permission updates). + +### Status + +🚀 Version [v0.3.2](https://github.com/privacy-scaling-explorations/excubiae/releases/tag/v0.3.2) has been officially released! Excubiae has reached a fully-fledged MVP, and the focus is now on adoption and integration. The roadmap includes: + - ✅ A set of ready-to-use Checkers & Policies and their respective Factories ("extensions"). We are going to start by porting the [MACI Gatekeepers](https://github.com/privacy-scaling-explorations/maci/tree/dev/apps/website/versioned_docs/version-v1.2/solidity-docs/gatekeepers) as Excubiae Policy-Checker contracts. - - The current version supports the porting of MACI's [Semaphore](https://github.com/privacy-scaling-explorations/excubiae/tree/main/packages/contracts/contracts/extensions) gatekeeper as extension. This extension enforces membership proofs for a Semaphore group with frontrunning resistance. + - The current version supports the porting of MACI's [Semaphore](https://github.com/privacy-scaling-explorations/excubiae/tree/main/packages/contracts/contracts/extensions) gatekeeper as extension. This extension enforces membership proofs for a Semaphore group with frontrunning resistance. - ✅ Deployment scripts, guides, and examples for seamless integration. - - You can already find a [BaseVoting or AdvancedVoting](https://github.com/privacy-scaling-explorations/excubiae/tree/main/packages/contracts/contracts/test/core) examples, plus the Semaphore extension built on the Base core contracts. + - You can already find a [BaseVoting or AdvancedVoting](https://github.com/privacy-scaling-explorations/excubiae/tree/main/packages/contracts/contracts/test/core) examples, plus the Semaphore extension built on the Base core contracts. - ⚠️ Some lower-priority features are on hold and may be revisited based on adoption trends. -### Contributing -We welcome contributions! Whether you're interested in integrating Excubiae, developing custom Policies or Checkers, or providing feedback, we'd love to hear from you. +### Contributing + +We welcome contributions! Whether you're interested in integrating Excubiae, developing custom Policies or Checkers, or providing feedback, we'd love to hear from you. + +🔗 Join the conversation: -🔗 Join the conversation: - 📢 [PSE Discord](https://discord.com/invite/sF5CT5rzrR) (#🚪-excubiae channel) -- 🛠️ Open an [Issue](https://github.com/privacy-scaling-explorations/excubiae/issues/new) or [Pull Request](https://github.com/privacy-scaling-explorations/excubiae/compare) on the [GitHub monorepo](https://github.com/privacy-scaling-explorations/excubiae). +- 🛠️ Open an [Issue](https://github.com/privacy-scaling-explorations/excubiae/issues/new) or [Pull Request](https://github.com/privacy-scaling-explorations/excubiae/compare) on the [GitHub monorepo](https://github.com/privacy-scaling-explorations/excubiae). ### Learn More -For deeper insights into the core design, philosophy, roadmap, and integration guides, check out our [documentation](https://github.com/privacy-scaling-explorations/excubiae/tree/main/documentation). -`, - }, -} -export const excubiae: ProjectInterface = { - id: "excubiae", - category: ProjectCategory.DEVTOOLS, - content, - projectStatus: ProjectStatus.MAINTAINED, - section: "pse", - image: "", - license: "MIT", - name: "Excubiae", - links: { - github: "https://github.com/privacy-scaling-explorations/excubiae", - discord: - "https://discord.com/channels/943612659163602974/1332087370065117260", - }, - tags: { - keywords: ["Gatekeeper", "Access Control", "Policy", "Checker"], - themes: ["build"], - types: ["Legos/dev tools", "Lego sets/frameworks"], - builtWith: ["TypeScript", "Solidity"], - }, - extraLinks: {}, -} +For deeper insights into the core design, philosophy, roadmap, and integration guides, check out our [documentation](https://github.com/privacy-scaling-explorations/excubiae/tree/main/documentation). diff --git a/content/projects/interep.md b/content/projects/interep.md new file mode 100644 index 0000000..26516a3 --- /dev/null +++ b/content/projects/interep.md @@ -0,0 +1,21 @@ +--- +id: "interep" +name: "Interep" +image: "interep.svg" +section: "archived" +projectStatus: "inactive" +category: "devtools" +tldr: "An identity bridge from web2 to web3" +tags: + keywords: ["social", "reputation"] +links: + website: "https://docs.interep.link/" + github: "https://github.com/interep-project" + youtube: "https://www.youtube.com/watch?v=dYKgHkb_aqk" +extraLinks: + learn: + - label: "Interep: An on-ramp for reputation" + url: "https://mirror.xyz/privacy-scaling-explorations.eth/w7zCHj0xoxIfhoJIxI-ZeYIXwvNatP1t4w0TsqSIBe4" +--- + +Interep aims to provide an identity solution for Ethereum users by bridging from an established digital identity source such as Reddit, Twitter, and Github. The product provides an identity layer in the application stack and uses the Semaphore framework to ensure privacy. Interep allows users to establish sybil-resistant decentralized identities on web3 without starting from scratch. By leveraging zero-knowledge proofs, Interep ensures only essential information is disclosed. diff --git a/content/projects/jubmoji.md b/content/projects/jubmoji.md new file mode 100644 index 0000000..60528e7 --- /dev/null +++ b/content/projects/jubmoji.md @@ -0,0 +1,31 @@ +--- +id: "jubmoji" +name: "jubmoji.quest" +image: "jubmoji.webp" +section: "archived" +projectStatus: "inactive" +category: "application" +tldr: "Users of Jubmoji.quest tap NFC cards to collect signatures. By collecting these signatures, they complete quests." +tags: + keywords: + [ + "anonymity/privacy", + "education", + "data portability", + "social", + "wallets", + "identity", + "key management", + "reputation", + "toolkits", + ] + builtWith: ["snarkjs", "circom", "node"] + themes: ["build", "play"] +links: + github: "https://github.com/jubmoji/jubmoji.quest" + website: "https://www.jubmoji.quest/" +--- + +Jubmoji.quest is a place to keep personal, provable digital mementos from people you meet and places you visit IRL. Each time you tap a card, you collect a Jubmoji, a unique cryptographic signature that you can store privately and share as you wish! + +The learnings from this experiment influenced the creation of [Cursive](https://pse.dev/en/projects/cursive) which continues to explore applications of cryptography for human connection. diff --git a/data/projects/machina-iO.ts b/content/projects/machina-iO.md similarity index 73% rename from data/projects/machina-iO.ts rename to content/projects/machina-iO.md index 15b4b9a..9137a50 100644 --- a/data/projects/machina-iO.ts +++ b/content/projects/machina-iO.md @@ -1,16 +1,36 @@ -import { ProjectCategory, ProjectInterface, ProjectStatus } from "@/lib/types" +--- +id: "machina-iO" +name: "MachinaIO" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "Building the first practical indistinguishability obfuscation (iO) system for secure and scalable cryptographic applications." +tags: + keywords: + [ + "indistinguishability obfuscation", + "iO", + "cryptography", + "Ethereum", + "FHE", + "SNARKs", + ] + themes: ["cryptography", "privacy", "scalability"] + types: ["research", "development"] +links: + twitter: "https://x.com/machina__io" + github: "https://github.com/MachinaIO/" + website: "https://hackmd.io/@MachinaIO/H1w5iwmDke" +team: + - name: "Enrico Bottazzi" + email: "enrico@pse.dev" + - name: "Sora Suegami" + email: "sorasuegami@pse.dev" + - name: "Pia" + email: "pia@pse.dev" +--- -export const machinaIo: ProjectInterface = { - id: "machina-io", - image: "", - name: "MachinaIO", - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.RESEARCH, - content: { - en: { - tldr: "Building the first practical indistinguishability obfuscation (iO) system for secure and scalable cryptographic applications.", - description: ` ### Project Overview The MachinaIO project aims to develop the first practical implementation of Indistinguishability Obfuscation (iO). By converting programs into black-box representations, MachinaIO enables users to execute obfuscated programs locally without revealing their internal workings and hardcoded secrets, thus significantly enhancing security and scalability for blockchain applications and beyond. This removes the reliance on threshold-based committees from existing privacy-preserving applications based on MPC and (multi-key) FHE @@ -28,7 +48,7 @@ The primary goal of MachinaIO is to build a secure, and practical implementation ### Technical Approach -MachinaIO aims to create the first *practical* iO system based on formal security proofs, transforming any program into a black-box that hides its internals while preserving its functionality. By replacing committees in multi-party computation (MPC) or multi-key fully homomorphic encryption (FHE), iO can scale these applications securely and eliminate trust bottlenecks. +MachinaIO aims to create the first _practical_ iO system based on formal security proofs, transforming any program into a black-box that hides its internals while preserving its functionality. By replacing committees in multi-party computation (MPC) or multi-key fully homomorphic encryption (FHE), iO can scale these applications securely and eliminate trust bottlenecks. ### Contributions @@ -53,40 +73,6 @@ MachinaIO can transform blockchain and cryptographic applications, such as trust - Hello world: The first sign of practical iO ([blogpost](https://pse.dev/en/blog/hello-world-the-first-signs-of-practical-io)) ### Resources + - **GitHub Repository:** [Machina iO](https://github.com/MachinaIO/) - **Project Plan:** [HackMD Plan](https://hackmd.io/@MachinaIO/H1w5iwmDke) - `, - }, - }, - links: { - twitter: "https://x.com/machina__io", - github: "https://github.com/MachinaIO/", - website: "https://hackmd.io/@MachinaIO/H1w5iwmDke", - }, - team: [ - { - name: "Enrico Bottazzi", - email: "enrico@pse.dev", - }, - { - name: "Sora Suegami", - email: "sorasuegami@pse.dev", - }, - { - name: "Pia", - email: "pia@pse.dev", - }, - ], - tags: { - keywords: [ - "indistinguishability obfuscation", - "iO", - "cryptography", - "Ethereum", - "FHE", - "SNARKs", - ], - themes: ["cryptography", "privacy", "scalability"], - types: ["research", "development"], - }, -} diff --git a/content/projects/maci-platform.md b/content/projects/maci-platform.md new file mode 100644 index 0000000..5212576 --- /dev/null +++ b/content/projects/maci-platform.md @@ -0,0 +1,33 @@ +--- +id: "maci-platform" +name: "MACI Platform" +image: "maci-platform.png" +section: "pse" +projectStatus: "inactive" +category: "application" +tldr: "Run a voting round in your community! Forked from EasyRetroPGF and enhanced with MACI for privacy, anti-bribery and anti-collusion" +tags: + keywords: ["Anonymity/privacy", "Voting/governance"] + themes: ["build"] + types: ["Lego sets/toolkits", "Infrastructure/protocol", "Public Good"] + builtWith: ["MACI", "EAS", "EasyRetroPGF"] +links: + github: "https://github.com/privacy-scaling-explorations/maci-platform" + website: "https://maci.pse.dev" + twitter: "https://twitter.com/zkmaci" +--- + +### Overview + +[MACI Platform](https://github.com/privacy-scaling-explorations/maci-platform/tree/main) is an implementation of EasyRetroPGF with MACI. + +This project enables any community, organization or ecosystem to run a voting round. +It is highly configurable to enable different voting mechanisms (quadratic voting, quadratic funding, etc), gating mechanisms (token based, attestation based, hats-based, etc) and an easy-to-use UI for both round organizers and voters. + +### Features + +With MACI Platform, you can run different kind of voting rounds for your community, with the following features: + +1. Full benefit of MACI's properties - Plug into MACI's anti-collusion and privacy features +2. Clean UX - The interface is optimised for voters and projects that want to participate in rounds +3. Customisable - The platform can be customised quickly to fit different use cases diff --git a/data/projects/maci.ts b/content/projects/maci.md similarity index 53% rename from data/projects/maci.ts rename to content/projects/maci.md index 8536e7f..1cf6c65 100644 --- a/data/projects/maci.ts +++ b/content/projects/maci.md @@ -1,14 +1,23 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "maci" +name: "MACI" +image: "maci.png" +section: "pse" +projectStatus: "active" +category: "application" +tldr: "An on-chain voting solution that protects privacy and minimizes the risk of collusion and bribery" +tags: + keywords: ["Anonymity/privacy", "Voting/governance"] + themes: ["build"] + types: ["Lego sets/toolkits", "Infrastructure/protocol"] + builtWith: ["p0tion", "zk-kit", "snarkjs", "circom", "solidity"] +links: + github: "https://github.com/privacy-scaling-explorations/maci" + website: "https://maci.pse.dev" + twitter: "https://twitter.com/zkmaci" +--- -const content: ProjectContent = { - en: { - tldr: "An on-chain voting solution that protects privacy and minimizes the risk of collusion and bribery", - description: `### Overview +### Overview [MACI](https://github.com/privacy-scaling-explorations/maci/tree/dev) is a protocol designed to provide a highly secure e-voting solution. @@ -26,27 +35,4 @@ With MACI, you can take on chain voting to the next level: 1. Uncensorable - no one can censor votes, not even the coordinator 2. Votes are private - votes are sent encrypted on chain and only the voter and the coordinator can decrypt them -3. Fully verifiable voting process - anyone can verify the tally is correct thanks to zero-knowledge proofs`, - }, -} - -export const maci: ProjectInterface = { - id: "maci", - category: ProjectCategory.APPLICATION, - projectStatus: ProjectStatus.ACTIVE, - section: "pse", - content, - image: "maci.png", - name: "MACI", - links: { - github: "https://github.com/privacy-scaling-explorations/maci", - website: "https://maci.pse.dev", - twitter: "https://twitter.com/zkmaci", - }, - tags: { - keywords: ["Anonymity/privacy", "Voting/governance"], - themes: ["build"], - types: ["Lego sets/toolkits", "Infrastructure/protocol"], - builtWith: ["p0tion", "zk-kit", "snarkjs", "circom", "solidity"], - }, -} +3. Fully verifiable voting process - anyone can verify the tally is correct thanks to zero-knowledge proofs diff --git a/data/projects/mopro.ts b/content/projects/mopro.md similarity index 56% rename from data/projects/mopro.ts rename to content/projects/mopro.md index 820c8a7..7c2c623 100644 --- a/data/projects/mopro.ts +++ b/content/projects/mopro.md @@ -1,14 +1,37 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "mopro" +name: "Mopro" +image: "mopro.png" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "Mopro makes client-side proving on mobile simple." +license: "MIT" +tags: + keywords: ["Mobile", "Client", "iOS", "Android"] + themes: ["build", "play"] + types: + [ + "Legos/dev tools", + "Lego sets/toolkits", + "Infrastructure/protocol", + "Plugin", + ] + builtWith: ["halo2", "circom"] +links: + github: "https://github.com/zkmopro" + website: "https://zkmopro.org/" + telegram: "https://t.me/zkmopro" + twitter: "https://x.com/zkmopro" +extraLinks: + buildWith: + - label: "Getting Started with mopro" + url: "https://zkmopro.org/docs/getting-started" + play: + - label: "Try it out: Mopro Benchmark" + url: "https://testflight.apple.com/join/TBlBDicy" +--- -const content: ProjectContent = { - en: { - tldr: "Mopro makes client-side proving on mobile simple.", - description: ` ### Overview Mopro makes client-side proving simple. You can think of it as a toolkit for ZK app development. It primarily focuses on running natively mobile. @@ -17,9 +40,9 @@ How? Mopro connects different adapters with different platforms. You can think o ### Features -With mopro, developers can overcome the limitations of existing tools like \`snarkjs\`, which struggles with small circuit sizes and slow performance in browsers. Our solution leverages the growing power of mobile GPUs to deliver a fast, scalable, and secure proving experience directly on client-side applications +With mopro, developers can overcome the limitations of existing tools like `snarkjs`, which struggles with small circuit sizes and slow performance in browsers. Our solution leverages the growing power of mobile GPUs to deliver a fast, scalable, and secure proving experience directly on client-side applications -Mopro, short for Mobile Prover, redefines the landscape of mobile app development by introducing an innovative toolkit designed for zero-knowledge (zk) proofs. +Mopro, short for Mobile Prover, redefines the landscape of mobile app development by introducing an innovative toolkit designed for zero-knowledge (zk) proofs. Developer Capabilities: @@ -32,48 +55,3 @@ Developer Capabilities: ### Applications - iOS Mopro Benchmark - [TestFlight](https://testflight.apple.com/join/TBlBDicy) | [GitHub](https://github.com/zkmopro/benchmark-app) -`, - }, -} - -export const mopro: ProjectInterface = { - id: "mopro", - content, - category: ProjectCategory.DEVTOOLS, - projectStatus: ProjectStatus.ACTIVE, - section: "pse", - image: "mopro.png", - license: "MIT", - name: "Mopro", - links: { - github: "https://github.com/zkmopro", - website: "https://zkmopro.org/", - telegram: "https://t.me/zkmopro", - twitter: "https://x.com/zkmopro", - }, - tags: { - keywords: ["Mobile", "Client", "iOS", "Android"], - themes: ["build", "play"], - types: [ - "Legos/dev tools", - "Lego sets/toolkits", - "Infrastructure/protocol", - "Plugin", - ], - builtWith: ["halo2", "circom"], - }, - extraLinks: { - buildWith: [ - { - label: "Getting Started with mopro", - url: "https://zkmopro.org/docs/getting-started", - }, - ], - play: [ - { - label: "Try it out: Mopro Benchmark", - url: "https://testflight.apple.com/join/TBlBDicy", - }, - ], - }, -} diff --git a/data/projects/mpc-framework.ts b/content/projects/mpc-framework.md similarity index 54% rename from data/projects/mpc-framework.ts rename to content/projects/mpc-framework.md index 00c7088..6a1b7b9 100644 --- a/data/projects/mpc-framework.ts +++ b/content/projects/mpc-framework.md @@ -1,23 +1,53 @@ -import { ProjectCategory, ProjectInterface, ProjectStatus } from "@/lib/types" - -export const mpcFramework: ProjectInterface = { - id: "mpc-framework", - image: "mpc-framework.png", - name: "MPC Framework", - category: ProjectCategory.DEVTOOLS, - license: "MIT", - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - links: { - github: "https://github.com/privacy-scaling-explorations/mpc-framework", - website: "https://mpc.pse.dev", - telegram: "https://t.me/+FKnOHTkvmX02ODVl", - }, - content: { - en: { - tldr: "Create secure MPC apps easily in TypeScript.", - description: ` +--- +id: "mpc-framework" +name: "MPC Framework" +image: "mpc-framework.png" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "Create secure MPC apps easily in TypeScript." +license: "MIT" +tags: + keywords: ["MPC", "TypeScript", "privacy", "Garbled Circuits", "iZK"] + themes: ["buildWith", "play", "research"] + types: [] + builtWith: ["ValueScript", "Summon", "MPZ", "EMP-Toolkit"] +links: + github: "https://github.com/privacy-scaling-explorations/mpc-framework" + website: "https://mpc.pse.dev" + telegram: "https://t.me/+FKnOHTkvmX02ODVl" +team: + - name: "Andrew Morris" + image: "/avatars/andrew.png" + links: + github: "https://github.com/voltrevo" + twitter: "https://x.com/voltrevo" + - name: "Yanis Meziane" + image: "/avatars/yanis.png" + links: + github: "https://github.com/Meyanis95" + twitter: "https://x.com/yanis_mezn" +extraLinks: + buildWith: + - label: "Create MPC-powered apps in Typescript" + url: "https://github.com/privacy-scaling-explorations/mpc-framework" + - label: "Generate circuits with Summon" + url: "https://github.com/privacy-scaling-explorations/summon" + research: + - label: "Trinity: 2PC with Laconic OT + Garbled Circuits + PLONK" + url: "https://github.com/privacy-scaling-explorations/Trinity" + - label: "Authenticated Garbling" + url: "https://hackmd.io/@a37205y_SL2LtEA1y2OWhQ/Sy4-nZ3lyx" + play: + - label: "Hello world in MPC" + url: "https://mpc.pse.dev/apps/hello" + - label: "Lizard Spock in MPC" + url: "https://mpc.pse.dev/apps/lizard-spock" + - label: "More demos" + url: "https://mpc.pse.dev/showcase" +--- +# MPC Framework A framework that makes MPC easy, in TypeScript. @@ -30,13 +60,16 @@ Try [a demo app](https://mpc.pse.dev/apps/hello) or quickly [spin up your own](h To make an MPC app you need three things: **1) Engine** + - Implements the underlying cryptography. **2) Circuit Generator** + - The shared computation needs to be specified as a circuit, and you need something to generate -that. This is similar to using a compiler to get programs to run on your machine. + that. This is similar to using a compiler to get programs to run on your machine. **3) Messaging with each Party** + - Send and receive bytes. MPC Framework brings these pieces together in a straightforward TypeScript API to make MPC @@ -73,67 +106,3 @@ lovers' app described in the talk has been implemented using mpc-framework [here](https://mpc.pse.dev/apps/2pc-is-for-lovers). For a more technical introduction, see [Computerphile's video on Garbled Circuits](https://www.youtube.com/watch?v=FMZ-HARN0gI). For a deeper dive: [Pragmatic MPC](https://securecomputation.org/). - `, - }, - }, - team: [ - { - name: "Andrew Morris", - image: "/avatars/andrew.png", - links: { - github: "https://github.com/voltrevo", - twitter: "https://x.com/voltrevo", - }, - }, - { - name: "Yanis Meziane", - image: "/avatars/yanis.png", - links:{ - github: "https://github.com/Meyanis95", - twitter: "https://x.com/yanis_mezn", - } - }, - ], - tags: { - keywords: ["MPC", "TypeScript", "privacy", "Garbled Circuits", "iZK"], - themes: ["buildWith", "play", "research"], - types: [], - builtWith: ["ValueScript", "Summon", "MPZ", "EMP-Toolkit"], - }, - extraLinks: { - buildWith: [ - { - label: "Create MPC-powered apps in Typescript", - url: "https://github.com/privacy-scaling-explorations/mpc-framework" - }, - { - label: "Generate circuits with Summon", - url: "https://github.com/privacy-scaling-explorations/summon" - }, - ], - research: [ - { - label: "Trinity: 2PC with Laconic OT + Garbled Circuits + PLONK", - url: "https://github.com/privacy-scaling-explorations/Trinity", - }, - { - label: "Authenticated Garbling", - url: "https://hackmd.io/@a37205y_SL2LtEA1y2OWhQ/Sy4-nZ3lyx", - }, - ], - play: [ - { - label: "Hello world in MPC", - url: "https://mpc.pse.dev/apps/hello", - }, - { - label: "Lizard Spock in MPC", - url: "https://mpc.pse.dev/apps/lizard-spock", - }, - { - label: "More demos", - url: "https://mpc.pse.dev/showcase", - }, - ] - }, -} diff --git a/data/projects/mpc-stats.ts b/content/projects/mpc-stats.md similarity index 64% rename from data/projects/mpc-stats.ts rename to content/projects/mpc-stats.md index 7c17905..f810c71 100644 --- a/data/projects/mpc-stats.ts +++ b/content/projects/mpc-stats.md @@ -1,36 +1,32 @@ -import { ProjectCategory, ProjectInterface, ProjectStatus } from "@/lib/types" +--- +id: "mpc-stats" +name: "MPCStats" +image: "mpc-stats.png" +section: "pse" +projectStatus: "inactive" +category: "applications" +tldr: "A framework for private and verifiable statistical analysis across multiple data providers." +tags: + keywords: ["MPC", "statistics", "data analysis"] + themes: ["build"] + types: ["Legos/dev tools", "Lego sets/toolkits"] + builtWith: ["MP-SPDZ", "tlsn", "python"] +links: + github: "https://github.com/MPCStats" + website: "https://mpcstats.github.io/docs" +--- -export const mpcStats: ProjectInterface = { - id: "mpc-stats", - image: "mpc-stats.png", - name: "MPCStats", - category: ProjectCategory.APPLICATION, - projectStatus: ProjectStatus.INACTIVE, - section: "pse", - content: { - en: { - tldr: "A framework for private and verifiable statistical analysis across multiple data providers.", - description: ` ## Overview + MPCStats is a framework that enables data consumers to query statistical computations across multiple data providers while ensuring privacy and result correctness. By integrating privacy-preserving technologies such as ZKP, MPC, and FHE, our goal is to provide tools and guidance for integrating privacy-preserving analysis into their workflows. We also aim to identify real-world applications that can benefit from this framework. + ## Features + - **Privacy-preserving and verifiable statistical analysis**: Allows data providers to keep their inputs confidential while giving data consumers the assurance that computations are performed accurately and securely. - **Data validity**: Integrates TLSNotary to authenticate inputs from verified web sources, ensuring data consumers can trust that data inputs are genuine and accurate. + ## Use Cases + - **Cross-department data sharing and surveys**: Enables secure, private data sharing across government departments for streamlined operations and collaborative analysis. - **Healthcare research**: Aggregates data from sources such as fitness apps and sleep trackers, allowing researchers to uncover relationships between health factors, such as fitness and sleep patterns. - **Salary survey**: A verifiable and anonymous alternative to platforms like Glassdoor, where users can contribute salary data with privacy guarantees. - `, - }, - }, - links: { - github: "https://github.com/MPCStats", - website: "https://mpcstats.github.io/docs", - }, - tags: { - keywords: ["MPC", "statistics", "data analysis"], - themes: ["build"], - types: ["Legos/dev tools", "Lego sets/toolkits"], - builtWith: ["MP-SPDZ", "tlsn", "python"], - }, -} diff --git a/content/projects/mpz.md b/content/projects/mpz.md new file mode 100644 index 0000000..3009066 --- /dev/null +++ b/content/projects/mpz.md @@ -0,0 +1,27 @@ +--- +id: "mpz" +name: "mpz" +image: "mpz-cover.png" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "A safe, performant, modular and portable multi-party computation (MPC) library." +license: "MIT or Apache-2.0" +tags: + themes: ["build", "play"] + types: ["Legos/dev tools", "Infrastructure/protocol"] + builtWith: ["rust"] + keywords: ["Anonymity/privacy", "mpc"] +links: + github: "https://github.com/privacy-scaling-explorations/mpz" +extraLinks: + play: + - label: "mpz-play (Exercises to get familiar with mpz)" + url: "https://github.com/th4s/mpz-play" +--- + +mpz (_pronounced as "em-peasy"_) is a collection of Rust-based libraries for multi-party computation (MPC), designed to be safe, performant and modular. + +Built with portability in mind, mpz runs natively or in the browser via WebAssembly (WASM). It serves as the core MPC implementation behind [TLSNotary](tlsn), but its architecture is broadly applicable across privacy-preserving and cryptographic use cases. + +mpz is part of Privacy & Scaling Explorations' broader effort to advance practical cryptographic tooling. It is dual-licensed under Apache-2.0 and MIT to encourage open-source collaboration. diff --git a/data/projects/openpassport.ts b/content/projects/openpassport.md similarity index 62% rename from data/projects/openpassport.ts rename to content/projects/openpassport.md index c0bc6a2..ea71b40 100644 --- a/data/projects/openpassport.ts +++ b/content/projects/openpassport.md @@ -1,14 +1,22 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "openpassport" +name: "OpenPassport" +image: "openpassport.jpg" +section: "grant" +projectStatus: "active" +category: "application" +tldr: "OpenPassport lets you check a passport is valid in zero-knowledge" +tags: + keywords: + ["Passports", "Identity", "Anonymity/privacy", "Signatures", "Social"] + builtWith: ["circom", "snarkjs"] +links: + github: "https://github.com/zk-passport/openpassport" + website: "https://openpassport.app" + twitter: "https://x.com/openpassportapp" + telegram: "https://t.me/openpassport" +--- -const content: ProjectContent = { - en: { - tldr: "OpenPassport lets you check a passport is valid in zero-knowledge", - description: ` OpenPassport originally started at ETHGlobal Paris 2023 as a hackathon project, with the goal of verifying the validity of passports in zero knowledge. The idea was simple: electronic passports are embedded with a chip that contains an attestation signed by the issuing country. It should be possible to read the chip's content using NFC and use it to generate zk proofs. @@ -17,32 +25,3 @@ After the first prototype, OpenPassport developed the ability to do selective di The motivation behind this work lies in the fact that it can help break the deadlock identity verification is currently stuck in. Traditional KYC requires sharing all private data with a centralized verifier, and it's becoming easily manipulable using deepfakes. It can also aid in Sybil resistance, in combination with other identity solutions for users who don't have a biometric passport. After getting help from PSE for more than a year, OpenPassport graduated and grew to a team of five. In February 2025, OpenPassport joined Self Protocol to get the firepower to ship zk passport verification at a large scale. They launched in production with support for 130+ countries and are now working on adding support for other identity documents. - ` - }, -} - -export const OpenPassport: ProjectInterface = { - id: "openpassport", - category: ProjectCategory.APPLICATION, - projectStatus: ProjectStatus.ACTIVE, - section: "grant", - content, - image: "openpassport.jpg", - name: "OpenPassport", - links: { - github: "https://github.com/zk-passport/openpassport", - website: "https://openpassport.app", - twitter: "https://x.com/openpassportapp", - telegram: "https://t.me/openpassport", - }, - tags: { - keywords: [ - "Passports", - "Identity", - "Anonymity/privacy", - "Signatures", - "Social", - ], - builtWith: ["circom", "snarkjs"], - }, -} diff --git a/data/projects/p0tion.ts b/content/projects/p0tion.md similarity index 54% rename from data/projects/p0tion.ts rename to content/projects/p0tion.md index 507ce07..8bcd2a5 100644 --- a/data/projects/p0tion.ts +++ b/content/projects/p0tion.md @@ -1,44 +1,32 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "p0tion" +name: "p0tion" +image: "p0tion.png" +section: "archived" +projectStatus: "maintained" +category: "devtools" +tldr: "Toolkit for Groth16 Phase 2 Trusted Setup ceremonies." +tags: + keywords: ["Toolkits", "Infrastructure/protocol"] + themes: ["build"] + types: ["Legos/dev tools"] + builtWith: [] +links: + website: "https://ceremony.pse.dev/" + github: "https://github.com/privacy-scaling-explorations/p0tion" +--- + +# p0tion -const content: ProjectContent = { - en: { - tldr: "Toolkit for Groth16 Phase 2 Trusted Setup ceremonies.", - description: ` ### Overview + p0tion is an agnostic-from-ceremony public good toolkit, with the aim of making Groth16 zk-applications scale and become production-ready in a safe and secure manner by running Phase 2 Trusted Setup ceremonies. ### Status + This project has been sunset and it is entering a long term support phase (no further development). p0tion toolkit is available for developers to use and run their own trusted setups ceremonies. We encourage the community to fork and continue the improvement of this toolkit. ### Resources - **p0tion**: A tool to help developers create and manage trusted setups - [GitHub](https://github.com/privacy-scaling-explorations/p0tion) - **DefinitelySetup WebApp**: A WebApp to monitor and contribute to trusted setups - [Website](https://ceremony.pse.dev/) | [GitHub](https://github.com/privacy-scaling-explorations/DefinitelySetup) - `, - }, -} - -export const p0tion: ProjectInterface = { - id: "p0tion", - category: ProjectCategory.DEVTOOLS, - projectStatus: ProjectStatus.MAINTAINED, - section: "archived", - content, - image: "p0tion.png", - name: "p0tion", - links: { - website: "https://ceremony.pse.dev/", - github: "https://github.com/privacy-scaling-explorations/p0tion", - }, - tags: { - keywords: ["Toolkits", "Infrastructure/protocol"], - themes: ["build"], - types: ["Legos/dev tools"], - builtWith: [], - }, -} diff --git a/content/projects/p256.md b/content/projects/p256.md new file mode 100644 index 0000000..34aca86 --- /dev/null +++ b/content/projects/p256.md @@ -0,0 +1,27 @@ +--- +id: "p256" +name: "P256" +image: "" +section: "pse" +projectStatus: "inactive" +category: "devtools" +tldr: "Smart contract wallet enabling transactions through familiar flows like touchID, faceID, WebAuth, and Passkeys." +tags: + keywords: + [ + "Toolkits", + "Infrastructure/protocol", + "User Experience", + "Key management", + "Wallets", + "Account Abstraction", + ] + themes: ["build"] + types: ["Legos/dev tools"] + builtWith: ["halo2"] +links: + website: "https://www.p256wallet.org/" + github: "https://github.com/privacy-scaling-explorations/p256-circom" +--- + +P256 is an ERC-4337 smart contract wallet that leverages zk-SNARKs for WebAuthn and P-256 signature verification. It aims to simplify Ethereum transactions by incorporating familiar authentication methods like touchID and faceID. The project addresses the challenges of seed phrase management and leverages the biometric capabilities of billions of cellphones to create a more user-friendly crypto experience. Technically, it is an end-to-end ERC-4337 smart contract wallet that verifies ZK proofs of Passkey signatures using the Halo2 proving system. diff --git a/data/projects/pir-scaling-semaphore.ts b/content/projects/pir-scaling-semaphore.md similarity index 52% rename from data/projects/pir-scaling-semaphore.ts rename to content/projects/pir-scaling-semaphore.md index 0fa021d..ff4c5bd 100644 --- a/data/projects/pir-scaling-semaphore.ts +++ b/content/projects/pir-scaling-semaphore.md @@ -1,82 +1,80 @@ -import { ProjectCategory, ProjectInterface, ProjectStatus } from "@/lib/types" - -export const scalingSemaphore: ProjectInterface = { - id: "scaling-semaphore-pir", - image: "", // add cover image or leave blank - name: "Scaling Semaphore – PIR Merkle-Path Retrieval", - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.RESEARCH, - content: { - en: { - tldr: "Private Information Retrieval lets Semaphore users fetch their Merkle path from a server without revealing which identity they own, enabling truly private proofs for groups with millions of members.", - description: ` -### Scaling Semaphore – Private Merkle-Path Retrieval with PIR - -#### Project Overview -The project tackles the privacy bottleneck that appears when Semaphore groups grow to millions of members. In large groups, a user must obtain their Merkle-path (all sibling hashes from leaf to root) from a remote database before they can create a zero-knowledge membership proof. Asking for that path naïvely reveals **which identity** they own. - -This project solves the problem by letting users **query the server with Private Information Retrieval (PIR)**. PIR lets a client fetch database records without the server learning which records were requested, preserving full anonymity at Internet scale. - -#### Why PIR matters -Traditional PIR protocols were too heavy for on-chain use. Recent schemes—e.g. **Respire** and Frodo-PIR—support 2²⁰ elements (≈ 1 million) with sub-second online latency and no trusted setup. By storing Merkle leaves/hashes in PIR-friendly chunks (32 B records) we can keep group trees on a server while users privately retrieve only the ~64 kB they need for a proof. - -#### Technical Approach - -| Component | Role | -|-----------|------| -| **Lean Incremental Merkle Tree (LeanIMT)** | Append-only tree used by Semaphore; gives deterministic indices so the client knows exactly which nodes to fetch. | -| **PIR Layer (Respire)** | Batched, lattice-based PIR with no offline phase; ideal for many small records. | -| **\`lean-imt\` integration** | Rust implementation and benchmarks with Respire | - -**Data flow** -1. Client computes the indices of its Merkle path. -2. Client sends a PIR query for those indices to the server. -3. Server responds with encrypted buckets; client decrypts to obtain hashes/leaves. -4. Client generates the standard Semaphore ZK proof locally; nothing is leaked to the server. - -#### Current Status (Apr 2025) -- ✅ ZK-Kit LeanIMT Rust implementation -- 🔄 PIR proof-of-concept fetching 32-byte records from a 2²⁰-element DB -- 🔜 Benchmarks -- 🔜 Post & L&S session - -#### Use-cases Enabled -- **World-scale anonymous voting** without delegating proofs to a company server. -- **On-chain reputation** where users prove historical actions privately. -- **Privacy-preserving NFT drops** that gate by membership but hide identities. - -#### Resources -- **Project Plan:** -- **Semaphore v4 (Rust):** -- **Respire PIR paper:** -- **Customizable LeanIMT implementation:** - -#### Contact -- **Brechy:** -- **Discord:** - `, - }, - }, - links: { - discord: "https://discord.com/invite/sF5CT5rzrR", - }, - team: [ - { - name: "Brechy", - email: "brechy@pse.dev", - }, - ], - tags: { - keywords: [ +--- +id: "scaling-semaphore-pir" +name: "Scaling Semaphore – PIR Merkle-Path Retrieval" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "Private Information Retrieval lets Semaphore users fetch their Merkle path from a server without revealing which identity they own, enabling truly private proofs for groups with millions of members." +tags: + keywords: + [ "Semaphore", "PIR", "LeanIMT", "zero-knowledge proofs", "privacy", "Merkle tree", - ], - themes: ["privacy", "scalability", "identity"], - types: ["research", "development"], - }, -} + ] + themes: ["privacy", "scalability", "identity"] + types: ["research", "development"] +links: + discord: "https://discord.com/invite/sF5CT5rzrR" +team: + - name: "Brechy" + email: "brechy@pse.dev" +--- + +# Scaling Semaphore – PIR Merkle-Path Retrieval + +### Scaling Semaphore – Private Merkle-Path Retrieval with PIR + +#### Project Overview + +The project tackles the privacy bottleneck that appears when Semaphore groups grow to millions of members. In large groups, a user must obtain their Merkle-path (all sibling hashes from leaf to root) from a remote database before they can create a zero-knowledge membership proof. Asking for that path naïvely reveals **which identity** they own. + +This project solves the problem by letting users **query the server with Private Information Retrieval (PIR)**. PIR lets a client fetch database records without the server learning which records were requested, preserving full anonymity at Internet scale. + +#### Why PIR matters + +Traditional PIR protocols were too heavy for on-chain use. Recent schemes—e.g. **Respire** and Frodo-PIR—support 2²⁰ elements (≈ 1 million) with sub-second online latency and no trusted setup. By storing Merkle leaves/hashes in PIR-friendly chunks (32 B records) we can keep group trees on a server while users privately retrieve only the ~64 kB they need for a proof. + +#### Technical Approach + +| Component | Role | +| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | +| **Lean Incremental Merkle Tree (LeanIMT)** | Append-only tree used by Semaphore; gives deterministic indices so the client knows exactly which nodes to fetch. | +| **PIR Layer (Respire)** | Batched, lattice-based PIR with no offline phase; ideal for many small records. | +| **`lean-imt` integration** | Rust implementation and benchmarks with Respire | + +**Data flow** + +1. Client computes the indices of its Merkle path. +2. Client sends a PIR query for those indices to the server. +3. Server responds with encrypted buckets; client decrypts to obtain hashes/leaves. +4. Client generates the standard Semaphore ZK proof locally; nothing is leaked to the server. + +#### Current Status (Apr 2025) + +- ✅ ZK-Kit LeanIMT Rust implementation +- 🔄 PIR proof-of-concept fetching 32-byte records from a 2²⁰-element DB +- 🔜 Benchmarks +- 🔜 Post & L&S session + +#### Use-cases Enabled + +- **World-scale anonymous voting** without delegating proofs to a company server. +- **On-chain reputation** where users prove historical actions privately. +- **Privacy-preserving NFT drops** that gate by membership but hide identities. + +#### Resources + +- **Project Plan:** +- **Semaphore v4 (Rust):** +- **Respire PIR paper:** +- **Customizable LeanIMT implementation:** + +#### Contact + +- **Brechy:** +- **Discord:** diff --git a/data/projects/plasma-fold.ts b/content/projects/plasma-fold.md similarity index 67% rename from data/projects/plasma-fold.ts rename to content/projects/plasma-fold.md index bf401a7..b9d8d87 100644 --- a/data/projects/plasma-fold.ts +++ b/content/projects/plasma-fold.md @@ -1,27 +1,36 @@ -import { ProjectCategory, ProjectInterface, ProjectStatus } from "@/lib/types" +--- +id: "plasma-fold" +name: "Plasma Fold" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "Integrating folding schemes into plasma-based L2 solutions for efficient and scalable Ethereum transactions." +tags: + keywords: + [ + "plasma", + "folding schemes", + "Ethereum", + "scalability", + "L2", + "zero-knowledge proofs", + ] + themes: ["scalability", "L2 solutions", "zk proofs"] + types: ["research", "development"] +--- -export const plasmaFold: ProjectInterface = { - id: "plasma-fold", - image: "", - name: "Plasma Fold", - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.RESEARCH, - content: { - en: { - tldr: "Integrating folding schemes into plasma-based L2 solutions for efficient and scalable Ethereum transactions.", - description: ` ## Plasma Fold **Reimagining Plasma with Folding Schemes** Plasma Fold is an experimental Layer 2 (L2) design that combines the original Plasma architecture with modern zero-knowledge folding schemes to dramatically scale Ethereum transaction throughput. By leveraging recent advances in Incremental Verifiable Computation (IVC) and folding-based proof systems, Plasma Fold achieves high-speed client-side proving while keeping on-chain data to a minimum. -Unlike traditional rollups that post extensive transaction data to L1, Plasma Fold operates using a *minimal data availability* model inspired by Intmax, where only essential metadata—like tree roots and signer indices—are recorded onchain. Validity is ensured through user-generated proofs, making this model far more efficient for resource-constrained environments. +Unlike traditional rollups that post extensive transaction data to L1, Plasma Fold operates using a _minimal data availability_ model inspired by Intmax, where only essential metadata—like tree roots and signer indices—are recorded onchain. Validity is ensured through user-generated proofs, making this model far more efficient for resource-constrained environments. ## Why Plasma Fold? -Most L2s today struggle to scale without relying on increasingly expensive data availability solutions (e.g., blobs). Plasma Fold offers a low-cost, high-throughput alternative. Inspired by Vitalik Buterin’s vision of a Plasma-EVM hybrid, Plasma Fold explores the use of folding schemes to support lightweight client-side proving—ideal for mobile or browser-based clients. In theory, this architecture could enable transaction rates in the range of 90k–260k TPS, matching or exceeding centralized systems like VISA. +Most L2s today struggle to scale without relying on increasingly expensive data availability solutions (e.g., blobs). Plasma Fold offers a low-cost, high-throughput alternative. Inspired by Vitalik Buterin's vision of a Plasma-EVM hybrid, Plasma Fold explores the use of folding schemes to support lightweight client-side proving—ideal for mobile or browser-based clients. In theory, this architecture could enable transaction rates in the range of 90k–260k TPS, matching or exceeding centralized systems like VISA. ## Key Innovations @@ -43,7 +52,7 @@ Most L2s today struggle to scale without relying on increasingly expensive data - **Q2 2025:** Initial circuit design and benchmarks against Plonky2 - **Q2–Q3 2025:** Drafting formal paper; collaborative review with Intmax -- **Q3 2025:** Reference implementation using Sonobe’s Nova-based tooling +- **Q3 2025:** Reference implementation using Sonobe's Nova-based tooling - **Beyond:** Explore multi-asset support, privacy enhancements, and programmability ## Learn More @@ -54,32 +63,3 @@ Most L2s today struggle to scale without relying on increasingly expensive data ## Get Involved Join the conversation on [PSE Discord](https://discord.com/invite/sF5CT5rzrR) - `, - }, - }, - team: [ - { - name: "Pierre Daix-Moreux", - email: "pierre@pse.dev", - links: { - twitter: "https://twitter.com/xyz_pierre", - }, - }, - { - name: "Chengru Zhang", - email: "winderica@pse.dev", - }, - ], - tags: { - keywords: [ - "plasma", - "folding schemes", - "Ethereum", - "scalability", - "L2", - "zero-knowledge proofs", - ], - themes: ["scalability", "L2 solutions", "zk proofs"], - types: ["research", "development"], - }, -} diff --git a/content/projects/pod2.md b/content/projects/pod2.md new file mode 100644 index 0000000..cdb8cf7 --- /dev/null +++ b/content/projects/pod2.md @@ -0,0 +1,42 @@ +--- +id: "pod2" +name: "POD2" +image: "pod2.png" +section: "collaboration" +projectStatus: "active" +category: "devtools" +tldr: "The second generation of cryptographic PODs: Provable Data Objects" +tags: + keywords: + ["anonymity/privacy", "data portability", "social", "identity", "toolkits"] + builtWith: ["Rust", "Plonky2", "Groth16", "Typescript"] + themes: ["build", "research"] +links: + github: "https://github.com/0xPARC/pod2" + website: "https://pod.org" + telegram: "https://t.me/zupass" +team: + - name: "Edu" + image: "/avatars/edu.jpeg" + links: + github: "https://github.com/ed255" +extraLinks: + buildWith: + - label: "PODify your proofs" + url: "https://pod.org/pod/introduction" + - label: "Config-driven proofs" + url: "https://pod.org/gpc/introduction" + - label: "Create and consume PODs in your web app" + url: "https://pod.org/z-api/introduction" + - label: "POD book (evolving)" + url: "https://0xparc.github.io/pod2/introduction.html" + research: + - label: "State of POD R&D" + url: "https://github.com/0xPARC/pod2/milestones" + - label: "Ideation on a logic VM for PODs" + url: "https://hackmd.io/@gubsheep/r1zxZGpQke" +--- + +POD2 is the next iteration of the Provable Object Datatype (POD). This new iteration introduces arbitrary computation on data via custom predicates, recursion and interoperability with other data provenance cryptographic tools. + +This is a 0xPARC project that PSE is collaborating on. diff --git a/content/projects/pollen-labs.md b/content/projects/pollen-labs.md new file mode 100644 index 0000000..fca82e2 --- /dev/null +++ b/content/projects/pollen-labs.md @@ -0,0 +1,34 @@ +--- +id: "pollen-labs" +name: "Pollen Labs" +image: "pollen-labs.svg" +section: "archived" +projectStatus: "inactive" +category: "application" +tldr: "Building a better world through open-source & blockchain technology." +tags: + keywords: ["Anonymity/privacy", "Scaling", "Public good"] + themes: ["play"] + types: ["Application"] + builtWith: [] +links: + website: "https://pollenlabs.org/" + twitter: "https://twitter.com/PollenLabs_" + discord: "https://discord.gg/5B3jP2sgWS" +--- + +Pollen Labs is driven by a mission to make a significant impact on global lives by addressing complex, pressing issues. We work alongside the community to break barriers, preserve privacy, and build a future where every voice is heard, and a free web is accessible to all. Our projects, like Channel 4, a content discovery engine, and Daisy, focusing on information transparency, embody this mission, enabling community members to earn while they engage. + +We are a small team with a diverse skillset including design, engineering, community growth, and operations. We serve as a product accelerator, facilitating solutions to real-world problems with advanced blockchain technology. Our core value as follow: + +- **A Decentralized Internet for All** + +- **Open Source at Our Core** + +- **Technology as Public Goods** + +- **Privacy as a Human Right** + +- **Collaboration for Impact** + +Pollen Labs exits the PSE in Q4 2024 and now operates as a self-autonomous collective. Join our conversation: https://discord.gg/5B3jP2sgWS diff --git a/data/projects/post-quantum-cryptography.ts b/content/projects/post-quantum-cryptography.md similarity index 78% rename from data/projects/post-quantum-cryptography.ts rename to content/projects/post-quantum-cryptography.md index 7665397..3c648a5 100644 --- a/data/projects/post-quantum-cryptography.ts +++ b/content/projects/post-quantum-cryptography.md @@ -1,16 +1,19 @@ -import { ProjectCategory, ProjectInterface, ProjectStatus } from "@/lib/types" +--- +id: "post-quantum-cryptography" +name: "Post-Quantum Cryptography and Ethereum" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "Ensuring Ethereum's cryptographic security against future quantum threats." +tags: + keywords: + ["post-quantum cryptography", "Ethereum", "security", "cryptography"] + themes: ["cryptography", "security"] + types: ["research", "development"] + builtWith: ["ECC", "PQC", "zero-knowledge proofs"] +--- -export const postQuantumCryptography: ProjectInterface = { - id: "post-quantum-cryptography", - image: "", - name: "Post-Quantum Cryptography and Ethereum", - category: ProjectCategory.RESEARCH, - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - content: { - en: { - tldr: "Ensuring Ethereum's cryptographic security against future quantum threats.", - description: ` Post-quantum cryptography (PQC) is crucial for securing digital communication against future quantum computers, which threaten to break widely used cryptographic schemes such as RSA, ECC, and DSA. A smooth transition to PQC requires careful consideration of performance trade-offs, compatibility with existing protocols, and resilience against potential future attacks. ### The Importance of PQC for Ethereum @@ -35,6 +38,7 @@ Traditional cryptography relied on ECC, which enables various cryptographic prim - Isogeny-based cryptography ### Publications + - Post Quantum signature aggregation with Falcon and LaBRADOR ([ethresear.ch post](https://pse.dev/en/blog/post-quantum-signature-aggregation-with-falcon-and-LaBRADOR)) - Are elliptic curves going to survive the quantum apocalypse? ([blogpost](https://pse.dev/en/blog/are-elliptic-curves-going-to-survive-the-quantum-apocalypse)) - Post quantum TXs in The Verge ([ethresear.ch post](https://ethresear.ch/t/post-quantum-txs-in-the-verge/21763)) @@ -42,18 +46,3 @@ Traditional cryptography relied on ECC, which enables various cryptographic prim ### Our Commitment to PQC at PSE At PSE, we are committed to staying at the forefront of the rapidly evolving field of PQC by continuously following, testing, and optimizing the latest advancements. Our goal is to ensure that the Ethereum ecosystem is well-prepared for the challenges and opportunities that come with the transition to quantum-safe systems. - `, - }, - }, - tags: { - keywords: [ - "post-quantum cryptography", - "Ethereum", - "security", - "cryptography", - ], - themes: ["cryptography", "security"], - types: ["research", "development"], - builtWith: ["ECC", "PQC", "zero-knowledge proofs"], - }, -} diff --git a/data/projects/powers-of-tau.ts b/content/projects/powers-of-tau.md similarity index 50% rename from data/projects/powers-of-tau.ts rename to content/projects/powers-of-tau.md index c7e12e1..d29a7f8 100644 --- a/data/projects/powers-of-tau.ts +++ b/content/projects/powers-of-tau.md @@ -1,46 +1,26 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "powers-of-tau" +name: "Perpetual Powers of Tau" +image: "powers-of-tau.png" +section: "archived" +projectStatus: "maintained" +category: "devtools" +tldr: "An ongoing (since 2019) zk-SNARK trusted setup ceremony for circuits up to 2^28 constraints." +tags: + keywords: ["scaling"] +links: + github: "https://github.com/privacy-scaling-explorations/perpetualpowersoftau" + website: "https://perpetualpowersoftau.com/" +extraLinks: + learn: + - label: "Announcing the Perpetual Powers of Tau Ceremony" + url: "https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377" +--- -const content: ProjectContent = { - en: { - tldr: "An ongoing (since 2019) zk-SNARK trusted setup ceremony for circuits up to 2^28 constraints.", - description: ` ### Overview The Perpetual Powers of Tau is a multi-party trusted setup ceremony, rooted in the Zcash Powers of Tau. Its primary objective is the secure generation of zk-SNARK parameters for circuits accommodating up to 2^28 (260+ million) constraints. This translates to the creation of over 530 million powers of tau. The ceremony's integrity hinges on the principle that as long as one participant acts honestly and remains uncompromised, the entire setup remains trustworthy. It's a pivotal step for zk-SNARK projects, ensuring the security and privacy of the system. Those who can handle a 100Gb download and many hours of compute time are invited to join by contacting [@nicoserranop on Twitter](https://twitter.com/NicoSerranoP) or Telegram, or asking questions via the PSE [Discord](https://discord.com/invite/sF5CT5rzrR). ### Status -This project is entering a long term support phase. The ceremony is ongoing and accepting new participants. There are no further development plans for the project. - `, - }, -} -export const PerpetualPowersOfTau: ProjectInterface = { - id: "powers-of-tau", - category: ProjectCategory.DEVTOOLS, - image: "powers-of-tau.png", - name: "Perpetual Powers of Tau", - projectStatus: ProjectStatus.MAINTAINED, - section: "archived", - content, - tags: { - keywords: ["scaling"], - }, - links: { - github: - "https://github.com/privacy-scaling-explorations/perpetualpowersoftau", - website: "https://perpetualpowersoftau.com/", - }, - extraLinks: { - learn: [ - { - label: "Announcing the Perpetual Powers of Tau Ceremony", - url: "https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377", - }, - ], - }, -} +This project is entering a long term support phase. The ceremony is ongoing and accepting new participants. There are no further development plans for the project. diff --git a/data/projects/private-proof-delegation.ts b/content/projects/private-proof-delegation.md similarity index 74% rename from data/projects/private-proof-delegation.ts rename to content/projects/private-proof-delegation.md index 4300713..c7b33f4 100644 --- a/data/projects/private-proof-delegation.ts +++ b/content/projects/private-proof-delegation.md @@ -1,17 +1,22 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "private-proof-delegation" +name: "Private proof delegation" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "Private Delegated Proving aims to unlock efficient zero-knowledge proof (ZKP) generation for resource-constrained clients such as mobile phones, without compromising privacy." +tags: + keywords: ["fhe", "zkp", "tee"] + themes: ["research"] +links: + github: "https://github.com/privacy-scaling-explorations/private-proof-delegation-docs" +--- -const content: ProjectContent = { - en: { - tldr: "Private Delegated Proving aims to unlock efficient zero-knowledge proof (ZKP) generation for resource-constrained clients such as mobile phones, without compromising privacy.", - description: ` # Private Delegated Proving ## Project Overview + Private Delegated Proving aims to unlock efficient zero-knowledge proof (ZKP) generation for resource-constrained clients such as mobile phones, without compromising privacy. The project explores how clients can securely delegate proof generation to external servers—be they trusted hardware, distributed MPC setups, or FHE —while keeping sensitive data protected. By focusing on delegation frameworks that avoid trust assumptions or excessive overhead, the project paves the way for scalable, privacy-preserving applications that are accessible to everyday users. @@ -25,7 +30,7 @@ The goal is to explore the space and potentially develop a practical, trust-mini - Exploring new polynomial commitment schemes (PCS) that are FHE-compatible. - Reducing client-side costs via packing, modulus switching, and interaction design. -Ultimately, the project seeks to identify viable building blocks for a future where client-side privacy doesn’t require massive compute or trusted intermediaries. +Ultimately, the project seeks to identify viable building blocks for a future where client-side privacy doesn't require massive compute or trusted intermediaries. ## Project Status @@ -71,39 +76,5 @@ Private Delegated Proving has potential to reshape the user experience and archi ## Contact - **Takamichi Tsutsumi:** [tkmct@pse.dev](mailto:tkmct@pse.dev) -- **Join the conversation:** on [PSE Discord](https://discord.com/invite/sF5CT5rzrR)`, - }, -} - -export const privateProofDelegation: ProjectInterface = { - id: "private-proof-delegation", - category: ProjectCategory.RESEARCH, - projectStatus: ProjectStatus.ACTIVE, - section: "pse", - content, - image: "", - imageAlt: "Private proof delegation", - name: "Private proof delegation", - team: [ - { - name: "Takamichi Tsutsumi", - email: "tkmct@pse.dev", - }, - { - name: "Wanseob Lim", - email: "wanseob@pse.dev", - }, - { - name: "Shouki Tsuda", - email: "shouki@pse.dev", - }, - ], - links: { - github: - "https://github.com/privacy-scaling-explorations/private-proof-delegation-docs", - }, - tags: { - keywords: ["fhe", "zkp", "tee"], - themes: ["research"], - }, -} +- **Wanseob Lim:** [wanseob@pse.dev](mailto:wanseob@pse.dev) +- **Join the conversation:** on [PSE Discord](https://discord.com/invite/sF5CT5rzrR) diff --git a/content/projects/pse-halo2.md b/content/projects/pse-halo2.md new file mode 100644 index 0000000..210f40b --- /dev/null +++ b/content/projects/pse-halo2.md @@ -0,0 +1,28 @@ +--- +id: "pse-halo2" +name: "PSE-Halo2" +image: "" +section: "pse" +projectStatus: "maintained" +tldr: "PSE-Halo2 is a re-architected, KZG-backended fork of Zcash's Halo2, an instantiation of PLONK, with support for more curves and other features." +tags: + keywords: ["Proof Systems", "PLONK", "KZG", "Halo2"] + themes: ["build"] + types: ["Infrastructure/protocol", "Lego sets/toolkits"] + builtWith: ["halo2", "rust"] +links: + github: "https://github.com/privacy-scaling-explorations/halo2" + website: "https://privacy-scaling-explorations.github.io/halo2/" +extraLinks: + learn: + - label: "Documentation" + url: "https://privacy-scaling-explorations.github.io/halo2/" + - label: "PLONK" + url: "https://www.youtube.com/watch?v=A0oZVEXav24" + - label: "Origins of Halo2" + url: "https://www.youtube.com/watch?v=KdkVTEHUxgo" +--- + +PSE-Halo2 modified, extended, and eventually [re-architected](https://github.com/privacy-scaling-explorations/halo2/pull/254) the [original Halo2 implementation by Zcash](https://github.com/zcash/halo2) - an instantiation of the PLONK proof system. + +The original IPA backend was swapped with KZG for cost-effective L1 verifiability, and comes with a Solidity verifier. Support for many [additional curves](https://github.com/privacy-scaling-explorations/halo2curves) and other [experimental features](https://github.com/kilic/tetris) were added, and the system was eventually re-architected by [splitting the front- and backends](https://github.com/privacy-scaling-explorations/halo2/pull/254). PSE-Halo2 has significant contributions from the wider community. diff --git a/content/projects/pse-security.md b/content/projects/pse-security.md new file mode 100644 index 0000000..308ae77 --- /dev/null +++ b/content/projects/pse-security.md @@ -0,0 +1,19 @@ +--- +id: "pse-security" +name: "PSE Security" +image: "pse-security.png" +section: "pse" +projectStatus: "inactive" +category: "research" +tldr: "Proactively securing Ethereum's L2 and ZK ecosystems." +tags: + keywords: + ["Anonymity/privacy", "Education", "Key management", "Scaling", "Security"] + themes: ["build"] + types: ["Legos/dev tools"] + builtWith: ["slither", "ecne", "circomspect", "echidna"] +links: + github: "https://github.com/privacy-scaling-explorations/security" +--- + +PSE Security is a division of the Privacy & Scaling Explorations team at the Ethereum Foundation. Its primary goal is to identify and rectify bugs, thereby enhancing the security of the Ethereum Layer 2 and Zero-Knowledge ecosystems. Recognizing the potential for critical bugs to cause significant setbacks, PSE Security is committed to preemptively addressing these issues. The team offers open-source projects like the ZK Bug Tracker and Bridge Bug Tracker, which track real bugs and exploits in production code, and encourages community contributions. PSE Security also conducts manual audits and plans to help teach the community more about security and ways they can prevent bugs themselves. diff --git a/content/projects/publicly-verifiable-garbled-circuit.md b/content/projects/publicly-verifiable-garbled-circuit.md new file mode 100644 index 0000000..3841f2d --- /dev/null +++ b/content/projects/publicly-verifiable-garbled-circuit.md @@ -0,0 +1,18 @@ +--- +id: "publicly-verifiable-garbled-circuit" +name: "Publicly verifiable garbled circuit" +image: "" +section: "pse" +projectStatus: "inactive" +category: "research" +tldr: "Publicly verifiable garbled circuit research" +tags: + keywords: ["mpc", "garbled circuit", "zkp"] + themes: ["research"] +links: + website: "https://hackmd.io/bPUw6M9qSL-AyE19A58tMw" +--- + +We are actively researching on publicly verifiable garbled circuit. This will lead to constant round publicly verifiable 2 party computation. Currently we're exploring two ways to achieve this. The first approach is based on authenticated garbling and vector OLE and the second approach is based on committed OT and zkp. + +See more details [here](https://hackmd.io/bPUw6M9qSL-AyE19A58tMw). diff --git a/data/projects/rln.ts b/content/projects/rln.md similarity index 50% rename from data/projects/rln.ts rename to content/projects/rln.md index 1217ae8..d73c23c 100644 --- a/data/projects/rln.ts +++ b/content/projects/rln.md @@ -1,35 +1,19 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "rln" +name: "Rate-Limiting Nullifier" +image: "rln.svg" +section: "pse" +projectStatus: "inactive" +category: "devtools" +tldr: "A protocol for deterring spam and maintaining anonymity in communication systems." +tags: + keywords: ["Anonymity/privacy"] + themes: ["build"] + types: ["Infrastructure/protocol"] + builtWith: ["circom", "solidity", "semaphore"] +links: + github: "https://github.com/Rate-Limiting-Nullifier/circom-rln" + website: "https://rate-limiting-nullifier.github.io/rln-docs/" +--- -const content: ProjectContent = { - en: { - tldr: "A protocol for deterring spam and maintaining anonymity in communication systems.", - description: ` Rate-Limiting Nullifier (RLN) is a protocol designed to combat spam and denial of service attacks in privacy-preserving environments. It allows users in an anonymous system to penalize those who exceed the rate limit, either by withdrawing the offender's stake or revealing their secrets. This mechanism helps maintain system integrity and deters abuse. RLN is built on the Semaphore protocol and uses zero-knowledge proofs and the Shamir's Secret Sharing scheme to reveal the spammer's private key. It's particularly useful for developers working on communication systems that require privacy and anonymity, such as chat apps, client-server communications, and peer-to-peer communications. It's already being used in projects like Zerokit and Waku, and is also being developed for use with the KZG polynomial commitment scheme. -`, - }, -} - -export const rln: ProjectInterface = { - id: "rln", - content, - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - image: "rln.svg", - name: "Rate-Limiting Nullifier", - links: { - github: "https://github.com/Rate-Limiting-Nullifier/circom-rln", - website: "https://rate-limiting-nullifier.github.io/rln-docs/", - }, - tags: { - keywords: ["Anonymity/privacy"], - themes: ["build"], - types: ["Infrastructure/protocol"], - builtWith: ["circom", "solidity", "semaphore"], - }, -} diff --git a/content/projects/scaling-semaphore.md b/content/projects/scaling-semaphore.md new file mode 100644 index 0000000..021e51f --- /dev/null +++ b/content/projects/scaling-semaphore.md @@ -0,0 +1,49 @@ +--- +id: "scaling-semaphore" +name: "Scaling Semaphore" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "A scalable implementation of the Semaphore protocol" +tags: + keywords: ["Privacy", "Scaling", "Zero Knowledge", "Semaphore"] + themes: ["privacy", "scalability"] + types: ["research", "development"] +links: + github: "https://github.com/semaphore-protocol" + website: "https://semaphore.pse.dev/" +--- + +### Scaling Semaphore + +The Scaling Semaphore project focuses on developing a scalable implementation of the Semaphore protocol, a zero-knowledge protocol for anonymous signaling and voting. This initiative addresses the growing need for privacy-preserving systems that can handle large-scale applications while maintaining security and performance. + +### Key Features + +- **Enhanced Scalability**: Optimized implementations that can handle thousands of users simultaneously +- **Privacy-First**: Maintains the core privacy guarantees of the Semaphore protocol +- **Zero-Knowledge Proofs**: Utilizes advanced cryptographic techniques for anonymous verification +- **Production-Ready**: Built for real-world deployment scenarios + +### Technical Approach + +The project implements various optimization techniques to improve the performance and scalability of Semaphore: + +- Efficient Merkle tree operations +- Optimized zero-knowledge circuits +- Batch processing capabilities +- Memory-efficient proof generation + +### Applications + +Scaling Semaphore enables various use cases including: + +- Large-scale anonymous voting systems +- Privacy-preserving surveys and polls +- Anonymous feedback collection +- Decentralized governance applications + +### Resources + +For more information about the Semaphore protocol and its scaling implementations, visit the official documentation and GitHub repositories. diff --git a/data/projects/semaphore.ts b/content/projects/semaphore.md similarity index 55% rename from data/projects/semaphore.ts rename to content/projects/semaphore.md index 0a1e8dc..5105748 100644 --- a/data/projects/semaphore.ts +++ b/content/projects/semaphore.md @@ -1,14 +1,56 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "semaphore" +name: "Semaphore" +image: "semaphore.webp" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "A zero-knowledge protocol for anonymous interactions." +previousBrandImage: "semaphorePrevious.jpg" +license: "MIT" +tags: + keywords: + [ + "Anonymity/privacy", + "Social", + "Identity", + "Transaction privacy", + "Voting/governance", + "Reputation", + "Education", + "Scaling", + "Key management", + "Other (group membership)", + ] + themes: ["build"] + types: ["Legos/dev tools", "Lego sets/toolkits", "Infrastructure/protocol"] + builtWith: ["zk-kit", "circom", "snarkjs"] +links: + github: "https://github.com/semaphore-protocol" + website: "https://semaphore.pse.dev/" + telegram: "https://semaphore.pse.dev/telegram" + twitter: "https://semaphore.pse.dev/x" +extraLinks: + play: + - label: "Semaphore Demo" + url: "https://demo.semaphore.pse.dev/" + buildWith: + - label: "Semaphore CLI (Getting Started)" + url: "https://docs.semaphore.pse.dev/getting-started" + - label: "Semaphore JS libraries" + url: "https://docs.semaphore.pse.dev/guides/identities" + - label: "Semaphore Boilerplate" + url: "https://github.com/semaphore-protocol/boilerplate" + learn: + - label: "Semaphore Website" + url: "https://semaphore.pse.dev" + - label: "Semaphore Documentation" + url: "https://docs.semaphore.pse.dev" + - label: "Semaphore Board" + url: "https://github.com/orgs/semaphore-protocol/projects/10/views/1" +--- -const content: ProjectContent = { - en: { - tldr: "A zero-knowledge protocol for anonymous interactions.", - description: `### Overview +### Overview [Semaphore](https://semaphore.pse.dev/) is a generic privacy layer. Leveraging zero-knowledge technology, users can prove their membership in groups and send messages (extending from votes to endorsements) off-chain or across EVM-compatible blockchains, all without revealing their personal identity. Use cases include private voting, whistleblowing, anonymous DAOs, and mixers. @@ -31,86 +73,13 @@ When a user broadcasts a message, Semaphore zero-knowledge proofs can ensure tha ### Ways to contribute -* Submit your idea to PSE's [acceleration program](https://github.com/privacy-scaling-explorations/acceleration-program) (check out this [discussion](https://github.com/orgs/semaphore-protocol/discussions/463) for potential ideas). -* Work on [open issues](https://github.com/semaphore-protocol/semaphore/contribute) -* Suggest new terms for our [glossary](https://semaphore.pse.dev/docs/glossary) ([website-issue](https://github.com/semaphore-protocol/website/issues/new?assignees=&labels=documentation&template=---glossary-term.md&title=)) -* Propose new networks for our [deployed contracts](https://semaphore.pse.dev/docs/deployed-contracts) ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=&template=----network.md&title=)) -* Suggest new developer tools ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=feature+%3Arocket%3A&template=---package.md&title=)) -* Share your Semaphore project with us ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=documentation++%F0%9F%93%96&template=----project.md&title=)) -* Share ideas for new features ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=feature+%3Arocket%3A&template=---feature.md&title=)) -* Create a report if you find any bugs in the code ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=bug+%F0%9F%90%9B&template=---bug.md&title=)) +- Submit your idea to PSE's [acceleration program](https://github.com/privacy-scaling-explorations/acceleration-program) (check out this [discussion](https://github.com/orgs/semaphore-protocol/discussions/463) for potential ideas). +- Work on [open issues](https://github.com/semaphore-protocol/semaphore/contribute) +- Suggest new terms for our [glossary](https://semaphore.pse.dev/docs/glossary) ([website-issue](https://github.com/semaphore-protocol/website/issues/new?assignees=&labels=documentation&template=---glossary-term.md&title=)) +- Propose new networks for our [deployed contracts](https://semaphore.pse.dev/docs/deployed-contracts) ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=&template=----network.md&title=)) +- Suggest new developer tools ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=feature+%3Arocket%3A&template=---package.md&title=)) +- Share your Semaphore project with us ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=documentation++%F0%9F%93%96&template=----project.md&title=)) +- Share ideas for new features ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=feature+%3Arocket%3A&template=---feature.md&title=)) +- Create a report if you find any bugs in the code ([semaphore-issue](https://github.com/semaphore-protocol/semaphore/issues/new?assignees=&labels=bug+%F0%9F%90%9B&template=---bug.md&title=)) -As a Semaphore contributor, you'll be able to claim a special GitPOAP per year 🏅`, - }, -} - -export const semaphore: ProjectInterface = { - id: "semaphore", - category: ProjectCategory.DEVTOOLS, - projectStatus: ProjectStatus.ACTIVE, - section: "pse", - content, - image: "semaphore.webp", - previousBrandImage: "semaphorePrevious.jpg", - license: "MIT", - name: "Semaphore", - links: { - github: "https://github.com/semaphore-protocol", - website: "https://semaphore.pse.dev/", - telegram: "https://semaphore.pse.dev/telegram", - twitter: "https://semaphore.pse.dev/x", - }, - tags: { - keywords: [ - "Anonymity/privacy", - "Social", - "Identity", - "Transaction privacy", - "Voting/governance", - "Reputation", - "Education", - "Scaling", - "Key management", - "Other (group membership)", - ], - themes: ["build"], - types: ["Legos/dev tools", "Lego sets/toolkits", "Infrastructure/protocol"], - builtWith: ["zk-kit", "circom", "snarkjs"], - }, - extraLinks: { - play: [ - { - label: "Semaphore Demo", - url: "https://demo.semaphore.pse.dev/", - }, - ], - buildWith: [ - { - label: "Semaphore CLI (Getting Started)", - url: "https://docs.semaphore.pse.dev/getting-started", - }, - { - label: "Semaphore JS libraries", - url: "https://docs.semaphore.pse.dev/guides/identities", - }, - { - label: "Semaphore Boilerplate", - url: "https://github.com/semaphore-protocol/boilerplate", - }, - ], - learn: [ - { - label: "Semaphore Website", - url: "https://semaphore.pse.dev", - }, - { - label: "Semaphore Documentation", - url: "https://docs.semaphore.pse.dev", - }, - { - label: "Semaphore Board", - url: "https://github.com/orgs/semaphore-protocol/projects/10/views/1", - }, - ], - }, -} +As a Semaphore contributor, you'll be able to claim a special GitPOAP per year 🏅 diff --git a/content/projects/sonobe.md b/content/projects/sonobe.md new file mode 100644 index 0000000..1d32f48 --- /dev/null +++ b/content/projects/sonobe.md @@ -0,0 +1,42 @@ +--- +id: "sonobe" +name: "Sonobe Folding Library" +image: "sonobe.png" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "Modular folding library supporting multiple schemes and decider backends" +tags: + keywords: ["Folding", "IVC"] + themes: ["build"] + types: ["Infrastructure/protocol", "Lego sets/toolkits"] + builtWith: ["rust"] +links: + github: "https://github.com/privacy-scaling-explorations/sonobe" + website: "https://privacy-scaling-explorations.github.io/sonobe-docs" +--- + +In collaboration with [0xPARC](https://0xparc.org), [Sonobe](https://github.com/privacy-scaling-explorations/sonobe) is a modular library to fold arithmetic circuit instances in an Incremental Verifiable computation (IVC) style. It supports multiple frontends, multiple folding schemes, and multiple decider backends, allowing users to plug-and-play different components. + +- **Frontends:** + - Arkworks + - Circom + - Noir + - Noname +- **Folding schemes:** + - [Nova](https://eprint.iacr.org/2021/370), supporting also both the [Mova](https://eprint.iacr.org/2024/1220) & [Ova](https://hackmd.io/V4838nnlRKal9ZiTHiGYzw) variants. + - [CycleFold](https://eprint.iacr.org/2023/1192) + - [HyperNova](https://eprint.iacr.org/2023/573) + - [ProtoGalaxy](https://eprint.iacr.org/2023/1106) +- **Decider backends:** + + - Groth16 and KZG commitment [proofs](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/decider-prove.html) which are [verifiable on-chain](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/solidity-verifier.html). + +- **Other features:** + + - [ZK Layer](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/nova-zk.html) + - In-browser [WASM usage](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/wasm.html) + +- **Example projects:** + - [Bitcoin light client](https://github.com/dmpierre/sonobe-btc) leveraging Sonobe + - [Hash chains](https://github.com/arnaucube/hash-chain-sonobe): proving chains of Sha256 and Keccak256 hashes diff --git a/content/projects/summa.md b/content/projects/summa.md new file mode 100644 index 0000000..40fef6a --- /dev/null +++ b/content/projects/summa.md @@ -0,0 +1,22 @@ +--- +id: "summa" +name: "Summa" +image: "summa.svg" +section: "pse" +projectStatus: "inactive" +category: "devtools" +tldr: "Protocol enabling centralized exchanges to prove solvency without compromising private information." +tags: + keywords: ["Anonymity/privacy", "Computational Integrity"] + themes: ["build", "play"] + types: ["Infrastructure/protocol", "Application"] + builtWith: ["halo2"] +links: + github: "https://github.com/summa-dev" +extraLinks: + learn: + - label: "Documentation" + url: "https://summa.gitbook.io/summa" +--- + +Summa allows centralized exchanges to demonstrate that their assets exceed their liabilities without revealing critical business information such as individual user balances, total number of users, and total liabilities or assets. It uses zero-knowledge proofs to ensure that exchanges can demonstrate they have sufficient assets to cover all user balances. The protocol involves building a Merkle Sum Tree of user balances, generating proofs for each user, and allowing users to verify these proofs. diff --git a/content/projects/tlsn.md b/content/projects/tlsn.md new file mode 100644 index 0000000..57c4be0 --- /dev/null +++ b/content/projects/tlsn.md @@ -0,0 +1,32 @@ +--- +id: "tlsn" +name: "TLSNotary" +image: "tlsn.webp" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "A protocol for creating cryptographic proofs of authenticity for any data on the web." +license: "MIT or Apache-2.0" +tags: + themes: ["build", "play"] + types: ["Legos/dev tools", "Infrastructure/protocol", "Plugin", "Application"] + builtWith: ["rust"] + keywords: + ["Anonymity/privacy", "Identity", "Reputation", "Data portability", "zkTLS"] +links: + github: "https://github.com/tlsnotary" + website: "https://tlsnotary.org/" + discord: "https://discord.gg/9XwESXtcN7" + twitter: "https://x.com/tlsnotary" +extraLinks: + play: + - label: "Getting started" + url: "https://tlsnotary.org/docs/quick_start/" + learn: + - label: "Documentation" + url: "https://tlsnotary.org/docs" +--- + +TLSNotary is ideal for developers of privacy-focused projects that require **data provenance** from secure web servers. It leverages the widely-used **Transport Layer Security (TLS)** protocol to securely and privately prove that a transcript of communications with a web server took place. The protocol divides TLS session keys between two parties: the Prover and the Verifier, using **Multi-Party Computation (MPC)**. Neither the User nor Notary are in possession of the full TLS session keys, they only hold a share of those keys. This retains the security assumptions of TLS while allowing the Prover to demonstrate the **authenticity of the communication** to the Verifier. The Verifier remains unaware of which webserver is being queried, and the Verifier never has access to the unencrypted communications, except for the data the Prover explicitly wants to disclose. + +**TLSNotary can help your project with secure and privacy-preserving data portability!** diff --git a/data/projects/trusted-setups.ts b/content/projects/trusted-setups.md similarity index 72% rename from data/projects/trusted-setups.ts rename to content/projects/trusted-setups.md index 08a79c4..eb6997a 100644 --- a/data/projects/trusted-setups.ts +++ b/content/projects/trusted-setups.md @@ -1,18 +1,26 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "trusted-setups" +name: "Trusted Setups" +image: "trusted-setups.svg" +section: "archived" +projectStatus: "inactive" +category: "devtools" +tldr: "Aiding developers with tools for trusted setups." +tags: + themes: ["play"] + types: ["Legos/dev tools", "Lego sets/toolkits"] + builtWith: [] + keywords: ["Scaling", "Education"] +links: + github: "https://github.com/zkparty" +--- -const content: ProjectContent = { - en: { - tldr: "Aiding developers with tools for trusted setups.", - description: ` ### Overview + The Trusted Setups project is dedicated to simplifying the process of trusted setups, which are crucial for privacy or scaling solutions. Trusted setups involve multiple participants contributing to the generation of secrets. As long as one participant forgets their part of the secret, the final solution remains secure. The team recognizes the complexity of developing contribution programs and coordinating the participants' queue in a trusted setup. To address this, they are developing tools, including scripts, WebApps, and APIs, to streamline the contribution and coordination effort. This allows developers to focus on building their circuits and applications, enhancing efficiency and productivity in the development of zero-knowledge applications. ### Status + This project has been sunset and there will be no further development. The tools and resources developed are available under no warranty and are provided as-is. We believe they are enough for developers to run their trusted setups on their own. The team encourages the community to fork and continue the development of these tools. ### Resources @@ -21,25 +29,3 @@ This project has been sunset and there will be no further development. The tools - **DefinitelySetup WebApp**: A WebApp to monitor and contribute to trusted setups - [Website](https://ceremony.pse.dev/) | [GitHub](https://github.com/privacy-scaling-explorations/DefinitelySetup) - **KZG WebApp**: A WebApp used to contributed to the KZG Ceremony - [Website](https://ceremony.ethereum.org/) | [GitHub](https://github.com/zkparty/trusted-setup-frontend) - **Perpetual Powers of Tau**: A phase 1 ceremony to generate Powers of Tau - [GitHub](https://github.com/privacy-scaling-explorations/perpetualpowersoftau) - `, - }, -} - -export const trustedSetups: ProjectInterface = { - id: "trusted-setups", - category: ProjectCategory.DEVTOOLS, - projectStatus: ProjectStatus.INACTIVE, - section: "archived", - content, - image: "trusted-setups.svg", - name: "Trusted Setups", - links: { - github: "https://github.com/zkparty", - }, - tags: { - themes: ["play"], - types: ["Legos/dev tools", "Lego sets/toolkits"], - builtWith: [], - keywords: ["Scaling", "Education"], - }, -} diff --git a/data/projects/unirep-protocol.ts b/content/projects/unirep-protocol.md similarity index 66% rename from data/projects/unirep-protocol.ts rename to content/projects/unirep-protocol.md index 410c270..f983446 100644 --- a/data/projects/unirep-protocol.ts +++ b/content/projects/unirep-protocol.md @@ -1,14 +1,34 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "unirep-protocol" +name: "UniRep Protocol" +image: "unirep.svg" +section: "archived" +projectStatus: "inactive" +category: "application" +tldr: "A Zero-Knowledge Protocol built to handle anonymous user data." +license: "MIT" +previousBrandImage: "unirep-previousBrand.png" +tags: + keywords: ["Anonymity/privacy", "Social", "Identity", "Reputation"] + themes: ["build", "play"] + types: ["Legos/dev tools, Protocol"] + builtWith: ["semaphore", "circom"] +links: + github: "https://github.com/Unirep" + website: "https://developer.unirep.io/docs/welcome" + twitter: "https://twitter.com/UniRep_Protocol" + discord: "https://discord.gg/VzMMDJmYc5" +extraLinks: + buildWith: + - label: "Getting Started with create-unirep-app" + url: "https://developer.unirep.io/docs/next/getting-started/create-unirep-app" + play: + - label: "Try it out: UniRep.social (Staging)" + url: "https://social-staging.unirep.workers.dev" + - label: "Try it out: Trustlist (coming soon) " + url: "https://trustlist.pse.dev" +--- -const content: ProjectContent = { - en: { - tldr: "A Zero-Knowledge Protocol built to handle anonymous user data.", - description: ` ### Overview UniRep is a zero-knowledge protocol that securely manages user data through anonymous identifiers, enabling trustless interactions and enhanced user privacy in applications. UniRep expands the notion of reputation to include various user data aspects, such as preferences, activity, alignments, and ownership. @@ -37,48 +57,3 @@ Key UniRep features include: - Sacred Protocol - [Website](https://www.sacredprotocol.com/) - My-Badge - [GitHub](https://github.com/kittybest/my-badge) - Voteathon - [Website](https://voteathon.org/) | [GitHub](https://github.com/NicoSerranoP/voteathon) -`, - }, -} - -export const unirepProtocol: ProjectInterface = { - id: "unirep-protocol", - content, - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.APPLICATION, - section: "archived", - image: "unirep.svg", - license: "MIT", - previousBrandImage: "unirep-previousBrand.png", - name: "UniRep Protocol", - links: { - github: "https://github.com/Unirep", - website: "https://developer.unirep.io/docs/welcome", - twitter: "https://twitter.com/UniRep_Protocol", - discord: "https://discord.gg/VzMMDJmYc5", - }, - tags: { - keywords: ["Anonymity/privacy", "Social", "Identity", "Reputation"], - themes: ["build", "play"], - types: ["Legos/dev tools, Protocol"], - builtWith: ["semaphore", "circom"], - }, - extraLinks: { - buildWith: [ - { - label: "Getting Started with create-unirep-app", - url: "https://developer.unirep.io/docs/next/getting-started/create-unirep-app", - }, - ], - play: [ - { - label: "Try it out: UniRep.social (Staging)", - url: "https://social-staging.unirep.workers.dev", - }, - { - label: "Try it out: Trustlist (coming soon) ", - url: "https://trustlist.pse.dev", - }, - ], - }, -} diff --git a/data/projects/vOPRF.ts b/content/projects/vOPRF.md similarity index 72% rename from data/projects/vOPRF.ts rename to content/projects/vOPRF.md index 9c3663a..508280c 100644 --- a/data/projects/vOPRF.ts +++ b/content/projects/vOPRF.md @@ -1,19 +1,22 @@ -import { ProjectCategory, ProjectInterface, ProjectStatus } from "@/lib/types" +--- +id: "vOPRF" +name: "Web2-ID Nullifiers using vOPRF" +image: "" +section: "pse" +projectStatus: "active" +category: "research" +tldr: "Enabling pseudonymous systems for Web2 identities using verifiable Oblivious PseudoRandom Functions (vOPRFs)." +tags: + keywords: ["vOPRF", "nullifiers", "Web2", "privacy", "ZK proofs", "MPC"] + themes: ["privacy", "identity", "zero-knowledge proofs"] + types: ["research", "development"] +links: + github: "https://github.com/privacy-scaling-explorations/vOPRF-ID/" +team: + - name: "Magamedrasul Ibragimov" + email: "curryrasul@pse.dev" +--- -export const vOPRF: ProjectInterface = { - id: "vOPRF", - image: "", - name: "Web2-ID Nullifiers using vOPRF", - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.RESEARCH, - links: { - github: "https://github.com/privacy-scaling-explorations/vOPRF-ID/", - }, - content: { - en: { - tldr: "Enabling pseudonymous systems for Web2 identities using verifiable Oblivious PseudoRandom Functions (vOPRFs).", - description: ` # Web2-ID Nullifiers using vOPRF ## Project Overview @@ -44,7 +47,7 @@ Key elements include: ## Milestones - **February 2025:** Full protocol spec and ethresearch post published - - See [ethresearch pos](https://ethresear.ch/t/web2-nullifiers-using-voprf/21762)t and full description of protocol [on Github](https://github.com/privacy-scaling-explorations/vOPRF-ID) and [this presentation](https://x.com/PrivacyScaling/status/1903084082529010174) + - See [ethresearch pos](https://ethresear.ch/t/web2-nullifiers-using-voprf/21762)t and full description of protocol [on Github](https://github.com/privacy-scaling-explorations/vOPRF-ID) and [this presentation](https://x.com/PrivacyScaling/status/1903084082529010174) - **March 2025:** Initial implementation (vOPRF + zk circuits) completed see https://github.com/privacy-scaling-explorations/vOPRF-ID - **May 2025:** Launch of PoC—fork of Stealthnote enabling pseudonymous posting via Web2-derived nullifiers - **July 2025 (planned):** Production-ready OPRF server with key rotation and node monitoring @@ -73,18 +76,4 @@ The protocol enables a broad range of applications requiring privacy and pseudon ## Contact - **Magamedrasul Ibragimov:** [curryrasul@pse.dev](mailto:curryrasul@pse.dev) | [@curryrasul](https://twitter.com/curryrasul) -- **Join** the PSE Discord](https://discord.com/invite/sF5CT5rzrR)`, - }, - }, - team: [ - { - name: "Magamedrasul Ibragimov", - email: "curryrasul@pse.dev", - }, - ], - tags: { - keywords: ["vOPRF", "nullifiers", "Web2", "privacy", "ZK proofs", "MPC"], - themes: ["privacy", "identity", "zero-knowledge proofs"], - types: ["research", "development"], - }, -} +- **Join** the PSE Discord](https://discord.com/invite/sF5CT5rzrR) diff --git a/content/projects/voice-deck.md b/content/projects/voice-deck.md new file mode 100644 index 0000000..c128502 --- /dev/null +++ b/content/projects/voice-deck.md @@ -0,0 +1,20 @@ +--- +id: "voice-deck" +name: "VoiceDeck" +image: "voiceDeck.svg" +section: "collaboration" +projectStatus: "inactive" +category: "application" +tldr: "From Individual Actions to Collective Impact, Every Voice Makes a Difference" +tags: + keywords: ["Public goods"] + themes: ["play"] + types: ["Application"] + builtWith: ["anonAadhaar", "Hypercerts"] +links: + github: "https://github.com/VoiceDeck" + website: "https://voicedeck.org/" + twitter: "https://twitter.com/VoiceDeckDAO" +--- + +VoiceDeck isn't just a platform; it's a movement. By enabling citizens to fund journalism that makes a real difference, we're crafting a narrative where every contribution paints a stroke on the canvas of our collective future. Join us to foster a legacy where journalism is powered by the very communities it serves. diff --git a/content/projects/wax.md b/content/projects/wax.md new file mode 100644 index 0000000..0f02e02 --- /dev/null +++ b/content/projects/wax.md @@ -0,0 +1,26 @@ +--- +id: "wax" +name: "Wallet Account eXperiments - WAX" +image: "wax.webp" +section: "pse" +projectStatus: "inactive" +category: "devtools" +tldr: "" +tags: + keywords: ["Scaling", "Key management", "WAX"] + themes: ["build"] + types: ["Prototype", "Proof of concept", "Lego sets/toolkits"] + builtWith: + [ + "foundry", + "hardhat", + "node", + "solidity bls library", + "sqlite", + "docker", + "ethers.js", + "deno", + ] +links: + github: "https://github.com/getwax" +--- diff --git a/content/projects/zk-email.md b/content/projects/zk-email.md new file mode 100644 index 0000000..e2f6f1f --- /dev/null +++ b/content/projects/zk-email.md @@ -0,0 +1,20 @@ +--- +id: "zk-email" +name: "zk-email" +image: "zk-email.jpeg" +section: "collaboration" +projectStatus: "active" +category: "application" +tldr: "ZK Email is a library that allows for anonymous verification of email signatures while masking specific data." +tags: + themes: [] + types: [] + keywords: ["email", "identity", "anonymity/privacy", "DKIM", "signatures"] + builtWith: ["circom", "snarkjs", "halo2"] +links: + github: "https://github.com/zkemail" + twitter: "https://twitter.com/zkemail" + website: "https://zk.email/" +--- + +ZK Email is a library for anonymous verification of emails while selectively revealing specific data. It allows a prover to demonstrate receipt of an email from a specific sender or domain or the presence of certain text in the subject or body. This can be used for Web 2.0 interoperability, email recovery solutions of smart accounts, anonymous KYC, or to create interesting applications based on anonymity sets. diff --git a/data/projects/zk-id.ts b/content/projects/zk-id.md similarity index 67% rename from data/projects/zk-id.ts rename to content/projects/zk-id.md index 287b436..89b7dd2 100644 --- a/data/projects/zk-id.ts +++ b/content/projects/zk-id.md @@ -1,30 +1,40 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "zk-id" +name: "zkID" +image: "zk-id.png" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "zkID advances privacy-preserving digital identity by drafting technical standards, building open-source infrastructure, and strategic outreach." +license: "" +tags: + keywords: + ["Identity", "Credentials", "Standards", "SSI", "Verifiable Credentials"] + themes: ["research"] + types: ["Legos/dev tools", "Lego sets/toolkits"] + builtWith: [] +links: + github: "https://github.com/privacy-scaling-explorations/zkID" +--- + +# zkID -const content: ProjectContent = { - en: { - tldr: "zkID advances privacy-preserving digital identity by drafting technical standards, building open-source infrastructure, and strategic outreach.", - description: ` ### Overview zkID is a strategic initiative of the Ethereum Foundation, in collaboration with Privacy and Scaling Explorations (PSE), focused on advancing the use of Zero Knowledge Proofs (ZKPs) in digital identity systems. We contribute to PSE by leading research, coordination, education, and development efforts that enable privacy-preserving, interoperable, and standards-aligned identity infrastructure. -Our team works and distributes grants across the identity ecosystem to draft technical standards, maintain open-source resources, and prototype infrastructure that aligns with evolving regulatory frameworks. By stewarding collaboration between researchers, developers, governments, and institutions, zkID bridges foundational cryptographic research with real-world deployment and impact. +Our team works and distributes grants across the identity ecosystem to draft technical standards, maintain open-source resources, and prototype infrastructure that aligns with evolving regulatory frameworks. By stewarding collaboration between researchers, developers, governments, and institutions, zkID bridges foundational cryptographic research with real-world deployment and impact. ### Vision -Our vision is a future where digital identity infrastructure is **privacy-preserving.** We are working to ensure that **privacy is** built into global digital identity systems *by default*. As governments make foundational decisions on how identity is issued, verified, and protected, we see an opportunity for EF and PSE to: +Our vision is a future where digital identity infrastructure is **privacy-preserving.** We are working to ensure that **privacy is** built into global digital identity systems _by default_. As governments make foundational decisions on how identity is issued, verified, and protected, we see an opportunity for EF and PSE to: - Embed **zero-knowledge proofs (ZKPs)** at the core of these systems - Define the underlying [blockchain and distributed ledger](https://github.com/orgs/eu-digital-identity-wallet/projects/29/views/1?pane=issue&itemId=86398709&issue=eu-digital-identity-wallet%7Ceudi-doc-standards-and-technical-specifications%7C202) technology used as trust registries and guiding [GPDR policies](https://www.edpb.europa.eu/system/files/2025-04/edpb_guidelines_202502_blockchain_en.pdf) ### Why It Is Urgent -The [European Union’s **EUDI Wallet**](https://ec.europa.eu/digital-building-blocks/sites/display/EUDIGITALIDENTITYWALLET/EU+Digital+Identity+Wallet+Home) is on track for rollout in **2026**. In parallel, countries are building identity stacks, with deployment frameworks and policies that mirror or precede the EU’s. This is a **critical inflection point**: [technical decisions](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/discussions/408) made today will determine whether future digital identity systems become tools for mass surveillance or embed privacy, user agency, and interoperability as defaults. +The [European Union's **EUDI Wallet**](https://ec.europa.eu/digital-building-blocks/sites/display/EUDIGITALIDENTITYWALLET/EU+Digital+Identity+Wallet+Home) is on track for rollout in **2026**. In parallel, countries are building identity stacks, with deployment frameworks and policies that mirror or precede the EU's. This is a **critical inflection point**: [technical decisions](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/discussions/408) made today will determine whether future digital identity systems become tools for mass surveillance or embed privacy, user agency, and interoperability as defaults. We are in a rare window of influence. Over the next 12 to 18 months: @@ -36,29 +46,29 @@ We are in a rare window of influence. Over the next 12 to 18 months: zkID operates across [three strategic workstreams](https://www.notion.so/zkID-Team-Strategy-Proposal-db3c5788dc7a4916a33e580a79177053?pvs=21) to ensure zero-knowledge proofs (ZKPs) are embedded in digital identity systems of the future: -1) **Proliferate Programmable ZKP Standards** +1. **Proliferate Programmable ZKP Standards** We work with standard bodies to embed ZKPs into emerging identity frameworks to ensure interoperability. Our [grant](https://hackmd.io/@therealyingtong/zkid-infopage)-backed efforts include: - [Technical reviews](https://docs.google.com/presentation/d/1C4D8zK4gAdafgIEW-2m_qDyyT39gWo0mmFYpwmA8N3M/edit#slide=id.g338a079cb64_0_15) of implementations from Orange, Google, and Microsoft - [Technical reviews](https://hackmd.io/@therealyingtong/vc-formats) of verifiable credential data models - Drafting an IETF [standard on Programmable ZKPs](https://datatracker.ietf.org/doc/draft-zkproof-polycommit/) -- [Engage](https://www.youtube.com/watch?v=LyvqyeSAvL0) the wider zkp community on standards collaboration +- [Engage](https://www.youtube.com/watch?v=LyvqyeSAvL0) the wider zkp community on standards collaboration - Participating in [DIF](https://github.com/decentralized-identity/zkp-self-attestations) and [W3C](https://docs.google.com/presentation/d/1HqFtSiS2hVHaSS8-u-8iecVFeMehMGBtZJnnbnXj83c/edit#slide=id.p) standards working groups - Shaping specifications within the [EUDI technical framework](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/discussions/408) -- Draft [informal technical specifications](https://github.com/zkspecs/zkspecs) on zk protocols +- Draft [informal technical specifications](https://github.com/zkspecs/zkspecs) on zk protocols Standards like the IETF and EUDI framework are **global signaling mechanisms.** Dozens of countries reference the EUDI frameworks to shape their own identity regulations. If we can ensure ZKPs are part of the EUDI ARF spec, we create downstream pressure to adopt privacy-preserving architecture across multiple jurisdictions. -2) **Research, Prototype, Subtraction** +2. **Research, Prototype, Subtraction** We [research](https://www.notion.so/Evaluation-Framework-for-SSI-Solutions-8eceb793a5b442cb8da65acc3c337d5c?pvs=21) and build standards-compliant, [**minimal and modular PoCs**](https://github.com/adria0/seediq-playground) like the [ZKP Wallet Unit](https://www.notion.so/External-zkID-ZKP-Wallet-Unit-Proposal-1bad57e8dd7e80c98d73fc7e7666375d?pvs=21). This is done in collaboration with governments, to ensure practical real-world ZKP integration pathways. By delivering vendor-neutral, open-source PoCs, zkID aims to provide tangible working proof in production-ready environments. -3) **Education and Strategic Outreach** +3. **Education and Strategic Outreach** -We publish research, [articles](https://mirror.xyz/privacy-scaling-explorations.eth/zRM7qQSt_igfoSxdSa0Pts9MFdAoD96DD3m43bPQJT8), [analysis](https://www.notion.so/Evaluation-Framework-for-SSI-Solutions-8eceb793a5b442cb8da65acc3c337d5c?pvs=21), lead [workshops](https://docs.google.com/presentation/d/1YROCEHK_t10wo5CukgYWmS1nuYKZi46NJBu-XZ8zXiw/edit#slide=id.p), and run [technical engagements](https://docs.google.com/presentation/d/1C4D8zK4gAdafgIEW-2m_qDyyT39gWo0mmFYpwmA8N3M/edit#slide=id.g338a079cb64_0_15). +We publish research, [articles](https://mirror.xyz/privacy-scaling-explorations.eth/zRM7qQSt_igfoSxdSa0Pts9MFdAoD96DD3m43bPQJT8), [analysis](https://www.notion.so/Evaluation-Framework-for-SSI-Solutions-8eceb793a5b442cb8da65acc3c337d5c?pvs=21), lead [workshops](https://docs.google.com/presentation/d/1YROCEHK_t10wo5CukgYWmS1nuYKZi46NJBu-XZ8zXiw/edit#slide=id.p), and run [technical engagements](https://docs.google.com/presentation/d/1C4D8zK4gAdafgIEW-2m_qDyyT39gWo0mmFYpwmA8N3M/edit#slide=id.p). [Zero-knowledge proofs](https://docs.zkproof.org/reference.pdf) are powerful, but often misunderstood or underutilized by policymakers and civic organizations. @@ -66,31 +76,28 @@ In parallel, we aim to advise institutions on selecting the right Layer 2 infras zkID serves as a neutral translator and strategic steward, helping institutions grasp the practical applications of ZKPs and guiding their integration into public goods. -`, - }, -} +### Mission -export const zkID: ProjectInterface = { - id: "zk-id", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "zk-id.png", - imageAlt: "ZK Identity", - name: "zkID", - links: { - github: "https://github.com/privacy-scaling-explorations/zkID", - }, - tags: { - keywords: [ - "Identity", - "Credentials", - "Standards", - "SSI", - "Verifiable Credentials", - ], - themes: ["research"], - types: ["Legos/dev tools", "Lego sets/toolkits"], - }, -} +Our mission is to establish zero-knowledge proofs as the foundational technology for privacy-preserving identity verification systems worldwide. + +### Current Focus Areas + +1. **Standards Development**: Leading the creation of technical standards for ZK-based identity systems +2. **Open Source Infrastructure**: Building and maintaining tools and libraries for ZK identity implementation +3. **Research & Development**: Advancing the state-of-the-art in privacy-preserving identity technologies +4. **Ecosystem Coordination**: Facilitating collaboration between stakeholders across the identity ecosystem + +### Key Initiatives + +- **W3C Standards Participation**: Active involvement in World Wide Web Consortium standards development +- **Government Outreach**: Engaging with policy makers and regulatory bodies +- **Academic Partnerships**: Collaborating with universities and research institutions +- **Industry Collaboration**: Working with technology companies and identity providers + +### Impact + +zkID's work aims to create a world where individuals have full control over their digital identity while maintaining privacy and security. Our efforts contribute to a more equitable and privacy-respecting digital future for all users. + +### Resources + +For more information about zkID initiatives, technical standards, and ongoing projects, visit our GitHub repository and follow our research publications. diff --git a/data/projects/zk-kit.ts b/content/projects/zk-kit.md similarity index 53% rename from data/projects/zk-kit.ts rename to content/projects/zk-kit.md index f01f8bf..3ec05e6 100644 --- a/data/projects/zk-kit.ts +++ b/content/projects/zk-kit.md @@ -1,14 +1,34 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "zk-kit" +name: "ZK-Kit" +image: "zk-kit.svg" +section: "pse" +projectStatus: "active" +category: "devtools" +tldr: "A set of reusable libraries for zero-knowledge technologies." +tags: + keywords: ["Education", "Toolkits", "Anonymity/Privacy", "Algorithms"] + themes: ["build"] + types: ["Legos/dev tools"] + builtWith: ["Circom", "JavaScript", "Solidity", "Noir", "Rust"] +links: + website: "https://zkkit.pse.dev" + github: "https://github.com/privacy-scaling-explorations/zk-kit" +extraLinks: + buildWith: + - label: "ZK-Kit JavaScript" + url: "https://github.com/privacy-scaling-explorations/zk-kit" + - label: "ZK-Kit Solidity" + url: "https://github.com/privacy-scaling-explorations/zk-kit.solidity" + - label: "ZK-Kit Circom" + url: "https://github.com/privacy-scaling-explorations/zk-kit.circom" + - label: "ZK-Kit Rust" + url: "https://github.com/privacy-scaling-explorations/zk-kit.rust" + - label: "ZK-Kit Noir" + url: "https://github.com/privacy-scaling-explorations/zk-kit.noir" +--- -const content: ProjectContent = { - en: { - tldr: "A set of reusable libraries for zero-knowledge technologies.", - description: `### Overview +### Overview ZK-Kit is an innovative toolkit that provides reference implementations of cryptographic primitives across multiple programming languages. It is designed to streamline the development of production-level projects involving zero-knowledge @@ -33,50 +53,4 @@ One of ZK-Kit's standout features is its commitment to providing a consistent de across various programming languages. By maintaining a common API structure, ZK-Kit enables developers to switch languages effortlessly. Additionally, ZK-Kit emphasizes code quality and reliability through rigorous code checks, integrating linters, -formatters, comprehensive testing, and regular audits, ensuring robust and maintainable code throughout development.`, - }, -} - -export const ZKKit: ProjectInterface = { - id: "zk-kit", - category: ProjectCategory.DEVTOOLS, - image: "zk-kit.svg", - name: "ZK-Kit", - projectStatus: ProjectStatus.ACTIVE, - section: "pse", - content, - links: { - website: "https://zkkit.pse.dev", - github: "https://github.com/privacy-scaling-explorations/zk-kit", - }, - tags: { - keywords: ["Education", "Toolkits", "Anonymity/Privacy", "Algorithms"], - themes: ["build"], - types: ["Legos/dev tools"], - builtWith: ["Circom", "JavaScript", "Solidity", "Noir", "Rust"], - }, - extraLinks: { - buildWith: [ - { - label: "ZK-Kit JavaScript", - url: "https://github.com/privacy-scaling-explorations/zk-kit", - }, - { - label: "ZK-Kit Solidity", - url: "https://github.com/privacy-scaling-explorations/zk-kit.solidity", - }, - { - label: "ZK-Kit Circom", - url: "https://github.com/privacy-scaling-explorations/zk-kit.circom", - }, - { - label: "ZK-Kit Rust", - url: "https://github.com/privacy-scaling-explorations/zk-kit.rust", - }, - { - label: "ZK-Kit Noir", - url: "https://github.com/privacy-scaling-explorations/zk-kit.noir", - }, - ], - }, -} +formatters, comprehensive testing, and regular audits, ensuring robust and maintainable code throughout development. diff --git a/content/projects/zkevm-community.md b/content/projects/zkevm-community.md new file mode 100644 index 0000000..1c91f6c --- /dev/null +++ b/content/projects/zkevm-community.md @@ -0,0 +1,18 @@ +--- +id: "zkevm-community" +name: "zkEVM Community Edition" +image: "zkevm.jpg" +section: "pse" +projectStatus: "inactive" +category: "devtools" +tldr: "A zero-knowledge proof mechanism for Ethereum block verification." +tags: + keywords: ["Scaling"] + themes: ["build"] + types: ["Infrastructure/protocol", "Lego sets/toolkits"] + builtWith: ["halo2", "rust", "geth"] +links: + github: "https://github.com/privacy-scaling-explorations/zkevm-circuits" +--- + +zkEVM Community Edition is a project aimed at validating Ethereum blocks using zero-knowledge proofs. It is designed to be fully compatible with Ethereum's EVM and serves two primary goals. First, it enables the creation of a layer 2 network (zkRollup) compatible with the Ethereum ecosystem, which uses zero-knowledge proofs to validate blocks, thus enhancing scalability. Second, it allows the generation of zero-knowledge proofs for blocks from the existing layer 1 Ethereum network, enabling light clients to quickly synchronize many blocks with low resource consumption while ensuring block correctness without needing trust in external parties. diff --git a/data/projects/zkitter.ts b/content/projects/zkitter.md similarity index 58% rename from data/projects/zkitter.ts rename to content/projects/zkitter.md index f27354a..bc1572e 100644 --- a/data/projects/zkitter.ts +++ b/content/projects/zkitter.md @@ -1,44 +1,28 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "zkitter" +name: "Zkitter" +image: "zkitter.webp" +section: "archived" +projectStatus: "inactive" +category: "applications" +tldr: "A decentralized social network prioritizing privacy and anonymity" +tags: + keywords: ["Anonymity/privacy", "Social", "Identity"] + themes: ["build"] + types: ["Application", "Infrastructure/protocol"] + builtWith: ["semaphore", "rln", "interep", "zkchat"] +links: + github: "https://github.com/zkitter" + website: "https://www.zkitter.com/explore/" + discord: "https://discord.gg/Em4Z9yE8eW" +--- -const content: ProjectContent = { - en: { - tldr: "A decentralized social network prioritizing privacy and anonymity", - description: ` ### Overview Zkitter is a decentralized social network that emphasizes privacy by default. It allows users to share thoughts and communicate in various modes: as known identities, as a member of a group, or entirely anonymously. Built with Semaphore and RLN, Zkitter offers familiar social media features such as posting, chatting, following, and liking, but with a strong focus on user privacy and anonymity. It serves as an experiment to explore new ways of engaging in conversations without the fear of damaging one's personal reputation and is an example of a user-facing application using zero-knowledge primitives such as Semaphore, CryptKeeper, ZK-Chat, and Interep. Users can sign up using an Ethereum address or ENS name, or create an anonymous account, with options for anonymous chat and posting. ### Learn more + - [Zkitter: An Anon-friendly Social Network](https://mirror.xyz/privacy-scaling-explorations.eth/P4jDH1gLrVQ-DP5VyIKQrlPAJUTDhtXZkFl2vp8ewSg) - Introductory post from the PSE blog - [Zkitter - Anonymous Social Network](https://www.youtube.com/watch?v=GOQZHWC3cH0) - Devcon 6 talk - [Zkitter documentation](https://docs.zkitter.com/) -`, - }, -} - -export const zkitter: ProjectInterface = { - id: "zkitter", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.APPLICATION, - section: "archived", - content, - image: "zkitter.webp", - name: "Zkitter", - links: { - github: "https://github.com/zkitter", - website: "https://www.zkitter.com/explore/", - discord: "https://discord.gg/Em4Z9yE8eW", - }, - - tags: { - keywords: ["Anonymity/privacy", "Social", "Identity"], - themes: ["build"], - types: ["Application", "Infrastructure/protocol"], - builtWith: ["semaphore", "rln", "interep", "zkchat"], - }, -} diff --git a/content/projects/zkml.md b/content/projects/zkml.md new file mode 100644 index 0000000..d69d33d --- /dev/null +++ b/content/projects/zkml.md @@ -0,0 +1,18 @@ +--- +id: "zkml" +name: "ZKML" +image: "zkml.png" +section: "pse" +projectStatus: "inactive" +category: "research" +tldr: "ZKML (Zero-Knowledge Machine Learning) leverages zero-knowledge proofs for privacy-preserving machine learning, enabling model and data privacy with transparent verification." +tags: + keywords: ["Anonymity/privacy", "Scaling"] + themes: ["research"] + types: ["Proof of concept", "Infrastructure/protocol"] + builtWith: ["circom", "halo2", "nova"] +links: + github: "https://github.com/socathie/circomlib-ml" +--- + +ZKML is a solution that combines the power of zero-knowledge proofs (ZKPs) and machine learning to address the privacy concerns in traditional machine learning. It provides a platform for machine learning developers to convert their TensorFlow Keras models into ZK-compatible versions, ensuring model privacy, data privacy, and transparent verification. ZKML can be used to verify if a specific machine learning model was used to generate a particular piece of content, without revealing the input or the model used. It has potential use cases in on-chain biometric authentication, private data marketplace, proprietary ML model sharing, and AIGC NFTs. diff --git a/data/projects/zkopru.ts b/content/projects/zkopru.md similarity index 52% rename from data/projects/zkopru.ts rename to content/projects/zkopru.md index 23e7a8d..2903cb0 100644 --- a/data/projects/zkopru.ts +++ b/content/projects/zkopru.md @@ -1,76 +1,49 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" +--- +id: "zkopru" +name: "ZKOPRU" +image: "zkopru.svg" +section: "archived" +projectStatus: "inactive" +category: "devtools" +tldr: "Optimistic Rollup with zk-SNARKs for private Ethereum transactions." +tags: + keywords: ["anonymity/privacy", "private transactions"] +links: + website: "https://zkopru.network/" + github: "https://github.com/zkopru-network" +--- -const content: ProjectContent = { - en: { - tldr: "Optimistic Rollup with zk-SNARKs for private Ethereum transactions.", - description: `### Overview +### Overview -ZkOPRU (Zero-Knowledge Optimistic Private Rollup) is a Layer 2 scaling solution for Ethereum designed to enable private transactions while maintaining scalability and compatibility with -the Ethereum ecosystem. It combines zero-knowledge proofs (specifically zk-SNARKs) with optimistic rollup technology to provide a privacy-focused framework for transferring ETH, -ERC-20 tokens, and ERC-721 NFTs. The project aims to address Ethereum's limitations in transaction privacy and cost by moving computation off-chain while ensuring security through +ZkOPRU (Zero-Knowledge Optimistic Private Rollup) is a Layer 2 scaling solution for Ethereum designed to enable private transactions while maintaining scalability and compatibility with +the Ethereum ecosystem. It combines zero-knowledge proofs (specifically zk-SNARKs) with optimistic rollup technology to provide a privacy-focused framework for transferring ETH, +ERC-20 tokens, and ERC-721 NFTs. The project aims to address Ethereum's limitations in transaction privacy and cost by moving computation off-chain while ensuring security through cryptographic proofs and Ethereum's mainnet as the settlement layer. ### History -ZkOPRU was developed as an open-source initiative, with significant contributions from developers like Barry Whitehat and Wanseob Lim. Its first testnet was announced in July 2020, -marking a milestone in bringing privacy to Ethereum's public blockchain. The system operates by batching transactions into a rollup, where zk-SNARKs shield sensitive details—such -as sender, recipient, and amount—while optimistic rollups assume transaction validity unless challenged, reducing the need for immediate on-chain verification. This hybrid approach +ZkOPRU was developed as an open-source initiative, with significant contributions from developers like Barry Whitehat and Wanseob Lim. Its first testnet was announced in July 2020, +marking a milestone in bringing privacy to Ethereum's public blockchain. The system operates by batching transactions into a rollup, where zk-SNARKs shield sensitive details—such +as sender, recipient, and amount—while optimistic rollups assume transaction validity unless challenged, reducing the need for immediate on-chain verification. This hybrid approach allows ZkOPRU to offer low-cost, private transactions with the ability to scale, supporting use cases like confidential payments and private NFT transfers. -The project emerged from earlier efforts like ZK Rollup but distinguishes itself with its optimistic mechanism, which avoids the high computational cost of generating zero-knowledge -proofs for every transaction on-chain. Instead, it uses a challenge period during which invalid transactions can be disputed, balancing efficiency and security. ZkOPRU also includes +The project emerged from earlier efforts like ZK Rollup but distinguishes itself with its optimistic mechanism, which avoids the high computational cost of generating zero-knowledge +proofs for every transaction on-chain. Instead, it uses a challenge period during which invalid transactions can be disputed, balancing efficiency and security. ZkOPRU also includes a coordinator system to manage transaction batching, though it aims to minimize trust assumptions over time. ### Features -* **Privacy**: Transactions are shielded using zk-SNARKs, ensuring confidentiality on a public ledger. -* **Scalability**: Optimistic rollups bundle hundreds of transactions into a single proof, lowering gas fees and increasing throughput. -* **Compatibility**: Supports Ethereum-native assets (ETH, ERC-20, ERC-721), making it versatile for existing applications. -* **Decentralization**: Relies on Ethereum for final settlement, inheriting its security while offloading computation. +- **Privacy**: Transactions are shielded using zk-SNARKs, ensuring confidentiality on a public ledger. +- **Scalability**: Optimistic rollups bundle hundreds of transactions into a single proof, lowering gas fees and increasing throughput. +- **Compatibility**: Supports Ethereum-native assets (ETH, ERC-20, ERC-721), making it versatile for existing applications. +- **Decentralization**: Relies on Ethereum for final settlement, inheriting its security while offloading computation. ### Impact -As of March 26, 2025, ZkOPRU remains a notable experiment in Ethereum's privacy and scaling landscape, though its development has been somewhat overshadowed by other Layer 2 solutions -like zkSync and Arbitrum. Its GitHub repository (under the zkWizard organization) and initial testnet documentation provide insight into its technical design, which includes a -UTXO-based model for transaction tracking and a focus on user accessibility via wallet integration. While it hasn't achieved widespread adoption, ZkOPRU's influence is seen in the +As of March 26, 2025, ZkOPRU remains a notable experiment in Ethereum's privacy and scaling landscape, though its development has been somewhat overshadowed by other Layer 2 solutions +like zkSync and Arbitrum. Its GitHub repository (under the zkWizard organization) and initial testnet documentation provide insight into its technical design, which includes a +UTXO-based model for transaction tracking and a focus on user accessibility via wallet integration. While it hasn't achieved widespread adoption, ZkOPRU's influence is seen in the broader trend of combining zero-knowledge cryptography with rollup technology, paving the way for projects like Aztec and Polygon Nightfall. -In summary, ZkOPRU is a pioneering effort to bring privacy to Ethereum's Layer 2 ecosystem, leveraging zk-SNARKs and optimistic rollups to offer a scalable, confidential transaction -layer as of its last significant updates around 2020-2021.`, - }, -} - -export const Zkopru: ProjectInterface = { - id: "zkopru", - image: "zkopru.svg", - name: "ZKOPRU", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "archived", - content, - links: { - website: "https://zkopru.network/", - github: "https://github.com/zkopru-network", - youtube: "https://www.youtube.com/watch?v=GvRsJxu9X6w", - }, - extraLinks: { - learn: [ - { - label: "ZKOPRU: Wat, Y & Wen", - url: "https://mirror.xyz/privacy-scaling-explorations.eth/kfuuBPtGtDjl_J2wBq-jrtyURGLmQpUhZfDTuZChEy8", - }, - { - label: "ZKOPRU on Testnet", - url: "https://mirror.xyz/privacy-scaling-explorations.eth/EB0KcMY0k9ucN8iQSBeOYksoupDYRBQ4ZffhRt477FE", - }, - ], - }, - tags: { - keywords: ["anonymity/privacy", "private transactions"], - }, -} +In summary, ZkOPRU is a pioneering effort to bring privacy to Ethereum's Layer 2 ecosystem, leveraging zk-SNARKs and optimistic rollups to offer a scalable, confidential transaction +layer as of its last significant updates around 2020-2021. diff --git a/content/projects/zkp2p.md b/content/projects/zkp2p.md new file mode 100644 index 0000000..7190f56 --- /dev/null +++ b/content/projects/zkp2p.md @@ -0,0 +1,20 @@ +--- +id: "zkp2p" +name: "ZKP2P" +image: "zkp2p.png" +section: "grant" +projectStatus: "active" +category: "application" +tldr: "Instant fiat to crypto onramp connecting traditional peer-to-peer payment services with zero-knowledge proofs." +tags: + keywords: ["Private communications"] + themes: ["play"] + types: ["Proof of concept", "Application"] + builtWith: ["circom", "halo2"] +links: + github: "https://github.com/zkp2p" + website: "https://zkp2p.xyz/" + twitter: "https://twitter.com/zkp2p" +--- + +ZKP2P is for defi consumers looking to onramp assets on chain quickly without going through a CEX as an intermediary. ZKP2P generates a privacy-preserving proof of payment between two users on existing payment rails like Venmo or Paypal and uses said proof to unlock escrowed digital assets on-chain. diff --git a/app/(pages)/content/resources.md b/content/resources.md similarity index 100% rename from app/(pages)/content/resources.md rename to content/resources.md diff --git a/data/programs/accelerationProgramFaq.tsx b/data/programs/accelerationProgramFaq.tsx deleted file mode 100644 index 7397192..0000000 --- a/data/programs/accelerationProgramFaq.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Faq } from "@/lib/types" - -export const accelerationProgramFaq: Faq[] = [ - { - question: "Who can apply?", - answer: - "The Acceleration program is open to alumni of our entry level programs (e.g. Launch Program, ZK Playground) and other applicants at beginner to intermediate levels with programmable cryptography.", - }, - { - question: "What platform does the program use?", - answer: - "We will primarily utilize a Github repository for managing documents and staging of the grant proposals, grantees, and their progress. Stakeholders involved can utilize Github issues and pull requests to comment and collaborate.", - }, - { - question: "How does the grant funding work?", - answer: ( - <> - - While the core funding this program comes through PSE via the Ethereum - Ecosystem Support Program (ESP), some bounties are supported by - specific teams. - - - Selected grantees will receive a small amount of funding after the - completion of the first milestone. Following milestones will be - awarded larger amounts. - - - ), - }, - { - question: "How many proposals are accepted per open task?", - answer: - "Generally one proposal will be accepted. However, it is possible for applicants to form a team and work collaboratively.", - }, - { - question: "How long will I have to tackle the open tasks?", - answer: - "Though our rounds are run in three month periods, the duration of your grant may be shorter or longer depending on task details.", - }, - { - question: "Can I propose an open task?", - answer: - "If you have an interesting idea, you can submit it as an self proposed open task. Just to make sure you clearly credit to the original idea and clearly state if that idea is also funded by someone else.", - }, - { - question: "What if I have more questions?", - answer: - "For any further questions or additional information, you can join our Telegram group!", - }, -] diff --git a/data/programs/coreProgramFaq.tsx b/data/programs/coreProgramFaq.tsx deleted file mode 100644 index 1ad8259..0000000 --- a/data/programs/coreProgramFaq.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Faq } from "@/lib/types" - -export const coreProgramFaq: Faq[] = [ - { - question: "Who can apply?", - answer: - "The Core Program is open to university students based in Japan, South Korea, Taiwan, Costa Rica, Ecuador and Argentina with a basic understanding of programming. If you're currently enrolled in a mathematics or computer science program, you're likely an excellent fit.", - }, - { - question: "What is the structure of the program?", - answer: - "We use a hybrid learning model with the majority of learning happening online and weekly in-person meetings for discussions and problem-solving. The program consists of three stages: 1) self-driven exploration & guidance, 2) hands-on circuit writing, and 3) open-source project contribution.", - }, - { - question: "How much time will I need to commit?", - answer: - "We're looking for dedicated students who can commit 40 hours a week from mid-July to September. You will be required to attend in-person meetups once a week and make presentations.", - }, - { - question: "Can I participate remotely?", - answer: - "Unfortunately no, the weekly in-person sessions are required for in-depth discussions and collaborative problem-solving.", - }, - { - question: "What will I gain from this program?", - answer: - "Upon completing the program, you'll have comprehensive knowledge about programmable cryptography, a bolstered GitHub portfolio, and opportunities to apply for grants for further research and contributions.", - }, - { - question: "What if I have more questions?", - answer: - "For any further questions or additional information, you can join our Telegram group!", - }, -] diff --git a/data/projects.ts b/data/projects.ts deleted file mode 100644 index 9171ae3..0000000 --- a/data/projects.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { ProjectInterface } from "@/lib/types" - -import { anonAadhaar } from "./projects/anon-aadhaar" -import { anonKlub } from "./projects/anon-klub" -import { bandada } from "./projects/bandada" -import { channel4 } from "./projects/channel-4" -import { chiquito } from "./projects/chiquito" -import { Coco } from "./projects/coco" -import { cryptkeeper } from "./projects/cryptkeeper" -import { discreetly } from "./projects/discreetly" -import { dslWorkingGroup } from "./projects/dsl-working-group" -import { ECIPHalo2 } from "./projects/ecip-halo2" -import { eigenTrust } from "./projects/eigen-trust" -import { excubiae } from "./projects/excubiae" -import { pse_halo2 } from "./projects/pse-halo2" -import { Interep } from "./projects/interep" -import { jubmoji } from "./projects/jubmoji" -import { maci } from "./projects/maci" -import { maciPlatform } from "./projects/maci-platform" -import { mopro } from "./projects/mopro" -import { circomMpc } from "./projects/circom-mpc" -import { mpcStats } from "./projects/mpc-stats" -import { nfctap } from "./projects/cursive" -import { OpenPassport } from "./projects/openpassport" -import { p0tion } from "./projects/p0tion" -import { p256 } from "./projects/p256" -import { pollenLabs } from "./projects/pollen-labs" -import { PerpetualPowersOfTau } from "./projects/powers-of-tau" -import { pseSecurity } from "./projects/pse-security" -import { publiclyVerifiableGarbledCircuit } from "./projects/publicly-verifiable-garbled-circuit" -import { rln } from "./projects/rln" -import { semaphore } from "./projects/semaphore" -import { sonobe } from "./projects/sonobe" -import { summa } from "./projects/summa" -import { tlsn } from "./projects/tlsn" -import { trustedSetups } from "./projects/trusted-setups" -import { unirepProtocol } from "./projects/unirep-protocol" -import { voicedeck } from "./projects/voice-deck" -import { wax } from "./projects/wax" -import { zkemail } from "./projects/zk-email" -import { zkID } from "./projects/zk-id" -import { ZKKit } from "./projects/zk-kit" -import { zkevmCommunity } from "./projects/zkevm-community" -import { zkitter } from "./projects/zkitter" -import { zkml } from "./projects/zkml" -import { Zkopru } from "./projects/zkopru" -import { zkp2p } from "./projects/zkp2p" -import { mpcFramework } from "./projects/mpc-framework" -import { privateProofDelegation } from "./projects/private-proof-delegation" -import { pod2 } from "./projects/pod2" -import { postQuantumCryptography } from "./projects/post-quantum-cryptography" -import { machinaIo } from "./projects/machina-iO" -import { plasmaFold } from "./projects/plasma-fold" -import { vOPRF } from "./projects/vOPRF" -import { mpz } from "./projects/mpz" -import { clientSideProving } from "./projects/client-side-proving" -import { scalingSemaphore } from "./projects/pir-scaling-semaphore" - -/** - * List of Projects - * - * Every 'description' props supports markdown syntax https://www.markdownguide.org/basic-syntax/ - */ -export const projects: ProjectInterface[] = [ - scalingSemaphore, - clientSideProving, - pse_halo2, - sonobe, - rln, - zkitter, - mopro, - mpcStats, - maci, - wax, - discreetly, - cryptkeeper, - semaphore, - pseSecurity, - zkevmCommunity, - bandada, - dslWorkingGroup, - zkml, - trustedSetups, - tlsn, - eigenTrust, - anonKlub, - summa, - anonAadhaar, - channel4, - pollenLabs, - unirepProtocol, - PerpetualPowersOfTau, - ECIPHalo2, - Coco, - Interep, - Zkopru, - ZKKit, - p256, - p0tion, - jubmoji, - nfctap, - zkp2p, - voicedeck, - zkemail, - chiquito, - maciPlatform, - OpenPassport, - zkID, - excubiae, - circomMpc, - publiclyVerifiableGarbledCircuit, - mpcFramework, - privateProofDelegation, - pod2, - postQuantumCryptography, - machinaIo, - plasmaFold, - vOPRF, - mpz, -] diff --git a/data/projects/README.md b/data/projects/README.md deleted file mode 100644 index 5a8f010..0000000 --- a/data/projects/README.md +++ /dev/null @@ -1,150 +0,0 @@ -## How to Add a New Project to the Projects List - -#### 1. Create a New Project File: - -- Go to the `../data/projects` folder in your project. -- Create a new file named `[project-name].ts` - -#### 2. Add Project Details: - -- Open the newly created `[project-name].ts` file. -- Use the ProjectInterface template to add the necessary details. Here's a basic example (please copy this for a quick start): - -```js -import { ProjectInterface, ProjectStatus } from "@/lib/types" - -export const projectName: ProjectInterface = { - id: "project-name", - image: "", - name: "Project Example", - section: "pse", - projectStatus: ProjectStatus.ACTIVE, - content: { - en: { - tldr: "Short description", - description: ` -## Heading - -Sample project description goes here. You can also use **Markdown** for formatting. - `, - }, - }, - tags: { - keywords: [], - themes: [], - types: [], - builtWith: [], - }, -} -``` - -**Note**: Make sure to add all the necessary language versions (locales) under content to support every language you need. Markdown is supported, so feel free to format accordingly. - -#### 3. Register the New Project: - -- Open the `[...]/data/projects.ts` file where all projects are listed. -- Add your new project to the projects array to make it visible: - -```js -import { projectName } from './projects/[project-name].ts'; - -const projects: ProjectInterface[] = [ - // other projects - projectName, -]; -``` - -That's it! Your new project will now be visible. Here is Overview example - -![Project overview](/public/project/example-project-badge.jpg) - -## Show links in project page detail - -To add extra link to projects we need to add `extraLinks` for the projects we are going to add links for. -Make sure that for every "themes" value there is a specific "extraLinks" object will all the links. - -```js -import { ProjectCategory, ProjectInterface, ProjectStatus } from '@/lib/types' - -export const example: ProjectInterface = { - id: "example", - image: "", - name: "This is an example of the project", - category: ProjectCategory.RESEARCH, // 'APPLICATIONS', 'RESEARCH' or 'DEVTOOLS' - section: "pse", // 'pse', 'grant', 'collaboration', 'archived' - projectStatus: ProjectStatus.ACTIVE, - tags: { - themes: ["play", "buildWith"], - keywords: ["Anonymity/privacy", "Voting/governance"], - types: ["Lego sets/toolkits", "Infrastructure/protocol"], - builtWith: ["p0tion", "JubjubLib"], - }, - extraLinks: { - buildWith: [ - { - label: "Link to get started", - url: 'https://google.it"', - }, - ], - play: [ - { - label: "Link to get started", - url: 'https://google.it"', - }, - ], - }, -} -``` - -This is the result - -![Project links](/public/project/example-project-detail.jpg) - -## Adding YouTube Videos to a Project - -Add YouTube videos to your project by including a `youtubeLinks` array: - -```js -export const projectName: ProjectInterface = { - // other properties... - youtubeLinks: [ - "https://www.youtube.com/watch?v=XXXXXXXXXXX", - "https://youtu.be/XXXXXXXXXXX", - "XXXXXXXXXXX" // Just the YouTube video ID - ], -} -``` - -The videos will appear as clickable thumbnails with titles on the project page: - -![YouTube Videos](/public/project/example-project-video.png) - -## Adding Team Members to a Project - -Add team members to your project using the `team` array: - -```js -export const projectName: ProjectInterface = { - // other properties... - team: [ - { - name: "John Doe", - role: "Lead Developer", - image: "/team/john-doe.jpg", // Optional - email: "john.doe@example.com", // Optional - links: { // Optional - github: "https://github.com/johndoe", - twitter: "https://twitter.com/johndoe" - } - } - ], -} -``` - -Supported link types: `github`, `website`, `discord`, `twitter`, `youtube`, `telegram` - -![Project Team Members](/public/project/example-project-team.png) - -### Project detail now supports markdown - -Please note the keyword and theme is curated by the comms & design team. If you wish to change, please create a PR. diff --git a/data/projects/anon-klub.ts b/data/projects/anon-klub.ts deleted file mode 100644 index 722b411..0000000 --- a/data/projects/anon-klub.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A mechanism for anonymous proof of Ethereum address ownership.", - description: - "AnonKlub is a tool designed for Ethereum developers that allows for anonymous proof of Ethereum address ownership. It doesn't directly address the public observability of Ethereum transactions but provides a workaround for privacy. Users can prepare a list of Ethereum addresses, sign a message from an address they own, and use that signature to generate a zero-knowledge proof. This proof enables users to perform actions anonymously that would typically require ownership of an address from the initial list. Use cases include anonymous NFT minting and Discord verification for DAOs without disclosing the public address.", - }, -} - -export const anonKlub: ProjectInterface = { - id: "anon-klub", - category: ProjectCategory.APPLICATION, - section: "archived", - content, - projectStatus: ProjectStatus.INACTIVE, - image: "anonklub.svg", - name: "AnonKlub", - links: { - github: "https://github.com/anonklub", - website: "https://anonklub.github.io", - }, - extraLinks: { - learn: [ - { - label: - "Sunsetting Blog Post: Reflections on Our Journey in Privacy-Preserving Solutions", - url: "https://mirror.xyz/privacy-scaling-explorations.eth/7VTKFVR4PM75WtNnBzuQSBZW-UYoJOsnzBBQmB9MWbY", - }, - ], - }, - tags: { - keywords: [ - "Transaction privacy", - "Anonymity/privacy", - "Social", - "Identity", - "Voting/governance", - ], - themes: ["build", "play"], - types: ["Infrastructure/protocol", "Prototype", "Proof of concept"], - builtWith: ["circom", "snarkjs", "halo2"], - }, -} diff --git a/data/projects/channel-4.ts b/data/projects/channel-4.ts deleted file mode 100644 index 494e2c3..0000000 --- a/data/projects/channel-4.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Content discovery through community contributions, using state channels to reward users for popular posts.", - description: - "Channel 4 is a community-driven platform where users can submit and discover content. It uses state channels to incentivize user engagement. When a user likes the content you've submitted, a state channel closes and rewards are dropped into their wallet. This approach combines entertainment with the power of state channels, enabling community members to earn while they engage.", - }, -} - -export const channel4: ProjectInterface = { - id: "channel-4", - content, - category: ProjectCategory.APPLICATION, - section: "archived", - projectStatus: ProjectStatus.INACTIVE, - image: "channel4.svg", - name: "Channel 4", - links: { - github: "https://github.com/State-Channel-4", - website: "https://channel4.wtf/", - discord: "https://discord.gg/76UrYgVyEx", - }, - tags: { - keywords: ["Scaling"], - themes: ["play"], - types: ["Application"], - builtWith: ["state channel", "smart contract"], - }, -} diff --git a/data/projects/chiquito.ts b/data/projects/chiquito.ts deleted file mode 100644 index 18588ed..0000000 --- a/data/projects/chiquito.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A modern ZKP language and compiler for plonkish and AIR arithmetizations", - description: - "Chiquito is a high-level structured language for implementing zero knowledge proof circuits, currently being implemented in the DSL Working Group of PSE. It is a state machine zk-language that provides better syntax and abstraction. It can automatically compiler arbitrary boolean expressions for state machine transitions. It can optimise the resulting arithmetization. Chiquito has a Halo2 backend, which is a low level zkDSL that writes circuits using the PLONKish arithmetization and is working on supporting additional backends. Chiquito circuits can be written using both Python and Rust. ", - }, -} - -export const chiquito: ProjectInterface = { - id: "chiquito", - category: ProjectCategory.DEVTOOLS, - projectStatus: ProjectStatus.INACTIVE, - section: "pse", - content, - image: "", - name: "chiquito", - links: { - github: "https://github.com/privacy-scaling-explorations/chiquito", - website: "https://docs.pecadorplonkish.xyz/", - twitter: "", - }, - tags: { - themes: ["build"], - types: [ - "Legos/dev tools", - "Lego sets/toolkits", - "Proof of concept", - "language", - "dsl", - ], - keywords: ["DSL", "language", "rust", "python", "halo2"], - builtWith: ["halo2", "rust"], - }, -} diff --git a/data/projects/client-side-proving.ts b/data/projects/client-side-proving.ts deleted file mode 100644 index f3caf04..0000000 --- a/data/projects/client-side-proving.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Developing efficient zero-knowledge proving systems for mobile devices, enabling private digital ID and secure communication with minimal resources.", - description: ` - ### Project Overview - - The Client-Side Proving project aims to develop practical and efficient zero-knowledge (ZK) proving systems tailored specifically for mobile devices. By exploring various proving systems - including Binius, Spartan, Plonky2, Scribe, and WHIR - we provide benchmarks, insights, and optimized implementations that enable performant client-side applications. - - ### Objective - - Our primary objective is to identify and optimize ZK proof systems that require minimal resources, have no trusted setup, and maintain post-quantum security. These efforts are particularly focused on supporting applications in digital identity, secure communications, and privacy-preserving credential management. - - ### Project Status - - - **Stage:** MVP Development - - **Status:** Active - - **Team Lead:** Alex Kuzmin - - **Team Members:** Guorong Du - - ### Technical Approach - - The project rigorously benchmarks mobile-friendly ZK proving systems based on critical criteria including computational complexity, RAM efficiency and proof size. Key innovations and strategies include: - - - **Benchmarking Binius, Spartan, Plonky2, and Scribe** for mobile usability. - - **Optimizing RAM usage** through streaming techniques. - - **Evaluation and integration of lookups** to enhance proving efficiency in computationally intensive ZK circuits. - - ### Milestones - - - **April 2025:** Established baseline benchmarks for common mobile hardware. - - **May 2025 (planned):** Comprehensive benchmarking results published for selected ZK proving systems. - - **June 2025 (planned):** Optimization of Spartan using WHIR PCS and/or Scribe's read-write streaming techniques. - - **Q3 2025 (planned):** Collaboration with an Identity initiative, integrating optimized proving systems. - - ### Applications - - Client-Side Proving enables numerous privacy-focused mobile applications, including: - - - Mobile Digital ID wallets ensuring user privacy. - - Anonymous online communication and collaboration tools. - - ### How to get in touch - - Join the [PSE Discord](https://discord.com/invite/sF5CT5rzrR) - - Reach out via email Alex: alex.kuzmin@pse.dev or Guorong Du: dgr009@pse.dev - - ### Publications -- [Benchmarks for Digital ID Wallet](https://hackmd.io/@clientsideproving/S1wiUc0n1e) -- [Mobile Hardware Survey](https://hackmd.io/@clientsideproving/ByqafXAv1e) -- [Plonky2 Sha256 Benchmarks](https://hackmd.io/@clientsideproving/B1xLCuJL5yg) -- [Proof Systems Survey](https://hackmd.io/@clientsideproving/HyKBkz7jye) - - Benchmark findings and technical write-ups will be released regularly, highlighting the project's research outcomes and performance evaluations. - `, - }, -} - -export const clientSideProving: ProjectInterface = { - id: "client-side-proving", - category: ProjectCategory.RESEARCH, - section: "pse", - content, - projectStatus: ProjectStatus.ACTIVE, - image: "", - license: "MIT", - name: "Client-Side Proving", - team: [ - { - name: "Alex Kuzmin", - email: "alex.kuzmin@pse.dev", - }, - { - name: "Guorong Du", - email: "dgr009@pse.dev", - }, - ], - tags: { - keywords: ["Zero Knowledge", "Mobile", "Privacy", "Digital Identity"], - themes: ["build", "research"], - types: ["Legos/dev tools", "Benchmarking", "Proof systems"], - }, - extraLinks: {}, -} diff --git a/data/projects/coco.ts b/data/projects/coco.ts deleted file mode 100644 index 623de43..0000000 --- a/data/projects/coco.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Integrating Nova into the EVM involves wrapping Liam Eagen's theoretical ECIP argument in Halo 2", - description: - "With Coco, groups can collaborate to curate feeds of any topic they're interested in. As you scroll through your Coco feed, rather than upvoting or downvoting posts, you'll spend WETH to predict what other group members and the group's moderators will want to see. When you're right, you'll get back your original WETH and more — but if you're wrong, you'll lose what you put in. Through this process, you help Coco filter value from noise to make sure group feeds only consist of posts that the group cares about.With Coco, groups can collaborate to curate feeds of any topic they're interested in. As you scroll through your Coco feed, rather than upvoting or downvoting posts, you'll spend WETH to predict what other group members and the group's moderators will want to see. When you're right, you'll get back your original WETH and more — but if you're wrong, you'll lose what you put in. Through this process, you help Coco filter value from noise to make sure group feeds only consist of posts that the group cares about.", - }, -} - -export const Coco: ProjectInterface = { - id: "coco", - image: "coco.svg", - category: ProjectCategory.APPLICATION, - section: "archived", - name: "COCO", - projectStatus: ProjectStatus.INACTIVE, - content, - tags: { - keywords: ["prediction market", "scaling"], - }, - extraLinks: { - learn: [ - { - label: "Meet COCO!", - url: "https://mirror.xyz/privacy-scaling-explorations.eth/tEf7iYa8l7ECZwN2T57yyiws7h9Uchip30CQvx-JBBQ", - }, - ], - buildWith: [ - { - label: "Smart contracts", - url: "https://github.com/Janmajayamall/coco-contracts", - }, - { - label: "Frontend", - url: "https://github.com/Janmajayamall/coco-frontend", - }, - { - label: "Frontend (General)", - url: "https://github.com/Janmajayamall/coco-frontend-general", - }, - ], - }, -} diff --git a/data/projects/cryptkeeper.ts b/data/projects/cryptkeeper.ts deleted file mode 100644 index 8c75c08..0000000 --- a/data/projects/cryptkeeper.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A browser extension for secure, portable anonymous identity management across applications.", - description: - "CryptKeeper is a browser extension that generates Semaphore and RLN proofs for websites, providing a secure and portable solution for managing anonymous identity secrets across different applications. It simplifies the integration of zero-knowledge (ZK) identities and proofs into applications, allowing developers to focus on building the front-end and logic of their applications. By handling complex aspects of cryptography, circuits, caching, and storage, CryptKeeper enables users to interact with decentralized applications (dapps) without revealing their private identity secrets. It is aimed at building secure community standards for the growing ZK ecosystem.", - }, -} - -export const cryptkeeper: ProjectInterface = { - id: "cryptkeeper", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.APPLICATION, - section: "archived", - content, - image: "cryptkeeper.webp", - name: "CryptKeeper", - links: { - github: "https://github.com/CryptKeeperZK", - }, - tags: { - keywords: ["Anonymity/privacy", "Social", "Identity"], - themes: ["build"], - types: ["Application", "Infrastructure/protocol", "Lego sets/toolkits"], - builtWith: ["semaphore", "rln"], - }, -} diff --git a/data/projects/discreetly.ts b/data/projects/discreetly.ts deleted file mode 100644 index 6d3e1b0..0000000 --- a/data/projects/discreetly.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "An anonymous, federated, chat application using ZK.", - description: - "An anonymous, federated, chat application that uses Rate-Limiting Nullifier for spam prevention.", - }, -} - -export const discreetly: ProjectInterface = { - id: "discreetly", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.APPLICATION, - section: "pse", - content, - image: "discreetly.svg", - name: "Discreetly", - links: { - github: "https://github.com/Discreetly", - website: "https://app.discreetly.chat/", - }, - tags: { - keywords: ["Anonymity/privacy", "Social"], - themes: ["play"], - types: ["Legos/dev tools", "Proof of concept", "Application"], - builtWith: ["rln", "semaphore"], - }, -} diff --git a/data/projects/dsl-working-group.ts b/data/projects/dsl-working-group.ts deleted file mode 100644 index 9112be3..0000000 --- a/data/projects/dsl-working-group.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Exploration of languages for writing zk circuits", - description: - "The DSL Working Group is focused on the exploration and improvement of languages used to write zero-knowledge circuits. The group's primary goal is to enhance the state of zk circuit languages, making them easier to write and review by offering the right abstractions. They also aim to make it harder to write unsound circuits by implementing static analysis and enforcing safer patterns. Additionally, they are working to support next-generation (Incrementally Verifiable Computation or IVC) proving systems. The group is currently working on Chiquito, a high-level Domain-Specific Language (DSL) for Halo2 circuits that lowers the entry barrier to write zk circuits with a state-machine abstraction API.", - }, -} - -export const dslWorkingGroup: ProjectInterface = { - id: "dsl-working-group", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.RESEARCH, - section: "pse", - content, - image: "", - imageAlt: "DSL Working Group", - name: "DSL Working Group", - links: { - github: "https://github.com/privacy-scaling-explorations/chiquito/", - }, - tags: { - types: ["Legos/dev tools", "Proof of concept", "Developer tooling"], - keywords: [], - themes: ["research"], - builtWith: [], - }, -} diff --git a/data/projects/ecip-halo2.ts b/data/projects/ecip-halo2.ts deleted file mode 100644 index 704b439..0000000 --- a/data/projects/ecip-halo2.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Integrating Nova into the EVM involves wrapping Liam Eagen's theoretical ECIP argument in Halo 2", - description: - 'Liam Eagen has developed a ZK proof for Elliptic Curve Inner Products (ECIPs) to overcome a significant bottle neck in recursive proof composition over elliptic curve cycles. The process of integrating Nova into the EVM requires an efficient method or "argument" for handling large elliptic Multi-Scalar Multiplications (MSMs). The final step in this integration process involves wrapping this argument Halo 2.', - }, -} - -export const ECIPHalo2: ProjectInterface = { - id: "ecip-halo2", - image: "", - category: ProjectCategory.DEVTOOLS, - projectStatus: ProjectStatus.INACTIVE, - section: "pse", - content, - imageAlt: "ECIP + Halo 2", - name: "ECIP (Elliptic Curve Inner Products) Halo 2 Implementation", - links: { - github: "https://github.com/levs57/sage-circuits/", - }, - extraLinks: { - learn: [ - { - label: "Designing a plonk circuit for Liam Eagen's protocol", - url: "https://hackmd.io/@levs57/r1n77YvP3", - }, - { - label: - "ZKPs of Elliptic Curve Inner Products from Principal Divisors and Weil Reciprocity", - url: "https://eprint.iacr.org/2022/596", - }, - ], - }, -} diff --git a/data/projects/eigen-trust.ts b/data/projects/eigen-trust.ts deleted file mode 100644 index 470ca13..0000000 --- a/data/projects/eigen-trust.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A distributed reputation system with zero-knowledge features.", - description: - "EigenTrust is a library designed to manage trust within a distributed network, incorporating zero-knowledge features. It serves as a reputation bank for the Ethereum ecosystem, providing an interoperable layer for managing reputation and trust. The protocol creates zero-knowledge proofs of reputation scores based on ratings given by network participants. This allows for the creation of a reputation system for peer-to-peer marketplaces and exchanges, reputation-weighted voting, and community gatekeeping.", - }, -} - -export const eigenTrust: ProjectInterface = { - id: "eigen-trust", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.RESEARCH, - section: "archived", - content, - image: "", - name: "EigenTrust", - links: { - github: "https://github.com/eigen-trust/protocol", - }, - tags: { - keywords: ["Reputation", "Identity"], - themes: ["build"], - types: ["Infrastructure/protocol"], - builtWith: ["ethereum attestation service", "halo2", "ethers.rs"], - }, -} diff --git a/data/projects/interep.ts b/data/projects/interep.ts deleted file mode 100644 index 8de9c03..0000000 --- a/data/projects/interep.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "An identity bridge from web2 to web3", - description: - "Interep aims to provide an identity solution for Ethereum users by bridging from an established digital identity source such as Reddit, Twitter, and Github. The product provides an identity layer in the application stack and uses the Semaphore framework to ensure privacy. Interep allows users to establish sybil-resistant decentralized identities on web3 without starting from scratch. By leveraging zero-knowledge proofs, Interep ensures only essential information is disclosed.", - }, -} - -export const Interep: ProjectInterface = { - id: "interep", - image: "interep.svg", - name: "Interep", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "archived", - content, - tags: { - keywords: ["social", "reputation"], - }, - links: { - website: "https://docs.interep.link/", - github: "https://github.com/interep-project", - youtube: "https://www.youtube.com/watch?v=dYKgHkb_aqk", - }, - extraLinks: { - learn: [ - { - label: "Interep: An on-ramp for reputation", - url: "https://mirror.xyz/privacy-scaling-explorations.eth/w7zCHj0xoxIfhoJIxI-ZeYIXwvNatP1t4w0TsqSIBe4", - }, - ], - }, -} diff --git a/data/projects/jubmoji.ts b/data/projects/jubmoji.ts deleted file mode 100644 index e4faeac..0000000 --- a/data/projects/jubmoji.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Users of Jubmoji.quest tap NFC cards to collect signatures. By collecting these signatures, they complete quests.", - description: ` -Jubmoji.quest is a place to keep personal, provable digital mementos from people you meet and places you visit IRL. Each time you tap a card, you collect a Jubmoji, a unique cryptographic signature that you can store privately and share as you wish! - -The learnings from this experiment influenced the creation of [Cursive](https://pse.dev/en/projects/cursive) which continues to explore applications of cryptography for human connection. -`, - }, -} - -export const jubmoji: ProjectInterface = { - id: "jubmoji", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.APPLICATION, - section: "archived", - content, - image: "jubmoji.webp", - name: "jubmoji.quest", - links: { - github: "https://github.com/jubmoji/jubmoji.quest", - website: "https://www.jubmoji.quest/", - }, - tags: { - keywords: [ - "anonymity/privacy", - "education", - "data portability", - "social", - "wallets", - "identity", - "key management", - "reputation", - "toolkits", - ], - builtWith: ["snarkjs", "circom", "node"], - themes: ["build", "play"], - }, -} diff --git a/data/projects/maci-platform.ts b/data/projects/maci-platform.ts deleted file mode 100644 index b2e5e31..0000000 --- a/data/projects/maci-platform.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Run a voting round in your community! Forked from EasyRetroPGF and enhanced with MACI for privacy, anti-bribery and anti-collusion", - description: `### Overview - -[MACI Platform](https://github.com/privacy-scaling-explorations/maci-platform/tree/main) is an implementation of EasyRetroPGF with MACI. - -This project enables any community, organization or ecosystem to run a voting round. -It is highly configurable to enable different voting mechanisms (quadratic voting, quadratic funding, etc), gating mechanisms (token based, attestation based, hats-based, etc) and an easy-to-use UI for both round organizers and voters. - -### Features - -With MACI Platform, you can run different kind of voting rounds for your community, with the following features: - -1. Full benefit of MACI's properties - Plug into MACI's anti-collusion and privacy features -2. Clean UX - The interface is optimised for voters and projects that want to participate in rounds -3. Customisable - The platform can be customised quickly to fit different use cases`, - }, -} - -export const maciPlatform: ProjectInterface = { - id: "maci-platform", - category: ProjectCategory.APPLICATION, - projectStatus: ProjectStatus.INACTIVE, - section: "pse", - content, - image: "maci-platform.png", - name: "MACI Platform", - links: { - github: "https://github.com/privacy-scaling-explorations/maci-platform", - website: "https://maci.pse.dev", - twitter: "https://twitter.com/zkmaci", - }, - tags: { - keywords: ["Anonymity/privacy", "Voting/governance"], - themes: ["build"], - types: ["Lego sets/toolkits", "Infrastructure/protocol", "Public Good"], - builtWith: ["MACI", "EAS", "EasyRetroPGF"], - }, -} diff --git a/data/projects/mpz.ts b/data/projects/mpz.ts deleted file mode 100644 index a9298c8..0000000 --- a/data/projects/mpz.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A safe, performant, modular and portable multi-party computation (MPC) library.", - description: `mpz (*pronounced as “em-peasy”*) is a collection of Rust-based libraries for multi-party computation (MPC), designed to be safe, performant and modular. - -Built with portability in mind, mpz runs natively or in the browser via WebAssembly (WASM). It serves as the core MPC implementation behind [TLSNotary](tlsn), but its architecture is broadly applicable across privacy-preserving and cryptographic use cases. - -mpz is part of Privacy & Scaling Explorations’ broader effort to advance practical cryptographic tooling. It is dual-licensed under Apache-2.0 and MIT to encourage open-source collaboration.`, - }, -} - -export const mpz: ProjectInterface = { - id: "mpz", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "mpz-cover.png", - name: "mpz", - license: "MIT or Apache-2.0", - links: { - github: "https://github.com/privacy-scaling-explorations/mpz", - }, - tags: { - themes: ["build", "play"], - types: ["Legos/dev tools", "Infrastructure/protocol"], - builtWith: ["rust"], - keywords: ["Anonymity/privacy", "mpc"], - }, - extraLinks: { - play: [ - { - label: "mpz-play (Exercises to get familiar with mpz)", - url: "https://github.com/th4s/mpz-play", - }, - ], - }, -} diff --git a/data/projects/p256.ts b/data/projects/p256.ts deleted file mode 100644 index 66a3d27..0000000 --- a/data/projects/p256.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Smart contract wallet enabling transactions through familiar flows like touchID, faceID, WebAuth, and Passkeys.", - description: - "P256 is an ERC-4337 smart contract wallet that leverages zk-SNARKs for WebAuthn and P-256 signature verification. It aims to simplify Ethereum transactions by incorporating familiar authentication methods like touchID and faceID. The project addresses the challenges of seed phrase management and leverages the biometric capabilities of billions of cellphones to create a more user-friendly crypto experience. Technically, it is an end-to-end ERC-4337 smart contract wallet that verifies ZK proofs of Passkey signatures using the Halo2 proving system.", - }, -} - -export const p256: ProjectInterface = { - id: "p256", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "", - name: "P256", - links: { - website: "https://www.p256wallet.org/", - github: "https://github.com/privacy-scaling-explorations/p256-circom", - }, - tags: { - keywords: [ - "Toolkits", - "Infrastructure/protocol", - "User Experience", - "Key management", - "Wallets", - "Account Abstraction", - ], - themes: ["build"], - types: ["Legos/dev tools"], - builtWith: ["halo2"], - }, -} diff --git a/data/projects/pod2.ts b/data/projects/pod2.ts deleted file mode 100644 index c4e1089..0000000 --- a/data/projects/pod2.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "The second generation of cryptographic PODs: Provable Data Objects", - description: ` -POD2 is the next iteration of the Provable Object Datatype (POD). This new iteration introduces arbitrary computation on data via custom predicates, recursion and interoperability with other data provenance cryptographic tools. - -This is a 0xPARC project that PSE is collaborating on. -`, - }, -} - -export const pod2: ProjectInterface = { - id: "pod2", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "collaboration", - content, - image: "pod2.png", - name: "POD2", - links: { - github: "https://github.com/0xPARC/pod2", - website: "https://pod.org", - telegram: "https://t.me/zupass" - }, - team: [ - { - name: "Edu", - image: "/avatars/edu.jpeg", - links: { - github: "https://github.com/ed255", - }, - }, - ], - tags: { - keywords: [ - "anonymity/privacy", - "data portability", - "social", - "identity", - "toolkits", - ], - builtWith: ["Rust", "Plonky2", "Groth16", "Typescript"], - themes: ["build", "research"], - }, - extraLinks: { - buildWith: [ - { - label: "PODify your proofs", - url: "https://pod.org/pod/introduction" - }, - { - label: "Config-driven proofs", - url: "https://pod.org/gpc/introduction" - }, - { - label: "Create and consume PODs in your web app", - url: "https://pod.org/z-api/introduction" - }, - { - label: "POD book (evolving)", - url: "https://0xparc.github.io/pod2/introduction.html" - }, - ], - research: [ - { - label: "State of POD R&D", - url: "https://github.com/0xPARC/pod2/milestones", - }, - { - label: "Ideation on a logic VM for PODs", - url: "https://hackmd.io/@gubsheep/r1zxZGpQke", - }, - ], - }, -} diff --git a/data/projects/pollen-labs.ts b/data/projects/pollen-labs.ts deleted file mode 100644 index ec9ada3..0000000 --- a/data/projects/pollen-labs.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Building a better world through open-source & blockchain technology.", - description: `Pollen Labs is driven by a mission to make a significant impact on global lives by addressing complex, pressing issues. We work alongside the community to break barriers, preserve privacy, and build a future where every voice is heard, and a free web is accessible to all. Our projects, like Channel 4, a content discovery engine, and Daisy, focusing on information transparency, embody this mission, enabling community members to earn while they engage. - - We are a small team with a diverse skillset including design, engineering, community growth, and operations. We serve as a product accelerator, facilitating solutions to real-world problems with advanced blockchain technology. Our core value as follow: - - - **A Decentralized Internet for All** - - - **Open Source at Our Core** - - - **Technology as Public Goods** - - - **Privacy as a Human Right** - - - **Collaboration for Impact** - - Pollen Labs exits the PSE in Q4 2024 and now operates as a self-autonomous collective. Join our conversation: https://discord.gg/5B3jP2sgWS `, - }, -} - -export const pollenLabs: ProjectInterface = { - id: "pollen-labs", - content, - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.APPLICATION, - section: "archived", - image: "pollen-labs.svg", - name: "Pollen Labs", - links: { - website: "https://pollenlabs.org/", - twitter: "https://twitter.com/PollenLabs_", - discord: "https://discord.gg/5B3jP2sgWS", - }, - tags: { - keywords: ["Anonymity/privacy", "Scaling", "Public good"], - themes: ["play"], - types: ["Application"], - builtWith: [], - }, -} diff --git a/data/projects/pse-halo2.ts b/data/projects/pse-halo2.ts deleted file mode 100644 index 47284c6..0000000 --- a/data/projects/pse-halo2.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ProjectInterface, ProjectStatus } from "@/lib/types" - -export const pse_halo2: ProjectInterface = { - id: "pse-halo2", - image: "", - name: "PSE-Halo2", - section: "pse", - projectStatus: ProjectStatus.MAINTAINED, - links: { - github: "https://github.com/privacy-scaling-explorations/halo2", - website: "https://privacy-scaling-explorations.github.io/halo2/", - }, - content: { - en: { - tldr: "PSE-Halo2 is a re-architected, KZG-backended fork of Zcash's Halo2, an instantiation of PLONK, with support for more curves and other features.", - description: ` -PSE-Halo2 modified, extended, and eventually [re-architected](https://github.com/privacy-scaling-explorations/halo2/pull/254) the [original Halo2 implementation by Zcash](https://github.com/zcash/halo2) - an instantiation of the PLONK proof system. - -The original IPA backend was swapped with KZG for cost-effective L1 verifiability, and comes with a Solidity verifier. Support for many [additional curves](https://github.com/privacy-scaling-explorations/halo2curves) and other [experimental features](https://github.com/kilic/tetris) were added, and the system was eventually re-architected by [splitting the front- and backends](https://github.com/privacy-scaling-explorations/halo2/pull/254). PSE-Halo2 has significant contributions from the wider community.`, - }, - }, - tags: { - keywords: ["Proof Systems", "PLONK", "KZG", "Halo2"], - themes: ["build"], - types: ["Infrastructure/protocol", "Lego sets/toolkits"], - builtWith: ["halo2", "rust"], - }, - extraLinks: { - learn: [ - { - label: "Documentation", - url: "https://privacy-scaling-explorations.github.io/halo2/", - }, - { - label: "PLONK", - url: "https://www.youtube.com/watch?v=A0oZVEXav24", - }, - { - label: "Origins of Halo2", - url: "https://www.youtube.com/watch?v=KdkVTEHUxgo", - }, - ], - }, -} diff --git a/data/projects/pse-security.ts b/data/projects/pse-security.ts deleted file mode 100644 index 4b36d8e..0000000 --- a/data/projects/pse-security.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Proactively securing Ethereum's L2 and ZK ecosystems.", - description: - "PSE Security is a division of the Privacy & Scaling Explorations team at the Ethereum Foundation. Its primary goal is to identify and rectify bugs, thereby enhancing the security of the Ethereum Layer 2 and Zero-Knowledge ecosystems. Recognizing the potential for critical bugs to cause significant setbacks, PSE Security is committed to preemptively addressing these issues. The team offers open-source projects like the ZK Bug Tracker and Bridge Bug Tracker, which track real bugs and exploits in production code, and encourages community contributions. PSE Security also conducts manual audits and plans to help teach the community more about security and ways they can prevent bugs themselves.", - }, -} - -export const pseSecurity: ProjectInterface = { - id: "pse-security", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.RESEARCH, - section: "pse", - content, - image: "pse-security.png", - name: "PSE Security", - links: { - github: "https://github.com/privacy-scaling-explorations/security", - }, - tags: { - keywords: [ - "Anonymity/privacy", - "Education", - "Key management", - "Scaling", - "Security", - ], - themes: ["build"], - types: ["Legos/dev tools"], - builtWith: ["slither", "ecne", "circomspect", "echidna"], - }, -} diff --git a/data/projects/publicly-verifiable-garbled-circuit.ts b/data/projects/publicly-verifiable-garbled-circuit.ts deleted file mode 100644 index 0ade126..0000000 --- a/data/projects/publicly-verifiable-garbled-circuit.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Publicly verifiable garbled circuit research", - description: ` -We are actively researching on publicly verifiable garbled circuit. This will lead to constant round publicly verifiable 2 party computation. Currently we're exploring two ways to achieve this. The first approach is based on authenticated garbling and vector OLE and the second approach is based on committed OT and zkp. -See more details [here](https://hackmd.io/bPUw6M9qSL-AyE19A58tMw).`, - }, -} - -export const publiclyVerifiableGarbledCircuit: ProjectInterface = { - id: "publicly-verifiable-garbled-circuit", - category: ProjectCategory.RESEARCH, - projectStatus: ProjectStatus.INACTIVE, - section: "pse", - content, - image: "", - imageAlt: "Publicly verifiable garbled circuit", - name: "Publicly verifiable garbled circuit", - links: { - website: "https://hackmd.io/bPUw6M9qSL-AyE19A58tMw", - }, - tags: { - keywords: ["mpc", "garbled circuit", "zkp"], - themes: ["research"], - }, -} diff --git a/data/projects/sonobe.ts b/data/projects/sonobe.ts deleted file mode 100644 index db341b6..0000000 --- a/data/projects/sonobe.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Modular folding library supporting multiple schemes and decider backends", - description: `In collaboration with [0xPARC](https://0xparc.org), [Sonobe](https://github.com/privacy-scaling-explorations/sonobe) is a modular library to fold arithmetic circuit instances in an Incremental Verifiable computation (IVC) style. It supports multiple frontends, multiple folding schemes, and multiple decider backends, allowing users to plug-and-play different components. - -- **Frontends:** - - Arkworks - - Circom - - Noir - - Noname - -- **Folding schemes:** - - [Nova](https://eprint.iacr.org/2021/370), supporting also both the [Mova](https://eprint.iacr.org/2024/1220) & [Ova](https://hackmd.io/V4838nnlRKal9ZiTHiGYzw) variants. - - [CycleFold](https://eprint.iacr.org/2023/1192) - - [HyperNova](https://eprint.iacr.org/2023/573) - - [ProtoGalaxy](https://eprint.iacr.org/2023/1106) - -- **Decider backends:** - - Groth16 and KZG commitment [proofs](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/decider-prove.html) which are [verifiable on-chain](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/solidity-verifier.html). - -- **Other features:** - - [ZK Layer](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/nova-zk.html) - - In-browser [WASM usage](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/wasm.html) - -- **Example projects:** - - [Bitcoin light client](https://github.com/dmpierre/sonobe-btc) leveraging Sonobe - - [Hash chains](https://github.com/arnaucube/hash-chain-sonobe): proving chains of Sha256 and Keccak256 hashes - `, - }, -} - -export const sonobe: ProjectInterface = { - id: "sonobe", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "sonobe.png", - name: "Sonobe Folding Library", - links: { - github: "https://github.com/privacy-scaling-explorations/sonobe", - website: "https://privacy-scaling-explorations.github.io/sonobe-docs", - }, - tags: { - keywords: ["Folding", "IVC"], - themes: ["build"], - types: ["Infrastructure/protocol", "Lego sets/toolkits"], - builtWith: ["rust"], - }, -} diff --git a/data/projects/summa.ts b/data/projects/summa.ts deleted file mode 100644 index 1a0baf5..0000000 --- a/data/projects/summa.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Protocol enabling centralized exchanges to prove solvency without compromising private information.", - description: - "Summa allows centralized exchanges to demonstrate that their assets exceed their liabilities without revealing critical business information such as individual user balances, total number of users, and total liabilities or assets. It uses zero-knowledge proofs to ensure that exchanges can demonstrate they have sufficient assets to cover all user balances. The protocol involves building a Merkle Sum Tree of user balances, generating proofs for each user, and allowing users to verify these proofs.", - }, -} - -export const summa: ProjectInterface = { - id: "summa", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "summa.svg", - name: "Summa", - links: { - github: "https://github.com/summa-dev", - }, - tags: { - keywords: ["Anonymity/privacy", "Computational Integrity"], - themes: ["build", "play"], - types: ["Infrastructure/protocol", "Application"], - builtWith: ["halo2"], - }, - extraLinks: { - learn: [ - { - label: "Documentation", - url: "https://summa.gitbook.io/summa", - }, - ], - }, -} diff --git a/data/projects/tlsn.ts b/data/projects/tlsn.ts deleted file mode 100644 index 604dbd6..0000000 --- a/data/projects/tlsn.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A protocol for creating cryptographic proofs of authenticity for any data on the web.", - description: `TLSNotary is ideal for developers of privacy-focused projects that require **data provenance** from secure web servers. It leverages the widely-used **Transport Layer Security (TLS)** protocol to securely and privately prove that a transcript of communications with a web server took place. The protocol divides TLS session keys between two parties: the Prover and the Verifier, using **Multi-Party Computation (MPC)**. Neither the User nor Notary are in possession of the full TLS session keys, they only hold a share of those keys. This retains the security assumptions of TLS while allowing the Prover to demonstrate the **authenticity of the communication** to the Verifier. The Verifier remains unaware of which webserver is being queried, and the Verifier never has access to the unencrypted communications, except for the data the Prover explicitly wants to disclose. - -**TLSNotary can help your project with secure and privacy-preserving data portability!**`, - }, -} - -export const tlsn: ProjectInterface = { - id: "tlsn", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "tlsn.webp", - name: "TLSNotary", - license: "MIT or Apache-2.0", - links: { - github: "https://github.com/tlsnotary", - website: "https://tlsnotary.org/", - discord: "https://discord.gg/9XwESXtcN7", - twitter: "https://x.com/tlsnotary", - }, - tags: { - themes: ["build", "play"], - types: [ - "Legos/dev tools", - "Infrastructure/protocol", - "Plugin", - "Application", - ], - builtWith: ["rust"], - keywords: [ - "Anonymity/privacy", - "Identity", - "Reputation", - "Data portability", - "zkTLS", - ], - }, - extraLinks: { - play: [ - { - label: "Getting started", - url: "https://tlsnotary.org/docs/quick_start/", - }, - ], - learn: [ - { - label: "Documentation", - url: "https://tlsnotary.org/docs", - }, - ], - }, -} diff --git a/data/projects/voice-deck.ts b/data/projects/voice-deck.ts deleted file mode 100644 index 320b11c..0000000 --- a/data/projects/voice-deck.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "From Individual Actions to Collective Impact, Every Voice Makes a Difference", - description: - "VoiceDeck isn't just a platform; it's a movement. By enabling citizens to fund journalism that makes a real difference, we're crafting a narrative where every contribution paints a stroke on the canvas of our collective future. Join us to foster a legacy where journalism is powered by the very communities it serves.", - }, -} - -export const voicedeck: ProjectInterface = { - id: "voice-deck", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.APPLICATION, - section: "collaboration", - content, - image: "voiceDeck.svg", - name: "VoiceDeck", - links: { - github: "https://github.com/VoiceDeck", - website: "https://voicedeck.org/", - twitter: "https://twitter.com/VoiceDeckDAO", - }, - tags: { - keywords: ["Public goods"], - themes: ["play"], - types: ["Application"], - builtWith: ["anonAadhaar", "Hypercerts"], - }, -} diff --git a/data/projects/wax.ts b/data/projects/wax.ts deleted file mode 100644 index b1f2ca1..0000000 --- a/data/projects/wax.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "", - description: ` - -`, - }, -} - -export const wax: ProjectInterface = { - id: "wax", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "wax.webp", - name: "Wallet Account eXperiments - WAX", - links: { - github: "https://github.com/getwax", - }, - tags: { - builtWith: [ - "foundry", - "hardhat", - "node", - "solidity bls library", - "sqlite", - "docker", - "ethers.js", - "deno", - ], - keywords: ["Scaling", "Key management", "WAX"], - themes: ["build"], - types: ["Prototype", "Proof of concept", "Lego sets/toolkits"], - }, -} diff --git a/data/projects/zk-email.ts b/data/projects/zk-email.ts deleted file mode 100644 index e6b31cd..0000000 --- a/data/projects/zk-email.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "ZK Email is a library that allows for anonymous verification of email signatures while masking specific data.", - description: - "ZK Email is a library for anonymous verification of emails while selectively revealing specific data. It allows a prover to demonstrate receipt of an email from a specific sender or domain or the presence of certain text in the subject or body. This can be used for Web 2.0 interoperability, email recovery solutions of smart accounts, anonymous KYC, or to create interesting applications based on anonymity sets.", - }, -} - -export const zkemail: ProjectInterface = { - id: "zk-email", - category: ProjectCategory.APPLICATION, - projectStatus: ProjectStatus.ACTIVE, - section: "collaboration", - content, - image: "zk-email.jpeg", - name: "zk-email", - links: { - github: "https://github.com/zkemail", - twitter: "https://twitter.com/zkemail", - website: "https://zk.email/", - }, - tags: { - themes: [], - types: [], - keywords: ["email", "identity", "anonymity/privacy", "DKIM", "signatures"], - builtWith: ["circom", "snarkjs", "halo2"], - }, -} diff --git a/data/projects/zkevm-community.ts b/data/projects/zkevm-community.ts deleted file mode 100644 index 9c639b8..0000000 --- a/data/projects/zkevm-community.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "A zero-knowledge proof mechanism for Ethereum block verification.", - description: - "zkEVM Community Edition is a project aimed at validating Ethereum blocks using zero-knowledge proofs. It is designed to be fully compatible with Ethereum's EVM and serves two primary goals. First, it enables the creation of a layer 2 network (zkRollup) compatible with the Ethereum ecosystem, which uses zero-knowledge proofs to validate blocks, thus enhancing scalability. Second, it allows the generation of zero-knowledge proofs for blocks from the existing layer 1 Ethereum network, enabling light clients to quickly synchronize many blocks with low resource consumption while ensuring block correctness without needing trust in external parties.", - }, -} - -export const zkevmCommunity: ProjectInterface = { - id: "zkevm-community", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.DEVTOOLS, - section: "pse", - content, - image: "zkevm.jpg", - name: "zkEVM Community Edition", - links: { - github: "https://github.com/privacy-scaling-explorations/zkevm-circuits", - }, - tags: { - keywords: ["Scaling"], - themes: ["build"], - types: ["Infrastructure/protocol", "Lego sets/toolkits"], - builtWith: ["halo2", "rust", "geth"], - }, -} diff --git a/data/projects/zkml.ts b/data/projects/zkml.ts deleted file mode 100644 index d3949ce..0000000 --- a/data/projects/zkml.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "ZKML (Zero-Knowledge Machine Learning) leverages zero-knowledge proofs for privacy-preserving machine learning, enabling model and data privacy with transparent verification.", - description: - "ZKML is a solution that combines the power of zero-knowledge proofs (ZKPs) and machine learning to address the privacy concerns in traditional machine learning. It provides a platform for machine learning developers to convert their TensorFlow Keras models into ZK-compatible versions, ensuring model privacy, data privacy, and transparent verification. ZKML can be used to verify if a specific machine learning model was used to generate a particular piece of content, without revealing the input or the model used. It has potential use cases in on-chain biometric authentication, private data marketplace, proprietary ML model sharing, and AIGC NFTs.", - }, -} - -export const zkml: ProjectInterface = { - id: "zkml", - projectStatus: ProjectStatus.INACTIVE, - category: ProjectCategory.RESEARCH, - section: "pse", - image: "zkml.png", - name: "ZKML", - content, - links: { - github: "https://github.com/socathie/circomlib-ml", - }, - tags: { - keywords: ["Anonymity/privacy", "Scaling"], - themes: ["research"], - types: ["Proof of concept", "Infrastructure/protocol"], - builtWith: ["circom", "halo2", "nova"], - }, -} diff --git a/data/projects/zkp2p.ts b/data/projects/zkp2p.ts deleted file mode 100644 index 5edc581..0000000 --- a/data/projects/zkp2p.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - ProjectCategory, - ProjectContent, - ProjectInterface, - ProjectStatus, -} from "@/lib/types" - -const content: ProjectContent = { - en: { - tldr: "Instant fiat to crypto onramp connecting traditional peer-to-peer payment services with zero-knowledge proofs.", - description: - "ZKP2P is for defi consumers looking to onramp assets on chain quickly without going through a CEX as an intermediary. ZKP2P generates a privacy-preserving proof of payment between two users on existing payment rails like Venmo or Paypal and uses said proof to unlock escrowed digital assets on-chain.", - }, -} - -export const zkp2p: ProjectInterface = { - id: "zkp2p", - projectStatus: ProjectStatus.ACTIVE, - category: ProjectCategory.APPLICATION, - section: "grant", - content, - image: "zkp2p.png", - name: "ZKP2P", - links: { - github: "https://github.com/zkp2p", - website: "https://zkp2p.xyz/", - twitter: "https://twitter.com/zkp2p", - }, - tags: { - keywords: ["Private communications"], - themes: ["play"], - types: ["Proof of concept", "Application"], - builtWith: ["circom", "halo2"], - }, -} diff --git a/hooks/useGetProjectRelatedArticles.ts b/hooks/useGetProjectRelatedArticles.ts index 62a50d0..9edd117 100644 --- a/hooks/useGetProjectRelatedArticles.ts +++ b/hooks/useGetProjectRelatedArticles.ts @@ -1,5 +1,5 @@ import { useState, useEffect } from "react" -import { Article } from "@/lib/blog" +import { Article } from "@/lib/content" interface UseGetProjectRelatedArticlesProps { projectId: string diff --git a/lib/blog.ts b/lib/blog.ts deleted file mode 100644 index 27cfcea..0000000 --- a/lib/blog.ts +++ /dev/null @@ -1,158 +0,0 @@ -import fs from "fs" -import path from "path" -import matter from "gray-matter" -import jsYaml from "js-yaml" - -export interface Article { - id: string - title: string - image?: string - tldr?: string - content: string - date: string - authors?: string[] - signature?: string - publicKey?: string - hash?: string - canonical?: string - tags?: { id: string; name: string }[] - projects?: string[] -} - -const articlesDirectory = path.join(process.cwd(), "articles") - -// Get all articles from /articles -export function getArticles(options?: { - limit?: number - tag?: string - project?: string -}) { - const { limit = 1000, tag, project } = options ?? {} - // Get file names under /articles - const fileNames = fs.readdirSync(articlesDirectory) - const allArticlesData = fileNames.map((fileName: string) => { - const id = fileName.replace(/\.md$/, "") - if (id.toLowerCase() === "readme") { - return null - } - - // Read markdown file as string - const fullPath = path.join(articlesDirectory, fileName) - const fileContents = fs.readFileSync(fullPath, "utf8") - - try { - // Use matter with options to handle multiline strings - const matterResult = matter(fileContents, { - engines: { - yaml: { - // Ensure multiline strings are parsed correctly - parse: (str: string) => { - try { - // Use js-yaml's safe load to parse the YAML with type assertion - return jsYaml.load(str) as object - } catch (e) { - console.error(`Error parsing frontmatter in ${fileName}:`, e) - // Fallback to empty object if parsing fails - return {} - } - }, - }, - }, - }) - - // Ensure tags are always an array, combining 'tags' and 'tag' - const tags = [ - ...(Array.isArray(matterResult.data?.tags) - ? matterResult.data.tags - : []), - ...(matterResult.data?.tag ? [matterResult.data.tag] : []), - ] - - return { - id, - ...matterResult.data, - tags: tags.map((tag) => ({ - id: tag - .toLowerCase() - .replace(/\s+/g, "-") - .replace(/[^a-z0-9-]/g, ""), - name: tag, - })), - content: matterResult.content, - } - } catch (error) { - console.error(`Error processing ${fileName}:`, error) - // Return minimal article data if there's an error - return { - id, - title: `Error processing ${id}`, - content: "This article could not be processed due to an error.", - date: new Date().toISOString().split("T")[0], - tags: [], - } - } - }) - - let filteredArticles = allArticlesData.filter(Boolean) as Article[] - - // Filter by tag if provided - if (tag) { - filteredArticles = filteredArticles.filter((article) => - article.tags?.some((t) => t.id === tag) - ) - } - - // Filter by project if provided - if (project) { - filteredArticles = filteredArticles.filter( - (article) => - Array.isArray(article.projects) && article.projects.includes(project) - ) - } - - // Sort posts by date - return filteredArticles - .sort((a, b) => { - const dateA = new Date(a.date) - const dateB = new Date(b.date) - - // Sort in descending order (newest first) - return dateB.getTime() - dateA.getTime() - }) - .slice(0, limit) - .filter((article) => article.id !== "_article-template") -} - -export const getArticleTags = () => { - const articles = getArticles() - const allTags = - articles - .map((article) => article.tags?.map((t) => t.name)) - .flat() - .filter(Boolean) ?? [] - - return Array.from(new Set(allTags)) as string[] -} - -export const getArticleTagsWithIds = () => { - const tags = getArticleTags() - return tags.map((tag) => ({ - id: tag - .toLowerCase() - .replace(/\s+/g, "-") - .replace(/[^a-z0-9-]/g, ""), - name: tag, - })) -} - -export function getArticleById(slug?: string) { - // Note: This might need adjustment if you expect getArticleById to also have tags - // Currently relies on the base getArticles() which fetches all tags - const articles = getArticles() // Fetch all articles to find the one by ID - - return articles.find((article) => article.id === slug) -} - -const lib = { getArticles, getArticleById } - -export default lib diff --git a/lib/content.ts b/lib/content.ts new file mode 100644 index 0000000..c961e23 --- /dev/null +++ b/lib/content.ts @@ -0,0 +1,239 @@ +import fs from "fs" +import path from "path" +import matter from "gray-matter" +import jsYaml from "js-yaml" + +export interface Project { + id: string + title: string + description: string + [key: string]: any +} + +export interface ArticleTag { + id: string + name: string +} + +export interface Article { + id: string + title: string + image?: string + tldr?: string + content: string + date: string + authors?: string[] + signature?: string + publicKey?: string + hash?: string + canonical?: string + tags?: ArticleTag[] + projects?: string[] +} + +const articlesDirectory = path.join(process.cwd(), "content/articles") +const projectsDirectory = path.join(process.cwd(), "content/projects") + +// Generic function to read and process markdown content from any directory +export function getMarkdownContent(options: { + directory: string + excludeFiles?: string[] + processContent?: (data: any, content: string, id: string) => T +}): T[] { + const { directory, excludeFiles = ["readme"], processContent } = options + + const fileNames = fs.readdirSync(directory) + const allContentData = fileNames.map((fileName: string) => { + const id = fileName.replace(/\.md$/, "") + if ( + excludeFiles.some((exclude) => id.toLowerCase() === exclude.toLowerCase()) + ) { + return null + } + + // Read markdown file as string + const fullPath = path.join(directory, fileName) + const fileContents = fs.readFileSync(fullPath, "utf8") + + try { + // Use matter with options to handle multiline strings + const matterResult = matter(fileContents, { + engines: { + yaml: { + // Ensure multiline strings are parsed correctly + parse: (str: string) => { + try { + // Use js-yaml's safe load to parse the YAML with type assertion + return jsYaml.load(str) as object + } catch (e) { + console.error(`Error parsing frontmatter in ${fileName}:`, e) + // Fallback to empty object if parsing fails + return {} + } + }, + }, + }, + }) + + // Use custom processor if provided + if (processContent) { + return processContent(matterResult.data, matterResult.content, id) + } + + // Default processing - return raw data with content + return { + id, + ...matterResult.data, + content: matterResult.content, + } + } catch (error) { + console.error(`Error processing ${fileName}:`, error) + // Return minimal content data if there's an error + return { + id, + title: `Error processing ${id}`, + content: "This content could not be processed due to an error.", + date: new Date().toISOString().split("T")[0], + } + } + }) + + return allContentData.filter(Boolean) as T[] +} + +export function getArticles(options?: { + limit?: number + tag?: string + project?: string +}) { + const { limit = 1000, tag, project } = options ?? {} + + const allArticles = getMarkdownContent
({ + directory: articlesDirectory, + excludeFiles: ["readme", "_readme", "_article-template"], + processContent: (data, content, id) => { + // Normalize tags from both 'tags' and 'tag' fields + const rawTags = [ + ...(Array.isArray(data?.tags) ? data.tags : []), + ...(data?.tag ? [data.tag] : []), + ] + + // Process and normalize tags + const normalizedTags = rawTags + .map((tag) => { + if (typeof tag !== "string") return null + const name = tag.trim() + if (!name) return null + return { + id: name + .toLowerCase() + .replace(/\s+/g, "-") + .replace(/[^a-z0-9-]/g, ""), + name, + } + }) + .filter((tag): tag is ArticleTag => tag !== null) + + return { + id, + ...data, + tags: normalizedTags, + content, + } + }, + }) + + let filteredArticles = allArticles + + // Filter by tag if provided + if (tag) { + const tagId = tag.toLowerCase() + filteredArticles = filteredArticles.filter((article) => + article.tags?.some((t) => t.id === tagId) + ) + } + + // Filter by project if provided + if (project) { + filteredArticles = filteredArticles.filter( + (article) => + Array.isArray(article.projects) && article.projects.includes(project) + ) + } + + // Sort posts by date + return filteredArticles + .sort((a, b) => { + const dateA = new Date(a.date) + const dateB = new Date(b.date) + + // Sort in descending order (newest first) + return dateB.getTime() - dateA.getTime() + }) + .slice(0, limit) + .filter((article) => article.id !== "_article-template") +} + +export function getProjects(options?: { + tag?: string + limit?: number + status?: string +}) { + const { tag, limit, status } = options ?? {} + let allProjects = getMarkdownContent({ + directory: projectsDirectory, + excludeFiles: ["readme", "_readme", "_project-template"], + }) + + // Filter by tag if provided + if (tag) { + allProjects = allProjects.filter((project) => project.tags?.includes(tag)) + } + + // Filter by status if provided + if (status) { + allProjects = allProjects.filter((project) => project.status === status) + } + + // Apply limit if provided + if (limit && limit > 0) { + allProjects = allProjects.slice(0, limit) + } + + return allProjects +} + +export const getArticleTags = () => { + const articles = getArticles() + const allTags = articles.reduce((acc, article) => { + article.tags?.forEach((tag) => { + if (!acc.some((t) => t.id === tag.id)) { + acc.push(tag) + } + }) + return acc + }, []) + + // Sort tags alphabetically by name + return allTags.sort((a, b) => a.name.localeCompare(b.name)) +} + +export const getArticleTagsWithIds = () => { + const tags = getArticleTags() + return tags.map((tag: any) => ({ + id: tag + ?.toLowerCase() + .replace(/\s+/g, "-") + .replace(/[^a-z0-9-]/g, ""), + name: tag, + })) +} + +export function getArticleById(slug?: string) { + const articles = getArticles() + return articles.find((article) => article.id === slug) +} + +const lib = { getArticles, getArticleById, getProjects } + +export default lib diff --git a/lib/projectsUtils.ts b/lib/projectsUtils.ts deleted file mode 100644 index 97c6b29..0000000 --- a/lib/projectsUtils.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { projects } from "@/data/projects" - -import { ProjectInterface } from "./types" - -export const getProjectById = (id: string | number) => { - const project: ProjectInterface = - projects.filter( - (project) => - String(project.id?.toLowerCase()) === id.toString().toLowerCase() - )[0] ?? {} - - const content = project?.content?.["en"] // TODO: To remove after all projects are updated - - return { - project, - content, - } -} diff --git a/lib/types.ts b/lib/types.ts index ab22359..3c4fcc5 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -139,6 +139,7 @@ export interface ProjectInterface { projectStatus: ProjectStatus tags?: ProjectTags extraLinks?: ActionLinkType + tldr?: string cardTags?: { primary?: string secondary?: string diff --git a/locales/en/devcon-7.json b/locales/en/devcon-7.json deleted file mode 100644 index ef5265c..0000000 --- a/locales/en/devcon-7.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "showMore": "Show More" -} diff --git a/state/useProjectFiltersState.ts b/state/useProjectFiltersState.ts deleted file mode 100644 index 76d392a..0000000 --- a/state/useProjectFiltersState.ts +++ /dev/null @@ -1,351 +0,0 @@ -import { projects } from "@/data/projects" -import Fuse from "fuse.js" -import { create } from "zustand" - -import { ProjectCategory, ProjectInterface } from "@/lib/types" -import { uniq } from "@/lib/utils" -import { LABELS } from "@/app/labels" - -export type ProjectSortBy = "random" | "asc" | "desc" | "relevance" -export type ProjectFilter = - | "keywords" - | "builtWith" - | "themes" - | "fundingSource" -export type FiltersProps = Record -export const DEFAULT_PROJECT_SORT_BY: ProjectSortBy = "asc" -interface ProjectInterfaceScore extends ProjectInterface { - score: number -} - -export const SortByFnMapping: Record< - ProjectSortBy, - (a: ProjectInterfaceScore, b: ProjectInterfaceScore) => number -> = { - random: () => Math.random() - 0.5, - asc: (a, b) => a.name.localeCompare(b.name), - desc: (a, b) => b.name.localeCompare(a.name), - relevance: (a, b) => b?.score - a?.score, // sort from most relevant to least relevant -} - -export const FilterLabelMapping: Record = { - keywords: LABELS.COMMON.FILTER_LABELS.KEYWORDS, - builtWith: LABELS.COMMON.FILTER_LABELS.BUILT_WITH, - themes: LABELS.COMMON.FILTER_LABELS.THEMES, - fundingSource: LABELS.COMMON.FILTER_LABELS.FUNDING_SOURCE, -} - -export const FilterTypeMapping: Partial< - Record -> = { - keywords: "checkbox", - builtWith: "checkbox", - themes: "button", - fundingSource: "checkbox", -} -interface ProjectStateProps { - sortBy: ProjectSortBy - projects: ProjectInterface[] - researchs: ProjectInterface[] - filters: FiltersProps - activeFilters: Partial - queryString: string - searchQuery: string -} - -interface SearchMatchByParamsProps { - searchPattern: string - activeFilters?: Partial - findAnyMatch?: boolean - projects?: ProjectInterface[] -} - -interface toggleFilterProps { - tag: ProjectFilter - value: string - searchQuery?: string -} -interface ProjectActionsProps { - toggleFilter: ({ tag, value, searchQuery }: toggleFilterProps) => void - setFilterFromQueryString: (filters: Partial) => void - onFilterProject: (searchPattern: string) => void - onSelectTheme: (theme: string, searchPattern?: string) => void - sortProjectBy: (sortBy: ProjectSortBy) => void -} - -const createURLQueryString = (params: Partial): string => { - if (Object.keys(params)?.length === 0) return "" // no params, return empty string - const qs = Object.keys(params) - .map((key: any) => `${key}=${encodeURIComponent((params as any)[key])}`) - .join("&") - - return qs -} - -const getProjectFilters = (): FiltersProps => { - const filters: FiltersProps = { - themes: ["play", "build", "research"], - keywords: [], - builtWith: [], - fundingSource: [], - } - - // get list of all tags from project list - projects.forEach((project) => { - if (project?.tags?.builtWith) { - filters.builtWith.push( - ...project.tags.builtWith.map((tag) => { - if (typeof tag === "string") { - return tag.toLowerCase() - } - return "" - }) - ) - } - - if (project?.tags?.keywords) { - filters.keywords.push( - ...project.tags.keywords.map((keyword) => - typeof keyword === "string" ? keyword.toLowerCase() : "" - ) - ) - } - }) - - // duplicate-free array for every tags - Object.entries(filters).forEach(([key, entries]) => { - filters[key as ProjectFilter] = uniq(entries) - }) - - return filters -} - -export const filterProjects = ({ - searchPattern = "", - activeFilters = {}, - findAnyMatch = false, - projects: projectListItems = projects, -}: SearchMatchByParamsProps) => { - const projectList = projectListItems.map((project: any) => { - return { - ...project, - id: project?.id?.toLowerCase(), // force lowercase id - } - }) - // keys that will be used for search - const keys = [ - "name", - "tldr", - "tags.themes", - "tags.keywords", - "tags.builtWith", - "projectStatus", - ] - - const tagsFiltersQuery: Record[] = [] - - Object.entries(activeFilters).forEach(([key, values]) => { - values.forEach((value) => { - if (!value) return // skip empty values - tagsFiltersQuery.push({ - [`tags.${key}`]: value, - }) - }) - }) - - const noActiveFilters = - tagsFiltersQuery.length === 0 && searchPattern.length === 0 - - if (noActiveFilters) return projectList - - let query: any = {} - - if (findAnyMatch) { - // find any match of filters - query = { - $or: [...tagsFiltersQuery, { name: searchPattern }], - } - } else if (searchPattern?.length === 0) { - query = { - $and: [...tagsFiltersQuery], - } - } else if (tagsFiltersQuery.length === 0) { - query = { - name: searchPattern, - } - } else { - query = { - $and: [ - { - $and: [...tagsFiltersQuery], - }, - { name: searchPattern }, - ], - } - } - - const fuse = new Fuse(projectList, { - threshold: 0.3, - useExtendedSearch: true, - includeScore: true, - findAllMatches: true, - distance: 200, - keys, - }) - - const result = fuse.search(query)?.map(({ item, score }) => { - return { - ...item, - score, // 0 indicates a perfect match, while a score of 1 indicates a complete mismatch. - } - }) - return result ?? [] -} - -const sortProjectByFn = ({ - projects = [], - sortBy = DEFAULT_PROJECT_SORT_BY, - category = null, - ignoreCategories = [ProjectCategory.RESEARCH], -}: { - projects: ProjectInterface[] - sortBy?: ProjectSortBy - category?: ProjectCategory | null - ignoreCategories?: ProjectCategory[] -}) => { - const sortedProjectList: ProjectInterface[] = [ - ...(projects as ProjectInterfaceScore[]), - ] - .sort(SortByFnMapping[sortBy]) - .filter((project) => !ignoreCategories.includes(project.category as any)) - - if (category) { - return sortedProjectList.filter((project) => project.category === category) - } - - return sortedProjectList.map((project: any) => { - return { - id: project?.id?.toLowerCase(), // force lowercase id - ...project, - } - }) -} - -export const useProjectFiltersState = create< - ProjectStateProps & ProjectActionsProps ->()((set) => ({ - sortBy: DEFAULT_PROJECT_SORT_BY, - projects: sortProjectByFn({ - projects, - ignoreCategories: [ProjectCategory.RESEARCH], - }), - researchs: sortProjectByFn({ - projects, - sortBy: DEFAULT_PROJECT_SORT_BY, - category: ProjectCategory.RESEARCH, - ignoreCategories: [ProjectCategory.DEVTOOLS, ProjectCategory.APPLICATION], - }), - queryString: "", - searchQuery: "", - filters: getProjectFilters(), // list of filters with all possible values from projects - activeFilters: {}, // list of filters active in the current view by the user - toggleFilter: ({ tag: filterKey, value, searchQuery }: toggleFilterProps) => - set((state: any) => { - if (!filterKey) return - const values: string[] = state?.activeFilters?.[filterKey] ?? [] - const index = values?.indexOf(value) - if (index > -1) { - values.splice(index, 1) - } else { - values.push(value) - } - - const activeFiltersNormalized = values.filter(Boolean) - - const activeFilters: Partial = { - ...state.activeFilters, - [filterKey]: activeFiltersNormalized, - } - const queryString = createURLQueryString(activeFilters) - const filteredProjects = filterProjects({ - searchPattern: searchQuery ?? "", - activeFilters, - }) - - return { - ...state, - activeFilters, - queryString, - projects: sortProjectByFn({ - projects: filteredProjects, - sortBy: state.sortBy, - }), - } - }), - onSelectTheme: (theme: string, searchQuery = "") => { - set((state: any) => { - // toggle theme when it's already selected - const themes = state?.activeFilters?.themes?.includes(theme) - ? [] - : [theme] - - const activeFilters = { - ...state.activeFilters, - themes, - } - - const filteredProjects = filterProjects({ - searchPattern: searchQuery ?? "", - activeFilters, - }) - - return { - ...state, - activeFilters, - projects: sortProjectByFn({ - projects: filteredProjects, - sortBy: state.sortBy, - }), - searchQuery, - } - }) - }, - onFilterProject: (searchPattern: string) => { - set((state: any) => { - const filteredProjects = filterProjects({ - searchPattern, - activeFilters: state.activeFilters, - }) - - return { - ...state, - projects: sortProjectByFn({ - projects: filteredProjects, - sortBy: state.sortBy, - ignoreCategories: [], // when filtering, show all projects regardless of category - }), - } - }) - }, - setFilterFromQueryString: (filters: Partial) => { - set((state: any) => { - return { - ...state, - activeFilters: filters, - queryString: createURLQueryString(filters), - } - }) - }, - sortProjectBy(sortBy: ProjectSortBy) { - set((state: any) => { - return { - ...state, - sortBy, - projects: sortProjectByFn({ - projects: state.projects, - sortBy, - }), - } - }) - }, -})) diff --git a/styles/globals.css b/styles/globals.css index 80009cc..416af81 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -4,8 +4,19 @@ @layer base { :root { - --background: 0 0% 100%; - --foreground: 222.2 47.4% 11.2%; + --background: #FFFFFF; + --foreground: #0F172A; + + --active-selection: #50C3E0; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + + --text-primary: #242528; + --text-secondary: #808590; + + /* TODO: */ --muted: 210 40% 96.1%; --muted-foreground: 215.4 16.3% 46.9%; @@ -19,8 +30,7 @@ --card: 0 0% 100%; --card-foreground: 222.2 47.4% 11.2%; - --primary: 222.2 47.4% 11.2%; - --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; --secondary-foreground: 222.2 47.4% 11.2%; @@ -38,8 +48,21 @@ } .dark { - --background: 224 71% 4%; - --foreground: 213 31% 91%; + --background: #000000; + --foreground: #FFFFFF; + + --active-selection: #E1523A; + + --text-primary: #242528; + --text-secondary: #808590; + + + + + /* TODO: */ + + --primary: #E1523A; + --primary-foreground: #FFF; --muted: 223 47% 11%; --muted-foreground: 215.4 16.3% 56.9%; diff --git a/tailwind.config.js b/tailwind.config.js index 1e51695..0b358eb 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -62,10 +62,15 @@ module.exports = { 700: "#4A4C54", 950: "#242528", }, - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", + + background: "var(--background)", + foreground: "var(--foreground)", + active: { + selection: "var(--active-selection)", + }, + primary: { - DEFAULT: "hsl(var(--primary))", + DEFAULT: "var(--primary)", foreground: "hsl(var(--primary-foreground))", }, secondary: {