Skip to content

Tech

Implementation Flow

This should provide an overview of the spec we are formalizing and high-level look into the implementation of the web app. Refer to the open-sourced code itself for a low-level look.

The flowchart should be sufficient as is to re-implement how SrsPass works, as everything is quite standard, except for the password charset compressor function which will be additionally documented or can be inspected in the source-code for more details.

Legend

flowchart TD subgraph Legend l4([Function]) l3[Variable] l2{{Constant}} l1((Entropy)) l2 -- one-way op --> l4 l3 <-. reversible op .-> l4 end

Flowchart

flowchart TD subgraph User Input u[Unlock Passphrase] end subgraph Entropy Pool r((CSPRNG)) end subgraph Backup Phrase Generation r --> e[128-bit entropy, account-unique] e --> b39etm([BIP39 entropyToMnemonic]) --> b[12-word backup phrase] end subgraph Encryption Key r --> ueks[256-bit salt, device-unique] ueks -- salt --> haek([Argon2id KDF]) u -- pw -----> haek -- Heavy 256-bit --> uek[256-bit key] end subgraph Constants csm{{Backup Seeding Salt}} csg{{Unlock Pass Generator Salt}} end subgraph Backup Seed Derivation hadm([Argon2id KDF]) hadm -- Heavy 256-bit --> bps[Backup Seed] end b -- pw --> hadm csm -- salt -----> hadm subgraph Seed Authenticated Encryption/Decryption aes([AES256-GCM]) iv[96-bit entropy] r -- 96-bit --> iv bps <-. payload .-> aes uek -- key ---> aes iv -- iv --> aes aes <-. auth encrypt/decrypt .-> es[encrypted seed] es <-.-> eob([Encrypted Object Builder]) iv <-.-> eob ueks <-.-> eob aes <-. encrypt artifact .-> at[authentication tag] at <-.-> eob eob <-.-> eo[Encrypted Object] end subgraph Seed Blob Encoder eo <-.-> cbor([CBOR]) cbor <-. encode/decode .-> bs58c([Base58check]) <-. checksum encode/decode .-> eb[Encrypted Blob] end subgraph Browser Local Storage eb <-. save/load .-> lssb[(seedBlob)] end subgraph Password Generator Key - secure with user entropy hagp([Argon2id KDF]) u -- pw -------------------> hagp csg -- salt ------------------> hagp hagp -- Heavy 256-bit --> gk[Generator Key] end subgraph User Input Pass Parameters log[login] uri[uri] len[pass length * 8] idx[pass index] alp[alphabet] fmt[pass format] alp & fmt --> vc vc[variable charset] end subgraph Final Password Generation gk -- P --> hapg([Argon2id KDF]) len -- T --> hapg hapg -->|Light Variable-bit| srskey[Pass Length x 64 bit Key] srskey -- array ---> pce([64-bit array to variable charset compressor]) vc -- charset --> pce pce --> fp[Final SrsPass Output] end subgraph SrsPass Account ad-hoc Salt concf([seed + $idx? + $uri + $login]) concs[Concatenated Salt] concs -- salt --> hapg bps -----------> concf idx & uri & log ---> concf --> concs end

Footnotes

CSPRNG → Cryptographically Secure Pseudo-Random Number Generator

Heavy Argon2id parameters →

# used for the keys and seed
time cost   = 12 iterations
memory cost = 32768 KiB
parallelism = 1 thread

Light Argon2id parameters →

# used for password generation
time cost   = 19 iterations
memory cost = 512 KiB
parallelism = 1 thread

$ prefix → stringified

? suffix → only included if not nil or 0