Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// Security headers applied to every response. We deliberately do NOT set a
// restrictive script-src/style-src CSP here: the app relies on inline styles,
// Next.js inline bootstrap scripts, the crawlproof.com analytics script, and
// Supabase image/websocket origins, so an enforcing CSP would break it. We only
// set `frame-ancestors` (clickjacking protection) plus the other low-risk
// hardening headers. HSTS only affects HTTPS responses (ignored over the Tor
// http onion service, which is fine).
const securityHeaders = [
{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'Content-Security-Policy', value: "frame-ancestors 'self'" },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'geolocation=(), browsing-topics=()' },
];

/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
Expand All @@ -6,6 +22,9 @@ const nextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
async headers() {
return [{ source: '/:path*', headers: securityHeaders }];
},
};

export default nextConfig;
91 changes: 91 additions & 0 deletions public/llms-full.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# QryptChat — Full Content

> Quantum-resistant, end-to-end encrypted messaging by Profullstack, Inc.
> Concatenated Markdown of the key public pages for LLM/RAG ingestion.

## Home

QryptChat is quantum-resistant, end-to-end encrypted messaging. It uses NIST-approved
post-quantum algorithms — ML-KEM-1024 (CRYSTALS-Kyber) for key encapsulation and
CRYSTALS-Dilithium for digital signatures — to protect messages, files, and calls against
both current attackers and future quantum computers. It is free, open source (MIT),
self-hostable, and accessible over Tor.

How it works:

1. Register with a phone number. A one-time SMS code verifies you — no email and no password.
2. Keys are generated on your device. Your ML-KEM-1024 key pair never leaves your device, so
QryptChat cannot read your messages (zero-knowledge architecture).
3. Every message is encrypted end-to-end — text, files, and voice & video calls.
4. Stay private everywhere: use the web app or the Tor onion service, and self-host from the
open-source repository.

Built for privacy-conscious individuals, journalists, activists, and security-minded teams.

## About

QryptChat is built by Profullstack, Inc. (founded 2024). Team: Anthony Ettinger
(Founder & Developer) and mrpthedev (Developer). Mission: make communication that stays
private for decades using cryptography already standardized by NIST, kept open source so it
can be independently verified and self-hosted.

## Security

- Key encapsulation: ML-KEM-1024 (CRYSTALS-Kyber), NIST FIPS 203.
- Digital signatures: CRYSTALS-Dilithium (ML-DSA), NIST FIPS 204.
- Coverage: text messages, file transfers, and 1:1 and group voice & video calls are end-to-end encrypted.
- Key custody: private keys are created and stored on-device; the server only ever sees ciphertext.
- Why post-quantum: defends against "harvest now, decrypt later" attacks.
- Privacy & resilience: phone-number auth (no email/password), no ads or trackers, Tor access,
a public warrant canary, and MIT-licensed self-hostable source.
- Responsible disclosure: security@qrypt.chat and /.well-known/security.txt.

## Pricing & Premium

QryptChat is free and open source (MIT). All core messaging, calling, and encryption features
are free, and you can self-host. An optional paid Premium tier is in development.

| Feature | Free | Premium (coming soon) |
| --- | --- | --- |
| Post-quantum end-to-end encryption | yes | yes |
| Encrypted voice & video calls | yes | yes |
| Disappearing messages & file sharing | yes | yes |
| Tor access & self-hosting | yes | yes |
| Price | $0 forever | TBA |

## FAQ

Q: Is QryptChat free?
A: Yes — free and open source (MIT). Optional Premium tier is in development.

Q: What platforms does QryptChat run on?
A: Any modern web browser, plus installable as a PWA on Android, iOS, and desktop, and reachable over Tor.

Q: What makes QryptChat quantum-resistant?
A: It encrypts with ML-KEM-1024 (CRYSTALS-Kyber) and CRYSTALS-Dilithium, protecting against
"harvest now, decrypt later" attacks.

Q: How is QryptChat different from Signal?
A: It uses post-quantum cryptography by design, is MIT-licensed and self-hostable, and is accessible over Tor.

Q: Does QryptChat require an email or password?
A: No — sign up with a phone number and an SMS code.

Q: Can I self-host QryptChat?
A: Yes — https://github.com/profullstack/qryptchat-web

Q: Can QryptChat read my messages?
A: No — keys are generated on your device and the server only handles ciphertext.

## Company

- Name: Profullstack, Inc.
- Product: QryptChat
- Founded: 2024
- Team: Anthony Ettinger (Founder & Developer), mrpthedev (Developer)
- Support: support@qrypt.chat
- Security: security@qrypt.chat
- Business: business@qrypt.chat
- GitHub: https://github.com/profullstack/qryptchat-web
- License: MIT
- Pricing: Free / open source
2 changes: 2 additions & 0 deletions public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ QryptChat uses NIST-approved post-quantum algorithms (ML-KEM-1024 / CRYSTALS-Kyb
- [Home](https://qrypt.chat/) — Product overview and feature highlights
- [About](https://qrypt.chat/about) — Mission, team, and differentiators
- [Security](https://qrypt.chat/security) — Encryption algorithms, zero-knowledge architecture, audit status
- [FAQ](https://qrypt.chat/faq) — Common questions about pricing, platforms, and post-quantum encryption
- [Pricing & Premium](https://qrypt.chat/premium) — Free vs. Premium tiers (free and open source)
- [Encryption Test](https://qrypt.chat/encryption-test) — Live ML-KEM-1024 demo in the browser
- [Contact](https://qrypt.chat/contact) — Support, security, and business contact emails
- [Privacy Policy](https://qrypt.chat/privacy) — Data minimization, GDPR rights, no ads or tracking
Expand Down
54 changes: 50 additions & 4 deletions src/app/about/page.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,55 @@
export const metadata = {
title: 'About',
description:
'QryptChat is quantum-resistant, end-to-end encrypted messaging by Profullstack, Inc. Learn about our mission, our team, and why we built a post-quantum messenger.',
alternates: { canonical: '/about' },
openGraph: { url: '/about', title: 'About QryptChat' },
};

const containerStyle = { padding: '4rem 0', maxWidth: '760px' };
const paraStyle = { fontSize: '1.0625rem', lineHeight: 1.8, color: 'var(--color-text-secondary)', margin: '0 0 1.25rem' };
const h2Style = { fontSize: '1.5rem', fontWeight: 700, margin: '2.5rem 0 1rem' };

export default function AboutPage() {
return (
<div className="container" style={{padding: '4rem 0'}}>
<h1 style={{fontSize: '2.5rem', fontWeight: 800, marginBottom: '1.5rem'}}>About QryptChat</h1>
<p style={{fontSize: '1.125rem', lineHeight: 1.8, color: 'var(--color-text-secondary)', maxWidth: '720px'}}>
QryptChat is a quantum-resistant, end-to-end encrypted messaging platform. Built with ML-KEM-1024 (CRYSTALS-Kyber) and CRYSTALS-Dilithium — NIST-approved post-quantum algorithms — your conversations are safe against both current and future threats including quantum computers.
<div className="container" style={containerStyle}>
<h1 style={{ fontSize: '2.5rem', fontWeight: 800, marginBottom: '1.5rem' }}>About QryptChat</h1>

<p style={paraStyle}>
QryptChat is a quantum-resistant, end-to-end encrypted messaging platform built by{' '}
<strong>Profullstack, Inc.</strong> (founded 2024). It uses ML-KEM-1024 (CRYSTALS-Kyber) and
CRYSTALS-Dilithium — NIST-approved post-quantum algorithms — so your conversations stay private
against both today&apos;s attackers and tomorrow&apos;s quantum computers.
</p>

<h2 style={h2Style}>Our mission</h2>
<p style={paraStyle}>
Most messengers were designed for a world without quantum computers. Encrypted traffic captured
today can be stored and decrypted later once large-scale quantum hardware arrives — a
&ldquo;harvest now, decrypt later&rdquo; attack. Our mission is to make communication that is
private not just today but decades from now, using cryptography that is already standardized by
NIST, and to keep it open source so anyone can verify and self-host it.
</p>

<h2 style={h2Style}>What makes QryptChat different</h2>
<ul style={{ ...paraStyle, paddingLeft: '1.5rem' }}>
<li>Post-quantum end-to-end encryption using ML-KEM-1024 and CRYSTALS-Dilithium.</li>
<li>Phone-number sign-up — no email address and no password required.</li>
<li>Encrypted voice &amp; video calls, disappearing messages, and file sharing.</li>
<li>Open source under the MIT license and fully self-hostable.</li>
<li>Accessible over Tor as a hidden service, plus a public warrant canary.</li>
</ul>

<h2 style={h2Style}>Team</h2>
<ul style={{ ...paraStyle, paddingLeft: '1.5rem' }}>
<li><strong>Anthony Ettinger</strong> — Founder &amp; Developer</li>
<li><strong>mrpthedev</strong> — Developer</li>
</ul>

<p style={paraStyle}>
QryptChat is free and open source. See the code on{' '}
<a href="https://github.com/profullstack/qryptchat-web" target="_blank" rel="noopener noreferrer">GitHub</a>,
read our <a href="/security">security overview</a>, or <a href="/contact">get in touch</a>.
</p>
</div>
);
Expand Down
9 changes: 8 additions & 1 deletion src/app/blog/[slug]/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ export default async function BlogPostPage({ params }) {
'@type': 'BlogPosting',
headline: post.title,
datePublished: post.date,
dateModified: post.date,
...(post.excerpt ? { description: post.excerpt } : {}),
author: { '@type': 'Organization', name: 'QryptChat' },
publisher: {
'@type': 'Organization',
name: 'Profullstack, Inc.',
logo: { '@type': 'ImageObject', url: `${siteUrl}/logo.svg` },
},
mainEntityOfPage: `${siteUrl}/blog/${post.slug}`,
...(post.image_url ? { image: [post.image_url] } : {}),
}),
Expand All @@ -51,7 +58,7 @@ export default async function BlogPostPage({ params }) {
<h1 style={{ fontSize: '2.25rem', fontWeight: 700, marginTop: '0.5rem', lineHeight: 1.2 }}>{post.title}</h1>
{post.image_url && (
// eslint-disable-next-line @next/next/no-img-element
<img src={post.image_url} alt="" style={{ width: '100%', borderRadius: '0.5rem', marginTop: '1.5rem', border: '1px solid var(--color-border)' }} />
<img src={post.image_url} alt={post.title} style={{ width: '100%', borderRadius: '0.5rem', marginTop: '1.5rem', border: '1px solid var(--color-border)' }} />
)}
{post.html ? (
<article
Expand Down
2 changes: 1 addition & 1 deletion src/app/blog/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default async function BlogPage() {
<Link href={`/blog/${p.slug}`} style={{ display: 'flex', gap: '1rem', padding: '1rem', textDecoration: 'none', color: 'inherit' }}>
{p.image_url ? (
// eslint-disable-next-line @next/next/no-img-element
<img src={p.image_url} alt="" loading="lazy" width={80} height={80}
<img src={p.image_url} alt={p.title} loading="lazy" width={80} height={80}
style={{ width: '5rem', height: '5rem', objectFit: 'cover', borderRadius: '0.375rem', flexShrink: 0 }} />
) : (
<div style={{ width: '5rem', height: '5rem', borderRadius: '0.375rem', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--color-bg-secondary)', fontSize: '0.75rem', fontWeight: 700, color: 'var(--color-accent)' }}>
Expand Down
32 changes: 28 additions & 4 deletions src/app/contact/page.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
export const metadata = {
title: 'Contact',
description: 'How to reach QryptChat — support, security, and business contacts, plus our Discord community.',
alternates: { canonical: '/contact' },
openGraph: { url: '/contact', title: 'Contact QryptChat' },
};

const containerStyle = { padding: '4rem 0', maxWidth: '760px' };
const paraStyle = { fontSize: '1.0625rem', lineHeight: 1.8, color: 'var(--color-text-secondary)', margin: '0 0 0.75rem' };

export default function ContactPage() {
return (
<div className="container" style={{padding: '4rem 0'}}>
<h1 style={{fontSize: '2.5rem', fontWeight: 800, marginBottom: '1.5rem'}}>Contact</h1>
<p>Email: <a href="mailto:hello@profullstack.com">hello@profullstack.com</a></p>
<p>Discord: <a href="https://discord.gg/w5nHdzpQ29">discord.gg/w5nHdzpQ29</a></p>
<div className="container" style={containerStyle}>
<h1 style={{ fontSize: '2.5rem', fontWeight: 800, marginBottom: '1.5rem' }}>Contact</h1>

<p style={paraStyle}>
<strong>Support:</strong> <a href="mailto:support@qrypt.chat">support@qrypt.chat</a>
</p>
<p style={paraStyle}>
<strong>Security &amp; responsible disclosure:</strong> <a href="mailto:security@qrypt.chat">security@qrypt.chat</a>
</p>
<p style={paraStyle}>
<strong>Business &amp; partnerships:</strong> <a href="mailto:business@qrypt.chat">business@qrypt.chat</a>
</p>
<p style={paraStyle}>
<strong>General:</strong> <a href="mailto:hello@profullstack.com">hello@profullstack.com</a>
</p>
<p style={paraStyle}>
<strong>Discord:</strong> <a href="https://discord.gg/w5nHdzpQ29" target="_blank" rel="noopener noreferrer">discord.gg/w5nHdzpQ29</a>
</p>
</div>
);
}
68 changes: 68 additions & 0 deletions src/app/faq/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export const metadata = {
title: 'FAQ',
description:
'Frequently asked questions about QryptChat: is it free, what platforms it runs on, how post-quantum encryption works, whether you can self-host, and how it compares to Signal.',
alternates: { canonical: '/faq' },
openGraph: { url: '/faq', title: 'QryptChat FAQ' },
};

const faqs = [
{
q: 'Is QryptChat free?',
a: 'Yes. QryptChat is free and open source under the MIT license. All core messaging, calling, and encryption features are available at no cost, and you can self-host it. An optional paid Premium tier is in development.',
},
{
q: 'What platforms does QryptChat run on?',
a: 'QryptChat runs in any modern web browser and installs as a Progressive Web App on Android, iOS, and desktop. It is also reachable as a Tor hidden service.',
},
{
q: 'What makes QryptChat quantum-resistant?',
a: 'QryptChat encrypts messages, files, and calls with NIST-approved post-quantum algorithms: ML-KEM-1024 (CRYSTALS-Kyber) for key encapsulation and CRYSTALS-Dilithium for digital signatures. These protect against "harvest now, decrypt later" attacks where traffic recorded today is decrypted once quantum computers exist.',
},
{
q: 'How is QryptChat different from Signal?',
a: 'Like Signal, QryptChat offers end-to-end encrypted messaging and calls with phone-number sign-up. The key difference is that QryptChat uses post-quantum cryptography (ML-KEM-1024 and CRYSTALS-Dilithium) by design, is MIT-licensed and self-hostable, and is accessible over Tor.',
},
{
q: 'Does QryptChat require an email address or password?',
a: 'No. You register with a phone number and a one-time SMS verification code. There is no password to leak and no email address to collect.',
},
{
q: 'Can I self-host QryptChat?',
a: 'Yes. QryptChat is open source and self-hostable. The full source code is available at github.com/profullstack/qryptchat-web.',
},
{
q: 'Can QryptChat read my messages?',
a: 'No. Encryption keys are generated on your device and never sent to our servers, so QryptChat operates on a zero-knowledge basis and only ever handles ciphertext.',
},
];

const faqJsonLd = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqs.map(({ q, a }) => ({
'@type': 'Question',
name: q,
acceptedAnswer: { '@type': 'Answer', text: a },
})),
};

const containerStyle = { padding: '4rem 0', maxWidth: '760px' };

export default function FaqPage() {
return (
<div className="container" style={containerStyle}>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqJsonLd) }}
/>
<h1 style={{ fontSize: '2.5rem', fontWeight: 800, marginBottom: '1.5rem' }}>Frequently Asked Questions</h1>
{faqs.map(({ q, a }) => (
<section key={q} style={{ margin: '0 0 1.75rem' }}>
<h2 style={{ fontSize: '1.25rem', fontWeight: 700, margin: '0 0 0.5rem' }}>{q}</h2>
<p style={{ fontSize: '1.0625rem', lineHeight: 1.8, color: 'var(--color-text-secondary)', margin: 0 }}>{a}</p>
</section>
))}
</div>
);
}
Loading
Loading