Cryptography CTFs - Cheat Sheet
Cryptography CTFs - Cheat Sheet
This document is a work in progress! I will update it every time I learn something new.
It will contain solution to my recurrent problems for Cryptography CTFs.
Sorry for any bad code, please reach out if you have suggestions or concerns. As this are my personal studies (and I’m almost not using AI) there WILL be errors and weird stuff.
C
Write a function that Returns Multiple Variables
1
2
3
4
5
6
7
8
9
10
11
typedef struct result{
int x;
int y;
} result;
result xgcd(int a, int b){
if (b==0) return (result) {1, 0};
result temp = xgcd(b, a%b);
int n = a/b;
return (result) {temp.y, temp.x-n*temp.y};
}
ReadFile
returns a char* containing the entire file as an array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
char* readFile(char filename[]){
//open file
FILE *file = fopen(filename,"r");
if (file == NULL){
printf("Cannot open file");
return NULL;
}
// get file size for memory allocation
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
// allocate memory
char *text_array = (char*)malloc(size*(sizeof(char))+1);
// info store
if(text_array){
fread(text_array, 1, size, file);
text_array[size] = '\0';
}
fclose(file);
return text_array;
}
// usage
char* file = readFile("output_legendre.txt");
Install libgmp for arbitrary precision numbers
1
2
3
4
5
6
7
8
# install the library
sudo apt install libgmp-dev
# include in the .c file
#include <gmp.h>
# to compile use -lgmp
gcc file.c -o file -lgmp
Use libgmp for arbitrary precision numbers
https://gmplib.org/manual/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// declare numbers and assign variables
mpz_t a,b;
// initialize single numbers to 0
mpz_init(a);
// initialize multiple numbers at once to 0 (last element must be NULL)
mpz_inits(a,b,NULL);
// initialize number from string (2nd is char*, 3rd is base)
mpz_init_set_str(a,"1337",10);
// set value
mpz_set(a,b); // a = b (both mpz_t)
//to mpz_t from int (initialize first)
mpz_set_ui(a,1337); //unsigned long
mpz_set_si(a,1337); //signed long
// Integer Functions (remember, a+1 does not work...)
// https://gmplib.org/manual/Integer-Functions
// first is always the result
// when without _si or _ui, the function is between mpz_t, else you can use normal integers
// + addition
mpz_add(res, x, y);
mpz_add_ui(res, x, 2);
// - subtraction
mpz_sub(res, x, y);
mpz_sub_ui(res,x,5);
// * multiplication
mpz_mul(res,a,b);
// / integer division
mpz_tdiv_q(res, num, den);
mpz_tdiv_q_ui(res, num, 3);
// ** power
mpz_powm(res,x,exp,p); // power with module (all mpz_t)
mpz_powm_ui(res,x,2,p); // exp is unsigned long
mpz_pow(res,base,exp);
mpz_ui_pow_ui(res,3,5); // base and exp are unsigned long
// % modular
mpz_mod(res,a,p);
mpz_mod_ui(res,a,3);
// print mpz type
gmp_printf("a = %Zd\n",a);
// compare (returns 0 if equal, >0 if a>b, <0 if a<b)
mpz_cmp(a,b);
mpz_cmp_si(a,1);
// write functions for mpz_t (pass result as param)
void fun(mpz_t res, mpz_t a, mpz_t b){
mpz_add(res,a,b);
}
// write function for mpz_t and return an int
int fun(mpz_t a, mpz_t b){
mpz_t temp;
mpz_tdiv_q(a,b);
//cast the mpz_t to unsigned long
return mpz_get_ui(temp);
}
Extract variable from file
For when you have a file containing something like: “p = 1337…”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int extractVarFromString(const char* string_array, mpz_t num, char* srch){
if (!string_array) return 0;
// copio la stringa (strtok modifica la stringa in locale)
char* string_copy = strdup(string_array);
// rimuovo caratteri dal file
char* temp_num = strtok(string_copy, "[,] \n=");
// cerco il nome della variabile nel file
while((tmp_num != NULL) && (strcmp(temp_num,srch))){ temp_num = strtok(NULL,"[,] \n=");}
// salto il nome della variabile
temp_num = strtok(NULL,"[,] \n=");
// inizializzo num a temp_num
if((tmp_num != NULL) && mpz_init_set_str(num,temp_num,10) == 0){
free(string_copy);
// printf("%s = %s\n",srch,temp_num);
return 1;
}
//gmp_printf("%s = %Zd\n",srch,num);
printf("La variabile %s non è stata trovata nel file\n",srch);
free(string_copy);
return 0;
}
// usage
char* file = readFile("output_legendre.txt");
mpz_t p;
mpz_init(p);
// p è il nome della variabile nel file
extractVarFromString(file,p,"p");
Code for an array of values.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
int extractVarsFromString(const char* string_array, mpz_t* nums, const char* srch, int size){
if (!string_array) return 0;
char* string_copy = strdup(string_array);
// file contains smth like "ints = [1,2,3..."
char* temp_ints = strtok(string_copy, "[,] \n=");
while (temp_ints != NULL){
// trova il nome dell'array
if (strcmp(temp_ints,srch) == 0){
// salta il nome dell'array
temp_ints = strtok(NULL,"[,] \n=");
// assegno i valori a nums
int i = 0;
while ((temp_ints != NULL) && (i < size)){
if (mpz_set_str(nums[i],temp_ints,10)==0) i++;
// gmp_printf("nums[%d] = %Zd\n",i,nums[i]);
temp_ints = strtok(NULL,"[,] \n=");
}
free(string_copy);
return i;
}
// printf("%s\n",temp_ints);
temp_ints = strtok(NULL,"[,] \n=");
}
printf("Array '%s' non trovato nel file.\n", srch);
free(string_copy);
return 0;
}
//usage
char* file = readFile("output_legendre.txt");
mpz_t ints[10];
for (int i = 0; i < 10; i++) mpz_init(ints[i]);
// p è il nome della variabile nel file
extractVarsFromString(file,ints,"ints",10);
Chronometer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Disclaimer: Gemini wrote this
double get_time_ms(struct timespec start, struct timespec end){
return (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_nsec - start.tv_nsec) / 1000000.0;
}
int main(){
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
//yourcode
clock_gettime(CLOCK_MONOTONIC, &end);
double tempo = get_time_ms(start, end);
printf("Calcolato in: %.6f ms\n\n", tempo);
}
1
2
#oppure da bash cronometrare la velocità di esecuzione di un binario
time ./programma
Python
Manipulation Snippets
1
2
3
4
5
6
7
8
9
10
11
12
13
chr(c) # from ascii(Dec) to char
ord(n) # from char to ascii (Dec)
import base64
base64.b64encode(bytes) # from bytes to base64
from Crypto.Util.number import *
long_to_bytes()
bytes_to_long()
# XOR each char
new = ''.join([chr(ord(c)^13) for c in string])
Sage
https://doc.sagemath.org/html/en/installation/index.html
Install conda
1
2
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
bash Miniforge3-$(uname)-$(uname -m).sh
Install SageMath
1
2
3
4
# remember to reboot since conda installation
conda create -n sage sage python=3.12
conda activate sage
sage
Use SageMath
Quando saprò come usarlo, sarete i primi a saperlo :)
Numbers
Long Primes
https://t5k.org/lists/small/small.html
This post is licensed under CC BY 4.0 by the author.