mirror of https://github.com/dirtbags/moth.git
Merge branch 'master' of cfl:/var/projects/gctf
This commit is contained in:
commit
f583b2851e
|
@ -15,6 +15,11 @@ rm -f /var/lib/ctf/flags/* || true
|
||||||
|
|
||||||
sv restart /var/service/ctf
|
sv restart /var/service/ctf
|
||||||
|
|
||||||
|
echo "Removing tanks history"
|
||||||
|
rm -f /var/lib/tanks/ai/players/*
|
||||||
|
rm -rf /var/lib/tanks/results/*
|
||||||
|
rm -f /var/lib/tanks/winner
|
||||||
|
|
||||||
echo "Things you may want to tweak:"
|
echo "Things you may want to tweak:"
|
||||||
find /var/lib/ctf/disabled
|
find /var/lib/ctf/disabled
|
||||||
find /var/lib/kevin/tokens
|
find /var/lib/kevin/tokens
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
<dl>
|
||||||
|
<dt>Alice
|
||||||
|
<dd>Welcome to Bletchley. It works like this: I'll say something to Bob,
|
||||||
|
and he'll say something back. Our communication will be encrypted in some
|
||||||
|
manner, or at least obfuscated. Your job is to get the plaintext, and
|
||||||
|
find the puzzle key.
|
||||||
|
<dt>Bob
|
||||||
|
<dd>Sometimes the plaintext from one puzzle will give you a hint (or the
|
||||||
|
cryptogaphic key) for the next. When we give you such keys, we'll always
|
||||||
|
do so in a straightforward manner. The puzzle key for each puzzle
|
||||||
|
is always in what I say, and there shouldn't be any tricks involved in
|
||||||
|
figuring out what it is.
|
||||||
|
<dt>Alice<dd>Good Luck!
|
||||||
|
<dt>Bob<dd>You'll need it. By the way, the key is 'dirtbags'.
|
||||||
|
</dl>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
dirtbags
|
|
@ -0,0 +1,3 @@
|
||||||
|
<dl><dt>Alice<dd>nyy unvy prnfne.
|
||||||
|
<dt>Bob<dd>prnfne vf gur xrl
|
||||||
|
</dl>
|
|
@ -0,0 +1 @@
|
||||||
|
ceasar
|
|
@ -0,0 +1,24 @@
|
||||||
|
plaintext = [b'all hail ceasar.', b'ceasar is the key']
|
||||||
|
|
||||||
|
alpha = b'abcdefghijklmnopqrstuvwxyz'
|
||||||
|
|
||||||
|
def ceasar(text, r):
|
||||||
|
out = bytearray()
|
||||||
|
for t in text:
|
||||||
|
if t in alpha:
|
||||||
|
t = t - b'a'[0]
|
||||||
|
t = (t + r)%26
|
||||||
|
out.append(t + b'a'[0])
|
||||||
|
else:
|
||||||
|
out.append(t)
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
encode = lambda text : ceasar(text, 13)
|
||||||
|
decode = lambda text : ceasar(text, -13)
|
||||||
|
|
||||||
|
c = encode(plaintext[0])
|
||||||
|
print('<dl><dt>Alice<dd>', str(c, 'utf-8'))
|
||||||
|
assert decode(c) == plaintext[0]
|
||||||
|
c = encode(plaintext[1])
|
||||||
|
print('<dt>Bob<dd>', str(c, 'utf-8'), '</dl>')
|
||||||
|
assert decode(c) == plaintext[1]
|
|
@ -0,0 +1,4 @@
|
||||||
|
<dl>
|
||||||
|
<dt>Alice<dd>Vkbd ntg duun puwtvbauwg dbnjwu, hlv bv'd vku dtnu htdbe jpbfebjwud td lduq bf d-hxyud, t vuekfbmlu lduq bf ntfg nxqupf epgjvxcptjkbe twcxpbvnd. Xi exlpdu, bfdvutq xi wuvvup dlhdvbvlvbxf, gxl'pu qxbfc hgvu dlhdvbvlvbxf.
|
||||||
|
<dt>Bob<dd>Vku fuyv vzx jlsswud tpu t hbv qbiiupufv; vkug tpuf'v 'ufepgjvuq' tv tww. Xk, hg vku ztg, vku oug vkbd vbnu bd: 'vku d bd ixp dleod'.
|
||||||
|
</dl>
|
|
@ -0,0 +1 @@
|
||||||
|
the s is for sucks
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
plaintext = [b"This may seem relatively simple, but it's the same basic "
|
||||||
|
b"principles as used in s-boxes, a technique used in many modern "
|
||||||
|
b"cryptographic algoritms. Of course, instead of letter substitution, "
|
||||||
|
b"you're doing byte substitution.",
|
||||||
|
b"The next two puzzles are a bit different; Frequency counts (of characters) "
|
||||||
|
b"will just reveal random noise. "
|
||||||
|
b"Oh, by the way, the key this time is: 'the s is for sucks'."]
|
||||||
|
|
||||||
|
key = b"thequickbrownfxjmpdvlazygs"
|
||||||
|
|
||||||
|
def encode(text):
|
||||||
|
ukey = key.upper()
|
||||||
|
lkey = key.lower()
|
||||||
|
assert len(set(key)) == 26, 'invalid key'
|
||||||
|
assert key.isalpha(), 'non alpha character in key'
|
||||||
|
out = bytearray()
|
||||||
|
for t in text:
|
||||||
|
if t in lkey:
|
||||||
|
out.append(lkey[t - ord('a')])
|
||||||
|
elif t in ukey:
|
||||||
|
out.append(ukey[t - ord('A')])
|
||||||
|
else:
|
||||||
|
out.append(t)
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
def decode(text):
|
||||||
|
ukey = key.upper()
|
||||||
|
lkey = key.lower()
|
||||||
|
assert len(set(key)) == 26, 'invalid key'
|
||||||
|
assert key.isalpha(), 'non alpha character in key'
|
||||||
|
out = bytearray()
|
||||||
|
for t in text:
|
||||||
|
if t in lkey:
|
||||||
|
out.append(ord('a') + lkey.index(bytes([t])))
|
||||||
|
elif t in ukey:
|
||||||
|
out.append(ord('A') + ukey.index(bytes([t])))
|
||||||
|
else:
|
||||||
|
out.append(t)
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
c = encode(plaintext[0])
|
||||||
|
print('<dl><dt>Alice<dd>', str(c, 'utf-8'))
|
||||||
|
assert decode(c) == plaintext[0]
|
||||||
|
c = encode(plaintext[1])
|
||||||
|
print('<dt>Bob<dd>', str(c, 'utf-8'), '</dl>')
|
||||||
|
assert decode(c) == plaintext[1]
|
|
@ -0,0 +1,6 @@
|
||||||
|
<dl>
|
||||||
|
<dt>Alice
|
||||||
|
<dd>KiTvXqBKSkdOiVHAKgyAdZXuTwudIHqzLHcJBCXRPnxCxuxhUmdKcqvNSgkHGgYmKIdQKAOPMatvHAalZzrZcMCFGaiSklvsNsgbLiJmPagZobKLLpgJJcIMDUvKEXFJMiwVbVFKZdjDMKSvTdugBqjPBdlJTlXnDAvFUPNAFpjFESbJNsgJTnCgNeeZIwGfMkmZwnhGCDrOWWYIPafuXZrKNroELoGjXwtQdlSZZwdDTEZxTulhKsAMFthZfHGqSyxnXzdPShkXVrRqDpoNmuTINniddWNvMThBQEWAVbaRLrChBicNXWYbGuwdAQrvLdfdxEJgPErTwysQ
|
||||||
|
<dt>Bob
|
||||||
|
<dd>LqItUzQMBgbWoNMNNavSLvNyBStVGUCWNjgQxghYZevZYvWuBcdweBUETsflAiXPPLxBFVHUOrdhFDARCngbRdLnHiytxFnSSpknmEvZDioBdxTRLnlAOcAfPKvODVUWJpstBLmtXskjWuBBHizDKXRtPobcLVyQHjtzKiFFMwzzOVnfHTqZGKKDQinlYgZDHzmWhHEKYwtDMmDiUKrZYARDIoceQDugJhrXVOZnAbbFneByTliWIpTsMWoVGGSAIzpBZXOvIihvSBcjABbCXEZIRblsPxJFUnuXrIDBFphHpFSzUrpsNUzbPXdLNBUAInuJifwtRigMdtzWGkvLAwYqIQmEetyEPSrMHNTBRLtZCJZPRcEdDQdEXdnILAAfNpwzEsVWPUzYJVBCVbUTVojLIviMzWRpMqpQotsYAqtDcFpe
|
||||||
|
</dl>
|
|
@ -0,0 +1 @@
|
||||||
|
Rat Fink
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
"""This is non-obvious, so let me elaborate. The message is translated to
|
||||||
|
binary with one character per binary bit. Lower case characters are 1's,
|
||||||
|
and upper case is 0. The letters are chosen at random. Tricky, eh?"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
lower = b'abcdefghijklmnopqrstuvwxyz'
|
||||||
|
upper = lower.upper()
|
||||||
|
|
||||||
|
plaintext = [b'The next puzzle starts in the same way, but the last step is '
|
||||||
|
b'different.',
|
||||||
|
b'We wouldn\'t want them to get stuck so early, would we? '
|
||||||
|
b'Rat Fink']
|
||||||
|
|
||||||
|
def encode(text):
|
||||||
|
out = bytearray()
|
||||||
|
mask = 0x80
|
||||||
|
for t in text:
|
||||||
|
for i in range(8):
|
||||||
|
if t & mask:
|
||||||
|
out.append(random.choice(lower))
|
||||||
|
else:
|
||||||
|
out.append(random.choice(upper))
|
||||||
|
t = t << 1
|
||||||
|
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
def decode(text):
|
||||||
|
out = bytearray()
|
||||||
|
i = 0
|
||||||
|
while i < len(text):
|
||||||
|
c = 0
|
||||||
|
mask = 0x80
|
||||||
|
for j in range(8):
|
||||||
|
if text[i] in lower:
|
||||||
|
c = c + mask
|
||||||
|
mask = mask >> 1
|
||||||
|
i = i + 1
|
||||||
|
out.append(c)
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
c = encode(plaintext[0])
|
||||||
|
print('<dl><dt>Alice<dd>', str(c, 'utf-8'))
|
||||||
|
assert decode(c) == plaintext[0]
|
||||||
|
c = encode(plaintext[1])
|
||||||
|
print('<dt>Bob<dd>', str(c, 'utf-8'), '</dl>')
|
||||||
|
assert decode(c) == plaintext[1]
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
'''This is the same as the previous, but it uses non-return to zero to encode
|
||||||
|
the binary.'''
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
lower = b'abcdefghijklmnopqrstuvwxyz'
|
||||||
|
upper = lower.upper()
|
||||||
|
|
||||||
|
plaintext = [b'The next one is in Morris Code. Unlike the previous two, '
|
||||||
|
b'they will actually need to determine some sort of key.',
|
||||||
|
b'Morris code with a key? That sounds bizarre. probable cause']
|
||||||
|
|
||||||
|
def encode(text):
|
||||||
|
out = bytearray()
|
||||||
|
mask = 0x80
|
||||||
|
state = 0
|
||||||
|
for t in text:
|
||||||
|
for i in range(8):
|
||||||
|
next = t & mask
|
||||||
|
if not state and not next:
|
||||||
|
out.append(random.choice(upper))
|
||||||
|
out.append(random.choice(lower))
|
||||||
|
elif not state and next:
|
||||||
|
out.append(random.choice(lower))
|
||||||
|
out.append(random.choice(upper))
|
||||||
|
elif state and not next:
|
||||||
|
out.append(random.choice(upper))
|
||||||
|
out.append(random.choice(lower))
|
||||||
|
elif state and next:
|
||||||
|
out.append(random.choice(lower))
|
||||||
|
out.append(random.choice(upper))
|
||||||
|
state = next
|
||||||
|
t = t << 1
|
||||||
|
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
def decode(text):
|
||||||
|
out = bytearray()
|
||||||
|
i = 0
|
||||||
|
while i < len(text):
|
||||||
|
c = 0
|
||||||
|
mask = 0x80
|
||||||
|
for j in range(8):
|
||||||
|
a = 0 if text[i] in lower else 1
|
||||||
|
b = 0 if text[i+1] in lower else 1
|
||||||
|
assert a != b, 'bad encoding'
|
||||||
|
if b:
|
||||||
|
c = c + mask
|
||||||
|
mask = mask >> 1
|
||||||
|
i = i + 2
|
||||||
|
out.append(c)
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
c = encode(plaintext[0])
|
||||||
|
print('<dl><dt>Alice<dd>', str(c, 'utf-8'))
|
||||||
|
assert decode(c) == plaintext[0]
|
||||||
|
c = encode(plaintext[1])
|
||||||
|
print('<dt>Bob<dd>', str(c, 'utf-8'), '</dl>')
|
||||||
|
assert decode(c) == plaintext[1]
|
|
@ -0,0 +1,2 @@
|
||||||
|
<dl><dt>Alice<dd> fj v jk taf phlp rpv zs z llo zy xq okb a fru rwzd uhjp ah mmnt je jvh pos r qnlx wsvm pvbr fpkx j dot sja obxxqy idpr csm o u thhh c vp h ihdo y zmm ia j tp cfs jxf yue uv h u kssx cn et bqk pw kzsc tc o u jgnt t mg gmy amr k hjp b pu br bkh dz tqk qtt xgxypy
|
||||||
|
<dt>Bob<dd> cy rurj xepn nt akxj rl jrrz c e oly nnt fu usiv rr dta wqyxnr goh sj aq ia m edvt fssp ps wtqd ohl r la rht szdupb </dl>
|
|
@ -0,0 +1 @@
|
||||||
|
giant chickens
|
|
@ -0,0 +1,90 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
"""This is morris code, except the dots and dashes are each represented by
|
||||||
|
many different possible characters. The 'encryption key' is the set of
|
||||||
|
characters that represent dots, and the set that represents dashes."""
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
dots = b'acdfhkjnpsrtx'
|
||||||
|
dashes = b'begilmoquvwyz'
|
||||||
|
|
||||||
|
morris = {'a': '.-',
|
||||||
|
'b': '-...',
|
||||||
|
'c': '-.-.',
|
||||||
|
'd': '-..',
|
||||||
|
'e': '.',
|
||||||
|
'f': '..-.',
|
||||||
|
'g': '--.',
|
||||||
|
'h': '....',
|
||||||
|
'i': '..',
|
||||||
|
'j': '.---',
|
||||||
|
'k': '-.-',
|
||||||
|
'l': '.-..',
|
||||||
|
'm': '--',
|
||||||
|
'n': '-.',
|
||||||
|
'o': '---',
|
||||||
|
'p': '.--.',
|
||||||
|
'q': '--.-',
|
||||||
|
'r': '.-.',
|
||||||
|
's': '...',
|
||||||
|
't': '-',
|
||||||
|
'u': '..-',
|
||||||
|
'v': '...-',
|
||||||
|
'w': '.--',
|
||||||
|
'x': '-..-',
|
||||||
|
'y': '-.--',
|
||||||
|
'z': '--..',
|
||||||
|
'.': '.-.-.-',
|
||||||
|
',': '--..--',
|
||||||
|
':': '---...'}
|
||||||
|
|
||||||
|
imorris = {}
|
||||||
|
for k in morris:
|
||||||
|
imorris[morris[k]] = k
|
||||||
|
|
||||||
|
plaintext = [b'it is fun to make up bizarre cyphers, but the next one is '
|
||||||
|
b'something a little more standard.',
|
||||||
|
b'all i have to say is: giant chickens.']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def encode(text):
|
||||||
|
out = bytearray()
|
||||||
|
for t in text:
|
||||||
|
if t == ord(' '):
|
||||||
|
out.extend(b' ')
|
||||||
|
else:
|
||||||
|
for bit in morris[chr(t)]:
|
||||||
|
if bit == '.':
|
||||||
|
out.append(random.choice(dots))
|
||||||
|
else:
|
||||||
|
out.append(random.choice(dashes))
|
||||||
|
out.append(ord(' '))
|
||||||
|
return bytes(out[:-1])
|
||||||
|
|
||||||
|
def decode(text):
|
||||||
|
text = text.replace(b' ', b'&')
|
||||||
|
# print(text)
|
||||||
|
words = text.split(b'&')
|
||||||
|
out = bytearray()
|
||||||
|
for word in words:
|
||||||
|
# print(word)
|
||||||
|
word = word.strip()
|
||||||
|
for parts in word.split(b' '):
|
||||||
|
code = []
|
||||||
|
for part in parts:
|
||||||
|
if part in dots:
|
||||||
|
code.append('.')
|
||||||
|
else:
|
||||||
|
code.append('-')
|
||||||
|
code = ''.join(code)
|
||||||
|
out.append(ord(imorris[code]))
|
||||||
|
out.append(ord(' '))
|
||||||
|
return bytes(out[:-1])
|
||||||
|
|
||||||
|
c = encode(plaintext[0])
|
||||||
|
print('<dl><dt>Alice<dd>', str(c, 'utf-8'))
|
||||||
|
assert decode(c) == plaintext[0]
|
||||||
|
c = encode(plaintext[1])
|
||||||
|
print('<dt>Bob<dd>', str(c, 'utf-8'), '</dl>')
|
||||||
|
assert decode(c) == plaintext[1]
|
|
@ -0,0 +1,2 @@
|
||||||
|
<dl><dt>Alice<dd> 1 11 eb 47 20 3f bf 11 20 eb d4 ef 11 20 a1 40 7b 34 ef ef 20 22 34 11 20 <BR>55 11 eb 47 34 98 11 c3 34 eb 11 eb 47 20 ef 11 da 3f 34 71 11 11 1 eb 11 <BR>3d 20 15 15 11 eb 99 bf 34 11 99 11 15 da eb 11 da 55 11 3d da 7b bf 11 eb <BR>da 11 c3 34 eb 11 20 eb 11 7b 20 c3 47 eb 71 11 11 5f 47 99 eb 11 20 ef f3 <BR>11 f1 3f 15 34 ef ef 11 eb 47 34 98 11 87 da 11 ef da a1 34 eb 47 20 3f c3 <BR>11 ef a1 99 7b eb 11 15 20 bf 34 11 c4 da 7b 7b 34 c4 eb 15 98 11 c3 f1 34 <BR>ef ef 11 eb 47 34 11 22 99 15 f1 34 11 da 55 11 ef 40 99 c4 34 ef 71 11 8f <BR>7b 34 6a f1 34 3f c4 98 11 c4 da f1 3f eb ef 11 3d da 3f d4 eb 11 be f1 ef <BR>eb 11 f 34 11 98 da f1 7b 11 55 7b 20 34 3f 87 11 47 34 7b 34 f3 11 20 eb <BR>d4 15 15 11 f 34 11 f1 ef 34 55 f1 15 11 20 3f 11 da eb 47 34 7b 11 40 15 <BR>99 c4 34 ef 11 eb da da 71
|
||||||
|
<dt>Bob<dd> 1 d4 a1 11 3f da eb 11 ef f1 7b 34 11 20 55 11 eb 47 99 eb d4 ef 11 34 3f <BR>da f1 c3 47 11 eb 34 90 eb 11 eb da 11 c3 20 22 34 11 eb 47 34 a1 11 eb 47 <BR>34 11 99 f 20 15 20 eb 98 11 eb da 11 a1 99 bf 34 11 99 11 c3 da da 87 11 <BR>55 7b 34 6a f1 34 3f c4 98 11 c4 da f1 3f eb 71 11 11 1 eb d4 ef 11 3f 20 <BR>c4 34 11 eb da 11 55 20 3f 99 15 15 98 11 f 34 11 99 eb 11 99 11 7b 34 99 <BR>15 11 c4 98 40 47 34 7b 11 eb 47 99 eb 11 99 15 15 da 3d ef 11 55 da 7b 11 <BR>eb 47 20 3f c3 ef 11 15 20 bf 34 11 40 7b da 40 34 7b 11 40 f1 3f c4 eb f1 <BR>99 eb 20 da 3f 11 99 3f 87 11 c4 99 40 20 eb 99 15 20 6f 99 eb 20 da 3f 71 <BR>11 8 3f 98 3d 99 98 f3 11 eb 47 34 11 bf 34 98 11 20 ef 6e 11 55 15 99 a1 <BR>20 3f c3 11 a1 99 ef eb 20 55 55 </dl>
|
|
@ -0,0 +1 @@
|
||||||
|
flaming mastiff
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import crypto
|
||||||
|
|
||||||
|
key = [43, 44, 227, 31, 255, 42, 194, 197, 187, 11, 92, 234, 57, 67, 45, 40, 66, 226, 214, 184, 167, 139, 210, 233, 22, 246, 150, 75, 186, 145, 86, 224, 17, 131, 24, 98, 74, 248, 213, 212, 72, 101, 160, 221, 243, 69, 113, 142, 127, 47, 141, 68, 247, 138, 124, 177, 192, 165, 110, 107, 203, 207, 254, 176, 154, 8, 87, 189, 228, 155, 143, 0, 220, 1, 128, 3, 169, 204, 162, 90, 156, 208, 170, 222, 95, 223, 188, 215, 174, 78, 48, 50, 244, 116, 179, 134, 171, 153, 15, 196, 135, 52, 85, 195, 71, 32, 190, 191, 21, 161, 63, 218, 64, 106, 123, 239, 235, 241, 34, 61, 144, 152, 111, 20, 172, 117, 237, 120, 80, 88, 200, 185, 109, 137, 37, 159, 183, 30, 202, 129, 250, 58, 9, 193, 41, 164, 65, 126, 46, 158, 132, 97, 166, 6, 23, 147, 105, 29, 38, 119, 76, 238, 240, 12, 201, 245, 230, 14, 206, 114, 10, 25, 60, 83, 236, 18, 231, 39, 77, 55, 252, 229, 100, 7, 28, 209, 51, 148, 181, 198, 225, 118, 173, 103, 35, 149, 91, 108, 219, 168, 140, 49, 33, 122, 82, 216, 53, 205, 13, 73, 249, 180, 81, 19, 112, 232, 217, 96, 62, 99, 4, 26, 178, 211, 199, 151, 102, 121, 253, 136, 130, 104, 133, 146, 89, 5, 157, 70, 84, 242, 182, 93, 251, 54, 16, 175, 56, 115, 94, 36, 27, 79, 59, 163, 125, 2]
|
||||||
|
ikey = [None]*256
|
||||||
|
for i in range(256):
|
||||||
|
ikey[key[i]] = i
|
||||||
|
|
||||||
|
alice = b'''I think it's impressive if they get this one. It will take a lot of work to get it right. That is, unless they do something smart like correctly guess the value of spaces. Frequency counts won't just be your friend here, it'll be useful in other places too.'''
|
||||||
|
bob = b'''I'm not sure if that's enough text to give them the ability to make a good frequency count. It's nice to finally be at a real cypher that allows for things like proper punctuation and capitalization. Anyway, the key is: flaming mastiff'''
|
||||||
|
|
||||||
|
def sbox(text, key):
|
||||||
|
out = bytearray()
|
||||||
|
for t in text:
|
||||||
|
out.append(key[t])
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
encode = lambda t: sbox(t, key)
|
||||||
|
decode = lambda t: sbox(t, ikey)
|
||||||
|
|
||||||
|
crypto.mkIndex(encode, decode, alice, bob, crypto.hexFormat)
|
|
@ -0,0 +1,2 @@
|
||||||
|
<dl><dt>Alice<dd> e8 c3 8c d5 c3 d9 8c d8 c4 c5 c2 c7 8c d8 c4 c9 d5 8b c0 c0 8c d8 de d5 8c <BR>cd c2 c3 d8 c4 c9 de 8c ca de c9 dd d9 c9 c2 cf d5 8c cf c3 d9 c2 d8 93 8c <BR>8c e5 d8 8c c1 c5 cb c4 d8 8c ce c9 8c ce c9 d8 d8 c9 de 8c c5 ca 8c d8 c4 <BR>c9 d5 8c c6 d9 df d8 8c c0 c3 c3 c7 c9 c8 8c ca c3 de 8c dc cd d8 d8 c9 de <BR>c2 df 82
|
||||||
|
<dt>Bob<dd> f5 c3 d9 8b c8 8c ce c9 8c cd c1 cd d6 c9 c8 8c cd d8 8c c4 c3 db 8c c3 ca <BR>d8 c9 c2 8c d8 c4 c5 df 8c c5 df 8c d9 df c9 c8 8c c5 c2 8c c0 c5 c9 d9 8c <BR>c3 ca 8c de c9 cd c0 8c cf de d5 dc d8 c3 82 8c 8c e5 d8 8b df 8c cd ce c3 <BR>d9 d8 8c cd df 8c c9 ca ca c9 cf d8 c5 da c9 8c cd df 8c cd 8c cf c9 cd df <BR>cd de 8c cf d5 dc c4 c9 de 82 8c 8c cf c4 de c3 c2 c5 cf 8c ca cd c5 c0 d9 <BR>de c9 </dl>
|
|
@ -0,0 +1 @@
|
||||||
|
chronic failure
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import crypto
|
||||||
|
|
||||||
|
alice = b'''Do you think they'll try another frequency count? It might be better if they just looked for patterns.'''
|
||||||
|
bob = b'''You'd be amazed at how often this is used in lieu of real crypto. It's about as effective as a ceasar cypher. chronic failure'''
|
||||||
|
|
||||||
|
key = 0xac
|
||||||
|
|
||||||
|
def encode(text):
|
||||||
|
out = bytearray()
|
||||||
|
for t in text:
|
||||||
|
out.append(t ^ key)
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
crypto.mkIndex(encode, encode, alice, bob, crypto.hexFormat)
|
|
@ -0,0 +1,2 @@
|
||||||
|
<dl><dt>Alice<dd> x_tee tnhpu __our faez_ lrszt<BR>le_ar l_ipa sston p_iyn hcok_<BR>eisel roi__ hnsta _er_n t.iss<BR>tooip elnk_ _i,ts sibit u__os<BR>,sins ltule _iond mid__ y_ern<BR>pcrts ts_ey o__m_ .__s
|
||||||
|
<dt>Bob<dd> ontpa ssrco i_iyn torp_ efshr<BR>_tonk wett_ _ihhw _eett ax_dn<BR>rea_g rloib to_n_ _cfsa okir_<BR>aentc ,d_hi _twae o_tsn fmt_r<BR>eied_ _nydt be.kh y__ee in_la<BR>ngdsa gtp_r _t_af eeore andpd<BR>d_nt_ _iuhw __lrs rolto a_dem<BR>nr_xe .rtt_ iigys nf_ni ee_cl<BR> </dl>
|
|
@ -0,0 +1 @@
|
||||||
|
terrifying silence
|
|
@ -0,0 +1,30 @@
|
||||||
|
import crypto
|
||||||
|
|
||||||
|
alpha = b'abcdefghiklmnoprstuw'
|
||||||
|
|
||||||
|
alice = b'''The next four puzzles are all transposition cyphers like this one. Transposition, like substition, is still used in modern crypto systems. '''
|
||||||
|
bob = b'''Transposition cyphers often work with the text arranged into blocks of a certain width, often as determined by the key. Dangling parts are often padded with nulls or random text. terrifying silence '''
|
||||||
|
alice = alice.replace(b' ', b'_').lower()
|
||||||
|
bob = bob.replace(b' ', b'_').lower()
|
||||||
|
|
||||||
|
map = [6, 3, 0, 5, 2, 7, 4, 1]
|
||||||
|
imap = [2, 7, 4, 1, 6, 3, 0, 5]
|
||||||
|
|
||||||
|
def transform(text, map):
|
||||||
|
assert len(text) % 8 == 0, 'Text must be multiple of 8 in length. '\
|
||||||
|
'%d more chars needed.' % (8 - len(text) % 8)
|
||||||
|
|
||||||
|
out = bytearray()
|
||||||
|
i = 0
|
||||||
|
while i < len(text):
|
||||||
|
for j in range(8):
|
||||||
|
out.append( text[i + map[j]] )
|
||||||
|
i = i+8
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
encode = lambda t : transform(t, map)
|
||||||
|
decode = lambda t : transform(t, imap)
|
||||||
|
|
||||||
|
crypto.mkIndex(encode, decode, alice, bob, crypto.groups)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
b"t_iwey_6hf_ussre'd_sysuysoshfsan_3_eonz_t.tr_noiutp_nteo_st0_7_rezmr__ewo_nbihade_ro_i_4.k_xluo_t_etagsoe_apk_nea1__ettecnihg'_p_tnrsr.etesl_5_yh__hg_elrapai__ey_yh_sl2_t_epi_ebyaell_tcac__"
|
||||||
|
<dl><dt>Alice<dd> t_iwe y_6hf _ussr e'd_s ysuys<BR>oshfs an_3_ eonz_ t.tr_ noiut<BR>p_nte o_st0 _7_re zmr__ ewo_n<BR>bihad e_ro_ i_4.k _xluo _t_et<BR>agsoe _apk_ nea1_ _ette cnihg<BR>'_p_t nrsr. etesl _5_yh __hg_<BR>elrap ai__e y_yh_ sl2_t _epi_<BR>ebyae ll_tc ac__
|
||||||
|
<dt>Bob<dd> it_tt e_t_i toti_ etz_e _hm_h<BR>_ahgt __hl_ yhztn taeue blmu_<BR>bhelt _ilht atas_ ag.ew ean_h<BR>fseie k_nes so_so _r,ie o__sn<BR>et_sa ir_sn td_t_ rpi_c _oi_m<BR>cii_' o_w?k _usse </dl>
|
|
@ -0,0 +1 @@
|
||||||
|
The key for this puzzle is this sentence
|
|
@ -0,0 +1,47 @@
|
||||||
|
import crypto
|
||||||
|
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
width = 7
|
||||||
|
|
||||||
|
alice = b'''The key for this one was essentially 0 1 2 3 4 5 6 7. The key for the next puzzle is much stronger. I bet they're glad we're not also applying a substitution cypher as a secondary step. '''
|
||||||
|
bob = b'''I take that to mean it uses the same basic algorithm. I guess it won't be too hard then, will it? The key for this puzzle is this sentence'''
|
||||||
|
alice = alice.lower().replace(b' ', b'_')
|
||||||
|
bob = bob.lower().replace(b' ', b'_')
|
||||||
|
|
||||||
|
def rotate(text):
|
||||||
|
out = bytearray()
|
||||||
|
assert len(text) % width == 0, 'At %d of %d.' % (len(text) % width, width)
|
||||||
|
|
||||||
|
slices = [bytearray(text[i:i+width]) for i in range(0, len(text), width)]
|
||||||
|
nextSlice = slices.pop(0)
|
||||||
|
while len(out) < len(text):
|
||||||
|
if nextSlice:
|
||||||
|
out.append(nextSlice.pop(0))
|
||||||
|
slices.append(nextSlice)
|
||||||
|
nextSlice = slices.pop(0)
|
||||||
|
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
def unrotate(text):
|
||||||
|
out = bytearray()
|
||||||
|
assert len(text) % width == 0
|
||||||
|
|
||||||
|
slices = []
|
||||||
|
for i in range(len(text) // width):
|
||||||
|
slices.append([])
|
||||||
|
|
||||||
|
inText = bytearray(text)
|
||||||
|
while inText:
|
||||||
|
slice = slices.pop(0)
|
||||||
|
slice.append(inText.pop(0))
|
||||||
|
slices.append(slice)
|
||||||
|
|
||||||
|
for slice in slices:
|
||||||
|
out.extend(slice)
|
||||||
|
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
print(rotate(alice))
|
||||||
|
|
||||||
|
crypto.mkIndex(rotate, unrotate, alice, bob, crypto.groups)
|
|
@ -0,0 +1,2 @@
|
||||||
|
<dl><dt>Alice<dd> e_mse o_rtt pii'i n_dru ueu._<BR>ieron niosn i,ot_ nuvi_ toowd<BR>_idcg o__st _nhae legoh lnfdh<BR>rceir tiasn d_koo efe_s ii_to<BR>__dp_ hroo_ tnyw_ _rt_t
|
||||||
|
<dt>Bob<dd> 'slu_ cnnmo eeq_b gutnn tptn_<BR>st_s_ sodsp ioyr; __r_r fmssl<BR>oiss. aiimn abato ebify t_nso<BR>i_til wamio asnte ensfn necoh<BR>on_tt _shtc na_ol ssloi talrf<BR>_io__ hti.m nsioo i_uor ni)is<BR>_n_u_ c_rgy utto_ o__ia ftase<BR>tt_ro h_c__ hmton _ehec nasta<BR>__rt( rooai ha'fo il_tp yao_e<BR>dacai imnpb _iaft tsiye toa_a<BR>fscu_ i_bu_ ghea_ tpisf thnii<BR>rpfpa _wtyg i_utt _ro_i _tcna<BR> </dl>
|
|
@ -0,0 +1,42 @@
|
||||||
|
import crypto
|
||||||
|
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
width = 5
|
||||||
|
|
||||||
|
alice = b'''If we did the morris code encoding prior to this transposition, I don't think anyone would ever figure out the solution.'''
|
||||||
|
bob = b'''That's basically true of the combination of many of these techniques. Combining a substitution along with a permutation (or transposition) satisfies the Shannon's diffusion principle of cryptography; you want to try to get rid of as much statistical information as possible. statistical information'''
|
||||||
|
alice = alice.lower().replace(b' ', b'_')
|
||||||
|
bob = bob.lower().replace(b' ', b'_')
|
||||||
|
|
||||||
|
key = [4,2,3,1,0]
|
||||||
|
|
||||||
|
def rotate(text):
|
||||||
|
out = bytearray()
|
||||||
|
assert len(text) % width == 0, 'At %d of %d.' % (len(text) % width, width)
|
||||||
|
|
||||||
|
slices = [bytearray(text[i:i+width]) for i in range(0, len(text), width)]
|
||||||
|
for i in range(width):
|
||||||
|
for slice in slices:
|
||||||
|
out.append(slice[key[i]])
|
||||||
|
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
def unrotate(text):
|
||||||
|
out = bytearray()
|
||||||
|
assert len(text) % width == 0
|
||||||
|
|
||||||
|
# Make column slices, and rearrange them according to the key.
|
||||||
|
size = len(text) // width
|
||||||
|
tSlices = [bytearray(text[i*size:i*size+size]) for i in range(width)]
|
||||||
|
slices = [None] * width
|
||||||
|
for i in range(width):
|
||||||
|
slices[key[i]] = tSlices[i]
|
||||||
|
|
||||||
|
while len(out) < len(text):
|
||||||
|
for i in range(5):
|
||||||
|
out.append(slices[i].pop(0))
|
||||||
|
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
crypto.mkIndex(rotate, unrotate, alice, bob, crypto.groups)
|
|
@ -0,0 +1,34 @@
|
||||||
|
def mkIndex(encode, decode, alice, bob,
|
||||||
|
format=lambda s: str(s, 'utf-8')):
|
||||||
|
"""Write out the index.html contents.
|
||||||
|
@param encode: function to encrypt the plaintext
|
||||||
|
@param decode: function to decrypt the plaintext
|
||||||
|
@param alice: plaintext of alice line
|
||||||
|
@param bob: plaintext of bob line
|
||||||
|
@param format: formatter for the cypher text, run out output of encode before
|
||||||
|
printing. Does string conversion by default."""
|
||||||
|
c = encode(alice)
|
||||||
|
print('<dl><dt>Alice<dd>', format(c))
|
||||||
|
assert decode(c) == alice
|
||||||
|
c = encode(bob)
|
||||||
|
print('<dt>Bob<dd>', format(c), '</dl>')
|
||||||
|
assert decode(c) == bob
|
||||||
|
|
||||||
|
def hexFormat(text):
|
||||||
|
return groups(text, 5, '{0:x} ')
|
||||||
|
|
||||||
|
def groups(text, perLine=5, format='{0:c}'):
|
||||||
|
i = 0
|
||||||
|
out = []
|
||||||
|
while i < len(text):
|
||||||
|
out.append(format.format(text[i]))
|
||||||
|
|
||||||
|
if i % (perLine*5) == (perLine * 5 - 1):
|
||||||
|
out.append('<BR>')
|
||||||
|
elif i % 5 == 4:
|
||||||
|
out.append(' ')
|
||||||
|
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
return ''.join(out)
|
||||||
|
|
Loading…
Reference in New Issue