OTP Implementation
**  
reverse  
picoctf

Yay reversing! Relevant files: otp flag.txt
The code generated by Ghidra:
undefined8 main(int param_1,undefined8 *param_2)

{
byte bVar1;
char cVar2;
int iVar3;
undefined8 uVar4;
long in_FS_OFFSET;
int i;
int local_ec;
char input [100];
undefined local_84;
char output [104];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
if (param_1 < 2) {
printf("USAGE: %s [KEY]\n",*param_2);
uVar4 = 1;
}
else {
strncpy(input,(char *)param_2[1],100);
local_84 = 0;
i = 0;
while( true ) {
iVar3 = valid_char((int)input[i]);
if (iVar3 == 0) break;
if (i == 0) {
cVar2 = jumble((int)input[0]);
output[0] = cVar2 % '\x10';
}
else {
cVar2 = jumble((int)input[i]);
bVar1 = (byte)((int)cVar2 + (int)output[i + -1] >> 0x1f);
output[i] = ((char)((int)cVar2 + (int)output[i + -1]) + (bVar1 >> 4) & 0xf) - (bVar1 >> 4);
}
i = i + 1;
}
for (local_ec = 0; local_ec < i; local_ec = local_ec + 1) {
output[local_ec] = output[local_ec] + 'a';
}
if (i == 100) {
iVar3 = strncmp(output,
"occdpnkibjefihcgjanhofnhkdfnabmofnopaghhgnjhbkalgpnpdjonblalfciifiimkaoenpeal ibelmkdpbdlcldicplephbo"
,100);
if (iVar3 == 0) {
puts("You got the key, congrats! Now xor it with the flag!");
uVar4 = 0;
goto LAB_001009ea;
}
}
puts("Invalid key!");
uVar4 = 1;
}
LAB_001009ea:
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return uVar4;
}


char jumble(char param_1)

{
char local_c;
local_c = param_1;
if ('`' < param_1) {
local_c = param_1 + '\t';
}
local_c = (local_c % '\x10') * '\x02';
if ('\x0f' < local_c) {
local_c = local_c + '\x01';
}
return local_c;
}



undefined8 valid_char(char param_1)

{
undefined8 uVar1;
if ((param_1 < '0') || ('9' < param_1)) {
if ((param_1 < 'a') || ('f' < param_1)) {
uVar1 = 0;
}
else {
uVar1 = 1;
}
}
else {
uVar1 = 1;
}
return uVar1;
}


The binary takes the input then uses an algorithm based on the letter before to encrypt it. I took the code and fixed it such that I was able to execute it.
The fixed code:
#include "stdio.h"
#include "string.h"


char jumble(char param_1)
{
char local_c;
local_c = param_1;
if ('`' < param_1) {
local_c = param_1 + '\t';
}
local_c = (local_c % '\x10') * '\x02';
if ('\x0f' < local_c) {
local_c = local_c + '\x01';
}
return local_c;
}


int valid_char(char param_1)

{
int uVar1;
if ((param_1 < '0') || ('9' < param_1)) {
if ((param_1 < 'a') || ('f' < param_1)) {
uVar1 = 0;
}
else {
uVar1 = 1;
}
}
else {
uVar1 = 1;
}
return uVar1;
}

int main(int argc, char* argv[]){
char input[100];
strncpy(input,argv[1],100);
int local_84 = 0;
int i = 0;
char local_78 [104];
int iVar3;
char cVar2;
char bVar1;
while(1) {
iVar3 = valid_char(input[i]);
if (iVar3 == 0) break;
if (i == 0) {
cVar2 = jumble(input[0]);
local_78[0] = cVar2 % '\x10';
}
else {
cVar2 = jumble(input[i]);
bVar1 = (char)((int)cVar2 + (int)local_78[i + -1] >> 0x1f);
local_78[i] =((char)((int)cVar2 + (int)local_78[i + -1]) + (bVar1 >> 4) & 0xf) - (bVar1 >> 4);
}
i = i + 1;
}
for (int i = 0; i < i; i = i + 1) {
local_78[i] = local_78[i] + 'a';
}
printf("%s",local_78);
// return 0;
}
After the changes I was able to run it and also see the output. The next thing I did was a python script to generate the key letter by letter. 
from subprocess import *
needed = "occdpnkibjefihcgjanhofnhkdfnabmofnopaghhgnjhbkalgpnpdjonblalfciifiimkaoenpealibelmkdpbdlcldicplephbo"

good_char = [str(x) for x in range(10)] + ["a","b","c","d","e","f"]
inp = ["7"]*100
# getting the first character
# for inp in good_char:
# output = subprocess.check_output(['./out', inp]).decode("ASCII")
# if output == "c":
# print(inp)

for i in range(len(needed)):
for c in good_char:
try:
inp[i] = c
output = check_output(['./out', "".join(inp) ]).decode("ASCII")
except:
continue
if output[:i+1] == needed[:i+1]:
print("".join(inp))
break
One of the things that made me struggle was the fact that the input should have the lenght of the output(100 characters). Every time I tested the code, the key didn't generate anymore ater 15 characters.
The key:
720867e7c4d89fd29be5bb459c1498d1b4888380fb675c3ddc7123af25ad5e30e9027373c1a6dec9b87c6114bc4a5e6cd45e
picoCTF{cust0m_jumbl3s_4r3nt_4_g0Od_1d3A_15e89ca4}