- Published on
Culinary Circles — GPN CTF 2026
Miscellaneous / OSINT challange from GPN CTF 2026

TL;DR
Nine people each post a clue to a restaurant. Geolocate all nine. The first names split into three alphabetical groups of three (A/B/C), and each group of three points sits on one circle drawn on the globe. The three circles cross at a single point, on the Isle of Skye near Colbost, and the restaurant sitting there is The Three Chimneys. Three circles, Three Chimneys = FLAG.
Flag: GPNCTF{The Three Chimneys}
Geolocating the nine clues
All nine came from Google reverse image search plus reading whatever text was in the shot. It was a team effort: T0m4sh found Adam, Carol, Alkalem, Beatrice, Bob and Bruno; I did Alice, Catherine and Cristoph. The names also split into three alphabetical groups of three, which turns out to matter later.
Group A (red)
Adam — Hofu, Vestergade 19C, 4600 Køge, Denmark · 55.456983, 12.178527 · found by T0m4sh

A plate of lamb chops and bao buns, a bottle of Danish Harboe water, and a menu booklet that reads "hofu". The name plus the Danish water put it at Hofu in Køge harbour.
Alice — The Peppermill, Kenyon St, Nenagh, Co. Tipperary, Ireland · 52.861898, -8.198358

Taken through a glass screen, so all the signage is mirrored. Flip it horizontally and the reflected shopfronts read "Nenagh" and "Talbot", which gives the town and the street.

Alkalem — Kippe23, Gottesauer Str. 23, 76131 Karlsruhe, Germany · 49.007618, 8.419181 · found by T0m4sh

Interior covered wall to wall in old German enamel advertising signs (Bärenbräu, SABA Radio, Coca-Cola, Welde Bräu). A reverse search lands on Kippe23 in Karlsruhe.
Group B (green)
Beatrice — BChef, 94 Rue des Godrans, Dijon, France · 47.322809, 5.038138 · found by T0m4sh

Storefront branded BCHEF, "Burgers de qualité", with the City Loft residence next door. That pins the Dijon branch.
Bob — Pastéis de nata, Pastéis de Belém, Lisbon, Portugal · 38.697560, -9.203180 · found by T0m4sh

Just one custard tart, no building, no text. T0m4sh knew this one from having been to Portugal: the classic pastel de nata is Pastéis de Belém in Lisbon. No searching needed.
Bruno — Mairie Restaurant & Events, Westersingel 80, Berkel en Rodenrijs, Netherlands · 51.995496, 4.475699 · found by T0m4sh

A Dutch street torn up for roadworks (Boels cabin, Dutch housing). The street-name plate was just readable: Westersingel, which leads to the Mairie restaurant in Berkel en Rodenrijs.
Group C (blue)
Carol — Skeppsbro Bageri, Tullhus 1, Skeppsbron 21, 111 30 Stockholm, Sweden · 59.324765, 18.076197 · found by T0m4sh

Also shot through glass. The etched slogan "ALLT ÄR EKOLOGISKT" ("everything is organic") is mirrored, and the panea van plus the waterfront across the channel place it on a Stockholm quay: Skeppsbro Bageri.
Catherine — Taste Buds, 65 W Main St, Armadale, Bathgate EH48 3PZ, UK · 55.898332, -3.702663

Only an aerial of green farmland with a town strip, central-belt Scotland (West Lothian). I picked a few candidate towns off the road and field layout and after a couple of minutes settled on Armadale and Taste Buds.
Cristoph — Café Marina, Marina Allé 8, 6400 Sønderborg, Denmark · 54.899522, 9.795485

Street View of a blue waterfront building at a marina with yacht masts behind it; the POI is labelled Marina. That is Café Marina in Sønderborg.
| Group | People | Lat | Lon |
|---|---|---|---|
| A | Adam | 55.456983 | 12.178527 |
| A | Alice | 52.861898 | -8.198358 |
| A | Alkalem | 49.007618 | 8.419181 |
| B | Beatrice | 47.322809 | 5.038138 |
| B | Bob | 38.697560 | -9.203180 |
| B | Bruno | 51.995496 | 4.475699 |
| C | Carol | 59.324765 | 18.076197 |
| C | Catherine | 55.898332 | -3.702663 |
| C | Cristoph | 54.899522 | 9.795485 |
Finding the actual puzzle
Geolocation wasn't the hard part. The hard part was working out how nine restaurants turn into one flag. A couple of ideas went nowhere first. I checked Michelin stars for a common thread, nothing there. I checked whether one reviewer on Google Maps / trip advisor had been to all of them, also nothing.
Then i found one the grouping made sense. The names split alphabetically into three groups of three: A (Adam, Alice, Alkalem), B (Beatrice, Bob, Bruno), C (Carol, Catherine, Cristoph). Three points define one circle, and the brief says "your culinary circles might intersect". One circle per group, three circles, and they should all meet at a single point. That point is the restaurant.
Grzechu helped me wrote a script to draw the three circles properly and cut the search area down.
The geometry, on the sphere not the plane
Treat each location as a point on the globe, i.e. a unit 3-vector. Any three points lie on one plane n·x = d, and that plane cuts the sphere along a circle. A point is on the circle when it sits on both the plane and the sphere. Two circles give two planes; their intersection is a line, and that line meets the sphere in at most two points. Run it for all three pairs and the results land on the answer.
The plane-versus-sphere choice matters. Fitting the circles in the raw lat/lon plane spreads the three pairwise intersections by about 350 km, which is useless. On the sphere they sit within a few km of each other. That is what "precision may be required" is about.
import numpy as np
groups = {
'A': {'Adam':(55.456983052476176,12.178526547052892),
'Alice':(52.8618975302306,-8.19835799391126),
'Alkalem':(49.00761764370541,8.419180928945096)},
'B': {'Beatrice':(47.32280860815571,5.038138189323006),
'Bob':(38.6975601815399,-9.203179980434458),
'Bruno':(51.9954957,4.4756986)},
'C': {'Carol':(59.32476452620663,18.076197175843628),
'Catherine':(55.89833236873583,-3.7026633509220592),
'Cristoph':(54.89952179441089,9.795484800441564)},
}
def vec(lat, lon):
la, lo = np.radians(lat), np.radians(lon)
return np.array([np.cos(la)*np.cos(lo), np.cos(la)*np.sin(lo), np.sin(la)])
def ll(v):
v = v/np.linalg.norm(v)
return np.degrees(np.arcsin(v[2])), np.degrees(np.arctan2(v[1], v[0]))
def plane(g): # three sphere points, plane n.x = d
P = [vec(*c) for c in g.values()]
n = np.cross(P[1]-P[0], P[2]-P[0]); n /= np.linalg.norm(n)
return n, np.dot(n, P[0])
def inter(pa, pb): # two circles, up to two sphere points
na, da = pa; nb, db = pb
d = np.cross(na, nb); d /= np.linalg.norm(d)
M = np.array([[1, np.dot(na, nb)], [np.dot(na, nb), 1]])
ab = np.linalg.solve(M, [da, db]); x0 = ab[0]*na + ab[1]*nb
B = 2*np.dot(x0, d); C = np.dot(x0, x0) - 1; s = np.sqrt(B*B - 4*C)
return [x0+((-B+s)/2)*d, x0+((-B-s)/2)*d]
pl = {g: plane(p) for g, p in groups.items()}
def skye(c): return min(c, key=lambda v: abs(ll(v)[0]-57.44)+abs(ll(v)[1]+6.63))
ab, ac, bc = skye(inter(pl['A'],pl['B'])), skye(inter(pl['A'],pl['C'])), skye(inter(pl['B'],pl['C']))
for nm,p in [('A-B',ab),('A-C',ac),('B-C',bc)]:
la,lo = ll(p); print(f"{nm}: {la:.4f}, {lo:.4f}")
print("centroid:", *(f"{x:.4f}" for x in ll((ab+ac+bc)/3)))
Three pairwise intersections:
| Pair | lat | lon |
|---|---|---|
| A–B | 57.4468 | -6.6161 |
| A–C | 57.4361 | -6.6295 |
| B–C | 57.4498 | -6.6497 |
The common point is about 57.444, -6.632, on the Isle of Skye near Colbost and Dunvegan.
On OpenStreetMap the three circles (A red, B green, C blue) cross on the restaurant pin out in Loch Dunvegan, between Colbost and Skinidin:

The restaurant
Those coordinates land on The Three Chimneys (Colbost, Dunvegan, IV55 8ZT, 57°26′36″N 6°38′31″W, about 57.4433, -6.6419), out on Loch Dunvegan and roughly 0.1 km from the centre of the three intersections. The next closest option, The Dunvegan in the village, is about 2.9 km east and outside the little triangle, so a single pair of circles can send you to the wrong place.
And the theme fits: three culinary circles, Three Chimneys.
GPNCTF{The Three Chimneys}
Notes
- Two clues (Alice, Carol) were shot through glass. Flip them horizontally to read the signs.
- Do the geometry on the sphere. In the plane the intersection drifts by hundreds of km.
- Use all three pairs and average them. A–B on its own sits about 1.4 km east of the real point and can push you to Dunvegan village instead of Colbost.
- The few-km spread comes from small errors in the nine source coordinates. Tighter coordinates tighten the result.
- Check the flag against the OSM name tag. The place brands itself "The Three Chimneys", which matches the "The French Laundry" example.
- This one was a good team effort. The geolocations were split across us, and once the circle idea clicked, Grzechu's plotting script turned "somewhere on Skye" into a single restaurant. Pretty sure none of us would have landed it alone in the time we had, so the shared work paid off.
