Status: measured, 2026-09-01. Checked against primary sources on this date — not recalled from training. Re-verify before submission; export regulations change and this file will go stale.
Not legal advice. The ambiguity in §3 needs export counsel before first submission.
---
> ## ✅ SETTLED — 5 September 2026: exempt, on a good-faith reading > > app/project.yml sets ITSAppUsesNonExemptEncryption: false, and that is the answer every > shipped build carries. This banner previously claimed the opposite; it was wrong about the code. > > Don, 5 Sep 2026: "we already discussed the non-exempt thing ... the controversy was whether our > protocols were somehow not standard but our protocols don't speak to the method of encryption so we > want our best good faith estimate as to our compliance posture without creating undue burden by > over broad interpretation of what is exempt vs non exempt." > > The reasoning. The app defines no cryptography of its own. It uses X25519, Ed25519, > ChaCha20-Poly1305, SHA-256 and AES-GCM, all standard and published. PROTOCOL.md specifies > routing, addressing, tokens and retention -- it does not specify a cipher, a mode, or a key > schedule of its own invention. Implementing a published algorithm in Rust rather than calling the > operating system's copy does not make the algorithm non-standard; the earlier sections of this > document treated it as if it did, and that was the over-broad reading Don is rejecting. > > The functionality is ordinary confidentiality for personal communication: not special-purpose, not > for government or military use, no proprietary cryptography. > > What must stay in agreement. Three places say this, and they must never disagree again: > app/project.yml (false), web/encryption.html §6, and this banner. The website said true > until 5 Sep 2026, which is how the disagreement was found. > > What would reopen it. Shipping a primitive of our own, a non-published algorithm, or a > special-purpose mode. Sections 3 to 6 below are kept as the record of the earlier analysis and its > stricter reading; where they conflict with this banner, this banner is the decision.
---
---
Key-length thresholds were the 1990s regime — the 40-bit and 56-bit limits, the PGP prosecution, Bernstein. Those are gone. Using X25519 and ChaCha20-Poly1305 does not put this project in a worse position than weaker choices would, and deliberately weakening anything would buy nothing.
What determines obligations is what kind of item it is, whether the source is public, and where it goes.
Framework: Export Administration Regulations (EAR), administered by the Commerce Department's Bureau of Industry and Security. Encryption software sits in Category 5 Part 2 of the Commerce Control List. This app classifies as ECCN 5D002.
---
### Route A — publicly available source code
> 15 CFR 742.15(b)(1): "Publicly available encryption source code classified under ECCN 5D002 is > not subject to the EAR."
Not "exempt." Not subject. No annual report, no classification request, no filing — provided the source is genuinely publicly available.
> 15 CFR 742.15(b)(2): notification to BIS and the ENC Encryption Request Coordinator by email is > required only for publicly available source code that "provides or performs non-standard > cryptography."
Discrepancy on record. BIS's own plain-language guidance page states that publicly available source "is not subject to the EAR once the email notification per section 742.15(b) is sent" — presenting notification as a blanket condition. The regulation limits it to non-standard cryptography. BIS's summary is stricter than BIS's rule.
Resolution: if we open-source, send the notification anyway. One email to crypt@bis.doc.gov and enc@nsa.gov with the repository URL. It costs nothing and moots §3's ambiguity entirely, whichever reading is correct.
### Route B — closed source
Export under License Exception ENC §740.17(b)(1), which carries a recurring obligation:
| What | Annual self-classification report |
|---|---|
| To | ENC Encryption Request Coordinator |
| By | 1 February, covering the prior calendar year (1 Jan – 31 Dec) |
| Format | CSV only, twelve fields: product name, model number, manufacturer, ECCN, authorization type, item type, submitter name, telephone, email, mailing address, non-US components, non-US manufacturing locations |
| Waived if | A CCATS classification has been submitted for the item |
| Not required if | No applicable exports occurred that year |
Each product is reported once, in the year it was self-classified. If nothing changed since the prior report, an email saying so suffices.
The second year is where this gets forgotten. Put it in a calendar, not in someone's head.
---
EAR Part 772 defines non-standard cryptography as proprietary or unpublished cryptographic functionality, "including encryption algorithms or protocols that have not been adopted or approved by a duly recognized international standards body" — IEEE, IETF, ISO, ITU, ETSI, 3GPP, TIA, GSMA.
Our primitives are unambiguously standard. X25519, ChaCha20-Poly1305, HKDF-SHA256, HMAC-SHA256 — all published IETF specifications (PROTOCOL.md §4.1). The project rule against inventing cryptography settles the algorithm question completely.
Our protocol is not standards-body adopted, and will not be. The Envelope, the fixed-layout AAD, the token derivation, the route-discovery state machine — all bespoke.
Two readings:
### Working determination, 2 Sep 2026
We self-classify as mass market using standard cryptography, and record the basis here. Don's reading, which drives this: "the nature of the encryption is what their concern is... the content of what is encrypted is not really a protocol that affects the nature of the encryption."
That is right about the axis. Envelope framing, transport selection and fragment reassembly do not change what X25519 or ChaCha20-Poly1305 do, or how hard either is to break. §1 already says strength is not the axis; capability is.
But the argument must not rest on "ours is not a cryptographic protocol," because parts of it are and a knowledgeable reviewer would say so: the handshake is a station-to-station exchange with a signed transcript, the HKDF info strings bind specific material, the AAD layout is fixed for security reasons, and destination tokens are derived from keys and time to be unlinkable. Those determine security properties. A flawed handshake breaks everything regardless of primitive strength.
The basis we actually rely on is the definition's own wording — non-standard cryptography is proprietary or unpublished functionality:
| Test | Us |
|---|---|
| Proprietary primitives? | No. X25519, Ed25519, ChaCha20-Poly1305, HKDF-SHA256, SHA-256 — all published IETF/FIPS, none invented here. The project rule against inventing cryptography settles it. |
| Unpublished? | No, as of 2 Sep 2026. <https://channelmessenger.netlify.app/encryption.html> documents the algorithms and their use, and PROTOCOL.md goes to anyone who asks. |
| Novel construction? | No. A signed ephemeral exchange with HKDF-derived keys is textbook. Signal's Double Ratchet is substantially more inventive and ships as mass market. |
#### Prior art for every mechanism — the concrete basis for "not novel"
Don asked the right question directly: "Novel? Are we novel?" The test is whether each mechanism can be traced to existing published work. Every one can:
| Mechanism | Prior art |
|---|---|
| Ed25519, X25519, ChaCha20-Poly1305, HKDF-SHA256, SHA-256 | Published IETF/FIPS specifications. PROTOCOL.md §4.1: no primitive outside that table appears anywhere. |
| Handshake v1 — signed ephemeral DH, three flights | Station-to-Station; Diffie, van Oorschot & Wiener, 1992. |
| HMAC-SHA256 truncated to 16 bytes for tokens | HMAC as a PRF, RFC 2104. Truncation is standard practice. |
Domain separation by label (mesh/presence-v1 vs mesh/destination-v1) | The purpose of HKDF/HMAC labels; TLS 1.3's key schedule does the same. |
| Direction byte, so both parties derive different tokens from one secret | TLS deriving client_write_key and server_write_key from one master secret. |
Epoch rotation, floor(unixTime / 600) | TOTP (RFC 6238) is floor(T/X). BLE Resolvable Private Addresses rotate identically. Apple and Google's Exposure Notification rolling proximity identifiers are the same shape, published and analysed at global scale. |
| Independent keys for routing and content | Key separation; textbook. |
| Sender identity inside the ciphertext | Sealed sender; Signal, 2018. |
| Mandatory padding | Standard traffic-analysis defence. |
Bespoke, not novel — and that is the distinction the regulation turns on. Nothing here is an invention; it is assembled from parts that each carry a citation.
Note also that being un-novel is a security property and not merely a regulatory convenience. Novel cryptography in a shipping product is almost always a mistake, and §4.1's rules — never invent cryptography, and no negotiable cipher suites because negotiation is a downgrade surface — are why this table can be written at all.
The Exposure Notification comparison is the one to lead with: Apple and Google shipped HMAC-derived, epoch-rotating, unlinkable identifiers to billions of devices. That mechanism is not treated as non-standard cryptography.
Why this is a determination we are entitled to make. Self-classification is not a permission granted to us; it is an assessment we make in good faith and document. Certainty about how a third party would read "or protocols" is not the standard and never was. Don: "we cannot know how somebody else will interpret the answer, but we have to answer in good faith." This section, and the published page, are that record.
Still get export counsel before external distribution, and before any French availability (§4). This determination is the working basis for internal testing and for answering Apple honestly; it is not a substitute for review when the stakes rise. Open-sourcing would moot the question entirely via the publicly-available route, which remains the cleanest resolution and is one more argument for it.
---
Two upload attempts and two API refusals settled how this app is actually handled, and the answer is less onerous than §4 implies.
Setting ITSAppUsesNonExemptEncryption: true in Info.plist breaks the upload:
`` Invalid Export Compliance Code. The export compliance key value [] in the app's Info.plist doesn't match the key value of the app's export compliance documentation. ``
Apple looks for a companion ITSEncryptionExportComplianceCode, which exists only for apps holding encryption-declaration paperwork.
Attempting to file that paperwork is refused, and the refusal is the useful part:
`` Cannot create appEncryptionDeclarations unless either containsProprietaryCryptography is True or containsThirdPartyCryptography and availableOnFrenchStore are both True. ``
Our honest answers are proprietary No, third-party Yes, French store No — a combination Apple will not let you file a declaration for, because that combination does not need one. Apple's own validation is confirming the §3 working determination from the other direction: an app using only published third-party standard algorithms, not sold in France, files nothing.
Therefore: the key is omitted from Info.plist and the truthful answer is given per build via PATCH /v1/builds/{id} with usesNonExemptEncryption: true. That is the same honest answer in the place Apple actually wants it for this app's situation.
> Never set the key to false to silence the prompt. That is the false declaration builds 1–4 > carried, and it is what this document exists to prevent. Absent ≠ false: absent means "answered per > build", and the per-build answer is yes.
Answered in App Store Connect for build 5 on 2 Sep 2026. The wording matters, because it is not the EAR wording this document has been wrestling with:
> What type of encryption algorithms does your app implement? > 1. Encryption algorithms that are proprietary or not accepted as standard by international standard > bodies (IEEE, IETF, ITU, etc.) > 2. Standard encryption algorithms instead of, or in addition to, using or accessing the encryption > within Apple's operating system > 3. Both algorithms mentioned above > 4. None of the algorithms mentioned above
Apple asks about ALGORITHMS. The phrase "or protocols" does not appear. The §3 ambiguity — whether a bespoke protocol assembled from standard parts counts as non-standard cryptography — simply does not arise here. Our algorithms are X25519, Ed25519, ChaCha20-Poly1305, HKDF-SHA256 and SHA-256, every one an IETF or FIPS publication, so option 2 is unambiguously correct and required no interpretation.
Second and final question: "Is your app going to be available for distribution in France?" Answered No, which keeps §4's separate French declaration out of scope for the beta. Revisit this before any App Store release that includes France.
Result: build 5 moved from Missing Compliance to Ready to Submit and was assigned to the tester group. No CCATS, no ERN, no BIS filing was requested at any point.
Note for future uploads. Apple's own dialog says the answers can be baked into Info.plist to avoid answering per submission — but that is the route that produced the "Invalid Export Compliance Code" upload failure in §3a, because ITSAppUsesNonExemptEncryption: true alone makes Apple demand a companion code. Answering per build in the TestFlight UI is the working path for this app. The API does not substitute: PATCH /v1/builds/{id} with usesNonExemptEncryption returns HTTP 200 and does not persist.
| Encryption in use | Upload to App Store Connect |
|---|---|
| Limited to what iOS provides | Nothing |
| Industry-standard algorithms, own implementation ← us | French declaration only |
| Proprietary algorithms not accepted by IEEE/IETF/ITU | CCATS and French declaration |
ITSAppUsesNonExemptEncryption = YES. We implement a protocol; we are not limited to OS-provided encryption.ITSEncryptionExportComplianceCode is added to Info.plist only after Apple approves documentation and issues a code — not before.Note for later: a dependency can change the answer even when our own code does not. Every Rust crate we link is part of what we ship.
---
Independent of any filing. No export to embargoed destinations — currently Cuba, Iran, North Korea, Syria, and specified Ukrainian regions. App Store territory availability handles this operationally, but the obligation is the developer's, not Apple's.
---
Settled by Don on 2026-09-01 (DECISIONS.md F7). We are on Route B.
An earlier draft of this file recommended Route A. That recommendation did not account for a possible future sale, and publishing is irreversible: every released version stays licensed forever, while closed → open remains available at any time. Route B costs one CSV filing a year and preserves the choice; Route A saves that filing and forecloses it.
Live obligations from first export (App Store release):
ITSAppUsesNonExemptEncryption = YES in Info.plistIf this is revisited later, Route A remains fully available, and the §742.15(b)(2) email should be sent regardless of which reading of §3 applies — it costs nothing and moots the ambiguity.
Licence caution if Route A is ever taken: a source-available licence (Business Source, PolyForm, or similar) may not qualify as "publicly available," since that turns on unrestricted dissemination. Choosing one could take every downside of publishing with none of the relief. Unverified — check before selecting a licence.
---
English is the reference text; any translation is a convenience. Help is stored on this phone and never contacts anyone.