upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrabble <evan@protest.net>2025-11-04 18:15:22 +1300
committerrabble <evan@protest.net>2025-11-04 18:15:22 +1300
commitd44476eee8c7b1df4ed99c760dc2a3c7874edc9a (patch)
tree322414c09d6f44a7c61fa83fd6d17f9e26f142e3
parent62f0b14ae81fd062bb84791bca698b29f6b573a3 (diff)
draft of the proofmode spec
-rw-r--r--XX.md358
1 files changed, 358 insertions, 0 deletions
diff --git a/XX.md b/XX.md
new file mode 100644
index 0000000..8888f42
--- /dev/null
+++ b/XX.md
@@ -0,0 +1,358 @@
1# NIP-XX: ProofMode - Cryptographic Video Verification
2
3`draft` `optional`
4
5## Abstract
6
7This NIP defines a standard for attaching cryptographic proof manifests to video events (NIP-71) to enable verification of video authenticity, recording continuity, and device integrity. ProofMode allows viewers to verify that a video was recorded on a specific device at a specific time without editing or tampering.
8
9## Motivation
10
11Social media platforms are increasingly vulnerable to deepfakes, edited videos, and synthetic media. While blockchain timestamping exists, it doesn't prove video continuity or prevent frame-level manipulation. ProofMode solves this by:
12
131. **Frame-level verification** - SHA256 hashes of captured frames prove recording continuity
142. **Hardware attestation** - iOS App Attest and Android Play Integrity verify the recording device
153. **Cryptographic signing** - PGP signatures ensure manifest authenticity
164. **Tamper detection** - Any edit to the video invalidates the proof chain
175. **Segment tracking** - Recording pauses are documented with sensor data
18
19## Specification
20
21### Event Tags
22
23ProofMode data is attached to video events (typically Kind 34236) using the following tags:
24
25#### Required Tags
26
27- `["verification", "<level>"]` - Verification level (see Verification Levels below)
28- `["proofmode", "<manifest_json>"]` - Complete ProofManifest as compact JSON
29
30#### Optional Tags
31
32- `["device_attestation", "<token>"]` - Hardware attestation token from iOS App Attest or Android Play Integrity
33- `["pgp_fingerprint", "<fingerprint>"]` - PGP public key fingerprint used to sign the manifest
34
35### Verification Levels
36
37The `verification` tag indicates the strength of cryptographic proof:
38
39- `verified_mobile` - Highest level: has device attestation + PGP signature + complete manifest
40- `verified_web` - Medium level: has PGP signature + complete manifest (no hardware attestation)
41- `basic_proof` - Low level: has proof data but no cryptographic signature
42- `unverified` - No meaningful proof data
43
44### ProofManifest Structure
45
46The `proofmode` tag contains a JSON object with the following structure:
47
48```json
49{
50 "sessionId": "<unique_session_id>",
51 "challengeNonce": "<16_char_nonce>",
52 "vineSessionStart": "<ISO8601_timestamp>",
53 "vineSessionEnd": "<ISO8601_timestamp>",
54 "totalDuration": 6500,
55 "recordingDuration": 6000,
56 "segments": [
57 {
58 "segmentId": "<segment_id>",
59 "startTime": "<ISO8601_timestamp>",
60 "endTime": "<ISO8601_timestamp>",
61 "duration": 3000,
62 "frameHashes": [
63 "<sha256_hash_1>",
64 "<sha256_hash_2>",
65 "..."
66 ],
67 "frameTimestamps": [
68 "<ISO8601_timestamp_1>",
69 "<ISO8601_timestamp_2>",
70 "..."
71 ],
72 "sensorData": {
73 "accelerometer": {"x": 0.1, "y": 0.2, "z": 9.8},
74 "gyroscope": {"x": 0.01, "y": 0.02, "z": 0.01}
75 }
76 }
77 ],
78 "pauseProofs": [
79 {
80 "startTime": "<ISO8601_timestamp>",
81 "endTime": "<ISO8601_timestamp>",
82 "duration": 500,
83 "sensorData": {
84 "timestamp": "<ISO8601_timestamp>",
85 "accelerometer": {"x": 0.1, "y": 0.2, "z": 9.8},
86 "gyroscope": {"x": 0.01, "y": 0.02, "z": 0.01},
87 "magnetometer": {"x": 45.0, "y": 12.0, "z": -30.0},
88 "light": 150.0
89 },
90 "interactions": [
91 {
92 "timestamp": "<ISO8601_timestamp>",
93 "interactionType": "touch",
94 "coordinates": {"x": 180, "y": 640},
95 "pressure": 0.5
96 }
97 ]
98 }
99 ],
100 "interactions": [
101 {
102 "timestamp": "<ISO8601_timestamp>",
103 "interactionType": "start|stop|touch",
104 "coordinates": {"x": 180, "y": 640},
105 "pressure": 0.5,
106 "metadata": {}
107 }
108 ],
109 "finalVideoHash": "<sha256_hash_of_complete_video>",
110 "deviceAttestation": {
111 "token": "<platform_specific_attestation_token>",
112 "platform": "iOS|Android|Web",
113 "deviceId": "<device_identifier>",
114 "isHardwareBacked": true,
115 "createdAt": "<ISO8601_timestamp>",
116 "challenge": "<challenge_nonce>",
117 "metadata": {
118 "attestationType": "app_attest|play_integrity|fallback",
119 "deviceInfo": {
120 "platform": "iOS",
121 "model": "iPhone 15 Pro",
122 "version": "17.0",
123 "manufacturer": "Apple"
124 }
125 }
126 },
127 "pgpSignature": {
128 "signature": "-----BEGIN PGP SIGNATURE-----\n...\n-----END PGP SIGNATURE-----",
129 "publicKey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...\n-----END PGP PUBLIC KEY BLOCK-----",
130 "publicKeyFingerprint": "1A2B3C4D5E6F7890..."
131 }
132}
133```
134
135### Field Descriptions
136
137#### Core Fields
138- `sessionId` - Unique identifier for the recording session
139- `challengeNonce` - Random nonce generated at session start, used in device attestation to prevent replay attacks
140- `vineSessionStart` / `vineSessionEnd` - Recording session boundaries
141- `totalDuration` - Total elapsed time in milliseconds (including pauses)
142- `recordingDuration` - Actual recording time in milliseconds (excluding pauses)
143
144#### Segments
145Recording can be paused and resumed, creating multiple segments. Each segment contains:
146- `segmentId` - Unique segment identifier
147- `startTime` / `endTime` - Segment boundaries
148- `frameHashes` - Array of SHA256 hashes of captured video frames
149- `frameTimestamps` - Timestamps when each frame was captured (optional)
150- `sensorData` - Device sensor readings during recording (optional)
151
152#### Pause Proofs
153When recording is paused, sensor data is collected to prove device continuity:
154- `startTime` / `endTime` - Pause boundaries
155- `sensorData` - Sensor readings during pause (accelerometer, gyroscope, magnetometer, light)
156- `interactions` - User touch/tap events during pause
157
158#### Interactions
159User interactions recorded throughout the session:
160- `timestamp` - When interaction occurred
161- `interactionType` - Type of interaction (start, stop, touch)
162- `coordinates` - Screen coordinates of interaction
163- `pressure` - Touch pressure (optional)
164
165#### Final Video Hash
166- `finalVideoHash` - SHA256 hash of the complete rendered video file
167
168#### Device Attestation
169Platform-specific hardware attestation proving the device is genuine:
170- **iOS**: Uses App Attest API (iOS 14+)
171- **Android**: Uses Play Integrity API
172- **Web/Other**: Fallback software attestation
173
174Fields:
175- `token` - Platform-specific attestation token
176- `platform` - Operating system (iOS, Android, Web)
177- `deviceId` - Device identifier
178- `isHardwareBacked` - Whether attestation uses hardware security module
179- `challenge` - Challenge nonce used in attestation (matches `challengeNonce`)
180- `metadata` - Platform-specific attestation details
181
182#### PGP Signature
183Cryptographic signature of the entire manifest:
184- `signature` - PGP signature in ASCII-armored format
185- `publicKey` - PGP public key in ASCII-armored format
186- `publicKeyFingerprint` - Key fingerprint for quick lookup
187
188## Implementation
189
190### Recording Phase
191
1921. **Start Session**
193 - Generate unique `sessionId` and `challengeNonce`
194 - Request hardware device attestation with challenge nonce
195 - Initialize ProofMode session
196
1972. **Capture Frames**
198 - During recording, periodically capture video frames
199 - Generate SHA256 hash of each frame
200 - Store frame hashes with timestamps
201 - Optionally collect sensor data (accelerometer, gyroscope, etc.)
202
2033. **Handle Pauses**
204 - When recording pauses, stop current segment
205 - Begin collecting pause proof data (sensor readings, interactions)
206 - When resuming, start new segment
207
2084. **Finalize Session**
209 - Stop recording and close final segment
210 - Hash complete video file
211 - Compile ProofManifest with all segments, pauses, and interactions
212 - Sign manifest with PGP private key
213 - Attach ProofManifest to video event as tags
214
215### Verification Phase
216
217To verify a ProofMode video, clients should:
218
2191. **Extract ProofManifest**
220 - Parse `proofmode` tag from video event
221 - Extract `deviceAttestation` and `pgpSignature` from separate tags
222
2232. **Verify PGP Signature**
224 - Extract PGP public key from manifest
225 - Verify signature of manifest JSON
226 - Check public key fingerprint matches `pgp_fingerprint` tag
227
2283. **Verify Device Attestation** (if present)
229 - Validate attestation token against platform-specific APIs
230 - Verify challenge nonce matches manifest `challengeNonce`
231 - Check attestation timestamp is recent (within 24 hours of recording)
232
2334. **Verify Frame Hashes** (advanced)
234 - Re-encode video to extract individual frames
235 - Generate SHA256 hashes of extracted frames
236 - Compare against hashes in manifest segments
237 - Verify frame count and timestamps match recording duration
238
2395. **Verify Recording Continuity**
240 - Check that segment timestamps are contiguous
241 - Verify pause durations match gaps between segments
242 - Validate total recording duration matches video length
243
2446. **Display Verification Badge**
245 - `verified_mobile` - Show "Verified" badge with hardware attestation icon
246 - `verified_web` - Show "Signed" badge
247 - `basic_proof` - Show "Basic Proof" indicator
248 - `unverified` - No badge or "Unverified" indicator
249
250## Example Event
251
252```json
253{
254 "kind": 34236,
255 "pubkey": "...",
256 "created_at": 1730326800,
257 "tags": [
258 ["d", "unique-video-identifier"],
259 ["title", "My Verified Video"],
260 ["url", "https://media.example.com/video.mp4", "720x1280"],
261 ["thumb", "https://media.example.com/thumb.jpg", "720x1280"],
262 ["duration", "6"],
263 ["verification", "verified_mobile"],
264 ["proofmode", "{\"sessionId\":\"session_1730326800000_1234\",\"challengeNonce\":\"a1b2c3d4e5f6789\",\"vineSessionStart\":\"2025-10-30T10:00:00.000Z\",\"vineSessionEnd\":\"2025-10-30T10:00:06.500Z\",\"totalDuration\":6500,\"recordingDuration\":6000,\"segments\":[{\"segmentId\":\"segment_1\",\"startTime\":\"2025-10-30T10:00:00.000Z\",\"endTime\":\"2025-10-30T10:00:06.000Z\",\"frameHashes\":[\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"]}],\"pauseProofs\":[],\"interactions\":[{\"timestamp\":\"2025-10-30T10:00:00.000Z\",\"interactionType\":\"start\",\"coordinates\":{\"x\":180,\"y\":640}}],\"finalVideoHash\":\"d4e5f6a7b8c9...\"}"],
265 ["device_attestation", "AAABBBCCC..."],
266 ["pgp_fingerprint", "1A2B3C4D5E6F7890..."]
267 ],
268 "content": "Check out this verified video!",
269 "sig": "..."
270}
271```
272
273## Security Considerations
274
275### Threat Model
276
277ProofMode protects against:
278- ✅ **Post-recording video editing** - Frame hashes detect any modifications
279- ✅ **Deepfakes and synthetic videos** - Hardware attestation proves real device
280- ✅ **Timestamp manipulation** - Device attestation includes trusted timestamps
281- ✅ **Replay attacks** - Challenge nonce prevents reuse of attestations
282
283ProofMode does NOT protect against:
284- ❌ **Screen recording** - A user can screen-record another video
285- ❌ **Camera lens manipulation** - Physical objects placed in front of camera
286- ❌ **Compromised devices** - Rooted/jailbroken devices may forge attestations
287- ❌ **Social engineering** - User can intentionally create misleading content
288
289### Privacy Considerations
290
291- **Device Identifiers**: The `deviceId` field may be sensitive. Clients should:
292 - Hash or truncate device IDs before publishing
293 - Allow users to opt-out of device attestation
294 - Clearly indicate when ProofMode is active
295
296- **Sensor Data**: Accelerometer and gyroscope data may reveal user location or behavior. Clients should:
297 - Allow disabling sensor data collection
298 - Sanitize or omit sensitive sensor readings
299 - Aggregate sensor data to reduce precision
300
301- **PGP Keys**: Users should be able to:
302 - Rotate PGP keys periodically
303 - Revoke compromised keys
304 - Use separate keys for different purposes
305
306### Verification Best Practices
307
308Verifying clients should:
309
3101. **Always check PGP signature** - This is the minimum verification
3112. **Validate device attestation** when present - But gracefully handle missing/invalid attestations
3123. **Display verification level prominently** - Users should understand confidence level
3134. **Cache verification results** - Re-verification is expensive
3145. **Handle expired attestations** - Attestations may expire after 24-48 hours
3156. **Warn on missing proofs** - But don't assume malice if ProofMode is absent
316
317## Reference Implementation
318
319OpenVine provides a complete reference implementation:
320- **Recording**: `ProofModeSessionService` in OpenVine mobile app
321- **Publishing**: `VideoEventPublisher` adds ProofMode tags to Nostr events
322- **Verification**: `ProofModeHelpers` and verification UI components
323
324Source: https://github.com/openvine/openvine
325
326## Backwards Compatibility
327
328This NIP is fully backwards compatible:
329- Events without ProofMode tags are treated as unverified
330- Older clients ignore ProofMode tags
331- ProofMode is opt-in - videos without it still work normally
332
333## Future Extensions
334
335Possible future enhancements:
336
3371. **Witness Signatures** - Multiple devices co-sign the same recording
3382. **Location Proofs** - GPS coordinates with cryptographic verification
3393. **Biometric Proof** - Prove human presence during recording
3404. **Chain of Custody** - Track video transfer and handling
3415. **Selective Disclosure** - Zero-knowledge proofs for privacy-preserving verification
342
343## References
344
345- [NIP-01: Basic protocol flow description](https://github.com/nostr-protocol/nips/blob/master/01.md)
346- [NIP-71: Video Events](https://github.com/nostr-protocol/nips/blob/master/71.md)
347- [iOS App Attest](https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity)
348- [Android Play Integrity](https://developer.android.com/google/play/integrity)
349- [ProofMode Original Project](https://proofmode.org)
350
351## Authors
352
353- Evan Henshaw-Plath (Rabble) - Divine.Video Project
354
355## License
356
357This NIP is released into the public domain.
358