Content Verification Flow

Content Verification Flow

Youseddit’s verification flow utilizes email source analysis, off-chain cryptographic proofs (IPFS with C2PA metadata), and on-chain evidence records to enable trustworthy content verification while maintaining GDPR compliance. While any email client can be used, encrypted and signed emails (S/MIME or PGP/GnuPG) are recommended for the highest level of provenance.

Verification Principles

The verification system is built on four core principles:

  1. Cryptographic Integrity: Hash-based verification ensures content hasn’t been altered
  2. Decentralized Storage: IPFS provides content-addressable, tamper-evident storage
  3. Blockchain Immutability: On-chain records provide permanent timestamping and authorization control
  4. Email Provenance: Verification based on email header analysis and user account information.

Email Processing Workflow

The email processing workflow involves these steps:

  1. User Upload: The user copies the full source code of an email (initial message or reply) and pastes it into the YouSeddit web interface.
  2. Header Parsing: The system parses key email headers (e.g., From, To, Date, Subject, Message-ID) to extract provenance metadata.
  3. IPFS Storage: The complete, unmodified email source code is stored securely on IPFS, generating a unique Content Identifier (CID).
  4. C2PA Manifest Generation: A C2PA manifest is created, embedding the extracted header metadata, the IPFS CID, and information linking the upload to the authenticated YouSeddit user account.
  5. Blockchain Record: An evidence record is created on the blockchain, containing cryptographic hashes (of the full email and specific quotes), the IPFS CID, and references to the user account and C2PA manifest, establishing an immutable link between the quote, its source, and the uploader.

(Note: While PGP/GnuPG or S/MIME signed/encrypted emails provide stronger cryptographic proof of origin and integrity, the system processes standard emails by relying on header information and user attestation.)

Publisher Verification Flow

When a publisher wants to verify a quote before publication:

sequenceDiagram
    autonumber
    Publisher->>Smart Contract: Query snippetHash
    Smart Contract->>Publisher: Return evidenceRecord (fullEmailHash, CID, status)
    Publisher->>IPFS: Retrieve encrypted file using CID
    IPFS->>Publisher: Return encrypted GPG file
    Publisher->>Publisher: Calculate hash of encrypted file
    Publisher->>Publisher: Verify hash matches fullEmailHash from contract
    Publisher->>Publisher: If approved source, decrypt file with proper key
    Publisher->>Publisher: Locate snippet in decrypted content
    Publisher->>Publisher: Calculate hash of snippet
    Publisher->>Publisher: Verify snippet hash matches snippetHash used for lookup
    Publisher->>Publisher: Check isPublished status is true
    Publisher->>License Contract: Request publication license
    License Contract->>Publisher: Issue license if conditions met

Reader Verification Flow

When an end-user wants to verify a published quote:

sequenceDiagram
    autonumber
    Reader->>Browser Extension: Encounters quote with C2PA marker
    Browser Extension->>C2PA Manifest: Extract snippetHash and blockchain address
    Browser Extension->>Smart Contract: Query snippetHash
    Smart Contract->>Browser Extension: Return source metadata and verification status
    Browser Extension->>Browser Extension: Verify publisher domain is authorized
    Browser Extension->>Reader: Display verification status and source information

Verification Components

1. Email Source Analysis & Provenance

The system establishes email provenance by:

  • Parsing Email Headers: Extracting standard metadata like From, To, Date, Subject, Message-ID from the raw email source.
  • User Attestation: Linking the uploaded email source to the authenticated YouSeddit user who submitted it.
  • C2PA Metadata: Embedding the extracted header information and user details within the C2PA manifest associated with the stored email source on IPFS.
  • (Recommended) Cryptographic Signatures: Leveraging S/MIME or PGP/GnuPG signatures when present in the email source for stronger sender verification.

2. Hash Verification

The system uses SHA-256 hashing at multiple levels:

  • Full Email Hash: Verifies the integrity of the complete encrypted source file
  • Snippet Hash: Provides unique identifier for specific quotable content
  • Transaction Hash: Links on-chain evidence to specific blockchain transactions

3. IPFS Content Addressing

IPFS CIDs (Content Identifiers) provide:

  • Content-addressable storage where the address is derived from the content itself
  • Built-in integrity checking via cryptographic hashing
  • Distributed retrieval from multiple nodes for availability

4. Smart Contract Verification

The EvidenceRecord smart contract provides:

  • Immutable timestamped records of snippet-to-source relationships
  • Authorization status controls managed by content owners
  • Public verification endpoints for third-party systems

5. C2PA Manifest Integration

C2PA manifests include:

  • Blockchain transaction references
  • Snippet hash references
  • Signature verification status
  • Original source metadata
  • Publication authorization indicators

Technical Implementation

Email Processing Pseudocode

// Process submitted email source code
async function processEmailSource(emailSourceCode, yousedditUserId) {
  // 1. Parse Headers
  const headers = parseEmailHeaders(emailSourceCode);
  // Example: headers = { from: '...', to: '...', date: '...', messageId: '...' }

  // 2. Store full source in IPFS
  const ipfsCid = await ipfs.add(emailSourceCode);
  const fullEmailHash = sha256(emailSourceCode);

  // 3. Generate C2PA Manifest
  const c2paManifest = createC2PAManifest({
    emailHeaders: headers,
    ipfsCid: ipfsCid,
    uploaderUserId: yousedditUserId,
    timestamp: new Date()
    // Include signature verification status if applicable
  });
  const c2paManifestCid = await ipfs.add(JSON.stringify(c2paManifest));

  // 4. Record Evidence on Blockchain
  // (Assuming snippetHash is generated when user selects quote later)
  const txId = await evidenceContract.methods
    .recordInitialEvidence(
      fullEmailHash,
      ipfsCid,
      c2paManifestCid,
      yousedditUserId // Link to the uploader
    )
    .send({ from: systemAccount });

  return {
    ipfsCid,
    c2paManifestCid,
    fullEmailHash,
    txId,
    processed: true
  };
}

// Function to associate a selected quote snippet later
async function recordQuoteSnippet(fullEmailHash, snippetText, yousedditUserId) {
  const snippetHash = sha256(snippetText);

  // Find the initial evidence record
  const initialRecord = await evidenceContract.methods.findEvidenceByFullHash(fullEmailHash).call();

  if (!initialRecord || initialRecord.owner !== yousedditUserId) {
    throw new Error("Unauthorized or evidence not found");
  }

  // Add the snippet hash to the record
  const txId = await evidenceContract.methods
    .addSnippetHash(fullEmailHash, snippetHash)
    .send({ from: yousedditUserId }); // User confirms quote selection

  return { snippetHash, txId, added: true };
}

Evidence Record Verification

// Verify a snippet against blockchain evidence
async function verifySnippet(snippetText, publisherDomain) {
  // Calculate hash of the snippet
  const snippetHash = sha256(snippetText);
  
  // Query the smart contract
  const evidenceRecord = await evidenceContract.methods
    .getEvidence(snippetHash)
    .call();
    
  // Verify publication status
  if (!evidenceRecord.isPublished) {
    return { verified: false, reason: 'not_published' };
  }
  
  // Retrieve encrypted file from IPFS
  const encryptedFile = await ipfs.cat(evidenceRecord.storagePointer);
  
  // Calculate hash of encrypted file
  const calculatedFullHash = sha256(encryptedFile);
  
  // Verify full file hash matches
  if (calculatedFullHash !== evidenceRecord.fullEmailHash) {
    return { verified: false, reason: 'file_hash_mismatch' };
  }
  
  // Verify publisher domain authorization
  const isDomainAuthorized = await licenseContract.methods
    .isAuthorizedPublisher(publisherDomain, snippetHash)
    .call();
    
  if (!isDomainAuthorized) {
    return { verified: false, reason: 'unauthorized_publisher' };
  }
  
  // Return successful verification with source info
  return {
    verified: true,
    source: {
      recordedAt: new Date(evidenceRecord.timestamp * 1000),
      owner: evidenceRecord.owner,
      verified: true
    }
  };
}

C2PA Integration

The C2PA manifest includes Youseddit-specific assertions that link to the blockchain evidence:

{
  "assertions": [
    {
      "label": "youseddit.blockchain",
      "data": {
        "snippetHash": "0x7d931ff3a802d6c5b8c94e5421ccd1e392bde1c9ff7283173121a1c52348ec5e",
        "contractAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
        "network": "polygon",
        "transactionHash": "0x9c742cd10ff11d6c1a0165fc108b6753970aa74daff87d9bee90920d613bdd3a"
      }
    },
    {
      "label": "youseddit.verification",
      "data": {
        "verificationTimestamp": "2025-03-15T14:22:31Z",
        "isPublished": true,
        "verificationMethod": "hash_ipfs_blockchain",
        "emailProvenance": {
          "method": "header_analysis_user_attestation",
          "uploaderUserId": "user_123abc", // Example YouSeddit User ID
          "headerFields": ["From", "To", "Date", "Subject", "Message-ID"], // Fields used
          "signatureVerified": false // Example: Set to true if PGP/S-MIME signature was present and verified
        }
      }
    }
  ]
}

Benefits of This Approach

  • GDPR Compliance: Sensitive personal data remains encrypted off-chain
  • Cryptographic Proof: Hashing, IPFS, C2PA, and blockchain provide tamper-evident verification (enhanced by optional email signatures).
  • User Attestation: Links the uploaded source to the authenticated user account.
  • Owner Control: Source individuals maintain publication control
  • Publisher Verification: Media outlets can verify authenticity before publishing
  • Reader Confidence: End-users can verify content authenticity through browser extensions
  • Searchable Quotes: Decryption on platform enables search and discovery while maintaining privacy
Last modified July 6, 2025: Update deploy.yml (d65b9c1)