Shamir Secret Sharing for GPS Coordinate Protection
GPS telemetry is the hardest case for threshold cryptography: traces are long-lived, high-frequency, and signed across the antimeridian, so the small modelling choices that the parent guide on secret sharing for coordinates treats generically — prime selection, bias mapping, share rotation — become the difference between a faithful round-trip and a silently corrupted fix. This page is the telemetry deep-dive inside the broader Secure Multi-Party Computation in Spatial Analytics architecture, where Shamir’s Secret Sharing (SSS) splits each latitude/longitude pair into n information-theoretically meaningless fragments and reconstructs the original only when a quorum of t nodes cooperates. The focus here is narrow and concrete: how to pick the field prime, how to map negative coordinates without two’s-complement ambiguity, and how to keep a continuously-emitting tracker safe under proactive share redistribution. Treat every latitude/longitude value not as an IEEE 754 float but as a fixed-point integer projected into a prime field, and the rest of the pipeline becomes deterministic.
Parameter Configuration and Calibration
SSS for GPS data exposes four tunable knobs, and each one has a direct privacy or correctness consequence rather than a performance-only trade-off. The masking front end described in coordinate masking protocols normalises geometry before it reaches this layer, so the values below assume canonical EPSG:4326 input.
COORD_SCALE— quantization resolution (10**9, nanodegrees). Decimal degrees must be scaled to integers before polynomial evaluation, because finite-field arithmetic is exact and floating point is not. Nanodegrees () preserve roughly 0.1 mm at the equator — overkill for most releases but cheap, and it guarantees that the quantization floor never becomes the dominant error term. Drop to microdegrees (, ~11 cm) only when share size is bandwidth-bound on constrained telemetry links.PRIME_MODULUS— the field prime (). The modulus must strictly exceed the maximum biased coordinate, with headroom for the random coefficients that fill the polynomial. A 31-bitINT_MAXfield is unsafe: negative-longitude wrapping and modular collisions silently alias distinct fixes onto the same residue. A 256-bit safe prime leaves the entire biased nanodegree range far below the field boundary and matches the modulus used by the parent guide, so shares interoperate across the pipeline.LAT_LON_BIAS— sign-handling offset (COORD_SCALE). Negative southern and western coordinates cannot enter the field as raw two’s-complement integers without ambiguity. A fixed additive bias of 200 degrees shifts the full longitude and latitude ranges into strictly positive field elements, and the offset is reversed losslessly on reconstruction.threshold/total_shares— the quorum. sets how many nodes must cooperate to reconstruct and sets availability; any shares reveal nothing. Derive from real trust boundaries — distinct legal entities, cloud accounts, or key custodians — calibrated against the risk tier from the spatial sensitivity scoring models. A dense urban tracker where a single nightly dwell point is highly identifying warrants a higher than a sparse fleet sensor.
For regulated workloads, bind these knobs to a clause through the compliance framework mapping: a configuration is the common HIPAA patient-mobility and GLBA asset-routing default, tolerating two node failures while requiring three independent custodians to reconstruct.
| Compliance driver | SSS control | Parameter constraint |
|---|---|---|
| HIPAA patient mobility | quorum across distinct custodians | nodes any one operator controls |
| GLBA asset routing | Independent per-axis polynomials | latitude/longitude shared separately |
| GDPR Art. 25 minimisation | Release-time DP after reconstruction | tied to sensitivity tier |
Reference Implementation
The class below is a single focused SSS module for GPS integers. It uses Python’s three-argument pow() for modular inversion (documented in the Python built-in functions reference), samples coefficients with os.urandom for cryptographic randomness, and keeps each coordinate axis on an independent polynomial so recovering one axis cannot constrain the other. Inline comments mark the points where a choice has a privacy consequence.
from __future__ import annotations
import os
from typing import List, Tuple
PRIME_MODULUS: int = (1 << 256) - 189 # 256-bit safe prime; far above biased range
COORD_SCALE: int = 10 ** 9 # nanodegree precision (~0.1 mm at equator)
LAT_LON_BIAS: int = 200 * COORD_SCALE # shifts [-180,180] / [-90,90] into F_p^+
Share = Tuple[int, int]
class GPSShamirSharer:
"""Shamir (t, n) threshold sharing sized for fixed-point GPS integers.
Latitude and longitude are quantized to a biased nanodegree integer and
shared on independent polynomials, so a quorum below the threshold leaks
nothing about either axis — not a region, not a bounding box, not a bit.
"""
def __init__(self, threshold: int, total_shares: int) -> None:
if not (2 <= threshold <= total_shares):
raise ValueError("require 2 <= threshold <= total_shares")
self.t: int = threshold
self.n: int = total_shares
@staticmethod
def quantize(coord: float) -> int:
"""Decimal degrees -> biased fixed-point integer in F_p (sign-safe)."""
return (round(coord * COORD_SCALE) + LAT_LON_BIAS) % PRIME_MODULUS
@staticmethod
def dequantize(val: int, axis: str = "lat") -> float:
"""Recover decimal degrees; interpret high residues as signed values."""
residue = val % PRIME_MODULUS
if residue > PRIME_MODULUS // 2: # negative biased value wrapped high
residue -= PRIME_MODULUS
raw = (residue - LAT_LON_BIAS) / COORD_SCALE
bound = 90.0 if axis == "lat" else 180.0
return max(-bound, min(bound, raw))
def split(self, coord: float) -> List[Share]:
"""Generate n shares (x, f(x)) for one coordinate axis."""
secret = self.quantize(coord)
# a_0 = secret; a_1..a_{t-1} uniform over F_p — the security foundation
coeffs = [secret] + [
int.from_bytes(os.urandom(32), "big") % PRIME_MODULUS
for _ in range(self.t - 1)
]
shares: List[Share] = []
for x in range(1, self.n + 1):
y = 0
for coeff in reversed(coeffs): # Horner evaluation mod p
y = (y * x + coeff) % PRIME_MODULUS
shares.append((x, y))
return shares
def reconstruct(self, shares: List[Share], axis: str = "lat") -> float:
"""Recover the coordinate from >= t shares via Lagrange at x = 0."""
if len(shares) < self.t:
raise ValueError(f"insufficient shares: {len(shares)} < {self.t}")
subset = shares[: self.t]
x_vals = [x for x, _ in subset]
if len(set(x_vals)) != len(x_vals):
raise ValueError("share x-indices must be unique for interpolation")
secret = 0
for i, (xi, yi) in enumerate(subset):
num, den = 1, 1
for j, (xj, _) in enumerate(subset):
if i != j:
num = (num * (0 - xj)) % PRIME_MODULUS
den = (den * (xi - xj)) % PRIME_MODULUS
lagrange = (num * pow(den, -1, PRIME_MODULUS)) % PRIME_MODULUS
secret = (secret + yi * lagrange) % PRIME_MODULUS
return self.dequantize(secret, axis=axis)
Validation Checkpoint
A misconfigured prime or bias fails silently — reconstruction returns a plausible wrong coordinate rather than raising — so the invariants below must run in CI, not be eyeballed. The harness exercises the round-trip, the antimeridian/sign edges, the exact-quorum boundary, and partition tolerance.
def _validate() -> None:
sharer = GPSShamirSharer(threshold=3, total_shares=5)
# 1. Faithful round-trip at sign/antimeridian extremes within 1 nanodegree.
for lat, lon in [(40.748817, -73.985428), (-33.8688, 151.2093),
(-89.999999, -179.999999), (89.999999, 179.999999)]:
lat_shares = sharer.split(lat)
lon_shares = sharer.split(lon)
assert len(lat_shares) == 5
# 2. Exactly t shares reconstruct; any 3 of 5 nodes suffice (partition ok).
assert abs(sharer.reconstruct(lat_shares[:3], "lat") - lat) <= 1 / COORD_SCALE
assert abs(sharer.reconstruct([lon_shares[0], lon_shares[2],
lon_shares[4]], "lon") - lon) <= 1 / COORD_SCALE
# 3. Below quorum must fail loudly, never return a wrong fix.
starved = sharer.split(40.0)[:2]
try:
sharer.reconstruct(starved, "lat")
except ValueError:
pass
else:
raise AssertionError("t-1 shares must not reconstruct")
# 4. Duplicate x-indices are a singular Lagrange denominator — reject them.
dupes = sharer.split(12.34)
try:
sharer.reconstruct([dupes[0], dupes[0], dupes[1]], "lat")
except ValueError:
pass
else:
raise AssertionError("duplicate share indices must be rejected")
print("all GPS secret-sharing invariants hold")
if __name__ == "__main__":
_validate()
After reconstruction, the recovered coordinate must pass through a calibrated differential-privacy mechanism before any model sees it — add Laplace noise scaled to and debit the spend from a Rényi accountant, so plaintext geometry exists only transiently inside the reconstruction boundary.
Incident Response and Edge Cases
Spatial SSS rarely fails loudly; the field below lists the failures that actually surface on live telemetry, each with a concrete remediation path.
- Field overflow / sign aliasing. A coordinate that skips the bias step, or a prime sized below the biased range, wraps a negative longitude onto a colliding residue and reconstructs to a wrong fix near the antimeridian. Detection: assert every secret satisfies entering
split. Remediation: route all input throughquantize, verify for your coefficient width, and re-run the round-trip property test at the boundary. - Quorum collusion below . If one operator controls nodes, that party reconstructs unilaterally and the information-theoretic guarantee is void. Detection: audit node ownership against . Remediation: raise or redistribute nodes across independent custodians until no single operator holds a quorum.
- Share replay and cross-round mixing. A high-frequency tracker emits many sharing rounds; a share captured in one round and replayed into another can corrupt reconstruction. Detection: deterministic indices plus a per-round nonce make stale shares verifiable. Remediation: bind each envelope to a round nonce, version shares, and route re-distribution through async routing for MPC so a partition does not block ingestion.
- Suspected share compromise on a long-lived trace. Static shares for a continuously-tracked subject accumulate exposure over months. Remediation: trigger proactive secret redistribution — generate a fresh polynomial with the same and threshold, compute and distribute new shares, then securely wipe the old shares from memory and storage. Retain share-generation timestamps and node attestation hashes for forensic reconstruction.
- Precision leakage through downstream compute. When shares feed an encrypted spatial join alongside homomorphic encryption, ciphertext noise can degrade coordinate precision post-decryption and reintroduce a fingerprintable sub-metre artefact. Remediation: keep the SSS layer integer-exact, apply DP noise only to the reconstructed scalar, and validate decryption drift against the quantized baseline.
Frequently Asked Questions
Why a 256-bit prime instead of a 64-bit field for GPS coordinates?
Biased nanodegree coordinates fit inside 64 bits, but the field must also hold uniformly random polynomial coefficients without modular collision, and a 31- or 64-bit prime makes negative-longitude wrapping and coefficient overflow hard to reason about. A 256-bit safe prime such as keeps the entire biased range orders of magnitude below the field boundary, eliminates aliasing at the antimeridian, and interoperates with the rest of the pipeline that already uses it.
How are negative latitudes and longitudes handled in the field?
Field elements are non-negative, so raw negative coordinates cannot enter directly without two’s-complement ambiguity. A fixed additive bias of 200 degrees (LAT_LON_BIAS) shifts the full latitude and longitude ranges into strictly positive integers before quantization, and dequantize reverses it by interpreting any residue above as its signed equivalent — making the round-trip exact for southern and western coordinates.
Why share latitude and longitude on separate polynomials?
Reusing one polynomial or its randomness across both axes correlates them: an attacker who recovers latitude can constrain longitude. Independent per-axis polynomials with independently sampled coefficients close that channel, so each axis is an information-theoretically independent secret.
What is proactive secret redistribution and when is it needed?
It regenerates a fresh polynomial for the same secret and threshold, issues new shares, and wipes the old ones — without ever reconstructing the coordinate centrally. It is needed whenever node topology changes or a share is suspected compromised, and it is especially important for long-lived GPS traces whose static shares would otherwise accumulate exposure over time.
Related
- Secret Sharing for Coordinates — the parent guide covering the full quantize → split → distribute → reconstruct pipeline this page drills into.
- Coordinate Masking Protocols — the deterministic front end that normalises geometry before sharing.
- Async Routing for MPC — partition-tolerant distribution and re-distribution of share envelopes.
- Homomorphic Encryption Basics — the compute-on-ciphertext alternative when reconstruction is unacceptable.
- Spatial Sensitivity Scoring Models — how to calibrate the threshold and post-reconstruction to a measured risk tier.
Up: Secret Sharing for Coordinates · Secure Multi-Party Computation in Spatial Analytics