Skip to content

Prime-Space Fingerprinting

Prime-Space fingerprinting is the core fingerprinting algorithm in PrimeStamp. It produces a multi-layered document fingerprint that supports partial proofs, progressive disclosure, and structural similarity comparison -- all derived from prime number geometry.

Based on Prime Space Theory by Brian Molidor (ORCID: 0009-0001-4839-5238).

Key Concepts

  • Prime-indexed decomposition: Documents are split into chunks, each assigned a prime number index.
  • Prime-Merkle tree: A Merkle tree built from prime-indexed chunks, enabling existence proofs for individual sections.
  • Shadow transforms: Multi-scale lossy projections of document content at prime scales (2, 3, 5, 7, 11, 13), allowing structural comparison at varying resolutions.
  • Crossover prime: The constant 127 (CROSSOVER_PRIME) from Prime Space Theory, used as the modulus in frequency signatures and shadow transforms.
  • Frequency signatures: Character, word, and n-gram frequency vectors mapped through prime-scaled buckets.
  • Partial proofs: Cryptographic proofs of existence, structure, similarity, or authorship without revealing the full document.

Generating a Fingerprint

from primestamp.fingerprint.prime_space import generate_fingerprint
from primestamp.core.models import DecompositionMethod

# Basic usage
fp = generate_fingerprint(b"Document content here...")

# With specific decomposition
fp = generate_fingerprint(
    b"Document content here...",
    method=DecompositionMethod.HIERARCHICAL,
)

The FingerprintGenerator class provides full control:

from primestamp.fingerprint.prime_space import FingerprintGenerator, SHADOW_SCALES
from primestamp.core.models import DecompositionMethod, HashAlgorithm
from primestamp.core.crypto import CROSSOVER_PRIME

generator = FingerprintGenerator(
    decomposition_method=DecompositionMethod.HIERARCHICAL,
    hash_algorithm=HashAlgorithm.SHA3_256,
    shadow_scales=SHADOW_SCALES,       # [2, 3, 5, 7, 11, 13]
    crossover_mod=CROSSOVER_PRIME,     # 127
)

fp = generator.generate(b"Document content here...")

Fingerprint Fields

Field Description
standard_hash Whole-document cryptographic hash
decomposition_method How the document was chunked
chunk_count Number of chunks
prime_indices Prime number assigned to each chunk
merkle_root Root hash of the Prime-Merkle tree
tree_depth Depth of the Merkle tree
sections Per-chunk hashes and shadow values
crossover_mod Prime modulus (127)
shadows Multi-scale shadow fingerprints (keyed by scale)
frequency Character, word, and n-gram frequency signatures

Document Decomposition

The DocumentDecomposer splits documents into prime-indexed chunks. Four strategies are available:

Hierarchical (default)

Splits on paragraph boundaries (double newlines). Falls back to single newlines, then to fixed-size chunks.

from primestamp.fingerprint.prime_space import DocumentDecomposer
from primestamp.core.models import DecompositionMethod

decomposer = DocumentDecomposer(method=DecompositionMethod.HIERARCHICAL)
chunks = decomposer.decompose(b"Paragraph one.\n\nParagraph two.\n\nParagraph three.")
# 3 chunks with prime indices [2, 3, 5]

Flat

Fixed-size byte chunks (default 1024 bytes each).

decomposer = DocumentDecomposer(
    method=DecompositionMethod.FLAT,
    chunk_size=512,
)

Content-Addressed

Flat decomposition, then primes are reassigned based on each chunk's content hash. The first 4 bytes of the hash select from the first 10,000 primes.

Semantic

NLP-based chunking. Currently falls back to hierarchical; designed as an extension point.


Shadow Transforms

Shadow transforms project document content to lower-resolution representations at prime scales. Lower scale values reveal more structural detail.

Default scales: 2, 3, 5, 7, 11, 13

# Access shadows from a fingerprint
for scale, shadow in fp.shadows.items():
    print(f"Scale {scale}: length={shadow.length}, hash={shadow.hash}")

Each ShadowFingerprint contains:

Field Description
scale Prime scale factor
hash SHA3-256 hash of the shadow values
length Number of values in the shadow
values The actual shadow transform values

Resolution decreases as scale increases: scale 2 gives ~50% resolution, scale 13 gives ~7%.


Comparing Fingerprints

from primestamp.fingerprint.prime_space import compare_fingerprints

similarities = compare_fingerprints(fp1, fp2)
# Returns: {2: 0.95, 3: 0.91, 5: 0.88, 7: 0.82, 11: 0.79, 13: 0.76}

Comparison is performed at each shared shadow scale using shadow_similarity from primestamp.core.crypto. Values range from 0.0 (completely different) to 1.0 (identical).


Partial Proofs

The ProofGenerator creates four types of partial proofs that reveal specific properties without disclosing the full document.

from primestamp.fingerprint.prime_space import ProofGenerator

generator = ProofGenerator(fp)

Existence Proof

Prove that a specific section exists in the document without revealing its content. Uses the section's Merkle path.

proof = generator.prove_existence(section_index=3)
# proof.section_prime   -- the prime index of the section
# proof.section_hash    -- the section's content hash
# proof.root_hash       -- Merkle root for verification

Structure Proof

Reveal the document's structure at a chosen shadow resolution. Higher scales disclose less detail.

proof = generator.prove_structure(scale=7)
# proof.shadow_scale    -- 7
# proof.shadow_values   -- the shadow transform at scale 7
# proof.root_hash       -- Merkle root

Similarity Proof

Prove that two documents are similar without revealing either document. Compares shadow transforms across all shared scales.

proof = generator.prove_similarity(other_fingerprint)
# proof.reference_root          -- Merkle root of the other document
# proof.shadow_similarities     -- {scale: similarity_score}

Authorship Proof

Compare a document's frequency signature against an author's style profile.

proof = generator.prove_authorship(author_profile)
# proof.author_profile_hash   -- hash of the author's signature
# proof.frequency_similarity  -- character frequency cosine similarity
# proof.ngram_similarity      -- n-gram overlap score

Frequency Analysis

Frequency signatures capture stylometric properties of the document.

Character Frequency

A 26-value vector (one per letter a-z) with frequencies mapped to prime-scaled buckets modulo 127.

from primestamp.fingerprint.prime_space import compute_character_frequency

sig = compute_character_frequency("Hello world", mod=127)
# Returns list of 26 integers

Word Frequency

Top-N word frequencies mapped to (word_hash_bucket, frequency_bucket) pairs.

from primestamp.fingerprint.prime_space import compute_word_frequency

sig = compute_word_frequency("the quick brown fox", top_n=50, mod=127)

N-gram Frequency

Character n-gram frequencies hashed to buckets.

from primestamp.fingerprint.prime_space import compute_ngram_frequency

sig = compute_ngram_frequency("hello world", n=3, mod=127)
# Returns dict of {bucket: normalized_frequency}

Shannon Entropy

from primestamp.fingerprint.prime_space import compute_entropy

entropy = compute_entropy("Hello world")

Frequency Similarity

Cosine similarity between two character frequency signatures:

from primestamp.fingerprint.prime_space import frequency_similarity

sim = frequency_similarity(sig_a, sig_b)  # 0.0 to 1.0

Prime-Merkle Tree

The PrimeMerkleTree wraps a standard Merkle tree where leaves are document chunks with prime indices.

from primestamp.fingerprint.prime_space import PrimeMerkleTree, DocumentDecomposer

decomposer = DocumentDecomposer()
chunks = decomposer.decompose(b"content...")

tree = PrimeMerkleTree.build(chunks)

print(tree.root_hex)   # Merkle root as hex string
print(tree.depth)      # Tree depth

# Get a Merkle proof for chunk 0
proof = tree.get_proof(0)
# Returns [(sibling_hash_hex, is_left), ...]

# Verify a proof
is_valid = tree.verify_proof(
    leaf_hash=chunks[0].content_hash,
    proof=proof,
)

Prime Utilities

from primestamp.fingerprint.prime_space import generate_primes, nth_prime

primes = generate_primes(10)    # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
p = nth_prime(5)                # 11 (1-indexed)