voidlogue-crypto 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +57 -0
- package/README.md +215 -0
- package/SECURITY.md +154 -0
- package/index.js +13 -0
- package/package.json +52 -0
- package/src/eff_wordlist.js +7778 -0
- package/src/vault.js +286 -0
- package/src/voidshield.js +353 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Voidlogue
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## License rationale
|
|
26
|
+
|
|
27
|
+
This package is published under the MIT license for the following reasons:
|
|
28
|
+
|
|
29
|
+
1. **Auditability over restriction.** The purpose of open-sourcing this package
|
|
30
|
+
is to allow independent verification of Voidlogue's privacy claims. A
|
|
31
|
+
permissive license removes barriers to inspection and review.
|
|
32
|
+
|
|
33
|
+
2. **Cryptographic primitives benefit from wide scrutiny.** Security research
|
|
34
|
+
is best served by making cryptographic code as accessible as possible.
|
|
35
|
+
Restrictive licenses discourage security researchers.
|
|
36
|
+
|
|
37
|
+
3. **The word list is already public.** The EFF long wordlist included in this
|
|
38
|
+
package is published by the Electronic Frontier Foundation under an open
|
|
39
|
+
license. There is no proprietary component to protect here.
|
|
40
|
+
|
|
41
|
+
4. **This package alone cannot replicate Voidlogue.** The client-side crypto
|
|
42
|
+
layer requires a server (Phoenix/Elixir backend, PostgreSQL, Oban jobs,
|
|
43
|
+
push infrastructure) which is not included here. Permissive licensing of
|
|
44
|
+
this package does not expose the platform's competitive differentiators.
|
|
45
|
+
|
|
46
|
+
## What the MIT license means for you
|
|
47
|
+
|
|
48
|
+
- You can read, inspect, fork, and use this code for any purpose
|
|
49
|
+
- You can use it in commercial products
|
|
50
|
+
- You must include the copyright notice in any copy or substantial portion
|
|
51
|
+
- There is no warranty — use at your own risk
|
|
52
|
+
|
|
53
|
+
## What this license does NOT cover
|
|
54
|
+
|
|
55
|
+
The Voidlogue platform server code, the Revelation product, the admin
|
|
56
|
+
infrastructure, and the marketing pages are proprietary and are NOT covered
|
|
57
|
+
by this license. This license applies only to the files in this repository.
|
package/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# voidlogue-crypto
|
|
2
|
+
|
|
3
|
+
**Open-source cryptographic layer for Voidlogue — published for independent audit and verification.**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/voidlogue-crypto)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
This package contains exactly the code running in the browser at [voidlogue.com](https://voidlogue.com).
|
|
9
|
+
It is published so that Voidlogue's privacy claims can be independently verified.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What this proves
|
|
14
|
+
|
|
15
|
+
| Claim | Code |
|
|
16
|
+
|---|---|
|
|
17
|
+
| "We cannot read your messages" | `VoidShield.roomId()`, `VoidShield.deriveKey()`, `VoidShield.encrypt()` |
|
|
18
|
+
| "We cannot read your Revelations" | `VoidShield.deriveRevelationKey()`, `VoidShield.encryptMedia()` |
|
|
19
|
+
| "Your saved shortcuts are encrypted locally" | `Vault.save()`, `Vault.load()` |
|
|
20
|
+
|
|
21
|
+
See [SECURITY.md](./SECURITY.md) for a full technical explanation of each claim.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install voidlogue-crypto
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
import { VoidShield, generateCodename } from "voidlogue-crypto";
|
|
37
|
+
|
|
38
|
+
// Derive a room hash (server never sees emails or codename)
|
|
39
|
+
const roomHash = await VoidShield.roomId(
|
|
40
|
+
"alice@example.com",
|
|
41
|
+
"bob@example.com",
|
|
42
|
+
"iron-falcon-sky"
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Derive encryption key
|
|
46
|
+
const key = await VoidShield.deriveKey("iron-falcon-sky", roomHash);
|
|
47
|
+
|
|
48
|
+
// Encrypt a message
|
|
49
|
+
const { ciphertextB64, ivB64 } = await VoidShield.encrypt("hello", key);
|
|
50
|
+
|
|
51
|
+
// Decrypt (throws if key is wrong — AES-GCM authentication)
|
|
52
|
+
const plaintext = await VoidShield.decrypt(ciphertextB64, ivB64, key);
|
|
53
|
+
|
|
54
|
+
// Generate a random codename from the EFF wordlist
|
|
55
|
+
const codename = generateCodename(4); // e.g. "correct-horse-battery-staple"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## API Reference
|
|
61
|
+
|
|
62
|
+
### `VoidShield`
|
|
63
|
+
|
|
64
|
+
#### Conversation
|
|
65
|
+
|
|
66
|
+
| Method | Description |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `hex(input)` | SHA-256 of input string → 64-char hex |
|
|
69
|
+
| `roomId(emailA, emailB, codename)` | Derives opaque room hash. Commutative. |
|
|
70
|
+
| `validateCodename(codename)` | Returns `{ valid, reason? }` |
|
|
71
|
+
| `deriveKey(codename, roomHash)` | PBKDF2 → AES-256-GCM key (non-extractable) |
|
|
72
|
+
| `encrypt(plaintext, key)` | AES-256-GCM → `{ ciphertextB64, ivB64 }` |
|
|
73
|
+
| `decrypt(ciphertextB64, ivB64, key)` | AES-256-GCM → plaintext string |
|
|
74
|
+
| `senderHash(uuid, roomHash)` | Room-scoped sender identifier |
|
|
75
|
+
|
|
76
|
+
#### Revelation
|
|
77
|
+
|
|
78
|
+
| Method | Description |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `deriveRevelationKey(senderEmail, recipientEmail, fieldValues[])` | Key from emails + security fields |
|
|
81
|
+
| `deriveRevelationKeyFromHashes(senderHash, recipientHash, fieldValues[])` | Key from pre-computed hashes |
|
|
82
|
+
| `hashFieldValue(value)` | Normalise + SHA-256 for server storage |
|
|
83
|
+
| `encryptMedia(file, key)` | Chunked file encryption → chunk array |
|
|
84
|
+
| `decryptMediaStream(chunks, key)` | Async generator → ArrayBuffer per chunk |
|
|
85
|
+
|
|
86
|
+
#### Utilities
|
|
87
|
+
|
|
88
|
+
| Method | Description |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `secureRandom(max)` | Uniform random int in `[0, max)` — rejection sampling |
|
|
91
|
+
|
|
92
|
+
### `generateCodename(wordCount?)`
|
|
93
|
+
|
|
94
|
+
Generates a hyphen-separated passphrase from the EFF long wordlist.
|
|
95
|
+
|
|
96
|
+
- Default: 3 words (~38 bits of entropy)
|
|
97
|
+
- Range: 2–8 words, clamped
|
|
98
|
+
- 4 words ≈ 51 bits, 5 words ≈ 64 bits, 6 words ≈ 77 bits
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
generateCodename() // "iron-falcon-sky"
|
|
102
|
+
generateCodename(5) // "correct-horse-battery-staple-moon"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `Vault`
|
|
106
|
+
|
|
107
|
+
PIN-based local encryption for saved conversation credentials.
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
import { Vault } from "voidlogue-crypto";
|
|
111
|
+
|
|
112
|
+
// Save email + codename encrypted with PIN
|
|
113
|
+
await Vault.save(roomHash, email, codename, "123456", "Alice — work");
|
|
114
|
+
|
|
115
|
+
// Load (returns {email, codename} or {error: "wrong_pin"|"locked"|"not_found"})
|
|
116
|
+
const result = await Vault.load(roomHash, "123456");
|
|
117
|
+
|
|
118
|
+
// List saved conversations (no sensitive data)
|
|
119
|
+
const list = Vault.list(); // [{roomHash, hint (encrypted), savedAt}]
|
|
120
|
+
|
|
121
|
+
// Wipe all (panic clear)
|
|
122
|
+
Vault.wipeAll();
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `EFF_WORDLIST`
|
|
126
|
+
|
|
127
|
+
The complete EFF long wordlist — 7776 words, frozen array.
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
import { EFF_WORDLIST } from "voidlogue-crypto";
|
|
131
|
+
console.log(EFF_WORDLIST.length); // 7776
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Cryptographic algorithm summary
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Room hash:
|
|
140
|
+
hA, hB = SHA-256(email.toLowerCase().trim())
|
|
141
|
+
roomHash = SHA-256(sort([hA,hB]).join(":") + ":" + codename + ":" + APP_SALT)
|
|
142
|
+
|
|
143
|
+
Conversation key:
|
|
144
|
+
key = PBKDF2(codename, salt=roomHash, iters=100_000, hash=SHA-256) → AES-256-GCM
|
|
145
|
+
|
|
146
|
+
Revelation key:
|
|
147
|
+
hS, hR = SHA-256(email.toLowerCase().trim())
|
|
148
|
+
fh[] = SHA-256(normalise(fieldValue))
|
|
149
|
+
input = sort([hS,hR]).join(":") + ":" + fh.join(":")
|
|
150
|
+
key = PBKDF2(input, salt="voidlogue-revelation-v1", iters=100_000) → AES-256-GCM
|
|
151
|
+
|
|
152
|
+
Vault PIN key:
|
|
153
|
+
key = PBKDF2(PIN, random_16B_salt, iters=100_000, hash=SHA-256) → AES-256-GCM
|
|
154
|
+
|
|
155
|
+
All encryption: AES-256-GCM with random 96-bit IV per operation
|
|
156
|
+
All randomness: crypto.getRandomValues() with rejection sampling
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
No third-party cryptographic libraries. All operations use the Web Crypto API.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Running the tests
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npm install
|
|
167
|
+
npm test
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Tests cover:
|
|
171
|
+
- SHA-256 against known vectors
|
|
172
|
+
- `roomId` commutativity, determinism, isolation
|
|
173
|
+
- Encrypt/decrypt round-trip and tamper detection
|
|
174
|
+
- Revelation key derivation cross-compatibility
|
|
175
|
+
- `secureRandom` uniformity and bounds
|
|
176
|
+
- Media chunk encryption and decryption
|
|
177
|
+
- `generateCodename` wordlist coverage
|
|
178
|
+
- `EFF_WORDLIST` integrity (7776 entries, no duplicates, frozen)
|
|
179
|
+
- Security invariants (ciphertext contains no plaintext, hashes contain no inputs)
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Verifying the deployed code
|
|
184
|
+
|
|
185
|
+
The code at [voidlogue.com](https://voidlogue.com) uses this package directly.
|
|
186
|
+
To verify:
|
|
187
|
+
|
|
188
|
+
1. Open voidlogue.com in your browser
|
|
189
|
+
2. DevTools → Sources → search for `VoidShield` or `roomId`
|
|
190
|
+
3. Compare the implementation against this repository
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## What is NOT in this package
|
|
195
|
+
|
|
196
|
+
- Server code (Phoenix/Elixir backend)
|
|
197
|
+
- Database schema or queries
|
|
198
|
+
- The Revelation product server logic
|
|
199
|
+
- Payment or subscription code
|
|
200
|
+
- Admin infrastructure
|
|
201
|
+
- Anything that runs outside the browser
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT — see [LICENSE](./LICENSE) for details and rationale.
|
|
208
|
+
|
|
209
|
+
## Security disclosure
|
|
210
|
+
|
|
211
|
+
See [SECURITY.md](./SECURITY.md) — email security@voidlogue.com for vulnerabilities.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
*Part of [Voidlogue](https://voidlogue.com) — Said once. Gone forever.*
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## What this package proves
|
|
4
|
+
|
|
5
|
+
This package is the open-source cryptographic layer for Voidlogue. It is
|
|
6
|
+
published so that the following privacy claims can be independently verified
|
|
7
|
+
against the actual code running in the browser.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
### Claim 1: "We cannot read your Conversation messages"
|
|
12
|
+
|
|
13
|
+
**Code that proves it:** `src/voidshield.js` — `roomId()`, `deriveKey()`, `encrypt()`
|
|
14
|
+
|
|
15
|
+
Room hashes are derived entirely client-side from the pair of email addresses
|
|
16
|
+
and the shared codename. The algorithm:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
hA = SHA-256(emailA.toLowerCase().trim())
|
|
20
|
+
hB = SHA-256(emailB.toLowerCase().trim())
|
|
21
|
+
roomHash = SHA-256(sort([hA, hB]).join(":") + ":" + codename + ":" + APP_SALT)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The server receives only `roomHash` — an opaque 64-character hex string. It
|
|
25
|
+
cannot reverse this to learn the email addresses or the codename.
|
|
26
|
+
|
|
27
|
+
The encryption key is derived from the codename:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
key = PBKDF2(codename, salt=roomHash, iterations=100_000, hash=SHA-256)
|
|
31
|
+
→ AES-256-GCM key (non-extractable)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The codename is never sent to the server. The server stores only
|
|
35
|
+
`AES-256-GCM(plaintext, key, random_IV)` — ciphertext it cannot decrypt
|
|
36
|
+
because it never held the key material.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### Claim 2: "We cannot read your Revelations"
|
|
41
|
+
|
|
42
|
+
**Code that proves it:** `src/voidshield.js` — `deriveRevelationKey()`,
|
|
43
|
+
`deriveRevelationKeyFromHashes()`, `encryptMedia()`
|
|
44
|
+
|
|
45
|
+
Revelation content is encrypted before upload. The key is derived from:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
hS = SHA-256(senderEmail.toLowerCase().trim())
|
|
49
|
+
hR = SHA-256(recipientEmail.toLowerCase().trim())
|
|
50
|
+
fh[] = SHA-256(normalise(fieldValue)) for each security field
|
|
51
|
+
|
|
52
|
+
input = sort([hS, hR]).join(":") + ":" + fh.join(":")
|
|
53
|
+
key = PBKDF2(input, salt="voidlogue-revelation-v1", iterations=100_000)
|
|
54
|
+
→ AES-256-GCM key
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The security field values (e.g. the recipient's date of birth, first name)
|
|
58
|
+
are never sent to the server. The server stores only the hashes of field
|
|
59
|
+
values for access control purposes — and never the values themselves. The
|
|
60
|
+
decryption key cannot be derived without the raw field values which only the
|
|
61
|
+
recipient holds.
|
|
62
|
+
|
|
63
|
+
Delivery does not require decryption. The server relays encrypted bytes it
|
|
64
|
+
cannot read.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### Claim 3: "Your saved conversation shortcuts are encrypted locally"
|
|
69
|
+
|
|
70
|
+
**Code that proves it:** `src/vault.js`
|
|
71
|
+
|
|
72
|
+
The Vault encrypts the user's email and codename on-device before storing
|
|
73
|
+
them in `localStorage`:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
key = PBKDF2(PIN, random_salt, iterations=100_000) → AES-256-GCM key
|
|
77
|
+
blob = AES-256-GCM(JSON({email, codename}), key, random_IV)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The PIN is never stored anywhere. The server is never involved. Even if
|
|
81
|
+
someone extracts the device's `localStorage` they receive AES-256-GCM
|
|
82
|
+
ciphertext that cannot be decrypted without the PIN.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Cryptographic primitive choices
|
|
87
|
+
|
|
88
|
+
| Primitive | Algorithm | Rationale |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| Symmetric encryption | AES-256-GCM | NIST-approved; provides authenticated encryption (tamper detection) |
|
|
91
|
+
| Key derivation | PBKDF2, SHA-256, 100k iterations | Standardised; makes brute-force computationally expensive |
|
|
92
|
+
| Hashing | SHA-256 | Collision-resistant; output is 256 bits |
|
|
93
|
+
| Randomness | `crypto.getRandomValues` with rejection sampling | Cryptographically secure; rejection sampling eliminates modular bias |
|
|
94
|
+
|
|
95
|
+
No third-party cryptographic libraries are used. All operations use the
|
|
96
|
+
Web Crypto API built into the browser.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## What this package does NOT prove
|
|
101
|
+
|
|
102
|
+
- That the server does not log data it should not log (requires server audit)
|
|
103
|
+
- That the server deletes messages as described (requires server audit)
|
|
104
|
+
- That the N=1 constraint is enforced server-side (requires server audit)
|
|
105
|
+
- That the server does not store session data beyond what is stated
|
|
106
|
+
|
|
107
|
+
These claims require auditing the server code, which is not included here.
|
|
108
|
+
We will answer specific questions about the server implementation directly.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Threat model
|
|
113
|
+
|
|
114
|
+
### Protects against
|
|
115
|
+
|
|
116
|
+
- Platform reading message content (server never holds keys)
|
|
117
|
+
- Server breach exposing message content (only ciphertext stored)
|
|
118
|
+
- Legal compulsion to produce message content (server has nothing to produce)
|
|
119
|
+
- Person with physical device access seeing conversation content
|
|
120
|
+
|
|
121
|
+
### Does NOT protect against
|
|
122
|
+
|
|
123
|
+
- Government subpoena for metadata (who talked to whom, when)
|
|
124
|
+
- Nation-state network surveillance
|
|
125
|
+
- The counterparty sharing decrypted content
|
|
126
|
+
- Screen photography
|
|
127
|
+
- A PIN brute-force attack on a stolen device (mitigated by lockout)
|
|
128
|
+
- Compromise of the user's Google account (authentication layer)
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Reporting vulnerabilities
|
|
133
|
+
|
|
134
|
+
**Please do not open a public issue for security vulnerabilities.**
|
|
135
|
+
|
|
136
|
+
Email: security@voidlogue.com
|
|
137
|
+
|
|
138
|
+
We will acknowledge within 48 hours and aim to resolve critical issues within
|
|
139
|
+
7 days. We will credit researchers in release notes unless anonymity is
|
|
140
|
+
requested.
|
|
141
|
+
|
|
142
|
+
## Scope
|
|
143
|
+
|
|
144
|
+
In scope:
|
|
145
|
+
- Cryptographic implementation errors in this package
|
|
146
|
+
- Key derivation weaknesses
|
|
147
|
+
- Randomness or bias issues in `secureRandom()`
|
|
148
|
+
- Any input that allows recovery of plaintext without the correct key
|
|
149
|
+
|
|
150
|
+
Out of scope:
|
|
151
|
+
- Social engineering attacks
|
|
152
|
+
- Physical device access attacks
|
|
153
|
+
- Issues in the server-side code (not in this repo)
|
|
154
|
+
- Theoretical weaknesses in AES-256-GCM or PBKDF2 as standardised algorithms
|
package/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* voidlogue-crypto — Voidlogue Client-Side Cryptography
|
|
3
|
+
*
|
|
4
|
+
* Open-source cryptographic layer for independent audit and verification.
|
|
5
|
+
* Published so that the privacy claims made at voidlogue.com can be verified
|
|
6
|
+
* against the actual code running in the browser.
|
|
7
|
+
*
|
|
8
|
+
* @module voidlogue-crypto
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export { VoidShield, generateCodename } from "./src/voidshield.js";
|
|
12
|
+
export { Vault, LabelCipher } from "./src/vault.js";
|
|
13
|
+
export { EFF_WORDLIST } from "./src/eff_wordlist.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "voidlogue-crypto",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Open-source client-side cryptographic primitives for Voidlogue — published for independent audit and verification of privacy claims.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.js",
|
|
9
|
+
"./voidshield": "./src/voidshield.js",
|
|
10
|
+
"./vault": "./src/vault.js",
|
|
11
|
+
"./eff_wordlist": "./src/eff_wordlist.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src/",
|
|
15
|
+
"index.js",
|
|
16
|
+
"README.md",
|
|
17
|
+
"SECURITY.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"encryption",
|
|
22
|
+
"privacy",
|
|
23
|
+
"ephemeral",
|
|
24
|
+
"messaging",
|
|
25
|
+
"aes-gcm",
|
|
26
|
+
"pbkdf2",
|
|
27
|
+
"web-crypto",
|
|
28
|
+
"voidlogue",
|
|
29
|
+
"e2e",
|
|
30
|
+
"zero-knowledge"
|
|
31
|
+
],
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/voidlogue/voidlogue-crypto.git"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://voidlogue.com",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/voidlogue/voidlogue-crypto/issues",
|
|
40
|
+
"email": "security@voidlogue.com"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"vitest": "^1.0.0"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest"
|
|
51
|
+
}
|
|
52
|
+
}
|