Xmas CTF 2020 - Santa's ELF Holomorphing Machine Writeup
Post
Cancel

# Xmas CTF 2020 - Santa's ELF Holomorphing Machine Writeup

## Brief

Santa’s ELF holomorphing machine was a programming challenge described by the following brief:

We’re also given a text file with about 800 functions and complex numbers, as follows:

1 2 3 4 5 6 u = -3 * x + 95 * y; z = -0.12652202789462033 + 0.006530883329643569 * i v = -65 * x + 5 * y; z = -0.16588235294117648 + 0.04352941176470588 * i u = 55 * x + -93 * y; z = 0.09379818399862944 + 0.023213979784135686 * i u = 71 * x + -26 * y; z = 0.09060696169319574 + 0.09358054923911142 * i v = 78 * x + -38 * y; z = -0.01487778958554729 + -0.056854410201912856 * i ... 

## Objective

After reading the brief, it looks like we need to find some function $$f_i$$ for each given complex number $$z_i$$, and then plot the points on a normal x-y plane. At this point I wasn’t sure what a holomorphic function was, so I did some reading and found that it has to do with complex differentiation - which wasn’t very helpful. However, all holomorphic functions have the following property:

If a complex function $$f(x + iy) = u(x ,y) + iv(x, y)$$ is holomorphic, then $$u$$ and $$v$$ have first partial derivatives with respect to $$x$$ and $$y$$, and satisfy the Cauchy-Riemann equation:

$$\frac{\partial u}{\partial x} = \frac{\partial v}{\partial y}, \frac{\partial u}{\partial y} = -\frac{\partial v}{\partial x}$$

Since we’re provided with either $$u$$ or $$v$$, we can use the above equation to work out the other corresponding part, and join it to have $$f_i(x + iy) = u(x ,y) + iv(x, y)$$ for each $$z_i$$. As an example, $$u = -3 * x + 95 * y;$$ has the following partial derivatives:

$$\frac{\partial u}{\partial x} = -3, \frac{\partial u}{\partial y} = 95,$$

So by the Cauchy-Riemann equation, we have:

$$\frac{\partial v}{\partial y} = -3, -\frac{\partial v}{\partial x} = 95,$$

## Piecing it together

We can piece this together to find that $$v = (-95) * x + (-3) * y$$. We’d then send $$z_i$$ to the new $$f_i(x + iy) = u(x ,y) + iv(x, y)$$ for each $$i$$ and plot the corresponding (x,y) points. I wrote the following code to do this:

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 #!/usr/bin/python3 from pylab import * xpoints = [] ypoints = [] lines = open("holoinput.txt").read().split('\n') for line in lines: if line.startswith("u"): u = line.split(';')[0] #get just the u = ax + by ua = u.split(' ')[2] #get just a ub = u.split(' ')[6] #get just b va = float(ub)*(-1) #v = -bx + ay vb = float(ua) #v = -bx + ay #now we need to send in z into u and v, to get f(z) z = line.split(';')[1] #just get z = a + bi za = z.split(' ')[3] #we just need the a from z = a + bi zb = z.split(' ')[5] #we just need the b from z = a + bi #work out u(za,zb) uz = float(ua) * float(za) + float(ub) * float(zb) #work out v(za,zb) vz = float(va) * float(za) + float(vb) * float(zb) #the affix is (u(za,zb), v(za,zb)) print("(" + str(uz) + ", " + str(vz) + ")") xpoints.append(uz) ypoints.append(-vz) #need to flip all points about the y-axis #do the same as above, but with the v functions if line.startswith("v"): v = line.split(';')[0] va = v.split(' ')[2] vb = v.split(' ')[6] ua = float(vb) ub = float(va)*(-1) z = line.split(';')[1] za = z.split(' ')[3] zb = z.split(' ')[5] uz = float(ua) * float(za) + float(ub) * float(zb) vz = float(va) * float(za) + float(vb) * float(zb) print("(" + str(uz) + ", " + str(vz) + ")") xpoints.append(uz) ypoints.append(-vz) #need to flip all points about the y-axis scatter(xpoints, ypoints, marker='.') show() 

After running the program, I found that we needed to flip the resulting scatter plot about the y-axis, which is why we have ypoints.append(-vz). The resulting scatter plot is the flag:

Thanks to @HTSP and the author for a fun challenge :)