[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-ethereum-rln":3,"mdc--m54lke-key":34,"related-repo-ethereum-rln":813,"related-org-ethereum-rln":846},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":32,"mdContent":33},"rln","build privacy-preserving rate-limiting applications","Route, build, adapt, and debug Rate-Limiting Nullifier (RLN) applications. Use when a user wants privacy-preserving rate limits, anonymous chat or posting with spam deterrence, nullifier-based abuse detection, RLN registration\u002Fsignaling\u002Fslashing flows, RLN V3 with Semaphore V4 or Noir, or guidance on choosing an RLN version.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"ethereum","Ethereum","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fethereum.png",[12,16,19,20],{"name":13,"slug":14,"type":15},"Security","security","tag",{"name":17,"slug":18,"type":15},"Web3","web3",{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},"Privacy","privacy",3,"https:\u002F\u002Fgithub.com\u002Fethereum\u002Fzk-skills","2026-08-20T03:53:24.30695",null,0,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":31},[],"AI-friendly skills for EF \u002F PSE Projects","https:\u002F\u002Fgithub.com\u002Fethereum\u002Fzk-skills\u002Ftree\u002FHEAD\u002Fskills\u002Frln","---\nname: rln\ndescription: Route, build, adapt, and debug Rate-Limiting Nullifier (RLN) applications. Use when a user wants privacy-preserving rate limits, anonymous chat or posting with spam deterrence, nullifier-based abuse detection, RLN registration\u002Fsignaling\u002Fslashing flows, RLN V3 with Semaphore V4 or Noir, or guidance on choosing an RLN version.\n---\n\n# RLN\n\n## Overview\n\nUse this skill to help an agent turn a product goal such as \"anonymous users can post once per epoch\" or \"detect and penalize anonymous spam without identifying honest users\" into a practical RLN design or prototype.\n\nRLN is a privacy-preserving rate-limiting pattern for anonymous systems. A user registers a commitment in a Merkle tree, sends messages with zero-knowledge proofs, and exposes public values that make repeated use of the same rate slot detectable. Depending on the deployment, exceeding the rate limit can reveal enough information to slash a stake, remove a user, or block future messages.\n\nThis file is the routing layer. Pick the relevant version note before giving code-level guidance:\n\n- `references\u002Frln-audited.md`: audited RLN guidance for the established Circom implementation.\n- `references\u002Frln-v3.md`: RLN V3 guidance for the Semaphore V4-based implementation with LeanIMT, EdDSA, Circom, and Noir paths.\n- `references\u002Frln-implementation.md`: compact implementation card with payload shape, duplicate detection, audited\u002Fv3 notes, and tests.\n\n## Version Routing\n\nRoute based on the version or technical requirement. If the user names a version, use that version directly.\n\nUse the audited RLN note when:\n\n- the user asks for the original, stable, or audited RLN implementation;\n- the task is a general RLN app and the user does not mention Semaphore V4, Noir, LeanIMT, or v3;\n- the user wants practical app guidance around registration, signaling, verification, duplicate detection, or slashing.\n\nFor code-level planning on this route, also read `references\u002Frln-implementation.md`.\n\nUse RLN V3 when:\n\n- the user explicitly mentions `rln-v3`, Semaphore V4, LeanIMT, EdDSA, Noir, browser benchmarks, or the Rate-Limiting-Nullifier\u002Frln-v3 repository;\n- the user wants the newer Semaphore V4 group\u002Fidentity structure;\n- the user wants to work with the Circom or Noir implementation in `rln-v3`;\n- the user wants benchmark or app guidance for the v3 repository.\n\nFor code-level planning on this route, also read `references\u002Frln-implementation.md`.\n\nIf both versions fit, offer both directly:\n\n- audited RLN: established and security-audited;\n- RLN V3: based on Semaphore V4, uses EdDSA and LeanIMT, includes Circom and Noir implementations, and should be described with the caveat that the v3 circuits have not been separately audited.\n\n## Common Workflow\n\n1. Clarify the abuse problem: spam, denial of service, anonymous posting limits, invite abuse, or rate-limited access.\n2. Decide whether RLN is the right primitive. Use RLN when the app needs anonymous membership plus per-epoch rate limiting or punishable spam. Use Semaphore when the app only needs one signal per scope. Use normal account or IP rate limiting when anonymity is not required.\n3. Route to audited RLN or RLN V3.\n4. Read `references\u002Frln-implementation.md` and use its field names at the app boundary.\n5. Define the epoch: time window, block window, room window, topic window, or application-specific round.\n6. Define the rate limit: usually one message per epoch for simple RLN, or `messageLimit` slots when the chosen circuit\u002Flibrary supports it.\n7. Define registration: identity commitment or rate commitment, stake or no stake, group tree, member lifecycle, and withdrawal\u002Fremoval path.\n8. Define signaling: message hash, epoch, external nullifier, proof payload, nullifier, share values, and verification endpoint.\n9. Define spam handling with `references\u002Frln-implementation.md`: duplicate evidence, secret recovery if supported, slashing\u002Fremoval\u002Fblocking behavior, and UX for honest users.\n10. Build the smallest verifiable prototype first, then add staking, decentralized storage, relays, or production circuits only after the core flow works.\n\n## Working RLN App Definition\n\nAn implementation is not a working RLN app merely because it has an anonymous-looking UI, server counters, or mock verification. To call the result working, the app must have:\n\n- a real registration or an explicit registration model that derives public commitments from private user secrets;\n- group or Merkle membership state and root handling;\n- epoch-bound signal generation with an app-specific identifier or external nullifier;\n- real proof generation against the selected audited or v3 circuit\u002Fartifact path;\n- real proof verification before accepting a signal;\n- nullifier\u002Fshare handling from verified public outputs;\n- duplicate detection and evidence storage from RLN public outputs, not from user IDs or client claims;\n- behavioral tests for valid, duplicate, next-epoch, multi-user, non-member or invalid-proof, wrong-message or wrong-epoch, and stale-root cases.\n\nIf a mock verifier, server-side counter, hardcoded proof, client-claimed nullifier, or fixture-only proof path remains, mark the implementation as incomplete. Mocks are acceptable only as temporary scaffolding while building the product shell or storage model.\n\n## Shared App Model\n\nA practical RLN app has three phases:\n\n- registration: create or receive a user's secret, derive a public commitment, and add that commitment to a group tree;\n- signaling: generate a proof that the sender is in the group and that the public RLN values were computed correctly for the message and epoch;\n- punishment or rejection: detect overuse of a rate slot, then slash, remove, block, or flag the sender depending on the system.\n\nCore values to keep straight:\n\n- `identitySecret` or `a0`: private user secret; never reveal for honest users;\n- `identityCommitment`: public registration value derived from the private secret;\n- `epoch`: rate-limit time window;\n- `rlnIdentifier`: application-specific random field value;\n- `externalNullifier`: usually derived from epoch and app identifier so use in one RLN app or epoch cannot be linked to another;\n- `messageId`: slot index for circuits that support more than one message per epoch;\n- `message`: content or content hash being sent;\n- `share`: public point tied to the message and the user's hidden polynomial;\n- `nullifier`: public value that lets verifiers associate duplicate use of the same rate slot without identifying honest users.\n\nDo not casually rename these values in code. RLN bugs often come from mixing up Semaphore-style nullifiers, app scopes, epochs, and RLN shares.\n\n## Product-Agnostic Lifecycle Checklist\n\nEvery RLN app should make these components explicit, even if the product UX is domain-specific:\n\n- identity manager: creates, stores, imports, or receives private user secrets without logging live secrets;\n- commitment derivation: derives the public registration value with the selected implementation's expected hash\u002Ffield format;\n- registration and group state: inserts commitments, tracks roots, and defines membership lifecycle;\n- epoch manager: derives the current rate-limit window server-side or validates it against a trusted source;\n- proof generator: creates proofs from message, epoch, membership path, and private secret;\n- verifier: rejects invalid proofs, stale roots, wrong message hashes, and wrong epochs before storage;\n- signal store: stores accepted verified signals and public outputs;\n- duplicate evidence store: stores both valid conflicting signals and proof metadata needed for later enforcement;\n- abuse response: defines reject, block, remove, slash, or flag behavior without confusing rejection with slashing.\n\nThe UI does not need a prescribed design, but the app should expose or make clear registration status, current epoch\u002Frate-limit window, proof generation and verification state, duplicate rejection reason, and group\u002Froot sync state or rationale.\n\n## Recommended References\n\n- PSE project page: https:\u002F\u002Fpse.dev\u002Fprojects\u002Frln\n- RLN docs: https:\u002F\u002Frate-limiting-nullifier.github.io\u002Frln-docs\u002F\n- RLN GitHub organization: https:\u002F\u002Fgithub.com\u002FRate-Limiting-Nullifier\n- Original overview article: https:\u002F\u002Fpse.dev\u002Fen\u002Fblog\u002Frate-limiting-nullifier-rln\n- RLN V3 repository: https:\u002F\u002Fgithub.com\u002FRate-Limiting-Nullifier\u002Frln-v3\n\n## When Not To Use RLN\n\n- The app does not need anonymity. Use ordinary authenticated rate limiting.\n- The app only needs one anonymous action per poll or proposal. Use Semaphore.\n- The app needs private credentials, age proofs, passport checks, or email ownership. Combine another identity proof system with Semaphore or RLN.\n- The app's abuse response cannot use slashing, removal, blocking, or another concrete penalty.\n\n## Shared Security Rules\n\n- Never log or commit `identitySecret`, `a0`, seed phrases, wallet signatures used as secrets, or recovered secrets from live users.\n- Do not reuse an RLN app identifier across unrelated apps.\n- Do not accept client-provided epochs blindly; derive or validate them server-side.\n- Do not hash messages with ad hoc string concatenation. Use explicit serialization and the hash function expected by the chosen library\u002Fcircuit.\n- Do not treat duplicate rejection as slashing. Slashing requires enough valid evidence and a correct contract or enforcement path.\n- Do not promise privacy if the anonymity set is tiny, transport metadata is exposed, or the app stores unique timing and device fingerprints.\n- Pin dependency versions or commits.\n\n## Output Expectations\n\nWhen building an RLN integration, produce:\n\n- the selected route: audited RLN or RLN V3;\n- why that route fits the task;\n- registration and group membership model;\n- epoch, rate limit, and app identifier;\n- proof payload format and verification path;\n- nullifier\u002Fshare storage and duplicate detection logic;\n- punishment, slashing, removal, or blocking behavior;\n- commands used for build and tests;\n- audit status and privacy limitations.\n- whether the final implementation uses real proof verification or remains incomplete because mocks\u002Fscaffolding are still present.\n\nWhen only planning, produce the same information without code edits and clearly mark unknowns such as deployed contracts, proof artifact source, audit requirements, or slashing requirements.\n\nBefore finishing implementation work, run the security, payload, duplicate, root, and epoch checks in `references\u002Frln-implementation.md`.\n",{"data":35,"body":36},{"name":4,"description":6},{"type":37,"children":38},"root",[39,47,54,60,65,70,109,115,120,125,143,155,160,198,208,213,226,232,308,314,319,362,367,373,378,396,401,511,516,522,527,575,580,586,646,652,675,681,733,739,744,797,802],{"type":40,"tag":41,"props":42,"children":43},"element","h1",{"id":4},[44],{"type":45,"value":46},"text","RLN",{"type":40,"tag":48,"props":49,"children":51},"h2",{"id":50},"overview",[52],{"type":45,"value":53},"Overview",{"type":40,"tag":55,"props":56,"children":57},"p",{},[58],{"type":45,"value":59},"Use this skill to help an agent turn a product goal such as \"anonymous users can post once per epoch\" or \"detect and penalize anonymous spam without identifying honest users\" into a practical RLN design or prototype.",{"type":40,"tag":55,"props":61,"children":62},{},[63],{"type":45,"value":64},"RLN is a privacy-preserving rate-limiting pattern for anonymous systems. A user registers a commitment in a Merkle tree, sends messages with zero-knowledge proofs, and exposes public values that make repeated use of the same rate slot detectable. Depending on the deployment, exceeding the rate limit can reveal enough information to slash a stake, remove a user, or block future messages.",{"type":40,"tag":55,"props":66,"children":67},{},[68],{"type":45,"value":69},"This file is the routing layer. Pick the relevant version note before giving code-level guidance:",{"type":40,"tag":71,"props":72,"children":73},"ul",{},[74,87,98],{"type":40,"tag":75,"props":76,"children":77},"li",{},[78,85],{"type":40,"tag":79,"props":80,"children":82},"code",{"className":81},[],[83],{"type":45,"value":84},"references\u002Frln-audited.md",{"type":45,"value":86},": audited RLN guidance for the established Circom implementation.",{"type":40,"tag":75,"props":88,"children":89},{},[90,96],{"type":40,"tag":79,"props":91,"children":93},{"className":92},[],[94],{"type":45,"value":95},"references\u002Frln-v3.md",{"type":45,"value":97},": RLN V3 guidance for the Semaphore V4-based implementation with LeanIMT, EdDSA, Circom, and Noir paths.",{"type":40,"tag":75,"props":99,"children":100},{},[101,107],{"type":40,"tag":79,"props":102,"children":104},{"className":103},[],[105],{"type":45,"value":106},"references\u002Frln-implementation.md",{"type":45,"value":108},": compact implementation card with payload shape, duplicate detection, audited\u002Fv3 notes, and tests.",{"type":40,"tag":48,"props":110,"children":112},{"id":111},"version-routing",[113],{"type":45,"value":114},"Version Routing",{"type":40,"tag":55,"props":116,"children":117},{},[118],{"type":45,"value":119},"Route based on the version or technical requirement. If the user names a version, use that version directly.",{"type":40,"tag":55,"props":121,"children":122},{},[123],{"type":45,"value":124},"Use the audited RLN note when:",{"type":40,"tag":71,"props":126,"children":127},{},[128,133,138],{"type":40,"tag":75,"props":129,"children":130},{},[131],{"type":45,"value":132},"the user asks for the original, stable, or audited RLN implementation;",{"type":40,"tag":75,"props":134,"children":135},{},[136],{"type":45,"value":137},"the task is a general RLN app and the user does not mention Semaphore V4, Noir, LeanIMT, or v3;",{"type":40,"tag":75,"props":139,"children":140},{},[141],{"type":45,"value":142},"the user wants practical app guidance around registration, signaling, verification, duplicate detection, or slashing.",{"type":40,"tag":55,"props":144,"children":145},{},[146,148,153],{"type":45,"value":147},"For code-level planning on this route, also read ",{"type":40,"tag":79,"props":149,"children":151},{"className":150},[],[152],{"type":45,"value":106},{"type":45,"value":154},".",{"type":40,"tag":55,"props":156,"children":157},{},[158],{"type":45,"value":159},"Use RLN V3 when:",{"type":40,"tag":71,"props":161,"children":162},{},[163,176,181,193],{"type":40,"tag":75,"props":164,"children":165},{},[166,168,174],{"type":45,"value":167},"the user explicitly mentions ",{"type":40,"tag":79,"props":169,"children":171},{"className":170},[],[172],{"type":45,"value":173},"rln-v3",{"type":45,"value":175},", Semaphore V4, LeanIMT, EdDSA, Noir, browser benchmarks, or the Rate-Limiting-Nullifier\u002Frln-v3 repository;",{"type":40,"tag":75,"props":177,"children":178},{},[179],{"type":45,"value":180},"the user wants the newer Semaphore V4 group\u002Fidentity structure;",{"type":40,"tag":75,"props":182,"children":183},{},[184,186,191],{"type":45,"value":185},"the user wants to work with the Circom or Noir implementation in ",{"type":40,"tag":79,"props":187,"children":189},{"className":188},[],[190],{"type":45,"value":173},{"type":45,"value":192},";",{"type":40,"tag":75,"props":194,"children":195},{},[196],{"type":45,"value":197},"the user wants benchmark or app guidance for the v3 repository.",{"type":40,"tag":55,"props":199,"children":200},{},[201,202,207],{"type":45,"value":147},{"type":40,"tag":79,"props":203,"children":205},{"className":204},[],[206],{"type":45,"value":106},{"type":45,"value":154},{"type":40,"tag":55,"props":209,"children":210},{},[211],{"type":45,"value":212},"If both versions fit, offer both directly:",{"type":40,"tag":71,"props":214,"children":215},{},[216,221],{"type":40,"tag":75,"props":217,"children":218},{},[219],{"type":45,"value":220},"audited RLN: established and security-audited;",{"type":40,"tag":75,"props":222,"children":223},{},[224],{"type":45,"value":225},"RLN V3: based on Semaphore V4, uses EdDSA and LeanIMT, includes Circom and Noir implementations, and should be described with the caveat that the v3 circuits have not been separately audited.",{"type":40,"tag":48,"props":227,"children":229},{"id":228},"common-workflow",[230],{"type":45,"value":231},"Common Workflow",{"type":40,"tag":233,"props":234,"children":235},"ol",{},[236,241,246,251,263,268,281,286,291,303],{"type":40,"tag":75,"props":237,"children":238},{},[239],{"type":45,"value":240},"Clarify the abuse problem: spam, denial of service, anonymous posting limits, invite abuse, or rate-limited access.",{"type":40,"tag":75,"props":242,"children":243},{},[244],{"type":45,"value":245},"Decide whether RLN is the right primitive. Use RLN when the app needs anonymous membership plus per-epoch rate limiting or punishable spam. Use Semaphore when the app only needs one signal per scope. Use normal account or IP rate limiting when anonymity is not required.",{"type":40,"tag":75,"props":247,"children":248},{},[249],{"type":45,"value":250},"Route to audited RLN or RLN V3.",{"type":40,"tag":75,"props":252,"children":253},{},[254,256,261],{"type":45,"value":255},"Read ",{"type":40,"tag":79,"props":257,"children":259},{"className":258},[],[260],{"type":45,"value":106},{"type":45,"value":262}," and use its field names at the app boundary.",{"type":40,"tag":75,"props":264,"children":265},{},[266],{"type":45,"value":267},"Define the epoch: time window, block window, room window, topic window, or application-specific round.",{"type":40,"tag":75,"props":269,"children":270},{},[271,273,279],{"type":45,"value":272},"Define the rate limit: usually one message per epoch for simple RLN, or ",{"type":40,"tag":79,"props":274,"children":276},{"className":275},[],[277],{"type":45,"value":278},"messageLimit",{"type":45,"value":280}," slots when the chosen circuit\u002Flibrary supports it.",{"type":40,"tag":75,"props":282,"children":283},{},[284],{"type":45,"value":285},"Define registration: identity commitment or rate commitment, stake or no stake, group tree, member lifecycle, and withdrawal\u002Fremoval path.",{"type":40,"tag":75,"props":287,"children":288},{},[289],{"type":45,"value":290},"Define signaling: message hash, epoch, external nullifier, proof payload, nullifier, share values, and verification endpoint.",{"type":40,"tag":75,"props":292,"children":293},{},[294,296,301],{"type":45,"value":295},"Define spam handling with ",{"type":40,"tag":79,"props":297,"children":299},{"className":298},[],[300],{"type":45,"value":106},{"type":45,"value":302},": duplicate evidence, secret recovery if supported, slashing\u002Fremoval\u002Fblocking behavior, and UX for honest users.",{"type":40,"tag":75,"props":304,"children":305},{},[306],{"type":45,"value":307},"Build the smallest verifiable prototype first, then add staking, decentralized storage, relays, or production circuits only after the core flow works.",{"type":40,"tag":48,"props":309,"children":311},{"id":310},"working-rln-app-definition",[312],{"type":45,"value":313},"Working RLN App Definition",{"type":40,"tag":55,"props":315,"children":316},{},[317],{"type":45,"value":318},"An implementation is not a working RLN app merely because it has an anonymous-looking UI, server counters, or mock verification. To call the result working, the app must have:",{"type":40,"tag":71,"props":320,"children":321},{},[322,327,332,337,342,347,352,357],{"type":40,"tag":75,"props":323,"children":324},{},[325],{"type":45,"value":326},"a real registration or an explicit registration model that derives public commitments from private user secrets;",{"type":40,"tag":75,"props":328,"children":329},{},[330],{"type":45,"value":331},"group or Merkle membership state and root handling;",{"type":40,"tag":75,"props":333,"children":334},{},[335],{"type":45,"value":336},"epoch-bound signal generation with an app-specific identifier or external nullifier;",{"type":40,"tag":75,"props":338,"children":339},{},[340],{"type":45,"value":341},"real proof generation against the selected audited or v3 circuit\u002Fartifact path;",{"type":40,"tag":75,"props":343,"children":344},{},[345],{"type":45,"value":346},"real proof verification before accepting a signal;",{"type":40,"tag":75,"props":348,"children":349},{},[350],{"type":45,"value":351},"nullifier\u002Fshare handling from verified public outputs;",{"type":40,"tag":75,"props":353,"children":354},{},[355],{"type":45,"value":356},"duplicate detection and evidence storage from RLN public outputs, not from user IDs or client claims;",{"type":40,"tag":75,"props":358,"children":359},{},[360],{"type":45,"value":361},"behavioral tests for valid, duplicate, next-epoch, multi-user, non-member or invalid-proof, wrong-message or wrong-epoch, and stale-root cases.",{"type":40,"tag":55,"props":363,"children":364},{},[365],{"type":45,"value":366},"If a mock verifier, server-side counter, hardcoded proof, client-claimed nullifier, or fixture-only proof path remains, mark the implementation as incomplete. Mocks are acceptable only as temporary scaffolding while building the product shell or storage model.",{"type":40,"tag":48,"props":368,"children":370},{"id":369},"shared-app-model",[371],{"type":45,"value":372},"Shared App Model",{"type":40,"tag":55,"props":374,"children":375},{},[376],{"type":45,"value":377},"A practical RLN app has three phases:",{"type":40,"tag":71,"props":379,"children":380},{},[381,386,391],{"type":40,"tag":75,"props":382,"children":383},{},[384],{"type":45,"value":385},"registration: create or receive a user's secret, derive a public commitment, and add that commitment to a group tree;",{"type":40,"tag":75,"props":387,"children":388},{},[389],{"type":45,"value":390},"signaling: generate a proof that the sender is in the group and that the public RLN values were computed correctly for the message and epoch;",{"type":40,"tag":75,"props":392,"children":393},{},[394],{"type":45,"value":395},"punishment or rejection: detect overuse of a rate slot, then slash, remove, block, or flag the sender depending on the system.",{"type":40,"tag":55,"props":397,"children":398},{},[399],{"type":45,"value":400},"Core values to keep straight:",{"type":40,"tag":71,"props":402,"children":403},{},[404,423,434,445,456,467,478,489,500],{"type":40,"tag":75,"props":405,"children":406},{},[407,413,415,421],{"type":40,"tag":79,"props":408,"children":410},{"className":409},[],[411],{"type":45,"value":412},"identitySecret",{"type":45,"value":414}," or ",{"type":40,"tag":79,"props":416,"children":418},{"className":417},[],[419],{"type":45,"value":420},"a0",{"type":45,"value":422},": private user secret; never reveal for honest users;",{"type":40,"tag":75,"props":424,"children":425},{},[426,432],{"type":40,"tag":79,"props":427,"children":429},{"className":428},[],[430],{"type":45,"value":431},"identityCommitment",{"type":45,"value":433},": public registration value derived from the private secret;",{"type":40,"tag":75,"props":435,"children":436},{},[437,443],{"type":40,"tag":79,"props":438,"children":440},{"className":439},[],[441],{"type":45,"value":442},"epoch",{"type":45,"value":444},": rate-limit time window;",{"type":40,"tag":75,"props":446,"children":447},{},[448,454],{"type":40,"tag":79,"props":449,"children":451},{"className":450},[],[452],{"type":45,"value":453},"rlnIdentifier",{"type":45,"value":455},": application-specific random field value;",{"type":40,"tag":75,"props":457,"children":458},{},[459,465],{"type":40,"tag":79,"props":460,"children":462},{"className":461},[],[463],{"type":45,"value":464},"externalNullifier",{"type":45,"value":466},": usually derived from epoch and app identifier so use in one RLN app or epoch cannot be linked to another;",{"type":40,"tag":75,"props":468,"children":469},{},[470,476],{"type":40,"tag":79,"props":471,"children":473},{"className":472},[],[474],{"type":45,"value":475},"messageId",{"type":45,"value":477},": slot index for circuits that support more than one message per epoch;",{"type":40,"tag":75,"props":479,"children":480},{},[481,487],{"type":40,"tag":79,"props":482,"children":484},{"className":483},[],[485],{"type":45,"value":486},"message",{"type":45,"value":488},": content or content hash being sent;",{"type":40,"tag":75,"props":490,"children":491},{},[492,498],{"type":40,"tag":79,"props":493,"children":495},{"className":494},[],[496],{"type":45,"value":497},"share",{"type":45,"value":499},": public point tied to the message and the user's hidden polynomial;",{"type":40,"tag":75,"props":501,"children":502},{},[503,509],{"type":40,"tag":79,"props":504,"children":506},{"className":505},[],[507],{"type":45,"value":508},"nullifier",{"type":45,"value":510},": public value that lets verifiers associate duplicate use of the same rate slot without identifying honest users.",{"type":40,"tag":55,"props":512,"children":513},{},[514],{"type":45,"value":515},"Do not casually rename these values in code. RLN bugs often come from mixing up Semaphore-style nullifiers, app scopes, epochs, and RLN shares.",{"type":40,"tag":48,"props":517,"children":519},{"id":518},"product-agnostic-lifecycle-checklist",[520],{"type":45,"value":521},"Product-Agnostic Lifecycle Checklist",{"type":40,"tag":55,"props":523,"children":524},{},[525],{"type":45,"value":526},"Every RLN app should make these components explicit, even if the product UX is domain-specific:",{"type":40,"tag":71,"props":528,"children":529},{},[530,535,540,545,550,555,560,565,570],{"type":40,"tag":75,"props":531,"children":532},{},[533],{"type":45,"value":534},"identity manager: creates, stores, imports, or receives private user secrets without logging live secrets;",{"type":40,"tag":75,"props":536,"children":537},{},[538],{"type":45,"value":539},"commitment derivation: derives the public registration value with the selected implementation's expected hash\u002Ffield format;",{"type":40,"tag":75,"props":541,"children":542},{},[543],{"type":45,"value":544},"registration and group state: inserts commitments, tracks roots, and defines membership lifecycle;",{"type":40,"tag":75,"props":546,"children":547},{},[548],{"type":45,"value":549},"epoch manager: derives the current rate-limit window server-side or validates it against a trusted source;",{"type":40,"tag":75,"props":551,"children":552},{},[553],{"type":45,"value":554},"proof generator: creates proofs from message, epoch, membership path, and private secret;",{"type":40,"tag":75,"props":556,"children":557},{},[558],{"type":45,"value":559},"verifier: rejects invalid proofs, stale roots, wrong message hashes, and wrong epochs before storage;",{"type":40,"tag":75,"props":561,"children":562},{},[563],{"type":45,"value":564},"signal store: stores accepted verified signals and public outputs;",{"type":40,"tag":75,"props":566,"children":567},{},[568],{"type":45,"value":569},"duplicate evidence store: stores both valid conflicting signals and proof metadata needed for later enforcement;",{"type":40,"tag":75,"props":571,"children":572},{},[573],{"type":45,"value":574},"abuse response: defines reject, block, remove, slash, or flag behavior without confusing rejection with slashing.",{"type":40,"tag":55,"props":576,"children":577},{},[578],{"type":45,"value":579},"The UI does not need a prescribed design, but the app should expose or make clear registration status, current epoch\u002Frate-limit window, proof generation and verification state, duplicate rejection reason, and group\u002Froot sync state or rationale.",{"type":40,"tag":48,"props":581,"children":583},{"id":582},"recommended-references",[584],{"type":45,"value":585},"Recommended References",{"type":40,"tag":71,"props":587,"children":588},{},[589,602,613,624,635],{"type":40,"tag":75,"props":590,"children":591},{},[592,594],{"type":45,"value":593},"PSE project page: ",{"type":40,"tag":595,"props":596,"children":600},"a",{"href":597,"rel":598},"https:\u002F\u002Fpse.dev\u002Fprojects\u002Frln",[599],"nofollow",[601],{"type":45,"value":597},{"type":40,"tag":75,"props":603,"children":604},{},[605,607],{"type":45,"value":606},"RLN docs: ",{"type":40,"tag":595,"props":608,"children":611},{"href":609,"rel":610},"https:\u002F\u002Frate-limiting-nullifier.github.io\u002Frln-docs\u002F",[599],[612],{"type":45,"value":609},{"type":40,"tag":75,"props":614,"children":615},{},[616,618],{"type":45,"value":617},"RLN GitHub organization: ",{"type":40,"tag":595,"props":619,"children":622},{"href":620,"rel":621},"https:\u002F\u002Fgithub.com\u002FRate-Limiting-Nullifier",[599],[623],{"type":45,"value":620},{"type":40,"tag":75,"props":625,"children":626},{},[627,629],{"type":45,"value":628},"Original overview article: ",{"type":40,"tag":595,"props":630,"children":633},{"href":631,"rel":632},"https:\u002F\u002Fpse.dev\u002Fen\u002Fblog\u002Frate-limiting-nullifier-rln",[599],[634],{"type":45,"value":631},{"type":40,"tag":75,"props":636,"children":637},{},[638,640],{"type":45,"value":639},"RLN V3 repository: ",{"type":40,"tag":595,"props":641,"children":644},{"href":642,"rel":643},"https:\u002F\u002Fgithub.com\u002FRate-Limiting-Nullifier\u002Frln-v3",[599],[645],{"type":45,"value":642},{"type":40,"tag":48,"props":647,"children":649},{"id":648},"when-not-to-use-rln",[650],{"type":45,"value":651},"When Not To Use RLN",{"type":40,"tag":71,"props":653,"children":654},{},[655,660,665,670],{"type":40,"tag":75,"props":656,"children":657},{},[658],{"type":45,"value":659},"The app does not need anonymity. Use ordinary authenticated rate limiting.",{"type":40,"tag":75,"props":661,"children":662},{},[663],{"type":45,"value":664},"The app only needs one anonymous action per poll or proposal. Use Semaphore.",{"type":40,"tag":75,"props":666,"children":667},{},[668],{"type":45,"value":669},"The app needs private credentials, age proofs, passport checks, or email ownership. Combine another identity proof system with Semaphore or RLN.",{"type":40,"tag":75,"props":671,"children":672},{},[673],{"type":45,"value":674},"The app's abuse response cannot use slashing, removal, blocking, or another concrete penalty.",{"type":40,"tag":48,"props":676,"children":678},{"id":677},"shared-security-rules",[679],{"type":45,"value":680},"Shared Security Rules",{"type":40,"tag":71,"props":682,"children":683},{},[684,703,708,713,718,723,728],{"type":40,"tag":75,"props":685,"children":686},{},[687,689,694,696,701],{"type":45,"value":688},"Never log or commit ",{"type":40,"tag":79,"props":690,"children":692},{"className":691},[],[693],{"type":45,"value":412},{"type":45,"value":695},", ",{"type":40,"tag":79,"props":697,"children":699},{"className":698},[],[700],{"type":45,"value":420},{"type":45,"value":702},", seed phrases, wallet signatures used as secrets, or recovered secrets from live users.",{"type":40,"tag":75,"props":704,"children":705},{},[706],{"type":45,"value":707},"Do not reuse an RLN app identifier across unrelated apps.",{"type":40,"tag":75,"props":709,"children":710},{},[711],{"type":45,"value":712},"Do not accept client-provided epochs blindly; derive or validate them server-side.",{"type":40,"tag":75,"props":714,"children":715},{},[716],{"type":45,"value":717},"Do not hash messages with ad hoc string concatenation. Use explicit serialization and the hash function expected by the chosen library\u002Fcircuit.",{"type":40,"tag":75,"props":719,"children":720},{},[721],{"type":45,"value":722},"Do not treat duplicate rejection as slashing. Slashing requires enough valid evidence and a correct contract or enforcement path.",{"type":40,"tag":75,"props":724,"children":725},{},[726],{"type":45,"value":727},"Do not promise privacy if the anonymity set is tiny, transport metadata is exposed, or the app stores unique timing and device fingerprints.",{"type":40,"tag":75,"props":729,"children":730},{},[731],{"type":45,"value":732},"Pin dependency versions or commits.",{"type":40,"tag":48,"props":734,"children":736},{"id":735},"output-expectations",[737],{"type":45,"value":738},"Output Expectations",{"type":40,"tag":55,"props":740,"children":741},{},[742],{"type":45,"value":743},"When building an RLN integration, produce:",{"type":40,"tag":71,"props":745,"children":746},{},[747,752,757,762,767,772,777,782,787,792],{"type":40,"tag":75,"props":748,"children":749},{},[750],{"type":45,"value":751},"the selected route: audited RLN or RLN V3;",{"type":40,"tag":75,"props":753,"children":754},{},[755],{"type":45,"value":756},"why that route fits the task;",{"type":40,"tag":75,"props":758,"children":759},{},[760],{"type":45,"value":761},"registration and group membership model;",{"type":40,"tag":75,"props":763,"children":764},{},[765],{"type":45,"value":766},"epoch, rate limit, and app identifier;",{"type":40,"tag":75,"props":768,"children":769},{},[770],{"type":45,"value":771},"proof payload format and verification path;",{"type":40,"tag":75,"props":773,"children":774},{},[775],{"type":45,"value":776},"nullifier\u002Fshare storage and duplicate detection logic;",{"type":40,"tag":75,"props":778,"children":779},{},[780],{"type":45,"value":781},"punishment, slashing, removal, or blocking behavior;",{"type":40,"tag":75,"props":783,"children":784},{},[785],{"type":45,"value":786},"commands used for build and tests;",{"type":40,"tag":75,"props":788,"children":789},{},[790],{"type":45,"value":791},"audit status and privacy limitations.",{"type":40,"tag":75,"props":793,"children":794},{},[795],{"type":45,"value":796},"whether the final implementation uses real proof verification or remains incomplete because mocks\u002Fscaffolding are still present.",{"type":40,"tag":55,"props":798,"children":799},{},[800],{"type":45,"value":801},"When only planning, produce the same information without code edits and clearly mark unknowns such as deployed contracts, proof artifact source, audit requirements, or slashing requirements.",{"type":40,"tag":55,"props":803,"children":804},{},[805,807,812],{"type":45,"value":806},"Before finishing implementation work, run the security, payload, duplicate, root, and epoch checks in ",{"type":40,"tag":79,"props":808,"children":810},{"className":809},[],[811],{"type":45,"value":106},{"type":45,"value":154},{"items":814,"total":23},[815,822,833],{"slug":4,"name":4,"fn":5,"description":6,"org":816,"tags":817,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[818,819,820,821],{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":823,"name":823,"fn":824,"description":825,"org":826,"tags":827,"stars":23,"repoUrl":24,"updatedAt":832},"semaphore","build anonymous group proof applications","Build, adapt, and debug Semaphore V4 applications. Use when a user wants anonymous voting, anonymous feedback, group membership proofs, nullifier-based double-spend prevention, off-chain Semaphore proof generation, on-chain Semaphore group management, or integration with Semaphore identities, groups, proofs, contracts, or subgraphs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[828,829,830,831],{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},"2026-08-20T03:53:28.249664",{"slug":834,"name":834,"fn":835,"description":836,"org":837,"tags":838,"stars":23,"repoUrl":24,"updatedAt":845},"tlsnotary","build and debug TLSNotary workflows","Build, adapt, and debug TLSNotary agent workflows and TLSNotary Extension plugins. Use when a user wants to prove data from a web service with TLSNotary, create or review a TLSNotary extension plugin, find a JSON API endpoint to notarize, design selective disclosure handlers, intercept browser auth headers, size maxRecvData\u002FmaxSentData, or troubleshoot TLSNotary proof generation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[839,842,843,844],{"name":840,"slug":841,"type":15},"Cryptography","cryptography",{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},"2026-08-20T03:53:27.874217",{"items":847,"total":882},[848,861,868,875],{"slug":849,"name":849,"fn":850,"description":851,"org":852,"tags":853,"stars":858,"repoUrl":859,"updatedAt":860},"state-actor","generate and verify Ethereum databases","Use this skill when a user wants to generate, boot, verify, or extend a state-actor-produced Ethereum database. Covers --client, --spec, --target-size, per-client boot recipes (geth \u002F reth \u002F besu \u002F nethermind \u002F ethrex \u002F erigon), and the canonical 29-entity spec fixture.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[854,857],{"name":855,"slug":856,"type":15},"Database","database",{"name":9,"slug":8,"type":15},10,"https:\u002F\u002Fgithub.com\u002Fethereum\u002Fstate-actor","2026-08-07T04:40:34.14665",{"slug":4,"name":4,"fn":5,"description":6,"org":862,"tags":863,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[864,865,866,867],{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":823,"name":823,"fn":824,"description":825,"org":869,"tags":870,"stars":23,"repoUrl":24,"updatedAt":832},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[871,872,873,874],{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":834,"name":834,"fn":835,"description":836,"org":876,"tags":877,"stars":23,"repoUrl":24,"updatedAt":845},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[878,879,880,881],{"name":840,"slug":841,"type":15},{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},4]