Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

rev/idk #51

Merged
merged 3 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions idk/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM gcc:4.9
COPY idk.c .
RUN gcc -o chall idk.c
20 changes: 20 additions & 0 deletions idk/chall.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: idk
categories:
- rev
value: 100
flag: bcactf{H1gH_QUAlITy_coDE_ccec60e091ba2}
description: |-
i threw some random stuff at a wall
hints:
- i didn't invent any of these
files:
- src: /chall
dest: idk
container: static
deploy:
static:
build: .
authors:
- Marvin
visible: true
# TODO: verify deployment
68 changes: 68 additions & 0 deletions idk/idk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <stdio.h>

int main() {
// read input in as char array
char flag[40];
printf("what: ");
scanf("%s", flag);
unsigned int cd[20];
// Interleave
for (int i = 0; i < 20; i ++) {
cd[i] = ((flag[2*i] * 0x0101010101010101ULL & 0x8040201008040201ULL) *
0x0102040810204081ULL >>
49) &
0x5555 |
((flag[2*i + 1] * 0x0101010101010101ULL & 0x8040201008040201ULL) *
0x0102040810204081ULL >>
48) &
0xAAAA;
}
// XOR Swap
int ind1[20] = {11, 19, 14, 1, 3, 5, 18, 13, 0, 17, 6, 7, 8, 16, 12, 10, 4, 9, 15, 2};
for (int i = 0; i < 19; i += 2) {
cd[ind1[i]] = cd[ind1[i]] ^ cd[ind1[i + 1]];
cd[ind1[i + 1]] = cd[ind1[i + 1]] ^ cd[ind1[i]];
cd[ind1[i]] = cd[ind1[i]] ^ cd[ind1[i + 1]];
}
// Max and min
int ind2[20] = {18, 6, 17, 4, 13, 12, 10, 5, 0, 14, 8, 11, 16, 7, 15, 1, 2, 19, 9, 3};
unsigned int check = 0;
for (int i = 0; i < 19; i += 2) {
unsigned int c = (cd[ind2[i]] < cd[ind2[i + 1]]);
check += c << i;
unsigned int temp = cd[ind2[i + 1]] ^ ((cd[ind2[i]] ^ cd[ind2[i + 1]]) & -c);
cd[ind2[i]] ^= ((cd[ind2[i]] ^ cd[ind2[i + 1]]) & -c);
cd[ind2[i + 1]] = temp;
}
// Get bit count and remove last bit
for (int i = 0; i < 20; i++) {
unsigned int t = cd[i];
t = t - ((t >> 1) & 0x55555555);
t = (t & 0x33333333) + ((t >> 2) & 0x33333333);
t = (((t + (t >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
cd[i] >>= 1;
cd[i] += t << 16;
}
// Advance bit permutations
for (int i = 0; i < 20; i++) {
for (int j = 0; j < i; j++) {
unsigned int temp = cd[i] | (cd[i]-1);
cd[i] = (temp + 1) | (((~temp & -~temp) - 1) >> (__builtin_ctz(cd[i]) + 1));
}
}

unsigned int goal_check = 333072;
unsigned int goal[20] = {466437, 528153, 333852, 530074, 728060, 531211, 400528, 399745, 396035, 530846, 662759, 395326, 397355, 663164, 399371, 532170, 465419, 466482, 532038, 399114};
if (check == goal_check) {
for (int i = 0; i < 20; i++) {
if (cd[i] != goal[i]) {
printf("no\n");
return 0;
}
}
printf("yes\n");
} else {
printf("no\n");
}
return 0;
}
59 changes: 59 additions & 0 deletions idk/solve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# most things stolen from https://graphics.stanford.edu/~seander/bithacks.html

goal_check = 333072
goal = [466437, 528153, 333852, 530074, 728060, 531211, 400528, 399745, 396035, 530846, 662759, 395326, 397355, 663164, 399371, 532170, 465419, 466482, 532038, 399114]

def bits(n):
c = 0
while n:
c += 1
n &= n - 1
return c


# previous bit permutation
for i in range(20):
for j in range(i):
bit_count = bits(goal[i])
goal[i] -= 1
while bits(goal[i]) != bit_count:
goal[i] -= 1

print(goal)

# reverse this thing "Get bit count and remove last bit"
for i in range(20):
bit_count = goal[i] >> 16
goal[i] = goal[i] & ((1 << 16) - 1)
goal[i] <<= 1
t = bits(goal[i])
if (t == bit_count): continue
if (t == bit_count - 1): goal[i] += 1; continue
raise Exception("???", t, bit_count)
print(goal)
# reverse Max and min with help of check
ind2 = [18, 6, 17, 4, 13, 12, 10, 5, 0, 14, 8, 11, 16, 7, 15, 1, 2, 19, 9, 3]
for i in range(0, 20, 2):
if not (goal_check & (1 << i)): # if 1st > 2nd in orig
# already correct order (this part sets the 2nd one to the min)
continue
goal[ind2[i]], goal[ind2[i + 1]] = goal[ind2[i + 1]], goal[ind2[i]]
print(goal)
# reverse XOR swap
ind = [11, 19, 14, 1, 3, 5, 18, 13, 0, 17, 6, 7, 8, 16, 12, 10, 4, 9, 15, 2]
for i in range(0, 20, 2):
goal[ind[i]], goal[ind[i + 1]] = goal[ind[i + 1]], goal[ind[i]]

flag = []
print(goal)
# uninterleave
for i in range(20):
temp_x = 0
temp_y = 0
for j in range(0, 16, 2):
temp_x |= ((goal[i] >> j) & 1) << (j//2)
temp_y |= ((goal[i] >> (j+1)) & 1) << (j//2)
flag.append(temp_x)
flag.append(temp_y)

print("".join([chr(x) for x in flag]))