Done challenge 7
authorNeil Smith <neil.git@njae.me.uk>
Thu, 14 May 2020 13:53:43 +0000 (14:53 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Thu, 14 May 2020 13:53:43 +0000 (14:53 +0100)
2020-early/2020-a-challenge7.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge7.md [new file with mode: 0644]
2020-early/7a.ciphertext [new file with mode: 0644]
2020-early/7a.plaintext [new file with mode: 0644]
2020-early/7b.ciphertext [new file with mode: 0644]
2020-early/7b.plaintext [new file with mode: 0644]

diff --git a/2020-early/2020-a-challenge7.ipynb b/2020-early/2020-a-challenge7.ipynb
new file mode 100644 (file)
index 0000000..b03b217
--- /dev/null
@@ -0,0 +1,376 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.column_transposition import *\n",
+    "from cipher.vigenere import *\n",
+    "\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 7\n",
+    "plaintext_a_filename = f'{challenge_number}a.plaintext'\n",
+    "plaintext_b_filename = f'{challenge_number}b.plaintext'\n",
+    "ciphertext_a_filename = f'{challenge_number}a.ciphertext'\n",
+    "ciphertext_b_filename = f'{challenge_number}b.ciphertext'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()\n",
+    "\n",
+    "sca = sanitise(ca)\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "ptb = depunctuate(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sca)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'soe'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kworda, score = vigenere_frequency_break(sca, fitness=Ptrigrams)\n",
+    "kworda"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Phil,\n",
+      "Sorry I haven’t been in touch much, Churchill asked BOSS to set up an operations wing in the UK under the name of the Special Operations Executive and that has occupied a lot of my time. As soon as we got set up I was put in touch with Einar Skinnarland, an engineer from Vemork who had hijacked a coastal steamer and sailed to Aberdeen to join the war effort here. Churchill ordered us to work up plans to attack the plant and Einar helped us to brief an intelligence gathering team to infiltrate the region. Operation Grouse was launched in October with an advance party of four officers and NCOs led by Jens-Anton Poulsson. They were parachuted into the Hardangervidda as German patrols tended to avoid it, and after a period of observation they prepared the ground for a glider assault. Under the codename Operation Freshman we sent over two gliders carrying commandos equipped with explosives and everything they needed to effect an escape, but a combination of bad weather and bad luck killed the mission. Both gliders made it to the Norwegian coast, but one crashed early on, and the other in the mountains. We were not aware of survivors, and unfortunately the Germans now knew that the plant was a target and stepped up security. They lit up the place with floodlights, mined the approaches and, for a while, stepped up the guard rotas. Grouse volunteered to stay in place, changing their callsign to Swallow and continued to send intelligence reports. They reported that although the mines and lights were still in place there were signs that security was beginning to slacken.\n",
+      "With these updates we decided to try again, and launched Operation Gunnerside. Six Norwegian commandos led by Joachim Ronnenberg were parachuted in from an RAF Halifax and joined up with Swallow. The attached document is their mission report. They sent it from the plateau while retreating from the plant in case they didn’t make it back, so have used a standard combination of basic ciphers to make it hard to crack but easy to implement. In training we recommended a combination of Casear shift and basic transposition. I leave it to you to decipher.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "ppa = vigenere_decipher(sca, kworda)\n",
+    "pa = repunctuate(ppa, pta)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2147"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(scb)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "10"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kcb, score = caesar_break(scb, fitness=Pletters)\n",
+    "kcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etrroopoarnetponuignnredeifsoawrslmotflaewrvorceeiusrgpnlfsperimmeohitscnsooitennirarrsdpoonebnnresmagestttteuooopujnwitawislhoehlttwomawestetfmaetsrervaedoslyfarcscsoonsyurktinaigdnhratptemieydtawotsyvamwkerholtaipreldaohrsddeecfuoehrthmgerifqhetyuchntweahetrhchatmslbeaithofsdleognlioweitpaorfhsnemrnbeahrtdpsieagntgnnhirnieveavhtoreeaermamnifdaeunlaulgryedndatdemmhoacdornguofttplhetriadeatascsuatlulodwerpbnouuvidtectdsiaewitdcehdtaeatmahdlsudosdneetcodnwurhdeteermitosthnrnieveaohtfderibrreevodnlacwihtlbeminohltlesrhaifeerdnaohtgcnhirreevbidawetsiotdfnouessboiplfobtoelsalwiogrtnealkdocosgaawrlyinhtioetlatpnnatnedethycsraawrodreuiwohttuieuotcnnegntiaryranudgtolsechlssaoabenigttnenahltpuilspepdiadtlednaelspnhcaseduasdenltardeihiapdgrnydetstuagohtatntriuhfrececsavcasaailnubtnelwdeniadnenwcoureotingylnntoeerhatckojarhenwnaehsaapoatsicirtnorigoeawwomnsratwneaihltglnoiorecpaoesethatppsprlecimadneshteitwmufidseshteneolrtecoeycslihsmsraeabpnnsaeltaydelhotfsealhsptmoosamnbcuiughenntseahctnpoetrevahottehawtssinatatcabirkbtysroifchsepeofhlhtuyalwpltlrivrteneerlapssigsnaitahcotlaeseelhxtlvipseohegcrsaeandottdtseerdytgonhietceerllsioseyuemqpniahttdendecaanjsartogtcbmeaehscerhotbdemntialiewlmolpnsiwutntiophgeterruetosapaehmsaiiuodgtnodetwesfxenrfoltairitnmaoebtiehwlaltlsdoooonitoujwmhptiioetlgarcllmirwmineinaliepcnahgetriendnoeipgtrnuhfrtsenricnouist'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ccb = caesar_decipher(scb, kcb)\n",
+    "ccb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((1, 5, 4, 0, 3, 6, 2), False, False), -4551.751064338015)"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kwordb, fillb, emptyb), score = column_transposition_break_mp(ccb, fitness=Ptrigrams)\n",
+    "(kwordb, fillb, emptyb), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'reportonoperationgunnersidefromswallowafterrecoveringsuppliesfromthemissioncontainerdropsronnenbergsteamsetouttojoinupwithswallowthetwoteamsmetafterseveraldaysofcrosscountryskiingandthepartymadeitswaytovemorkwhilepatrolshadreducedfromthehighfrequencythatthewehrmachtestablishedfollowingoperationfreshmanthebridgespanningtheravineoverthemanaremainedfullyguardedandthecommandogroupfeltthatadirectassaultwouldbeunproductiveitwasdecidedthatateamshoulddescendtwohundredmetersintotheravinefordtheriverbelowandclimbthehillonthefarsideonreachingtheriverbeditwasfoundtobepossibletofollowasingletrackgoodsrailwayintotheplantandtheentrywascarriedoutwithoutencounteringanyguardsthelocalbossagentintheplantsupplieddetailedplansandschedulesandtheraidingpartyusedthattogainfurtheraccessviaacabletunnelandwindowencounteringonlythecaretakerjohansenwhoasapatrioticnorwegianwasmorethanwillingtocooperatethesappersplacedmineswithtimedfusesontheelectrolysischambersasplannedtheyalsoleftathompsonsubmachinegunatthescenetoprovethatthiswasanattackbybritishforceshopefullythatwillpreventreprisalsagainstthelocalstheexplosivechargesdetonateddestroyingtheelectrolysisequipmentandtheadjacentstoragechambersthecombinedteamwillnowsplitupintothreegroupsteamaisheadingouttoswedenforexfiltrationteambwillheadtooslotojoinupwithmilorgteamcwillremaininplaceintheregionpendingfurtherinstructions'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = column_transposition_decipher(ccb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "report on operation gunner side from swallow after recovering supplies from the mission container\n",
+      "drops ronn enberg steam set out to join up with swallow the two teams met after several days of\n",
+      "crosscountry skiing and the party made its way to ve mork while patrols had reduced from the high\n",
+      "frequency that the wehrmacht established following operation freshman the bridge spanning the ravine\n",
+      "over the man a remained fully guarded and the commando group felt that a direct assault would be\n",
+      "unproductive it was decided that a team should descend two hundred meters into the ravine ford the\n",
+      "river below and climb the hill on the farside on reaching the riverbed it was found to be possible\n",
+      "to follow a singletrack goods railway into the plant and the entry was carried out without\n",
+      "encountering any guards the local boss agent in the plant supplied detailed plans and schedules and\n",
+      "the raiding party used that to gain further access via a cable tunnel and window encountering only\n",
+      "the caretaker johansen who as a patriotic norwegian was more than willing to cooperate the sappers\n",
+      "placed mines with timed fuses on the electrolysis chambers as planned they also left a thompson sub\n",
+      "machinegun at the scene to prove that this was an attack by british forces hopefully that will\n",
+      "prevent reprisals against the locals the explosive charges detonated destroying the electrolysis\n",
+      "equipment and the adjacent storage chambers the combined team will now split up into three groups\n",
+      "team a is heading out to sweden for exfiltration team b will head to oslo to join up with mil org\n",
+      "team c will remain in place in the region pending further instructions\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpb = lcat(tpack(segment(pb)))\n",
+    "print(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1635"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['hatreds',\n",
+       " 'lauries',\n",
+       " 'patrols',\n",
+       " 'patrons',\n",
+       " 'petrols',\n",
+       " 'fatheads',\n",
+       " 'lawmaker',\n",
+       " 'occupier',\n",
+       " 'occupies',\n",
+       " 'patricas',\n",
+       " 'payrolls',\n",
+       " 'odourless',\n",
+       " 'patricias',\n",
+       " 'petrifies']"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[kwordb]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "jupytext": {
+   "formats": "ipynb,md"
+  },
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.4"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2020-early/2020-a-challenge7.md b/2020-early/2020-a-challenge7.md
new file mode 100644 (file)
index 0000000..e3549f9
--- /dev/null
@@ -0,0 +1,117 @@
+---
+jupyter:
+  jupytext:
+    formats: ipynb,md
+    text_representation:
+      extension: .md
+      format_name: markdown
+      format_version: '1.2'
+      jupytext_version: 1.3.4
+  kernelspec:
+    display_name: Python 3
+    language: python
+    name: python3
+---
+
+```python
+import os,sys,inspect
+currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+parentdir = os.path.dirname(currentdir)
+sys.path.insert(0,parentdir) 
+```
+
+```python
+from cipher.caesar import *
+from cipher.affine import *
+from cipher.keyword_cipher import *
+from cipher.column_transposition import *
+from cipher.vigenere import *
+
+from support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+%matplotlib inline
+```
+
+```python
+challenge_number = 7
+plaintext_a_filename = f'{challenge_number}a.plaintext'
+plaintext_b_filename = f'{challenge_number}b.plaintext'
+ciphertext_a_filename = f'{challenge_number}a.ciphertext'
+ciphertext_b_filename = f'{challenge_number}b.ciphertext'
+```
+
+```python
+ca = open(ciphertext_a_filename).read()
+cb = open(ciphertext_b_filename).read()
+
+sca = sanitise(ca)
+pca = letters(ca)
+pta = depunctuate(ca)
+
+scb = sanitise(cb)
+pcb = letters(cb)
+ptb = depunctuate(cb)
+```
+
+```python
+fc = collections.Counter(sca)
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+kworda, score = vigenere_frequency_break(sca, fitness=Ptrigrams)
+kworda
+```
+
+```python
+ppa = vigenere_decipher(sca, kworda)
+pa = repunctuate(ppa, pta)
+print(pa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(pa)
+```
+
+```python
+fc = collections.Counter(scb)
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+kcb, score = caesar_break(scb, fitness=Pletters)
+kcb
+```
+
+```python
+ccb = caesar_decipher(scb, kcb)
+ccb
+```
+
+```python
+(kwordb, fillb, emptyb), score = column_transposition_break_mp(ccb, fitness=Ptrigrams)
+(kwordb, fillb, emptyb), score
+```
+
+```python
+pb = column_transposition_decipher(ccb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)
+pb
+```
+
+```python
+fpb = lcat(tpack(segment(pb)))
+print(fpb)
+```
+
+```python
+open(plaintext_b_filename, 'w').write(fpb)
+```
+
+```python
+transpositions[kwordb]
+```
+
+```python
+
+```
diff --git a/2020-early/7a.ciphertext b/2020-early/7a.ciphertext
new file mode 100644 (file)
index 0000000..c5aebf0
--- /dev/null
@@ -0,0 +1,3 @@
+Hvmd,
+Gsjfc A vensr’l piwb mf hsmql eigz, Qlmfgzwpd owcsh TCWK hs ksx md ef ctwfelwsfg aabk ab xzs YC irvsv lvi foqw cj lvi Kdiuwed Ctwfelwsfg Ipsgmhmns efr xzox zow gqgmdmwr e dcx gt qq hmes. Ek gsgb ek ki ycx ksx md M oow hix ab xgigz kmlv Iabej Goabrsfpsbh, sb ifumfsij tvga Zwasjy azc lsr laxeuyiv o ggowlop khisaij orv geaziv hs Spijriwb xg xsab xzs asf ixtsjh lwfi. Uvyjqlazp gfhwfiv iw lc agfo md tdork hs shxsqo lvi hzefh efr Iabej viddiv iw lc fjwix or abxwzpauifqi yoxzsvabk lsee hs abjazxjoxw hlw fiywsf. Ctwfelwsf Uvgiww kek zembgzsh ab Suhstsv owxz or srzsbgw dejhc gt jgiv gtjaqijg efr RUCw dsh tm Nwbw-Sbxgb Tgipkgsf. Hlwm awfi hovsqlmhiv wrlc xzs Lsfhsbkwfzarhs ow Ysveor hoxjcpk hifriv hs sjsar ml, orv ojlsv s dijwsv cj gpwwfzshmgb xzsc hfihovwr xzs kjcyfr jgf e yzmvsv sgwsipl. Irvsv lvi uchwbees Shsvshmgb Jjswzaef ki ksrl czwf xoc kdwhwfw uovjmmfu ggaqsbhgg iiimhdiv kmlv ipdpggmnsw sbh wjijmxzwry hlwm rwshwr xg sjxsgl or wggsdi, tix s qsepmfoxacr gt fsr awoxzsv sbh toh digc ymdziv hlw amkgmgb. Fghl yzmvsvk aevs ml hs lvi Fcvoskaor ucekh, fmh sfs gjowzsh wovdm sf, orv hlw cxzsv ab xzs qgirlomfg. Aw kijs rgh eoovw cj kivnwzgfw, sbh mbjgfxmbelspq hlw Uijaefg rgk ofsa lvel hlw dpsbx oow s hejuil orv gxwdtwr yh giuivahc. Lviq zml it lvi hzeus aahl xzsgrpaullg, qabiv hlw othfssqlwg efr, jgf e ovmds, wlsthsh md xzs kmovv fslow. Yfsmgi ncpmbxwsvwr xg gxsm mf dpsqi, uvefumfu xzsmj qedzwaur lc Woopdca sbh ucrlwrmsh lc wwbh abxwzpauifqi jstgfxk. Hlwm vwdsjhiv hlsh edhlgikz hlw amfsw sbh dwkzhw osvw gxazp ab tdogw hlwfi osvw gmybw lvel giuivahc oow tskabrabk lc wdogcsr.
+Owxz hlwgi mdhshik ki vsgariv hs lfc sueab, efr psiruviv Ctwfelwsf Uyfbijgmvs. Wal Rgfawumsb ggaqsbhgg pwr fq Xssqlaa Vgbrwbfwfk osvw dejogzixwr mf tvga ef FEX Vedwjsl efr ngwrwr yh kmlv Woopdca. Lvi shxsqlwr hgqyesrl ww lviaf qagwacr jstgfx. Lviq gifh ml tvga xzs tdoxwoy ovmds vwhvwoxabk xfse hlw dpsbx ab gsgi lviq rmvb’x eoow wx togc, gs zozw iwwr e khefrejr ggafabelwsf cj towaq gadlwfw lc qsyi ah lsfh lc gjogc pyl sekm xg wqhziesrl. Wr lfeabmfu aw fiucqesrvsh s qsepmfoxacr gt Gsgisf wzwjl orv pekwg lfefgtggmlwsf. W pwozw wx lc cgi xg riuwtzsv.
diff --git a/2020-early/7a.plaintext b/2020-early/7a.plaintext
new file mode 100644 (file)
index 0000000..18b1cee
--- /dev/null
@@ -0,0 +1,3 @@
+Phil,
+Sorry I haven’t been in touch much, Churchill asked BOSS to set up an operations wing in the UK under the name of the Special Operations Executive and that has occupied a lot of my time. As soon as we got set up I was put in touch with Einar Skinnarland, an engineer from Vemork who had hijacked a coastal steamer and sailed to Aberdeen to join the war effort here. Churchill ordered us to work up plans to attack the plant and Einar helped us to brief an intelligence gathering team to infiltrate the region. Operation Grouse was launched in October with an advance party of four officers and NCOs led by Jens-Anton Poulsson. They were parachuted into the Hardangervidda as German patrols tended to avoid it, and after a period of observation they prepared the ground for a glider assault. Under the codename Operation Freshman we sent over two gliders carrying commandos equipped with explosives and everything they needed to effect an escape, but a combination of bad weather and bad luck killed the mission. Both gliders made it to the Norwegian coast, but one crashed early on, and the other in the mountains. We were not aware of survivors, and unfortunately the Germans now knew that the plant was a target and stepped up security. They lit up the place with floodlights, mined the approaches and, for a while, stepped up the guard rotas. Grouse volunteered to stay in place, changing their callsign to Swallow and continued to send intelligence reports. They reported that although the mines and lights were still in place there were signs that security was beginning to slacken.
+With these updates we decided to try again, and launched Operation Gunnerside. Six Norwegian commandos led by Joachim Ronnenberg were parachuted in from an RAF Halifax and joined up with Swallow. The attached document is their mission report. They sent it from the plateau while retreating from the plant in case they didn’t make it back, so have used a standard combination of basic ciphers to make it hard to crack but easy to implement. In training we recommended a combination of Casear shift and basic transposition. I leave it to you to decipher.
diff --git a/2020-early/7b.ciphertext b/2020-early/7b.ciphertext
new file mode 100644 (file)
index 0000000..a86a33c
--- /dev/null
@@ -0,0 +1 @@
+ODBBY YZYKB XODZY XESQX XBONO SPCYK GBCVW YDPVK OGBFY BMOOS ECBQZ XVPCZ OBSWW OYRSD CMXCY YSDOX XSBKB BCNZY YXOLX XBOCW KQOCD DDDOE YYYZE TXGSD KGSCV RYORV DDGYW KGOCD ODPWK ODCBO BFKON YCVIP KBMCM CYYXC IEBUD SXKSQ NXRBK DZDOW SOIND KGYDC IFKWG UOBRY VDKSZ BOVNK YRBCN NOOMP EYORB DRWQO BSPAR ODIEM RXDGO KRODB RMRKD WCVLO KSDRY PCNVO YQXVS YGOSD ZKYBP RCXOW BXLOK RBDNZ CSOKQ XDQXX RSBXS OFOKF RDYBO OKOBW KWXSP NKOEX VKEVQ BIONX NKDNO WWRYK MNYBX QEYPD DZVRO DBSKN OKDKC MCEKD VEVYN GOBZL XYEEF SNDOM DNCSK OGSDN MORND KOKDW KRNVC ENYCN XOODM YNXGE BRNOD OOBWS DYCDR XBXSO FOKYR DPNOB SLBBO OFYNX VKMGS RDVLO WSXYR VDVOC BRKSP OOBNX KYRDQ MXRSB BOOFL SNKGO DCSYD NPXYE OCCLY SZVPY LDYOV CKVGS YQBDX OKVUN YMYCQ KKGBV ISXRD SYODV KDZXX KDXON ODRIM CBKKG BYNBO ESGYR DDESO EYDMX XOQXD SKBIB KXENQ DYVCO MRVCC KYKLO XSQDD XOXKR VDZES VCZOZ NSKND VONXK OVCZX RMKCO NEKCN OXVDK BNOSR SKZNQ BXINO DCDEK QYRDK DXDBS ERPBO MOMCK FMKCK KSVXE LDXOV GNOXS KNXOX GMYEB OYDSX QIVXX DYOOB RKDMU YTKBR OXGXK ORCKK ZYKDC SMSBD XYBSQ YOKGG YWXCB KDGXO KSRVD QVXYS YBOMZ KYOCO DRKDZ ZCZBV OMSWK NXOCR DOSDG WEPSN COCRD OXOYV BDOMY OIMCV SRCWC BKOKL ZXXCK OVDKI NOVRY DPCOK VRCZD WYYCK WXLME SEQRO XXDCO KRMDX ZYODB OFKRY DDORK GDCCS XKDKD MKLSB ULDIC BYSPM RCOZO YPRVR DEIKV GZVDV BSFBD OXOOB VKZCC SQCXK SDKRM YDVKO COOVR HDVFS ZCOYR OQMBC KOKXN YDDND COOBN IDQYX RSODM OOBVV CSYCO IEOWA ZXSKR DDNOX NOMKK XTCKB DYQDM LWOKO RCMOB RYDLN OWXDS KVSOG VWYVZ XCSGE DXDSY ZRQOD OBBEO DYCKZ KORWC KSSEY NQDXY NODGO CPHOX BPYVD KSBSD XWKYO LDSOR GVKVD VCNYY YYXSD YETGW RZDSS YODVQ KBMVV WSBGW SXOSX KVSOZ MXKRQ ODBSO XNXYO SZQDB XERPB DCOXB SMXYE SCD
diff --git a/2020-early/7b.plaintext b/2020-early/7b.plaintext
new file mode 100644 (file)
index 0000000..f27c768
--- /dev/null
@@ -0,0 +1,17 @@
+report on operation gunner side from swallow after recovering supplies from the mission container
+drops ronn enberg steam set out to join up with swallow the two teams met after several days of
+crosscountry skiing and the party made its way to ve mork while patrols had reduced from the high
+frequency that the wehrmacht established following operation freshman the bridge spanning the ravine
+over the man a remained fully guarded and the commando group felt that a direct assault would be
+unproductive it was decided that a team should descend two hundred meters into the ravine ford the
+river below and climb the hill on the farside on reaching the riverbed it was found to be possible
+to follow a singletrack goods railway into the plant and the entry was carried out without
+encountering any guards the local boss agent in the plant supplied detailed plans and schedules and
+the raiding party used that to gain further access via a cable tunnel and window encountering only
+the caretaker johansen who as a patriotic norwegian was more than willing to cooperate the sappers
+placed mines with timed fuses on the electrolysis chambers as planned they also left a thompson sub
+machinegun at the scene to prove that this was an attack by british forces hopefully that will
+prevent reprisals against the locals the explosive charges detonated destroying the electrolysis
+equipment and the adjacent storage chambers the combined team will now split up into three groups
+team a is heading out to sweden for exfiltration team b will head to oslo to join up with mil org
+team c will remain in place in the region pending further instructions
\ No newline at end of file