Fundamental Concepts
Bytes Representation
Bytes represent raw binary data used to manipulate, inspect, and convert values at a low level. The printable bytes are usually represented directly as ASCII, but the non-printable, are shown in a raw way using a hexadecimal value between 0-255 and with the \x
prefix, for example, \x00
for the null byte.
Here we find a little script with some examples of byte manipulation:
# We can observe its representation
print("Raw Byte:", b'\x00') # Raw byte that is not printable
print("Printable Byte:", b'\x41') # Raw byte but is printed as 'A'
# We can obtain an int value with the position in the 0-255 range
byte1 = b'B'
print("Byte Value:", byte1[0])
# For byte strings, we could do the same with the byte at any position
byte_str = b'flag'
print("String Byte Values:", byte_str[0],byte_str[1],byte_str[2],byte_str[3])
# We can concatenate bytes, or operate on them using their int representation
byte1 = b'\x03'
byte2 = b'\x02'
print("Concatenate:", byte1 + byte2)
print("Result Value:", byte1[0] + byte2[0]) # This return and the result int
print("Result Bytes:", bytes([byte1[0] + byte2[0]])) # This converts the result again in bytes
# As bytes only are in the 0-255 range, we could have errors outside this range
b1 = b'\xf0' # Its value is 240
b2 = b'\x3f' # Its value is 63
add = b1[0] + b2[0] # The result is 303, out of the range
# We can use the modular operator to truncate results in the range
add = add % 256 # Now, the result is b'\x47' which is b'/'
print("Result in range:", bytes([add]))
Long Integer Representation
Bytes can be represented as long numerical values to use them for mathematical operations.
Here we find a little script to convert bytes into long integers:
# This script converts bytes into a long
from Cryptodome.Util.number import bytes_to_long
def Bytes_to_Long(message):
long_number = bytes_to_long(message)
return long_number
#Usage Example
message = b"FLAG{f4k3_fl4g_f0r_t3st1ng}"
print("Integer Representation:", Bytes_to_Long(message))
In the same way, here we find a little script to convert integers into bytes:
# This script converts a long into bytes
from Cryptodome.Util.number import long_to_bytes
def Long_to_Bytes(long_number):
recovered = long_to_bytes(long_number)
return recovered
#Usage Example
long_number = 28918866808831822367805849580817521177463833928225773799944906621
print("Recovered Bytes:", Long_to_Bytes(long_number))
XOR Operation
It is a bitwise operator that returns 0 if the bits are the same, and 1 otherwise. It is usually denoted by the ⊕ symbol in math, but in most programming languages it is represented with the ^
symbol.
Properties
Involution: Making XOR to a value twice with the same key, returns the original value. For example: A^B = C ⇔ C^B = A
Commutation: The order of the XOR operands does not affect the result of the operation. For example: A^B = B^A
Associative: A chain of operations can be carried out without order, and the result will be the same. For example: A^(B^C) = (A^B)^C
Identity: The identity is 0, so XOR anything with 0 does not change the original value. For example: A^0 = A or A^\x00 = A if we are working with bytes
Self-Inverse: Making an XOR between any value and itself returns the identity (0). For example: A^A = 0
Implementation
Here we find some explanations and scripts to apply this operation:
For int and hex, they are first represented in binary, and then the XOR operation is done bit by bit
# This script performs an XOR operation between numbers or hex
def XOR_Int(num1,num2):
result = num1 ^ num2
return result
def XOR_Hex(hex1, hex2):
result = hex1 ^ hex2
return hex(result)
#Usage example
num1, num2 = 13, 11 # Xoring 1101 ^ 1011 = 0110 which is 6
print("Result Int:", XOR_Int(num1, num2))
hex1, hex2 = 0x1F, 0xF0 # Xoring 00011111 ^ 11110000 = 11101111 which 0xEF
print("Result Hex:", XOR_Hex(hex1, hex2))
For characters or bytes, they have to be converted to their ASCII values first, and then the XOR is applied to these values. For strings, we have to represent them as bytes and then loop through the previous process for each character
# This script performs an XOR operation between characters or strings
from Cryptodome.Util.number import long_to_bytes
def XOR_Char(char1,char2):
result = ord(char1) ^ ord(char2)
return long_to_bytes(result)
def XOR_String(str1, str2):
result = bytes([a ^ b for a, b in zip(str1, str2)])
return result
#Usage example
char1 = b'A' # ASCII 65 → 01000001
char2 = b'z' # ASCII 122 → 00111011
print("Result Char:", XOR_Char(char1,char2)) # Result 00111011 → 59 which is ";"
str1 = "flag1"
str2 = "flag2"
print("Result String:", XOR_String(str1.encode(), str2.encode())) # Used as bytes
To make it easier and operate between data types, we can use the
xor()
function from the pwntools Python library
# This script performs an XOR operation between different data types
from pwn import xor
xored = b'KALJvk9f>Rka9jRk=\x7fRy>~y<cjp'
print("Result", xor(xored, 13))
Modular Arithmetic
It is a mathematical system that deals with integers and their remainders when divided by a specific positive number, known as the modulus.
Instead of traditional arithmetic, where numbers can grow indefinitely, modular arithmetic operates on the principle of congruence, which gives a cyclic behavior to the numerical groups limited by the modulus value.
It enables operations over bounded sets, supports cyclic structures, and ensures that results stay within predictable limits, making it ideal for environments with constraints on data size, such as embedded systems or secure key generation.
It is implemented in many areas of computer science and cryptography, particularly in:
Hashing algorithms
Checksums and error detection
Cryptographic protocols like RSA and Diffie-Hellman
Finite fields in elliptic curve cryptography
Here we can describe some important concepts that are part of this field:
Congruence
Two integers a
and b
are said to be congruent modulo n
If they leave the same remainder when divided by n
. This is written as:
This could be understood in different ways:
a
andb
have the same remainder when divided byn
. For example,14%3 = 2
and5%3 = 2
, where the symbol%
represents the remainder of the division (Also known as the modulo operator)a
andb
are congruent modulon
becausea-b
is divisible byn
. For example,14≡5 mod 3
. As14-5=9
, and9
is divisible by3
Exits a value k that satisfies
n*k = a-b
In the same way,14
is congruent with5
modulo3
because withk = 3
it satifies3*3 = 14-5
Last updated