Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ic:labs:03 [2022/10/14 23:59]
razvan.smadu
ic:labs:03 [2023/10/16 20:53] (current)
razvan.smadu
Line 1: Line 1:
 ===== Laboratorul 03 - PRGs ===== ===== Laboratorul 03 - PRGs =====
  
-Prezentarea PowerPoint pentru acest laborator poate fi găsită [[https://​drive.google.com/​file/​d/​1IfyMkfV6jQDzW5KhS_B6wt_azV31SLjL/​view?​usp=sharing|aici]].+Prezentarea PowerPoint pentru acest laborator poate fi găsită [[https://​drive.google.com/​file/​d/​1IfyMkfV6jQDzW5KhS_B6wt_azV31SLjL/​view?​usp=sharing|aici]]. Puteți găsi o scurtă prezentare a noțiunii de avantaje în [[https://​drive.google.com/​file/​d/​1F_mtKi0zeAn1xYQs6Wc7IiiVX8ZW6aeG/​view?​usp=sharing|acest]] PDF.
  
  
-Puteți lucra acest laborator folosind ​și platforma Google Colab, accesând [[https://​colab.research.google.com/​drive/1dT6VieWJ1QeMLkb0UY3bAuKvTnkRmWBq?​usp=sharing+Puteți lucra acest laborator folosind platforma Google Colab, accesând [[https://​colab.research.google.com/​github/ACS-IC-labs/​IC-labs/​blob/​main/​labs/​lab03/​lab3.ipynb
 |acest]] link. |acest]] link.
  
 +<​hidden>​ 
 +<spoiler Click pentru a vedea utils.py>​
 <file python utils.py>​ <file python utils.py>​
 import base64 import base64
 +from typing import Generator
  
-# CONVERSION FUNCTIONS 
  
-def _chunks(stringchunk_size): +def _pad(data: strsize: int-> str
-    ​for i in range(0, ​len(string), chunk_size): +    ​reminder = len(data% size 
-        ​yield string[i:i+chunk_size]+    if reminder != 0
 +        ​data = "​0"​ * (size - reminder) ​data 
 +    return data
  
-def _hex(x): 
-    return format(x, '​02x'​) 
  
-def hex_2_bin(data): +def _chunks(data: str, chunk_size: int-> Generator[str,​ None, None]
-    ​return ''​.join(f'​{int(x16):​08b}' ​for in _chunks(data, ​2))+    ​data = _pad(datachunk_size) 
 +    ​for in range(0, len(data)chunk_size)
 +        yield data[i : i + chunk_size]
  
-def str_2_bin(data):​ 
-    return ''​.join(f'​{ord(c):​08b}'​ for c in data) 
  
-def bin_2_hex(data): +def _hex(data: int-> str
-    return ​''​.join(f'​{int(b2):02x}' for b in _chunks(data,​ 8))+    return ​format(data"02x")
  
-def str_2_hex(data):​ 
-    return ''​.join(f'​{ord(c):​02x}'​ for c in data) 
  
-def bin_2_str(data):​ +# Conversion functions
-    return ''​.join(chr(int(b,​ 2)) for b in _chunks(data,​ 8))+
  
-def hex_2_str(data):​ 
-    return ''​.join(chr(int(x,​ 16)) for x in _chunks(data,​ 2)) 
  
-# XOR FUNCTIONS+def hex_2_bin(data:​ str) -> str: 
 +    """​Converts a hexadecimal string to a binary representation.
  
-def strxor(a, b):  # xor two strings, trims the longer input +    Args: 
-    ​return ''​.join(chr(ord(x) ^ ord(y)) for (xy) in zip(a, b))+        data (str): The hexadecimal string to be converted. It should have an 
 +            even number of characters and only contain valid hexadecimal digits 
 +            ​(0-9, A-F, a-f).
  
-def bitxor(a, b) # xor two bit-stringstrims the longer input +    Returns: 
-    ​return ''​.join(str(int(x) ^ int(y)) for (x, y) in zip(a, b))+        str: The binary representation of the hexadecimal stringwhere each 
 +            pair of hexadecimal digits is encoded as an 8-bit binary number.
  
-def hexxor(a, b):  # xor two hex-strings,​ trims the longer input +    Examples: 
-    return ​''​.join(_hex(int(x, 16) ^ int(y, 16)) for (x, y) in zip(_chunks(a, 2), _chunks(b, 2)))+        >>>​ hex_2_bin("​01abcd"​) 
 +        '​000000011010101111001101'​ 
 +        >>>​ hex_2_bin("​0a"​) 
 +        '​00001010'​ 
 +    """​ 
 +    return ​""​.join(f"{int(x, 16):​08b}" ​for x in _chunks(data, 2))
  
-# BASE64 FUNCTIONS 
  
-def b64decode(data): +def bin_2_hex(data: str-> str
-    ​return bytes_to_string(base64.b64decode(string_to_bytes(data)))+    ​"""​Converts a binary string to a hexadecimal representation.
  
-def b64encode(data):​+    Args: 
 +        data (str): The binary string to be converted. It should have a multiple 
 +            of 8 characters and only contain valid binary digits (0 or 1). 
 + 
 +    Returns: 
 +        str: The hexadecimal representation of the binary string, where each 
 +            group of 8 binary digits is encoded as a pair of hexadecimal digits. 
 + 
 +    Examples: 
 +        >>>​ bin_2_hex("​000000011010101111001101"​) 
 +        '​01abcd'​ 
 +        >>>​ bin_2_hex("​00001010"​) 
 +        '​0a'​ 
 +    """​ 
 +    return ""​.join(f"​{int(b,​ 2):​02x}"​ for b in _chunks(data,​ 8)) 
 + 
 + 
 +def str_2_bin(data:​ str) -> str: 
 +    """​Converts a string to a binary representation. 
 + 
 +    Args: 
 +        data (str): The string to be converted. 
 + 
 +    Returns: 
 +        str: The binary representation of the string, where each character is 
 +            encoded as an 8-bit binary number. 
 + 
 +    Examples: 
 +        >>>​ str_2_bin("​Hello"​) 
 +        '​0100100001100101011011000110110001101111'​ 
 +        >>>​ str_2_bin("​IC"​) 
 +        '​0100100101000011'​ 
 +    """​ 
 +    return ""​.join(f"​{ord(c):​08b}"​ for c in data) 
 + 
 + 
 +def bin_2_str(data:​ str) -> str: 
 +    """​Converts a binary string to a string. 
 + 
 +    Args: 
 +        data (str): The binary string to be converted. It should have a multiple 
 +            of 8 characters and only contain valid binary digits (0 or 1). 
 + 
 +    Returns: 
 +        str: The string representation of the binary string, where each group 
 +            of 8 binary digits is decoded as a character. 
 + 
 +    Examples: 
 +        >>>​ bin_2_str("​0100100001100101011011000110110001101111"​) 
 +        '​Hello'​ 
 +        >>>​ bin_2_str("​0100100101000011"​) 
 +        '​IC'​ 
 +    """​ 
 +    return ""​.join(chr(int(b,​ 2)) for b in _chunks(data,​ 8)) 
 + 
 + 
 +def str_2_hex(data:​ str) -> str: 
 +    """​Converts a string to a hexadecimal representation. 
 + 
 +    Args: 
 +        data (str): The string to be converted. 
 + 
 +    Returns: 
 +        str: The hexadecimal representation of the string, where each character 
 +            is encoded as a pair of hexadecimal digits. 
 + 
 +    Examples: 
 +        >>>​ str_2_hex("​Hello"​) 
 +        '​48656c6c6f'​ 
 +        >>>​ str_2_hex("​IC"​) 
 +        '​4943'​ 
 +    """​ 
 +    return ""​.join(f"​{ord(c):​02x}"​ for c in data) 
 + 
 + 
 +def hex_2_str(data:​ str) -> str: 
 +    """​Converts a hexadecimal string to a string. 
 + 
 +    Args: 
 +        data (str): The hexadecimal string to be converted. It should have an 
 +            even number of characters and only contain valid hexadecimal digits 
 +            (0-9, A-F, a-f). 
 + 
 +    Returns: 
 +        str: The string representation of the hexadecimal string, where each 
 +            pair of hexadecimal digits is decoded as a character. 
 + 
 +    Examples: 
 +        >>>​ hex_2_str("​48656c6c6f"​) 
 +        '​Hello'​ 
 +        >>>​ hex_2_str("​4943"​) 
 +        '​IC'​ 
 +    """​ 
 +    return ""​.join(chr(int(x,​ 16)) for x in _chunks(data,​ 2)) 
 + 
 + 
 +# XOR functions 
 + 
 + 
 +def strxor(operand_1:​ str, operand_2: str) -> str: 
 +    """​Performs a bitwise exclusive OR (XOR) operation on two strings. 
 + 
 +    Args: 
 +        operand_1 (str): The first string to be XORed. 
 +        operand_2 (str): The second string to be XORed. 
 + 
 +    Returns: 
 +        str: The result of the XOR operation on the two strings, where each 
 +            character is encoded as an 8-bit binary number. The result has 
 +            the same length as the shorter input string. 
 + 
 +    Examples: 
 +        >>>​ strxor("​Hello",​ "​IC"​) 
 +        '​\\x01&'​ 
 +        >>>​ strxor("​secret",​ "​key"​) 
 +        '​\\x18\\x00\\x1a'​ 
 +    """​ 
 +    return ""​.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(operand_1,​ operand_2)) 
 + 
 + 
 +def bitxor(operand_1:​ str, operand_2: str) -> str: 
 +    """​Performs a bitwise exclusive OR (XOR) operation on two bit-strings. 
 + 
 +    Args: 
 +        operand_1 (str): The first bit-string to be XORed. It should only 
 +            contain valid binary digits (0 or 1). 
 +        operand_2 (str): The second bit-string to be XORed. It should only 
 +            contain valid binary digits (0 or 1). 
 + 
 +    Returns: 
 +        str: The result of the XOR operation on the two bit-strings,​ where each 
 +            bit is encoded as a character. The result has the same length as 
 +            the shorter input bit-string. 
 + 
 +    Examples: 
 +        >>>​ bitxor("​01001000",​ "​01000010"​) 
 +        '​00001010'​ 
 +        >>>​ bitxor("​10101010",​ "​00110011"​) 
 +        '​10011001'​ 
 +    """​ 
 +    return ""​.join(str(int(x) ^ int(y)) for (x, y) in zip(operand_1,​ operand_2)) 
 + 
 + 
 +def hexxor(operand_1:​ str, operand_2: str) -> str: 
 +    """​Performs a bitwise exclusive OR (XOR) operation on two hexadecimal 
 +    strings. 
 + 
 +    Args: 
 +        operand_1 (str): The first hexadecimal string to be XORed. It should 
 +            have an even number of characters and only contain valid hexadecimal 
 +            digits (0-9, A-F, a-f). 
 +        operand_2 (str): The second hexadecimal string to be XORed. It should 
 +            have an even number of characters and only contain valid 
 +            digits (0-9, A-F, a-f). 
 + 
 +    Returns: 
 +        str: The result of the XOR operation on the two hexadecimal strings, 
 +            where each pair of hexadecimal digits is encoded as a pair of 
 +            hexadecimal digits. The result has the same length as the shorter 
 +            input hexadecimal string. 
 + 
 +    Examples: 
 +        >>>​ hexxor("​48656c6c6f",​ "​42696e67"​) 
 +        '​0a0c020b'​ 
 +        >>>​ hexxor("​736563726574",​ "​6b6579"​) 
 +        '​18001a'​ 
 +    """​ 
 +    return ""​.join( 
 +        _hex(int(x, 16) ^ int(y, 16)) 
 +        for (x, y) in zip(_chunks(operand_1,​ 2), _chunks(operand_2,​ 2)) 
 +    ) 
 + 
 + 
 +# Python3 '​bytes'​ functions 
 + 
 + 
 +def bytes_to_string(bytes_data:​ bytearray | bytes) -> str: 
 +    """​Converts a byte array or a byte string to a string. 
 + 
 +    Args: 
 +        bytes_data (bytearray | bytes): The byte array or the byte string to be 
 +            converted. It should be encoded in Latin-1 format. 
 + 
 +    Returns: 
 +        str: The string representation of the byte array or the byte string, 
 +            decoded using Latin-1 encoding. 
 + 
 +    Examples: 
 +        >>>​ bytes_to_string(b'​Hello'​) 
 +        '​Hello'​ 
 +        >>>​ bytes_to_string(bytearray(b'​IC'​)) 
 +        '​IC'​ 
 +    """​ 
 +    return bytes_data.decode(encoding="​raw_unicode_escape"​) 
 + 
 + 
 +def string_to_bytes(string_data:​ str) -> bytes: 
 +    """​Converts a string to a byte string. 
 + 
 +    Args: 
 +        string_data (str): The string to be converted. 
 + 
 +    Returns: 
 +        bytes: The byte string representation of the string, encoded using 
 +        Latin-1 encoding. 
 + 
 +    Examples: 
 +        >>>​ string_to_bytes('​Hello'​) 
 +        b'​Hello'​ 
 +        >>>​ string_to_bytes('​IC'​) 
 +        b'​IC'​ 
 +    """​ 
 +    return string_data.encode(encoding="​raw_unicode_escape"​) 
 + 
 + 
 +# Base64 functions 
 + 
 + 
 +def b64encode(data: str-> str: 
 +    """​Encodes a string to base64. 
 + 
 +    Parameters:​ 
 +        data (str): The string to be encoded. 
 + 
 +    Returns: 
 +        str: The base64 encoded string, using Latin-1 encoding. 
 + 
 +    Examples: 
 +        >>>​ b64encode("​Hello"​) 
 +        '​SGVsbG8='​ 
 +        >>>​ b64encode("​IC"​) 
 +        '​SUM='​ 
 +    """​
     return bytes_to_string(base64.b64encode(string_to_bytes(data)))     return bytes_to_string(base64.b64encode(string_to_bytes(data)))
  
-# PYTHON3 '​BYTES'​ FUNCTIONS 
  
-def bytes_to_string(bytes_data): +def b64decode(data: str-> str
-    ​return bytes_data.decode() ​ # default utf-8+    ​"""​Decodes a base64 encoded string.
  
-def string_to_bytes(string_data): +    Args: 
-    return ​string_data.encode()  # default utf-8+        data (str): The base64 encoded string to be decoded. It should only 
 +            contain valid base64 characters (A-Z, a-z, 0-9, +, /, =). 
 + 
 +    Returns: 
 +        str: The decoded string, using Latin-1 encoding. 
 + 
 +    Examples: 
 +        >>>​ b64decode("​SGVsbG8="​) 
 +        '​Hello'​ 
 +        >>>​ b64decode("​SUM="​) 
 +        '​IC'​ 
 +    """​ 
 +    return ​bytes_to_string(base64.b64decode(string_to_bytes(data)))
 </​file>​ </​file>​
 +</​spoiler>​
 +
  
 ==== Exercițiul 1 (3p) ==== ==== Exercițiul 1 (3p) ====
Line 88: Line 337:
 Puteți folosi următorul schelet de cod: Puteți folosi următorul schelet de cod:
 <code python '​ex1_weak_rng.py'>​ <code python '​ex1_weak_rng.py'>​
 +from typing import List, Tuple
 +
 from utils import * from utils import *
  
  
 class WeakRNG: class WeakRNG:
-    """​ Simple class for weak RNG """​+    """​Simple class for weak RNG"""​
  
-    def __init__(self):​+    def __init__(self) ​-> None:
         self.rstate = 0         self.rstate = 0
         self.maxn = 255         self.maxn = 255
Line 101: Line 352:
         self.p = 257         self.p = 257
  
-    def init_state(self,​ rstate): +    def init_state(self,​ rstate: int-> None
-        """​ Initialise rstate """​+        """​Initialise rstate"""​
         self.rstate = rstate ​ # Set this to some value         self.rstate = rstate ​ # Set this to some value
         self.update_state()         self.update_state()
  
-    def update_state(self):​ +    def update_state(self) ​-> None
-        """​ Update state """​+        """​Update state"""​
         self.rstate = (self.a * self.rstate + self.b) % self.p         self.rstate = (self.a * self.rstate + self.b) % self.p
  
-    def get_prg_byte(self):​ +    def get_prg_byte(self) ​-> int
-        """​ Return a new PRG byte and update PRG state """​+        """​Return a new PRG byte and update PRG state"""​
         b = self.rstate & 0xFF         b = self.rstate & 0xFF
         self.update_state()         self.update_state()
Line 117: Line 368:
  
  
-def main():+def main() ​-> None:
     # Initialise weak rng     # Initialise weak rng
     wr = WeakRNG()     wr = WeakRNG()
Line 123: Line 374:
  
     # Print ciphertext     # Print ciphertext
-    CH = 'a432109f58ff6a0f2e6cb280526708baece6680acc1f5fcdb9523129434ae9f6ae9edc2f224b73a8'+    CH = "a432109f58ff6a0f2e6cb280526708baece6680acc1f5fcdb9523129434ae9f6ae9edc2f224b73a8"
     print("​Full ciphertext in hexa:",​ CH)     print("​Full ciphertext in hexa:",​ CH)
  
     # Print known plaintext     # Print known plaintext
-    pknown = 'Let all creation'+    pknown = "Let all creation"
     nb = len(pknown)     nb = len(pknown)
     print("​Known plaintext:",​ pknown)     print("​Known plaintext:",​ pknown)
Line 134: Line 385:
  
     # Obtain first nb bytes of RNG     # Obtain first nb bytes of RNG
-    gh = hexxor(pkh, CH[0:nb*2])+    gh = hexxor(pkh, CH[0 : nb * 2])
     print(gh)     print(gh)
     gbytes = []     gbytes = []
     for i in range(nb):     for i in range(nb):
-        gbytes.append(ord(hex_2_str(gh[2*i:​2*i+2])))+        gbytes.append(ord(hex_2_str(gh[2 * i : 2 * i + 2])))
     print("​Bytes of RNG: ")     print("​Bytes of RNG: ")
     print(gbytes)     print(gbytes)
Line 150: Line 401:
  
     # TODO 4: Print the full plaintext     # TODO 4: Print the full plaintext
-    p = ''​+    p = ...
     print("​Full plaintext is:", p)     print("​Full plaintext is:", p)
  
Line 241: Line 492:
 import random import random
  
-def get_random_string(n):​ +def get_random_string(n: int-> str
-    """​ Generate random bit string """​ +    """​Generate random bit string"""​ 
-    return bin(random.getrandbits(n)).lstrip('0b').zfill(n)+    return bin(random.getrandbits(n)).lstrip("0b").zfill(n)
 </​code>​ </​code>​
 </​note>​ </​note>​
Line 253: Line 504:
 </​note>​ </​note>​
  
 +<file python ex4.py>
 +import math
 +import random
 +
 +from utils import *
 +
 +
 +def get_random_string(n:​ int) -> str:
 +    """​Generate random bit string"""​
 +    return bin(random.getrandbits(n)).lstrip("​0b"​).zfill(n)
 +
 +
 +def main() -> None:
 +    N_RUNS = 100  # the number of runs
 +    N_BITS = 1000  # the number of bits to generate
 +
 +    # TODO: implement and run the multiple times (e.g., 100) the
 +    # statistical tests
 +
 +
 +if __name__ == "​__main__":​
 +    main()
 +</​file>​
 ==== Exercițiul 5 - Bonus (2p) ==== ==== Exercițiul 5 - Bonus (2p) ====
  
Line 272: Line 546:
  
 Încercați să implementați aceeași funcționalitate folosind OpenSSL. OpenSSL suportă RC4, dar nu și Salsa20. Folosiți ChaCha20 in loc de Salsa20, aceasta fiind o variantă îmbunătățită a algoritmului. Încercați să implementați aceeași funcționalitate folosind OpenSSL. OpenSSL suportă RC4, dar nu și Salsa20. Folosiți ChaCha20 in loc de Salsa20, aceasta fiind o variantă îmbunătățită a algoritmului.
 +
 +</​hidden>​
ic/labs/03.1665781191.txt.gz · Last modified: 2022/10/14 23:59 by razvan.smadu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0