In 1998 the cryptographer Jim Reeds showed that the 36 letter-tables of the Book of Soyga — the Aldaraia sive Soyga vocor, the Latin magical encyclopaedia John Dee asked the archangel Uriel to interpret at his first scrying session with Edward Kelley on 10 March 1581/2 — are generated by a deterministic recurrence X = N + f(W) mod 23, where N is the cell above and W the cell to the left. The auxiliary function f Reeds could determine only empirically; in his words it was "known to us only by a table of values determined empirically." Its origin has stood open since 1998. We show that the origin is printed in the book itself: the Section 18 verse assigns every letter of the 23-letter alphabet a numerical value V, and the identity f(W) = V(W) − 1 (mod 23) holds exactly for all 23 letters, with one uniform constant and zero free parameters. Under this identity the book's own letter-value system regenerates all 36 tables and all 46,656 cells identically to Reeds's construction. The manuscripts are probably Dee's own copies; Deborah Harkness identified the Aldaraia as the Book of Soyga in 1994. The two halves of the answer — the verse and the tables — sat in one codex for four centuries. The work was independently replicated in blinded conditions before publication and has passed seven adversarial review passes and a 21-test public verification suite.
Keywords: Book of Soyga; Aldaraia sive Soyga vocor; John Dee; Jim Reeds; table generation; Latin letter numerology; cryptography; history of mathematics; Renaissance magic; Enochian
On 10 March 1581/2, at Mortlake, John Dee sat opposite his skryer Edward Kelley and opened what he recorded as a communication with the archangel Uriel. Dee held up the Book of Soyga — the Aldaraia sive Soyga vocor, a Latin magical encyclopaedia he had probably copied in manuscript — and asked Uriel directly how to read its 36 letter-tables. The angel replied only that the interpretation of the book belonged to the archangel Michael, and that Zadzaczadlin was Adam.
The book’s identity as the manuscript text Aldaraia sive Soyga vocor was established by Deborah Harkness in 1994 [3], initiating modern scholarly engagement with the text. Jim Reeds, working from 1998 [1], solved the mechanical part of Dee’s question: the tables are generated by a deterministic recurrence over a 23-letter alphabet. But the auxiliary function f(W) he could find only by reverse-engineering it from the grids themselves — 23 empirical values with no stated origin. The full prose of the book was not transcribed until Jane L. Kupin’s 2014 edition [2]. The verse that defines the letter values sits in Section 18 of that prose, roughly 150 pages from the tables in the manuscript.
The origin was in the book all along — the value-verse and the tables, about 150 pages apart in the same volume, never read against each other until now.
Each of the Book of Soyga’s 36 tables is a 36×36 grid of letters from the 23-letter Latin alphabet (a b c d e f g h i k l m n o p q r s t u x y z; no j, v, or w). Each table is keyed to a 6-letter code word. The left column of the grid is the code word followed by its reverse, repeated three times to fill 36 rows.
Top row (no cell above). For columns 2–36 of row 1:
X = W + f(W) (mod 23)
where W is the cell to the left.
Interior cells (rows 2–36, columns 2–36):
X = N + f(W) (mod 23)
where N is the cell above and W is the cell to the left. The function f is applied to the left (west) cell; its output is added to the north cell.
Reeds’s empirical f, reproduced from Table II of his 1999 paper [1]:
Table 1. Reeds's empirical values of f(W), determined from the grids (1998). Origin unknown until 2026.
| W | a | b | c | d | e | f | g | h | i | k | l | m | n | o | p | q | r | s | t | u | x | y | z |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| f(W) | 2 | 2 | 3 | 5 | 14 | 2 | 6 | 5 | 14 | 15 | 20 | 22 | 14 | 8 | 13 | 20 | 11 | 8 | 8 | 15 | 15 | 15 | 2 |
Reeds noted: “f is known to us only by a table of values determined empirically.” Its origin was open from 1998 until 2026.
Book of Soyga, Section 18 (Aldaraia sive Soyga vocor). Text per Jane L. Kupin’s 2014 edition [2], Latin lines 8151–8172, English translation lines 8318–8337.
Heading: “Versibus ostendam quid monstret quaeque figura” — “In verses I will show what each figure denotes.”
"Tres numeros z, b; numeros tres continet a, f. / H bis tres numeros… / Septem G… /
O plenum cum T, comis est, S ter tria portat. / Bis sex, R… / Bis septem… P… /
E cum n tenet I, numeros ter quinque… / V cum K ut x, y, dat bis octo… / L ut Q, numeros ter vii… /
M xxti tria portat. / Terque novem per se C… / Vigintique novem D dat cum sumitur ampla."
An independent OCR pass concurs with Kupin’s readings of every number-word. The O/T/S line ("O plenum cum T, comis est, S ter tria portat") is fully legible in the printed edition (second independent review, 2026-06-09); o = t = s = 9 is attested, not inferred.
The verse assigns each letter a value V(W) through Latin number-words:
Table 1. Letter values V(W) assigned by the Section 18 verse, per Kupin [2] lines 8151–8172.
| Verse fragment (Latin) | Letter(s) | Number-word | V(W) |
|---|---|---|---|
| Tres numeros z, b; numeros tres continet a, f | z, b, a, f | tres = 3 | 3 |
| H bis tres numeros | h | bis tres = 2×3 = 6 | 6 |
| Septem G | g | septem = 7 | 7 |
| O plenum cum T, comis est, S ter tria portat | o, t, s | ter tria = 3×3 = 9 | 9 |
| Bis sex, R | r | bis sex = 2×6 = 12 | 12 |
| Bis septem P | p | bis septem = 2×7 = 14 | 14 |
| E cum n tenet I, numeros ter quinque | e, n, i | ter quinque = 3×5 = 15 | 15 |
| V cum K ut x, y, dat bis octo | u, k, x, y | bis octo = 2×8 = 16 | 16 |
| L ut Q, numeros ter vii | l, q | ter vii = 3×7 = 21 | 21 |
| M xxti tria portat | m | xx + tria = 20+3 = 23 | 23 |
| Terque novem per se C | c | ter × novem = 3×9 = 27 | 27 |
| Vigintique novem D dat cum sumitur ampla | d | viginti + novem = 20+9 = 29 | 29 |
The central finding of this paper:
f(W) = V(W) − 1 (mod 23)
— exact for all 23 letters, with one uniform constant and zero free parameters.
The mod-23 wrap is needed only for two letters whose value exceeds the alphabet size: for c, V = 27, so V−1 = 26, and 26 mod 23 = 3 = f(c); for d, V = 29, so V−1 = 28, and 28 mod 23 = 5 = f(d). No other letter requires the wrap.
Table 2. Letter-by-letter verification of f(W) = V(W) − 1 (mod 23). 23 of 23 letters match.
| Letter | a | b | c | d | e | f | g | h | i | k | l | m | n | o | p | q | r | s | t | u | x | y | z |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| V (verse) | 3 | 3 | 27 | 29 | 15 | 3 | 7 | 6 | 15 | 16 | 21 | 23 | 15 | 9 | 14 | 21 | 12 | 9 | 9 | 16 | 16 | 16 | 3 |
| (V−1) mod 23 | 2 | 2 | 3 | 5 | 14 | 2 | 6 | 5 | 14 | 15 | 20 | 22 | 14 | 8 | 13 | 20 | 11 | 8 | 8 | 15 | 15 | 15 | 2 |
| Reeds's f (1998) | 2 | 2 | 3 | 5 | 14 | 2 | 6 | 5 | 14 | 15 | 20 | 22 | 14 | 8 | 13 | 20 | 11 | 8 | 8 | 15 | 15 | 15 | 2 |
23/23. The uniqueness check: offset k = 1 is the only value giving 23/23 matches; every other constant k gives 0/23. A spurious fit would not survive that.
The −1 as inclusive/exclusive counting: the verse states the value V of each letter — a number treated as an inclusive ordinal (“the V-th letter, counting from and including the letter above”). Reeds’s recurrence uses f as an exclusive step count (“advance f steps past the cell above”). The gap between inclusive and exclusive counting is exactly 1. This gloss is ours — it is not a quoted instruction from the manuscript; under it, the arithmetic is perfect.
Under this identity the book’s own values regenerate all 36 tables, all 46,656 cells, identically to Reeds’s construction.
The same letter-values do arithmetic work in five independent sections of the book. No modern transcription could have been fitted to Reeds’s table after the fact:
Fitting one verse to Reeds’s values is conceivable; fitting the book’s whole arithmetic simultaneously is not a realistic contamination scenario.
A reviewer given only Reeds’s empirical f values and the raw Kupin text — with no access to these findings — was asked to search for the source of f. Without prompting, they rediscovered the verse and the identity. Of all the checks here, this one carries the most weight: the result is findable from the primary sources alone.
The verse and the tables live in the same manuscript book, copied roughly 400 years before Reeds’s 1998 analysis. The congruence is arithmetic fact regardless of compositional sequence within the book. Latin number-words (viginti novem, ter quinque, bis octo) are not graphically ambiguous the way Arabic numerals are; an independent OCR pass concurs with Kupin’s readings of every number-word. Five corrections to secondary figures were published on the record during the review process; these are documented in §7. The direction of dependence within the book’s composition is open, and we state this at confidence 0.92 for the historical-origin reading versus 0.97 for the arithmetic identity itself (§8).
The Book of Soyga answers Dee’s question in its own prose. Section 26.1 (the Liber Radiorum preface; Kupin lines 13565–13576) describes the tables as simultaneously an angel-binding grid (per virtutem tabularum exorcismo alligati — “bound by exorcism through the power of the tables”) and a scrying mirror (vicem speculi gerit… intuentibus faciet videre quod libuerit — “serves as a mirror and makes the gazer see what they wish”). Section 27 states that each letter in the tables summons a named count of spirits, and that all binding is per Agla virtutem — through the divine name AGLA.
On the book’s own account the tables are an instrument to operate, not a cryptogram concealing a message. The scoped null model (see §7) is consistent with that: standard traversals — rows, columns, main diagonals, broken diagonals, boustrophedon (snake-path), inward spirals, enumerated across all 36 tables in both directions — show words appear at chance level (0.99× shuffled controls). Entropy of rows, columns, and diagonals sits at the random baseline. We do not claim this covers every conceivable path; we make no universal negative.
Code-first arithmetic. The core implementation (soyga.py) is an independent reimplementation of Reeds’s generation algorithm from his prose description. The f values are derived as f = {c: (V[c] - 1) % 23 for c in ABC} — a single line making the identity explicit — not hard-coded from Reeds’s Table II.
Line-number sourcing. Every quotation from the Kupin edition is cited at its stated line number in kupin_soyga.txt. Key loci: Section 18 verse (Latin) 8151–8172; Section 18 verse (English) 8318–8337; Section 26.1 preface 13565–13576; Section 27 alphabet 22341–22358.
AI-assisted, disclosed. This work is AI-assisted and human-directed, disclosed plainly. All arithmetic was run in code; every quotation was verified at its stated line number.
Seven adversarial passes, including: (1) initial derivation in code; (2) cross-check against Reeds’s full typeset transcriptions (NISRAM 216/216, Leo 466/468, Moon 24/24); (3) independent AI review that rediscovered the verse without access to these findings; (4) deliberate search for overclaims; (5) full fresh reimplementation from scratch by a second reviewer; (6) blinded replication (§5.2); (7) hostile-room review from the perspective of a specialist audience.
Five published self-corrections on the record: (1) letter-frequency wording: “sources = under-represented” corrected (r is slightly over-represented, 1.03–1.07×); (2) consonant offsets: “+15/+16 two-value rule” corrected to +15 for 11 consonants, +14 for r and s, k = +3, q = +32; (3) hidden-text ratio: “0.80× chance” corrected to “0.99× chance”; (4) o/t/s attestation upgraded from “inferred” to “attested in the printed Kupin edition”; (5) selection-rule count “22/23” corrected to “13–19/23 depending on variant lane.”
21-test public suite. The verification bundle (soyga_verification_bundle.zip) contains a 21-test suite covering the 23-letter alphabet definition, the identity f(W) = V(W) − 1 (mod 23) for all 23 letters, machine-verified NISRAM row prefixes, full recurrence integrity across the 36×36 NISRAM table, and independent second-reviewer scripts (verify_soyga.py, verify_section28.py, verify_null.py).
| Claim | Confidence | Basis / caveat |
|---|---|---|
| Generator reproduces Reeds's full transcriptions: NISRAM 216/216 · Leo 466/468 · Moon margin+col 24/24 | 0.99 | Cell-for-cell computational check; independent second-reviewer reimplementation confirms. |
| f(W) = V(W) − 1 (mod 23) for all 23 letters as printed in Kupin | 0.97 | Pure arithmetic on primary text. Uniqueness: k=1 gives 23/23; every other k gives 0/23. Confirmed by blinded replication and two independent reviews. Single remaining dependency: paleographic check of Section 18 against the manuscript. |
| f = V − 1 as the historical origin of Reeds's f (not just arithmetic match) | 0.92 | Distinct from arithmetic 0.97. Raised by blinded replication and book-wide sums (§5). Reverse causality cannot be ruled out from the arithmetic alone. |
| Operative / scrying-mirror reading: tables are an angel-binding grid, not a steganographic cipher | 0.85 | Verbatim quotes from §§26.1, 27. Scoped null (§6) confirms no hidden text in standard traversals. |
Explicit not-claimed list.
Jim Reeds’s 1998/1999 paper is the foundation this work rests on entirely. Reeds solved the Book III cipher of Trithemius’s Steganographia independently of Thomas Ernst, and credited Ernst’s priority openly — a scholarly standard this work holds itself to. Deborah Harkness [3] identified the manuscript in 1994; without that identification, Reeds’s analysis would not have been possible. Jane L. Kupin [2] provided the complete 23,717-line edition that made the Section 18 verse accessible. Christopher Whitby [4] transcribed the Dee diaries.
book-of-soyga-john-dee).Six letters from the 23-letter alphabet: a b c d e f g h i k l m n o p q r s t u x y z (j→i, v/w→u). The margin is your word and its reverse, repeated; everything else follows from the verse’s numbers.
try nisram and compare with Bodley 908 / Sloane 8, Tabula 1
ABC = "abcdefghiklmnopqrstuxyz" # 23 letters, no j/v/w
V = dict(zip(ABC, [3,3,27,29,15,3,7,6,15,16,21,23,15,9,14,21,12,9,9,16,16,16,3]))
f = {c: (V[c] - 1) % 23 for c in ABC} # f = V - 1 (the whole discovery)
def table(word, n=36):
margin = (word + word[::-1]) * 3 # code word + reverse, repeated
g = [[margin[r] for c in range(n)] for r in range(n)]
for r in range(n):
for c in range(1, n):
prev = g[r][c-1] if r == 0 else g[r-1][c]
g[r][c] = ABC[(ABC.index(prev) + f[g[r][c-1]]) % 23]
return g
for row in table("nisram")[:3]: print(" ".join(row))
# n d i z b d i z b ...
# i s r l y t r l y ...
# s c u c b x i b a ...
The full verification bundle — independent reimplementation, Reeds-anchor checks, null models for hidden text, Section 28 code-word derivation scripts, and second-reviewer scripts — is available at:
Licensed MIT (code) / CC BY 4.0 (text and figures). Run with pytest (Python 3.10+).
DOI of the full findings dossier (timestamped Zenodo deposit): 10.5281/zenodo.20635591