Greek Target System - Complete Documentation¶
State on 2026-08-25 — this is implemented now.
Until this date
greekwas an alias: it resolved toGeometricForms, so a challenge naming it drew the same 24 shapes asgeometric_forms, and this document described an intention. The 24 letters exist as geometry insawabona-proof/src/targets/sets/greek.rs, drawn in their uppercase forms as multi-stroke glyphs on a common box.Two things below are out of date and left as written: the letters are uppercase, not the lowercase forms listed; and there is no
src/sawabona/targets/greek/greek_set.json— the geometry is Rust, not data, because the kernel ships to native, PyO3 and WASM from one source.Nothing selects this family. Which of the three a challenge draws from is derived from the licence's bootstrap secret, per challenge. It is not configurable and not named on the wire.
Overview¶
The Greek target system is the default geometric primitive set for Geometric Proof (GP) authentication. It uses the 24 letters of the Greek alphabet as geometric primitives for challenge-response authentication.
Key Features:
- 24 Greek letters as geometric primitives
- SVG-like path definitions for each letter
- Same geometric transformations as Zodiac (rotate, mirror, translate, scale, shear)
- Same invariant extraction (center of mass, perimeter, angle histogram)
- Same HMAC-based proof mechanism
- Default target set for all Geometric Proof operations
⚠️ Implementation status —
greekresolves toGeometricForms¶In the current Rust core (
sawabona-core/src/targets/sets/mod.rs), thegreektarget-set name — andzodiac— are aliases that both resolve to the unifiedGeometricFormscollection (24 geometric shapes), exactly likegeometric_forms:There are no distinct Greek-letter or zodiac-sign geometries implemented in
sawabona-core. The Greek-alphabet primitives, SVG-like path definitions, and PythonGreekLetter/GreekTileclasses described in the sections below document an intended design / the legacy Python prototype, not the shapes the Rust runtime actually builds. All three names produce byte-identical tiles today. Treat the per-letter geometry here as aspirational until real distinct collections are implemented.
Architecture¶
Greek Letters¶
The system includes all 24 letters of the Greek alphabet:
- Alpha (α) - First letter
- Beta (β) - Second letter
- Gamma (γ) - Third letter
- Delta (δ) - Fourth letter
- Epsilon (ε) - Fifth letter
- Zeta (ζ) - Sixth letter
- Eta (η) - Seventh letter
- Theta (θ) - Eighth letter
- Iota (ι) - Ninth letter
- Kappa (κ) - Tenth letter
- Lambda (λ) - Eleventh letter
- Mu (μ) - Twelfth letter
- Nu (ν) - Thirteenth letter
- Xi (ξ) - Fourteenth letter
- Omicron (ο) - Fifteenth letter
- Pi (π) - Sixteenth letter
- Rho (ρ) - Seventeenth letter
- Sigma (σ) - Eighteenth letter
- Tau (τ) - Nineteenth letter
- Upsilon (υ) - Twentieth letter
- Phi (φ) - Twenty-first letter
- Chi (χ) - Twenty-second letter
- Psi (ψ) - Twenty-third letter
- Omega (ω) - Twenty-fourth letter
Geometric Representation¶
Each Greek letter is defined as a geometric path with:
- Segments - Line segments connecting points
- Curves - Bezier curves for smooth shapes
- Transformations - Rotation, mirroring, translation, scaling, shearing
Data Structure¶
Greek letters are stored in src/sawabona/targets/greek/greek_set.json:
{
"greek_primitives": {
"vertical_line": ["L|90|2U"],
"horizontal_line": ["L|0|2U"],
"diagonal_up": ["L|45|1.41U"],
...
},
"Greek_set": {
"alpha": {
"symbol": "α",
"name": "alpha",
"numeric_value": 1,
"category": "vowel",
"path_square": [["2U, 2U"], "S", "triangle_up", "Y|0", "vertical_line"],
"latin_equiv": "a"
},
...
}
}
Key Fields:
symbol: Unicode symbol for the letter (e.g., "α")name: Lowercase name (e.g., "alpha")numeric_value: Position in Greek alphabet (1-24)category: "vowel" or "consonant"path_square: Geometric path definition using primitiveslatin_equiv: Latin alphabet equivalent
Usage¶
The family is not chosen — it is derived¶
Nothing selects greek, and nothing can. Which of the three families a
challenge draws from is derived from the bootstrap secret by
derive_target_set(bootstrap_secret, challenge_id), on the server and on the
client, per challenge. The challenge does not carry it and the server never
sends it, so an observer reading the traffic learns neither the family nor the
figure.
This section used to say otherwise. It told an operator to set
target_set: "greek" in config/challenges/default.yaml, or to export
SAWABONA_TARGET_SET=greek, and to pass target_set="greek" to
build_tile and compute_proof. None of that works now, and the reason it was
removed is the point: a deployment that could pin the family would be
announcing its choice to anyone who read its configuration, which is exactly
what deriving it prevents.
target_set still exists in the configuration file and is informational
only — see docs/security/GEOMETRIC-PROOF.md.
What a client passes instead¶
Nothing. compute_proof derives the family itself, from the same secret the
server used:
# The family is absent from the call. It is derived inside, from the bootstrap
# secret, and matches the server's derivation for this challenge id.
proof = compute_proof(
challenge_seed=12345,
ops=ops,
challenge_id="challenge-123",
client_secret=b"secret",
)
Every SDK does the same, in nine languages, and the C ABI has no target_set
parameter: sawabona_compute_proof_v2 (the _v2 is the ABI generation — see
sawabona-proof-ffi/include/sawabona_proof.h).
Seeing this family's figures¶
A challenge draws from greek roughly one time in three, so a run that wants
these figures specifically is a test concern, not a deployment one. Drive
resolve_collection("greek") directly:
from sawabona.targets import resolve_collection
collection = resolve_collection("greek") # the figures, not a deployment choice
Classes and Functions¶
GreekLetter Class¶
Located in src/sawabona/targets/greek/greek_keys.py:
class GreekLetter(KimbangulaItem):
"""Represents a Greek letter as a geometric primitive."""
def __init__(self, seed: int, greek_letter: str, segment_length: float = 1.0):
"""Initialize Greek letter."""
self.seed = seed
self.greek_letter = greek_letter
self.segment_length = segment_length
self.segments = []
self._load_letter()
def apply_operation(self, op_type: str, *args: Any) -> None:
"""Apply geometric transformation."""
# rotate, mirror_h, mirror_v, translate, scale, shear
def draw2D(self) -> None:
"""Draw 2D representation using matplotlib."""
def draw3D(self) -> None:
"""Draw 3D representation using matplotlib."""
GreekTile Class¶
Located in src/sawabona/client/geometric_proof_core.py:
class GreekTile(GeometricProofTile):
"""GP tile using Greek letters as geometric primitives."""
def __init__(self, seed: int, greek_letter: str = "alpha", segment_length: float = 1.0):
"""Initialize Greek tile."""
self.seed = seed
self.greek_letter = greek_letter
self.segment_length = segment_length
self.segments = []
self._generate_base_tile()
Geometric Transformations¶
All transformations work the same as Zodiac:
Rotation¶
Mirroring¶
tile.apply_operation("mirror_h") # Mirror horizontally
tile.apply_operation("mirror_v") # Mirror vertically
Translation¶
Scaling¶
Shearing¶
Invariant Extraction¶
The same invariants are extracted from Greek tiles as from Zodiac tiles:
- Center of Mass - Geometric center of all segments
- Total Perimeter - Sum of all segment lengths
- Stroke Order Parity - XOR of segment count and seed
- Angle Histogram - Distribution of segment angles (4 bins)
These 12 floats form the Geometric Proof Vector (GPV).
Comparison with Other Target Sets¶
Greek is the default target set. Two alternative families are also available, all sharing the same transformations, invariant extraction, HMAC proof mechanism, and security level:
| Target Set | Primitives | Origin |
|---|---|---|
| Greek (default) | 24 Greek letters (α → ω) | Ancient Greek alphabet |
| Zodiac | 24 signs (12 Western + 12 Chinese animals) | Astrology + Chinese zodiac (生肖) |
| Geometric Forms | 7 independent collections (3–4 shapes each, 24 combined) | Euclidean geometry |
Implementation note: As described in the ⚠️ callout above,
greekandzodiacare currently aliases forGeometricFormsin the Rust core — the "Primitives" / "Origin" columns above describe the intended distinction, not a runtime difference. All three resolve to the same 24-figure collection today.Figure-selection entropy: the protocol selects one figure per challenge, so a larger set (higher
count()) provides more entropy —log₂(N)bits. All three sets haveN = 24, so they remain equivalent in this regard.
See also: - Zodiac Target Set — Western + Chinese zodiac details - Geometric Proof System — full system documentation
Testing¶
Unit Tests¶
Located in tests/unit/test_greek_targets.py:
def test_greek_letter_creation():
"""Test creating a Greek letter."""
letter = GreekLetter(seed=12345, greek_letter="alpha")
assert letter.greek_letter == "alpha"
assert len(letter.segments) > 0
def test_greek_transformations():
"""Test Greek transformations."""
letter = GreekLetter(seed=12345, greek_letter="omega")
letter.apply_operation("rotate", 45)
# Verify rotation was applied
Integration Tests¶
Located in tests/integration/test_greek_gp.py:
def test_greek_gp_flow():
"""Test complete Greek GP flow."""
engine = get_challenge_engine("default")
ops = engine.generate_challenge_ops()
# The family is not passed. `build_tile` and `compute_proof` derive it
# from the bootstrap secret, so a test that wants greek specifically
# exercises the collection directly rather than steering the proof.
collection = resolve_collection("greek")
tile = build_tile(12345, ops, collection=collection)
proof = compute_proof(12345, ops, "id", b"secret")
assert len(proof) == 32
Performance¶
Greek letters are optimized for performance:
- Greek tile creation: ~1-2ms
- Greek transformation: ~0.5-1ms per operation
- Invariant extraction: ~2-3ms
- Total proof computation: ~5-10ms
Security¶
Greek target set provides equivalent security to Zodiac:
- ✅ Same HMAC-based proof mechanism
- ✅ Same invariant extraction algorithm
- ✅ Same challenge-response protocol
- ✅ Same computational difficulty
Security comes from the HMAC secret derived from the license key; the
geometric primitives are public constants. On top of that, the choice of
primitive is itself secret-derived (via derive_figure_index), the primitive's
canonical descriptor is folded into the proof key (via derive_proof_key), and
the geometry is secret-parameterized (derive_geo_params + build_tile), so an
attacker who knows the target set but not the license key cannot reconstruct the
GPV. The system is still not based on hard mathematical problems (see
GEOMETRIC-PROOF.md § Limitations).
Troubleshooting¶
Issue: "Greek module not available"¶
Cause: Greek module not installed
Solution: Ensure sawabona.targets.greek is available:
try:
from sawabona.targets.greek import GreekLetter
print("Greek available")
except ImportError:
print("Greek not available")
Issue: Invalid Greek letter¶
Cause: Greek letter name not recognized
Solution: Use valid letter names (lowercase):
valid_letters = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta",
"eta", "theta", "iota", "kappa", "lambda", "mu",
"nu", "xi", "omicron", "pi", "rho", "sigma",
"tau", "upsilon", "phi", "chi", "psi", "omega"]
References¶
- Geometric Proof System:
../GEOMETRIC-PROOF.md - Challenge Engine:
../IMPLEMENTATION_ROADMAP.md - API Reference:
../reference/API-REFERENCE.md - Zodiac Alternative:
ZODIAC-TARGETS.md