Rastislav Krivoš-Belluš

KRS - Kryptografické systémy a ich aplikácie (doc. RNDr. Jozef Jirásek, PhD.)

Lab 01

  1. How many keys are there for enciphering in English/Slovak/Uzbek alphabet?
    • monoalphabetic substitution cipher
    • affine cipher (Maple: ? numtheory[phi], Maxima: ? totient, Python: ? sympy.totient)
    • polygraphic substitution cipher of length 4
  2. Following ciphertext was encrypted using affine cipher. First two letters of plaintext are if. Decipher.
    NEJFX VPCOB PYUKN RUKPC TPUBP VKBO
  3. Decipher (monoalphabetic substitution cipher):
    1. cipher in image
    2. Zgyzhs rh z hrnkov hfyhgrgfgrlm xrksvi uli gsv Svyivd zokszyvg.

Lab 02

  1. Decipher (shift cipher of english text)
    1. frequence analysis
    2. frequence cross-correlation
    Dolu fvb dlyl h ahkwvsl huk P dhz h mpzo Pu aol Whslvgvpj aptl, Huk zpkl if zpkl vu aol liipun apkl Dl zwyhdslk aoyvbno aol vvgl huk zsptl, Vy zrpaalylk dpao thuf h jhbkhs mspw aoyvbno aol klwaoz vm Jhtiyphu mlu Tf olhya dhz ypml dpao aol qvf vm spml, Mvy P svclk fvb lclu aolu.
    eng_freq = [ .082, .015, .028, .043, .127, .022, .020, .061, .070, .002, .008, .040, .024, .067, .075, .019, .001, .060, .063, .091, .028, .010, .023, .001, .020, .001]
  2. Decipher (english text, Vigenere)
    opkjcpcsrqtkhespzxxsjmuinieiovvryaaqaeicjnystxnemmbyzrvvvjo pwxzinqjibxzjdmjfsxnizvjiqidfzzymlxyeiljiqidfzzzaspwxcbnihe spzxxsjmuinbnijiehjzutsvrxdvmwmwkihaujharvzvgqsgfqhwtroqvsa bnijycrzzgfwpzxtxuxsrkmvtxmgorxopkxwqvsaxafzmteoquroruxcmic piirjbkwwwjyzqtavmtlopkzipeimihmzmkcvxviovvhnwlxkeiiqmxwwse wvzkmriexdnoirmwoiwcrhlzwdvlsfqrxdwtmgtiinmtxshfrgggwowlqhi xcqsdtgmzirikedtyefirzvqreppvjmwsxvijspziiwrumxizirmexcmkrr rfxzxriowvrjbkxvekiqmtmtxyihmzlchfjvbzeqoyenvuxpivrpbopwdvh jzgrsbgpjqzwqvztoqyrcxtymzkrhppadlkpmemedtgfzifropkmbxvvimz edskiiboezzlpimxepmcmognegfviiqjibxzjdmjydhrxzazswxvqnivtse imioordvvzdwawwwjyzaujqcsimvuxswrvztowhiumijuprrvadvlsfqrxd wtgcrkedvkhwrklzcvhoxvadtredtvemqtmhecmxqfirgfpjzkhhioxrpkv segtgqieppvxcmzeppvpdazwogmiicsfsvzrmmjavmtlxwxvswgsilyxcxy ixwsqcrmygvkvofzpdboigeehzfvsgyiinkbizmjxvkuqdmceoqurcjjxvv jefhzdzlteaijjjzbyzrvvvjopwxzinithcxyimqtjcvdeoqurgitymqzcs bgsncxig

Lab 03

Jupyter notebook for Lab03
  1. Compute the sequence, which you get by modular sum of two LFSRs. What is the period of resulting sequence?
    ai+5 = ai+1, IV = [0, 1, 1, 0, 1]
    bi+2 = bi + bi+1, IV = [0, 1]
    ci = ai + bi
  2. Find the minimal LFSR which generates the resulting sequence from the previous task (c) (using Berlekamp-Massey algorithm). Encrypt and decrypt the text in format 'NAME (KRS2026) SURNAME' with this LFSR. Use ASCII table, 8-bit encoding.
  3. You have seen LFSR's xor-ed ciphertext '5398eb7d7a2198e295f1e822a0e244e7c52d27010e425e3c4046212be3384fd4b7ee7b410b7ecd4d6e4d6986c51097c42366d41e1d' (hex). Decode the whole plaintext, if you know that (partial) plaintext from (0-indexed) byte 14 was 'LFSR is not secure'.
    ciphertext = b'S\x98\xeb}z!\x98\xe2\x95\xf1\xe8"\xa0\xe2D\xe7\xc5-\'\x01\x0eB^<@F!+\xe38O\xd4\xb7\xee{A\x0b~\xcdMnMi\x86\xc5\x10\x97\xc4#f\xd4\x1e\x1d'

Lab 04

  1. Show that pycryptodome implementations work correctly for test vectors [or javax.crypto.Cipher in Java, list of ciphers]:
    1. RC4 (RFC 6229)
      !pip install pycryptodome
      from base64 import b64encode
      from Crypto.Random import get_random_bytes

      bytes.fromhex('0102030405')

      from Crypto.Cipher import ARC4
      cipher = ARC4.new(b'Key')
      ct = cipher.encrypt(b'Plaintext')
      ''.join(f'{c:02X}' for c in ct)
    2. ChaCha20 (RFC 7539)
      from Crypto.Cipher import ChaCha20
      cipher = ChaCha20.new(b'Key')
      ct = cipher.encrypt(b'Plaintext') #'\0'
    3. ChaCha20-Poly1305 (RFC 7539)
      from Crypto.Cipher import ChaCha20_Poly1305
    4. DES (Validating the Correctness of Hardware Implementations of the NBS Data Encryption Standard, data)
      from Crypto.Cipher import DES
      key = b'-8B key-'
      cipher = DES.new(key, DES.MODE_ECB)
      plaintext = b'KRS 2026'
      cipher.encrypt(plaintext)
  2. Choose plaintext (the same for all ciphers from the previous task, e.g. 128 bits long). Compute how many bits of ciphertext are changed if you change just one bit of the plaintext.
    n ^ 64 #invert one bit
    bin(n) #binary string
    bin(7).count('1') #number of ONEs
    7.bit_count() #number of ones, Python 3.10+

Lab 05

  1. Encipher some text, which length is not multiple of 8. Try different modes of padding.
    from Crypto.Util.Padding import pad, unpad
    from Crypto.Cipher import AES, DES
    from Crypto.Random import get_random_bytes
    from base64 import b64encode, b64decode

    #encryption
    data = b'TestUPJS'
    key = get_random_bytes(8)
    cipher = DES.new(key, DES.MODE_ECB)
    ct = cipher.encrypt(data)
    print(ct)
    print(b64encode(ct).decode('utf-8'))

    #decryption
    decipher = DES.new(key, DES.MODE_ECB)
    pt = decipher.decrypt(ct)
    print(pt)
  2. Display ciphertext encrypted in several modes ECB/CBC/OFB/CFB/CTR/OPENPGP (In Java you can use AES.GCM instead of OPENPGP) using the same key. Find the differencies in decrypted text after changing one bit in ciphertext for several modes of block cipher. Use at least 3 blocks and change bit in the second one.
    def wrap(text, size=8):
      for i in range((len(text)+size-1) // size):
        print(*[f'{c:02X}' for c in text[i*size:(i+1)*size]])

    DES.new(..., DES.MODE_CBC, iv=?)

    rb = get_random_bytes(8)
    cipher = DES.new(rb, DES.MODE_OPENPGP, iv=get_random_bytes(8))
    ct = cipher.encrypt(b'abcd1234')
    decipher = DES.new(rb, DES.MODE_OPENPGP, iv=ct[:10])
    pt = decipher.decrypt(ct[10:])

    from Crypto.Util import Counter

    rb = get_random_bytes(8)
    nonce = get_random_bytes(4)
    cipher = DES.new(rb, DES.MODE_CTR, counter=Counter.new(32, prefix=nonce))
    ct = cipher.encrypt(b'abcd1234')
    decipher = DES.new(rb, DES.MODE_CTR, counter=Counter.new(32, prefix=nonce))
    pt = decipher.decrypt(ct)
    Bonus*: Use modern modes of operation for AES.

Key Derivation Functions