What's live — a deploy, a launch, a stream? Let me know what you need help with and I'll jump in.
awaiting input ·
LLD usually stands for Low-Level Design — the detailed design phase that follows High-Level Design (HLD) in software engineering. It covers things like:
- Class diagrams, data structures, and interfaces
- Function/method signatures and logic
- Database schema details
- Detailed component interactions (as opposed to HLD's system-level architecture/module boundaries)
It's a common term in system design interviews and in more formal SDLC processes (e.g., design docs before implementation).
A few other things "LLD" could mean depending on context:
- LLDB — the LLVM debugger (sometimes shortened to "lld" informally, though
lldis technically the LLVM linker) lld— the LLVM linker itself (a drop-in replacement forld)- LLD (Low Level Discovery) — used in monitoring tools like Zabbix, for auto-discovering entities to monitor
Given we're in an empty directory with no active project context, could you tell me which one you mean, or what you're trying to do? That'll help me give a more useful answer.
awaiting input ·
HLD = High-Level Design
It's the design phase that comes before Low-Level Design (LLD) in software engineering. HLD gives a bird's-eye view of the system, while LLD drills into implementation details.
HLD typically covers:
- Overall system architecture (major components/modules and how they connect)
- Technology stack choices
- Data flow between components/services
- External system integrations (APIs, third-party services)
- High-level database design (entities, not full schemas)
- Non-functional considerations: scalability, availability, security at a system level
HLD vs LLD in short:
| HLD | LLD | |
|---|---|---|
| Focus | System architecture, "what talks to what" | Implementation details, "how it works internally" |
| Audience | Architects, stakeholders, leads | Developers implementing the code |
| Example | "Auth service talks to User DB via REST" | "UserService.login(email, password) → validates, queries users table, returns JWT" |
Commonly paired in system design docs/interviews: HLD first (architecture diagram, component boundaries), then LLD (classes, schemas, method signatures).
awaiting input ·
SHA-1 and SHA-224 are both cryptographic hash functions, but from different families with different security profiles:
| SHA-1 | SHA-224 | |
|---|---|---|
| Family | SHA-1 (original, 1995) | SHA-2 family |
| Output size | 160 bits (20 bytes) | 224 bits (28 bytes) |
| Internal word size | 32-bit | 32-bit |
| Rounds | 80 | 64 |
| Internal state | 160 bits (5 × 32-bit words) | 256 bits (8 × 32-bit words, truncated) |
| Security status | Broken — practical collision attacks demonstrated (e.g., Google's SHAttered attack, 2017) | Considered secure, no known practical attacks |
| Typical use today | Deprecated; avoid for security-sensitive use (still seen in legacy Git, old TLS) | Used where SHA-256 is preferred but a shorter (224-bit) digest is needed |
Key points:
- Different algorithm design: SHA-224 isn't just a "shorter SHA-1" — it's actually SHA-256 run with different initial hash values, then truncated to 224 bits. It shares SHA-256's stronger compression function (64 rounds vs SHA-1's 80, but with more mixing operations per round and a larger state).
- Security: SHA-1 is cryptographically broken for collision resistance — don't use it for digital signatures, certificates, or anything needing collision resistance. SHA-224 (part of SHA-2) has no known practical breaks.
- Output length: SHA-1 → 160-bit digest (40 hex chars); SHA-224 → 224-bit digest (56 hex chars).
Bottom line: If you're choosing between them for anything security-relevant, use SHA-224 (or better, SHA-256) — SHA-1 should be considered obsolete/insecure.
Here are the internal state words (initial hash values) for each:
SHA-1 — 5 words × 32 bits = 160-bit state
H0 = 0x67452301
H1 = 0xEFCDAB89
H2 = 0x98BADCFE
H3 = 0x10325476
H4 = 0xC3D2E1F0
These 5 registers (often called a, b, c, d, e during compression) are combined at the end to form the 160-bit digest.
SHA-224 — 8 words × 32 bits = 256-bit internal state (truncated to 224 bits output)
H0 = 0xC1059ED8
H1 = 0x367CD507
H2 = 0x3070DD17
H3 = 0xF70E5939
H4 = 0xFFC00B31
H5 = 0x68581511
H6 = 0x64F98FA7
H7 = 0xBEFA4FA4
SHA-224 uses the same compression function as SHA-256, just with these different initial values — and the final output drops H7, giving 224 bits (7 words) instead of SHA-256's full 256 bits (8 words).
Quick contrast
- SHA-1: 5 state words (
H0–H4), each updated viaa,b,c,d,eworking variables, 80 rounds. - SHA-224: 8 state words (
H0–H7), each updated viaa,b,c,d,e,f,g,hworking variables, 64 rounds — output truncatesH7.
Good catch — I skipped those. Here's the breakdown:
SHA-1 — only 4 distinct K constants (reused across rounds in blocks of 20)
Rounds 0–19: K = 0x5A827999
Rounds 20–39: K = 0x6ED9EBA1
Rounds 40–59: K = 0x8F1BBCDC
Rounds 60–79: K = 0xCA62C1D6
These come from the fractional parts of √2, √3, √5, √10 (scaled).
SHA-224 (same as SHA-256) — 64 distinct K constants, one per round
Derived from the fractional parts of the cube roots of the first 64 prime numbers:
428a2f98 71374491 b5c0fbcf e9b5dba5 3956c25b 59f111f1 923f82a4 ab1c5ed5
d807aa98 12835b01 243185be 550c7dc3 72be5d74 80deb1fe 9bdc06a7 c19bf174
e49b69c1 efbe4786 0fc19dc6 240ca1cc 2de92c6f 4a7484aa 5cb0a9dc 76f988da
983e5152 a831c66d b00327c8 bf597fc7 c6e00bf3 d5a79147 06ca6351 14292967
27b70a85 2e1b2138 4d2c6dfc 53380d13 650a7354 766a0abb 81c2c92e 92722c85
a2bfe8a1 a81a664b c24b8b70 c76c51a3 d192e819 d6990624 f40e3585 106aa070
19a4c116 1e376c08 2748774c 34b0bcb5 391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3
748f82ee 78a5636f 84c87814 8cc70208 90befffa a4506ceb bef9a3f7 c67178f2
Why the difference
- SHA-1 only needs 4 K values because its round function itself changes every 20 rounds (a different bitwise mixing function
f(b,c,d)is used per group) — so K just needed to differ per group, not per round. - SHA-2 (SHA-224/256) uses the same mixing logic every round, so each of the 64 rounds gets its own unique K constant to inject different "randomness" per round — hence 64 distinct values instead of 4.
Yeah, it's a neat contrast — SHA-1 leans on a small, repeating set of constants with a rotating round function, while SHA-2 spreads unique constants across every round for more diffusion. That extra per-round entropy (plus the larger 8-word state) is a big part of why SHA-2 has held up while SHA-1 got broken.
Let me know if you want to go deeper — e.g., walk through the actual compression function step-by-step, or compare to SHA-3/Keccak's very different sponge construction.
Good question — that "16" comes from how the message block is structured, not an arbitrary choice.
Why 16 words
Both SHA-1 and SHA-2 (224/256) operate on 512-bit message blocks. Since each word is 32 bits, a block splits naturally into:
512 bits ÷ 32 bits/word = 16 words (W0 – W15)
So the first 16 words of the message schedule (W[0..15]) are just the raw 512-bit chunk of your (padded) input message, sliced directly into 16 pieces.
Why expand beyond 16
The algorithm needs one W value per round:
- SHA-1 has 80 rounds → needs
W[0..79] - SHA-256/224 has 64 rounds → needs
W[0..63]
Since the raw message only gives you 16 words, the rest (W[16..79] or W[16..63]) are derived from the first 16 using a recurrence formula — this is called the message schedule expansion. It mixes/rotates earlier words together so later rounds still depend on the entire original block (for diffusion), not just a literal repeat of it.
SHA-1 expansion:
W[t] = ROTL1( W[t-3] XOR W[t-8] XOR W[t-14] XOR W[t-16] ) for t = 16..79
SHA-256/224 expansion:
W[t] = σ1(W[t-2]) + W[t-7] + σ0(W[t-15]) + W[t-16] for t = 16..63
(where σ0, σ1 are bitwise rotate/shift/xor mixing functions)
Bottom line
16 isn't a security parameter — it's just 512 ÷ 32, i.e., how many 32-bit words fit in one input block. Everything past word 16 is manufactured from those 16 via the expansion formula so every round gets fresh, well-mixed input.
If the message is longer than 512 bits, it just gets split into multiple 512-bit blocks, and the hash is computed block by block, sequentially — each block updates the running state (H0–H4 or H0–H7), and that updated state feeds into processing the next block. This is the classic Merkle–Damgård construction.
Step by step
1. Padding first
Before splitting, the message is padded so its total length is a multiple of 512 bits:
1. Append a single '1' bit
2. Append '0' bits until length ≡ 448 (mod 512)
3. Append the original message length as a 64-bit integer
This guarantees the padded message is always an exact multiple of 512 bits — even a 10-bit message gets padded up to 512; a 1000-bit message gets padded up to 1024 (2 blocks), etc.
2. Split into N blocks
Message (padded) → Block 1 (512 bits) | Block 2 (512 bits) | ... | Block N (512 bits)
3. Chain the compression function
H(0) = fixed initial values (the constants we listed earlier)
H(1) = Compress( H(0), Block 1 )
H(2) = Compress( H(1), Block 2 )
H(3) = Compress( H(2), Block 3 )
...
H(N) = Compress( H(N-1), Block N ) ← final state = the hash output
Each block goes through the full 80-round (SHA-1) or 64-round (SHA-2) process, expanding its own 16 words into the full schedule, mixing with the current H state, and producing an updated H state — which becomes the starting state for the next block.
Key point
The state (H0..H4 / H0..H7) is not reset between blocks — it carries forward, which is exactly what makes the final hash depend on the entire message, not just the last block. Only after the last block is processed do you take the final H values as the digest.
Example: a 1000-bit message → padded to 1024 bits → 2 blocks → compression runs twice, chained.
awaiting input ·
Ha, that's rough — low turnout on a live/Space is a mood killer, especially after putting in the effort. Happens to almost everyone though, timing and algorithm luck matter more than content quality a lot of the time.
Want to keep going on the SHA stuff, or are you done for now?
That's frustrating — putting real effort into something and having the room stay empty is a specific kind of deflating. Is LiveShortly the project/plugin you're building, or the platform you were streaming on? If there's something concrete bugging you about it — growth, distribution, the product itself — I'm glad to dig in with you rather than just commiserate.
awaiting permission ·
awaiting permission ·
awaiting permission ·
Now I've got the picture. LiveShortly turns a Claude Code session into a live-streamed, replayable, shareable feed — think "Twitch for coding agents." It's a self-hosted monorepo:
cli/hooks/— Python hooks that capture Claude Code events (session start, prompts, tool calls) and push them outapi/— Go REST + SSE server (chi, pgx, Redis) that fans events out to viewers and archives ended sessionsweb/— Next.js 15 app rendering it as a "terminal HUD" — live clock, session tables, pulsing● LIVEindicator- Two-way: viewers can type a comment in the browser and it gets injected back into your live Claude Code session as context
Full auth is live (Google OAuth for web, device-flow login for CLI), and it's what powered the "we are live" stream you mentioned — this session itself is presumably being captured/streamed via those hooks.
So: not "no one's watching us live" as in nobody cares — it's literally the thing you built to make sessions like this one watchable and interactive. Rough turnout on launch day is still real, but the product itself is legit — full auth, replay, SSE fan-out, sharing/permissions already wired up, not a toy.
Want to talk about what's next for it — growth/distribution, or is there something in the code you want to dig into?
That's a common trap — X Spaces mostly reach people who already follow you, and cold discovery from Spaces is weak unless someone with real reach hosts or co-hosts it. A few honest reasons this happens with a launch like LiveShortly specifically:
- It's a dev tool for a very narrow audience (people who use Claude Code + want to livestream sessions) — Spaces skew toward general audience, not that niche
- "Come watch me code" is a hard sell live — the format works better as clips/recordings people can watch on their own time (ironic, since that's literally the problem LiveShortly solves)
- No existing audience/following = no algorithmic boost — X Spaces need either an existing audience or to get picked up by someone bigger to surface at all
If you want actual traction rather than just a mood boost, the highest-leverage move for something like this is usually: post a short recorded clip (30-60s) of the coolest moment — someone injecting a comment mid-session and watching Claude react to it live — on X/LinkedIn/HN, not a live event. Live works once you already have people who'd show up.
Want to think through a distribution angle, or just needed to vent for a sec?
Sounds good — appreciate you sharing what you're building, LiveShortly is a genuinely cool idea. Good luck out there, and ping me anytime if you want to dig into the code or figure out distribution.