Rating:

# Complex RSA

> Things in this world sometimes are different than they appear!

> nc 167.71.62.250 14559

## Challenge

```
Challenge loading... be patinet :)
|-------------------------------------|
| Options: |
| [E]ncrypted message |
| [K]ey generation function |
| [S]end the decrypted message |
| [T]ry encryption |
| [Q]uit |
|-------------------------------------|
```

The key gen function:

```
def gen_key(e, nbit):
p = getPrime(nbit << 2)
q = getPrime(nbit >> 2)
print 'p =', p
print 'q =', q
n = p * q
return (e, n)
```

Here one prime would be small, so factorization should be quite easy

```
Send your Options:
T
Send your input as a pair (a, b):
(2,0)
((a + b √-1) ** e) (mod n) = (123370139733460288741582133541967208151544163810581515437516558669972425636530931666673004837858749022601996874821486288752958977088089060539584311969624273734612352083467285311016219043536527442528687720647804943357024821973693691292035336507137095064124150626846570159166238804148372798356772669L, 0L)
Send your Options:
T
Send your input as a pair (a, b):
(0,1)
((a + b √-1) ** e) (mod n) = (0L, 1L)
Send your Options:
T
Send your input as a pair (a, b):
(-1,0)
((a + b √-1) ** e) (mod n) = (337390295386784062735892530953812027731217626577827868683652203476748859812364337575664693191200613632654265062075499825596838397609731917692839810645496096834742890659029158682118916487432458937074956757871632389547383580967613523944154703997016734902928913508657661928209328770940675037982298198L, 0L)
```

Trying some inputs, we see that this basically extends RSA into the gaussian integers, and negative numbers works too.

Since negative numbers works, finding `n` is trivial `n = (n-1)+1`

Assuming `e` is small, finding `e` is simple by discrete log

Now we need a way to do complex modular arithmetic

## Complex modular arithmetic

Adding amd multiplying is trivial, exponentiation is done by square and multiply:

```
def cadd(a,b,n):
return (a[0]+b[0]%n,a[1]+b[1]%n)

def cmul(a,b,n):
return ((a[0]*b[0]-a[1]*b[1])%n,(a[0]*b[1]+a[1]*b[0])%n)

def cpow(a,k,n):
if(k==0):
return (1,0)
if(k==1):
return a
if(k%2==0):
a=cmul(a,a,n)
return cpow(a,k/2,n)
else:
return cmul(a,cpow(cmul(a,a,n),(k-1)/2,n),n)
```

## Order of multiplicative group

Usually in RSA, we simply compute `phi(n)` then invert `e` under `phi(n)`, but now it's with complex numbers, so this may not work

We first consider the order of `C/pC*` where `p` is a prime. The real and imaginary parts ranges from `0` to `p-1`, so a valid assumption is that the order is a multiple of `p*p-1`(since `0,0` can't be in the group). The order is exactly `p*p-1` for `p=3 mod 4` since it cannot be expressed as the sum of `2` squares, but for `p=1 mod 4` it is less, and it is a multiple of `p*p-1`.

Thus if we want to find `g` given `g^e=a mod p`, we simply invert `e` under `p*p-1`.

For `n=pq`, the order is a multiple of `lcm(p*p-1,q*q-1)`, then it's trivial

For factoring `n` we simply use yafu

> Flag : `CCTF{_____e^(i*PI)=-1_____}`

Original writeup (https://github.com/Ariana1729/CTF-Writeups/blob/master/2019/CryptoCTF/Complex%20RSA/README.md).