Done challenge 8
authorNeil Smith <neil.git@njae.me.uk>
Thu, 21 May 2020 16:21:50 +0000 (17:21 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Thu, 21 May 2020 16:21:50 +0000 (17:21 +0100)
2020-early/2020-a-challenge8.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge8.md [new file with mode: 0644]
2020-early/8a.ciphertext [new file with mode: 0644]
2020-early/8a.plaintext [new file with mode: 0644]
2020-early/8b.ciphertext [new file with mode: 0644]
2020-early/8b.plaintext [new file with mode: 0644]

diff --git a/2020-early/2020-a-challenge8.ipynb b/2020-early/2020-a-challenge8.ipynb
new file mode 100644 (file)
index 0000000..9789c1e
--- /dev/null
@@ -0,0 +1,405 @@
+{
+ "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": 2,
+   "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 = 8\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": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/home/neil/Programming/cipher-tools/support/plot_frequency_histogram.py:11: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  f.show()\n"
+     ]
+    },
+    {
+     "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": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'low'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kworda, score = vigenere_frequency_break(sca, fitness=Ptrigrams)\n",
+    "kworda"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'harrywemanagedtotapthephonelinesinosloandinterceptedgermanmilitarypolicereportstothessheadquarterstheyestablishedthatthegunnersideoperationwaseffectiveinwipingouttheexistingstocksofheavywaterbutthatthenaziengineerswereabletorestartproductionthiswasconfirmedincommunicationssmuggledoutoftheplantbyjomarbrunandeinnarskinnerlandthechiefengineeranddesigneroftheplantwhoarestillworkingthereassoeagentstheinformationwassenttointelligenceheadquartersinlondonintoothpastetubesusingacipherdevelopedforbossbyleomarksthisintelligencewaspassedtousaafwhostartedtodevelopaplantobombtheplantrunningtheriskofsignificantcivilianlossesluckilyoneofourbossofficialsspottedthemaponthewallofabriefingroomduringaprotocolvisitandrealisedwhatitwasheflaggedtheoperationandgotmeinvolvediwasabletocontactswallowviatheoslobranchofmilorgandwehavebeenworkingtogetherwithusaaftorefinethemissiondespitetheriskstheyagreedtoadaylightraidinthehopethattheaddedaccuracywouldreducenorwegiancasualtiesunfortunatelytheraidwasamixedsuccessasyoucanseefromtheattachedreportitisdoubleencryptedagainbutwasalottoughertocracktheyhaveusedanaffineshiftforthesubstitutionphasebeforeusingthesamesortoftranspositiontakealookandletmeknowwhatyouthinkmeanwhileiwilltrytocontactronnenbergtoseewhathewantstodonextgiventheneedtoprotectournetworkiwillincreasethekeylengthformymessagetoyounextweektoatleastsix'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sca, kworda)\n",
+    "pa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry we managed to tap the phone lines in oslo and intercepted german military police reports to\n",
+      "the ss headquarters they established that the gunner side operation was effective in wiping out the\n",
+      "existing stocks of heavy water but that the nazi engineers were able to restart production this was\n",
+      "confirmed in communications smuggled out of the plant by jomar brun and e in nar skinner land the\n",
+      "chief engineer and designer of the plant who are still working there as soe agents the information\n",
+      "was sent to intelligence headquarters in london in toothpaste tubes using a cipher developed for\n",
+      "boss by leo marks this intelligence was passed to usaaf who started to develop a plan to bomb the\n",
+      "plant running the risk of significant civilian losses luckily one of our boss officials spotted the\n",
+      "map on the wall of a briefing room during a protocol visit and realised what it was he flagged the\n",
+      "operation and got me involved i was able to contact swallow via the oslo branch of mil org and we\n",
+      "have been working together with usaaf to refine the mission despite the risks they agreed to a\n",
+      "daylight raid in the hope that the added accuracy would reduce norwegian casualties unfortunately\n",
+      "the raid was a mixed success as you can see from the attached report it is double encrypted again\n",
+      "but was alot tougher to crack they have used an affine shift for the substitution phase before using\n",
+      "the same sort of transposition take a look and let me know what you think meanwhile i will try to\n",
+      "contact ronn enberg to see what he wants to do next given the need to protect our network i will\n",
+      "increase the key length for my message to you next week to atleast six\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpa = lcat(tpack(segment(pa)))\n",
+    "print(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1644"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(fpa)"
+   ]
+  },
+  {
+   "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": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(11, 5, True)"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kmb, kab, kob), score = affine_break(scb, fitness=Pletters)\n",
+    "kmb, kab, kob"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etmhbnboiagoriendvrmaokaswciroredudtiudrnlagyhingtvnoobesmetirxnetetahheatstcaqkuodornincsisotnhfgttinreapelsnlesiiptonottogwrsucpeahamnkwiguotronhsnaetterwgtchsiphaapdreebthoeoetnkrdshpryoeotwriastaotnnnhderietaaptltnethiermsltetehoetaesttahtkascwtnaorfeoenesnwoirantsirtpecdteeabcyieorvnrladflaoetthakatcgirnaacirsfmtehteoeatvrnuerfemdretohsmoisynieieewtesnstsesaatthntrittmeintletdocuvcaoeeprpeaordsdtiprhuttetactuakhtbtaermjyiottoefhlxepiossvoaerduintyrhtnteosdrweprdoptweiehhvrhiygcaacuocryhniteatnrptnelntaotltywhooternetisohhtoterwpeasottnniahdetefirncosreutdrucwtrhietosttowhdesofrtetohsalsahtutoesbmifbadldetaaomtgrehueebtiuldrteemieuercltyoslscfiaiialtonydnusrectwookesfyahvtwwaeeerropcrtdteetbsyheeevtnesooyrseffriconrcecdotrnebeeaowhvoeehvroetprwaepinltethslbafsnemedeaagndhadsitsoercndaditopnhnleaaterihsstoeipslbsiyiattuthonrieehemseaevasngtrwnokigiwitthndiincissunisotwfihcfoilirasdofmaiheliecmesrtnpoguhibtanesecdeeihddttafthiaectlhiylosuedubsothdewsnxntiitgksofscoahweveaytnroadstpausyimodhrdxiieblwlhepsitepdhortebliaaorrtsioedannmauafucntragiflciiiietsenagrfnmyfotrurhrerehninmcentxadrpeeeiamnottiinngvetehsrfikclooeailsaopnwgieenlwldesetniogiinfcytalhecnaeensrcyuirftoitphsaeorotiinlnfawlhyelosuodtnttheaetthakatclkdiletewynetornnogwneivcaiiislaitnhsslivbuaaplperaaoganddaronueasgneatridtonihgeerhbseetrdalnidonntonnorseuhettanhtewoirepagnuotplniaodusnentrawdishosotabflmtoersheeelendseasdsteh'"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "acb = affine_decipher(scb, kmb, kab, kob)\n",
+    "acb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((2, 0, 5, 1, 3, 8, 6, 4, 7), False, False), -4688.2791775857195)"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kwordb, fillb, emptyb), score = column_transposition_break_mp(acb, fitness=Ptrigrams)\n",
+    "(kwordb, fillb, emptyb), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thebombingraidonvemorkwascarriedoutduringdaylightonnovembersixteenththeattacksquadronconsistingofthirteenplanessplitintotwogroupseachmakingtworunsonthetargetswhichappearedtobethenorskhydropowerstationandthenitrateplantthreemilestotheeasttheattackwasnotforeseennorwasitinterceptedbyaircoverandalloftheattackingaircraftseemtohavereturnedfromthemissioneyewitnessesstatethatintermittentcloudcoverappearedtodisrupttheattackbutthemajorityoftheexplosivesaroundthirtytonsweredroppedwithveryhighaccuracyonthenitrateplantonlytwotothreetonshitthepowerstationandthereinforcedstructurewithstoodtheworstoftheassaultthebombsfailedtodamagetherebuiltdeuteriumelectrolysisfacilityandournewstocksofheavywaterwereprotectedbythesevenstoreysofreinforcedconcreteabovehoweverthepowerplantitselfhasbeendamagedandthissecondraidontheplantraisesthepossibilitythatourenemieshaveagentsworkingwithinitindiscussionwithofficialsfromdiealchemistengroupithasbeendecidedthatthefacilityshouldbeshutdownexistingstocksofheavywaterandpotassiumhydroxidewillbeshippedtotheirlaboratoriesandmanufacturingfacilitiesingermanyforfurtherenrichmentandexperimentationgiventheriskoflocalespionagewewillneedtosignificantlyenhancesecurityforthisoperationfinallyweshouldnotethattheattackkilledtwentyonenorwegianciviliansthisisvaluablepropagandaandouragentsaredoingtheirbesthereandinlondontoensurethatthenorwegianpopulationunderstandswhoistoblamefortheseneedlessdeaths'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = column_transposition_decipher(acb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the bombing raid on ve mork was carried out during daylight on november sixteenth the attack\n",
+      "squadron consisting of thirteen planes split into two groups each making two runs on the targets\n",
+      "which appeared to be the norsk hydropower station and the nitrate plant three miles to the east the\n",
+      "attack was not foreseen nor was it intercepted by air cover and all of the attacking aircraft seem\n",
+      "to have returned from the mission eyewitnesses state that intermittent cloud cover appeared to\n",
+      "disrupt the attack but the majority of the explosives around thirty tons were dropped with very high\n",
+      "accuracy on the nitrate plant only two to three tons hit the powerstation and the reinforced\n",
+      "structure withstood the worst of the assault the bombs failed to damage the rebuilt deuterium\n",
+      "electrolysis facility and our new stocks of heavy water were protected by the seven storeys of\n",
+      "reinforced concrete above however the powerplant itself has been damaged and this second raid on the\n",
+      "plant raises the possibility that our enemies have agents working within it in discussion with\n",
+      "officials from die alchemist en group it has been decided that the facility should be shutdown\n",
+      "existing stocks of heavy water and potassium hydroxide will be shipped to their laboratories and\n",
+      "manufacturing facilities in germany for further enrichment and experimentation given the risk of\n",
+      "local espionage we will need to significantly enhance security for this operation finally we should\n",
+      "note that the attack killed twentyone norwegian civilians this is valuable propaganda and our agents\n",
+      "are doing their best here and in london to ensure that the norwegian population understands who is\n",
+      "to blame for these needless deaths\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpb = lcat(tpack(segment(pb)))\n",
+    "print(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1686"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['clampdown']"
+      ]
+     },
+     "execution_count": 18,
+     "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-challenge8.md b/2020-early/2020-a-challenge8.md
new file mode 100644 (file)
index 0000000..1b8cd88
--- /dev/null
@@ -0,0 +1,121 @@
+---
+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 = 8
+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
+pa = vigenere_decipher(sca, kworda)
+pa
+```
+
+```python
+fpa = lcat(tpack(segment(pa)))
+print(fpa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(fpa)
+```
+
+```python
+fc = collections.Counter(scb)
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+(kmb, kab, kob), score = affine_break(scb, fitness=Pletters)
+kmb, kab, kob
+```
+
+```python
+acb = affine_decipher(scb, kmb, kab, kob)
+acb
+```
+
+```python
+(kwordb, fillb, emptyb), score = column_transposition_break_mp(acb, fitness=Ptrigrams)
+(kwordb, fillb, emptyb), score
+```
+
+```python
+pb = column_transposition_decipher(acb, 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/8a.ciphertext b/2020-early/8a.ciphertext
new file mode 100644 (file)
index 0000000..876337f
--- /dev/null
@@ -0,0 +1 @@
+SONCM SPAWY OCPRP ZHWAH DPDDZ BAWWJ PGEYC OWCWY REYHA CQAAH AOUAC AWYAE WWPLF UACHT QACSL ZFPDH KEVAD GDPOZ BIWCH ACGPS SUPGP LPHTG DPRPS OPEVA RIJYS NDWZP CLPFW EWKYK WDSBQ SYEWR PWJHW LTBCZ IPEVA PLEDH EYUOE CYVGK QVALJ UHOPP FXFHP SOPEV AYOVT SJRWJ PSNDK ACSWM ZAECN PGPLF PAFKO IYEWK YHDTG SLGYZ BBTFI PREYQ KXAQY WYLHE ZBODA QRUHP RKFHK QHDPD HLBPM MFZAW CPNFB WYRAT BJLFO VWJYS NWOJO HDPQD TSBPB CTBAP FWYRZ PGERB ACCBE VAAZW YHSSC WCSOE WHWKK CYEYU PSSNP OODCA LUAYH OEVAT BBZFI LHEZB SLGOP BPECE YHAWZ ERSJN SDPOZ BIWCH ACGEY ZKYRK YWJEC KEVLL GPPHQ MSOFG EYUWN WLSSN OSRPZ KASZQ CNMCO DPUWS KXONV GPSWO TBPPZ HTUAY QAHOO AOODS ZECQD OWQKD ZGPLF PPRPZ RAGSH ZDWAZ WYHKM CIMHD PDHLB PCIJY WJRHD PFEDY KQGER BEQWY LBPNW RTZEL BHZGO PGHFQ GTZUZ BAZTK FFXZG OZTBT QELZO DDKEH AOHDP AWACJ EVAHO HWCBL PNTSB TBCCC KXRQC WJROL CCPZQ KWJED WPLBZ CSWWW OPRSS OPTHS LGDPT HLUCP RPSSK ASNLH EZBWY RCZHI PWJGC HGSZT KWDOX WSPZQ KYHWN HOHOH WCSGW WEVAZ GHZPN LBYSC BXWHZ FCLBZ HSDLJ AMSAY KKCYE YUPZU AEVAC KEEVQ DOWQH KCSBT BAEVA XWODW KYRAD DEESP SSNTG GDHDP MWRFA PRPZO ZLMHT UDEFW TREYH DPVKA SPSOP EVALR ZPRWN QQCOY JKKFZ ZCSZF QAYCN HSCTO JNOOF OHEWA DIJQC NEIJL HAWMP SSNLW ZHOOL AEISZ DIYNS ODOOJ CQNOJ DSAQF KXHDP OPEOY SSZCS LZFPT HEDRK FPHPS JNFUA HAOOC LWJMI PHOOL ZKEHK FUDPF PZQNL QGEVA JVWGS QDSZL BWQTE YSOSW BETKC HDPGQ MGPTH QEWKY DDLGA MSBZF AFGEY UPSSO LAADC NECBE FWYGL ZGEEW KYHWV SWWCK VOJOZ AEAAV BKHKD LHUZI PSWJV AALBS SWHPW STZHE FUECY ZBPLQ PCCJY SJMSN RHKDS AHVWE VAHOJ EGPZR KYSTE UEGSJ EVAYS AOHKA FKESY ECQCB AEKKC YEHWH WWJNF ALGAE VAVSU WSJRH DQCNX MIPGO LUAEC UZIJP LPHSA VHKLH HPOOE GEI
diff --git a/2020-early/8a.plaintext b/2020-early/8a.plaintext
new file mode 100644 (file)
index 0000000..5283f30
--- /dev/null
@@ -0,0 +1,17 @@
+harry we managed to tap the phone lines in oslo and intercepted german military police reports to
+the ss headquarters they established that the gunner side operation was effective in wiping out the
+existing stocks of heavy water but that the nazi engineers were able to restart production this was
+confirmed in communications smuggled out of the plant by jomar brun and e in nar skinner land the
+chief engineer and designer of the plant who are still working there as soe agents the information
+was sent to intelligence headquarters in london in toothpaste tubes using a cipher developed for
+boss by leo marks this intelligence was passed to usaaf who started to develop a plan to bomb the
+plant running the risk of significant civilian losses luckily one of our boss officials spotted the
+map on the wall of a briefing room during a protocol visit and realised what it was he flagged the
+operation and got me involved i was able to contact swallow via the oslo branch of mil org and we
+have been working together with usaaf to refine the mission despite the risks they agreed to a
+daylight raid in the hope that the added accuracy would reduce norwegian casualties unfortunately
+the raid was a mixed success as you can see from the attached report it is double encrypted again
+but was alot tougher to crack they have used an affine shift for the substitution phase before using
+the same sort of transposition take a look and let me know what you think meanwhile i will try to
+contact ronn enberg to see what he wants to do next given the need to protect our network i will
+increase the key length for my message to you next week to atleast six
\ No newline at end of file
diff --git a/2020-early/8b.ciphertext b/2020-early/8b.ciphertext
new file mode 100644 (file)
index 0000000..a5be515
--- /dev/null
@@ -0,0 +1 @@
+HQROA CANZP DNUZH CWMUR PNVPF XLZUN UHWBW QZBWU CGPDT OZCDQ MCNNA HFRHQ ZUICH QHQPO OHPQF QLPJV BNWNU CZCLF ZFNQC OSDQQ ZCUHP YHGFC GHFZZ YQNCN QQNDX UFBLY HPOPR CVXZD BNQUN COFCP HQQHU XDQLO FZYOP PYWUH HAQON HNHQC VUWFO YUTNH NQXUZ PFQPN QCCCO WHUZH QPPYQ GQCHQ OZHUR FGQHQ HONHQ PHFQQ POQVP FLXQC PNUSH NHCHF CXNZU PCQFZ UQYHL WQHHP ALTZH NUMCU GPWSG PNHQQ OPVPQ LDZUC PPLZU FSRQH OQHNH PQMUC BHUSH RWUHQ NOFRN ZFTCZ HZHHX QHFCF QFHFP PQQOC QUZQQ RHZCQ GHQWN LBMLP NHHYU YHPNU WFWQZ YUOBQ QHQPL QBPVO QAQPH URKTZ NQQNH SOGIH YZNFF MNPHU WBZCQ TUOQC QHNFW UXHYU WNYQX HZHOO MUOZT DLPPL BNLUT OCZQH PQCUY QCHGC QPNQG QTXON NQHUC HQZFN OOQNQ HUXYH PFNQQ CCZPO WHQHS ZUCLN FUHBQ WUBLX QUOZH QNFQQ NXOWH FNSUQ HQNOF PGFPO QBQNH FARZS APWGW HQPPN RQDUH OBHHA QZBGW UQHHR ZHBHU LGQTN FGFLS ZPZZP GQNCT WCBFU HLQXN NVHFS TPOMQ XXPHH HUUNY LUQWQ HHQAF TOHHH MQCHF NNTUF HSSUZ LNCUL HLWNQ UCHAH HPNXO MNHHO MUNHQ YUXPH YZCGQ HQOFG APSFC HRHWH PPDCW OPWFZ QFNHU LCWPW ZQNYC OCGHP PQHUZ OFFQN HZYFG AFZTZ PQQBQ ONCUZ HHOHR FHPHM PFCDQ UXCNV ZDZXZ QQOCW ZZCLZ FFBCZ FNQXS ZOLSN ZGZUP FWNSR PZOHG ZHLRH FUQCY NDBOZ AQPCH FHLWH HZOWW QQPSQ OZPHL QGOZT GNFBH WBAFN QOWHX FCICQ ZZQDV FNSFL NPOXH MHPTQ CUNPW FQYPB FTZRN WOUWI ZZHAG XGOHY FZQHY WONUQ HAGZP PNUUQ FZNHW PCCRP BPSBL CQUPD ZSGLZ ZZZHQ FHCPD USCRT SNQUB UOUHU HOCZC RLHCQ IPWUY HHHZP RCNQQ ZZCCD MHQHO FUSZV LGNNH PZGFP NYCXD ZHHCG XGWHF HQCZN DZZCS LTQPG OHLCP HHCFU LTBZU SQNZQ YOFPH NUNQZ ZCGCS PXGOT HGNFB NWQCQ QOHPH QQOPV PQLGV WZGHQ HXTCH QNUCC NDXCH ZMLPZ ZZFGP ZQCOF FGZMA BPPYG YHUPP NDPCW WPUNC BHPFD CHPQU ZWQNC ZODHH UOAFH HQUWP GCZWN CCQNC CNUFH BOHQQ PCOQH XNZUH YPDCB NQYGC ZPNWB FCHCQ UPXWZ FONFN QPASG RQNHU FOHHH GHCWF HPFWF QHO
diff --git a/2020-early/8b.plaintext b/2020-early/8b.plaintext
new file mode 100644 (file)
index 0000000..ad25c8c
--- /dev/null
@@ -0,0 +1,18 @@
+the bombing raid on ve mork was carried out during daylight on november sixteenth the attack
+squadron consisting of thirteen planes split into two groups each making two runs on the targets
+which appeared to be the norsk hydropower station and the nitrate plant three miles to the east the
+attack was not foreseen nor was it intercepted by air cover and all of the attacking aircraft seem
+to have returned from the mission eyewitnesses state that intermittent cloud cover appeared to
+disrupt the attack but the majority of the explosives around thirty tons were dropped with very high
+accuracy on the nitrate plant only two to three tons hit the powerstation and the reinforced
+structure withstood the worst of the assault the bombs failed to damage the rebuilt deuterium
+electrolysis facility and our new stocks of heavy water were protected by the seven storeys of
+reinforced concrete above however the powerplant itself has been damaged and this second raid on the
+plant raises the possibility that our enemies have agents working within it in discussion with
+officials from die alchemist en group it has been decided that the facility should be shutdown
+existing stocks of heavy water and potassium hydroxide will be shipped to their laboratories and
+manufacturing facilities in germany for further enrichment and experimentation given the risk of
+local espionage we will need to significantly enhance security for this operation finally we should
+note that the attack killed twentyone norwegian civilians this is valuable propaganda and our agents
+are doing their best here and in london to ensure that the norwegian population understands who is
+to blame for these needless deaths
\ No newline at end of file