oblivious transfer

Attachmentscrypto - 5001 solves

We do not do parties, we do multi-parties! One of the most important ingredients for these is (next to mate) oblivious transfers.

Time

3 hours
Solved 1 hour after the ctf end :(

Behavior

The server use paillier cryptosystem, we can provide generator cc and publickey nn, then the server computes a encrypted flag using following formula. x0=rand(sizeof(flag))x1=x0flagr0,r1=rand(n),rand(n)c0=(enc(1)×c(n1))x0×cr0c1=(enc(1)×c(n1))r1×cx1\begin{aligned} x_0 &= \text{rand}(\text{sizeof}(\text{flag}))\\ x_1 &= x_0 ^ \text{flag}\\ r_0, r_1 &= \text{rand}(n), \text{rand}(n)\\ c_0 &= \left(\text{enc}(1) \times c^{(n-1)}\right)^{x_0} \times c^{r_0}\\ c_1 &= \left(\text{enc}(1) \times c^{(n-1)}\right)^{r_1} \times c^{x_1}\\ \end{aligned} and returns ciphertext c0,c1c_0, c_1 to us.

Solution

TL;DR

  1. Generate a safe prime q=2p+1q = 2p + 1
  2. Use n=pqn = pq as public key
  3. Send enc(q)\text{enc}(q) as cc
  4. x0=dec(c0) mod px_0 = \text{dec}(c_0) \ \mod\ p
  5. x1=dec(c1) mod qx_1 = \text{dec}(c_1) \ \mod\ q

In paillier, multiplication in ciphertext is addition in plaintext, and power in ciphertext is multiplication in plaintext. So the decryption result will be: c:=enc(z)d0=x0z(x0r0) mod nd1=r1z(r1x1) mod n\begin{aligned} c &\coloneqq \text{enc}(z) \\ d_0 &= x_0 - z (x_0 - r_0)\ \mod\ n \\ d_1 &= r_1 - z (r_1 - x_1)\ \mod\ n \\ \end{aligned}

To solve this task, I use a safe prime as cc and private key, formally: q:=2p+1where p, q are both primen:=pqc:=enc(q)\begin{aligned} q &\coloneqq 2p + 1\quad\text{where p, q are both prime} \\ n &\coloneqq p q \\ c &\coloneqq enc(q) \\ \\ \end{aligned} After decryption, we'll have: d0=x0q(x0r0) mod pqd1=r1q(r1x1) mod pq\begin{aligned} d_0 &= x_0 - q (x_0 - r_0)\ \mod\ pq \\ d_1 &= r_1 - q (r_1 - x_1)\ \mod\ pq \\ \end{aligned} To get x0x_0, simply calculate the remainder over qq: d0=x0q(x0r0)=x0 mod qd_0 = x_0 - q (x_0 - r_0) = x_0\ \mod\ q

x1x_1 is more complicated. Recall that q=2p+1q = 2p+1, we can derive following formulas: r1:=pk+(r1mod p)d1=r1q(r1x1) mod pq=r1q(pk+(r1mod p)x1) mod pq=r1pqkq((r1mod p)x1) mod pq=r1q((r1mod p)x1) mod pq=r1(2p+1)((r1mod p)x1) mod pq: {Under modulo p}=r1(2p+1)((r1mod p)x1) mod p=r11((r1mod p)x1) mod p=r1(r1mod p)+x1 mod p=x1 mod p\begin{aligned} r_1 &\coloneqq p k + (r_1\mod\ p) \\ d_1 &= r_1 - q (r_1 - x_1)\ \mod\ pq \\ &= r_1 - q (p k + (r_1\mod\ p) - x_1)\ \mod\ pq \\ &= r_1 - p q k - q ((r_1\mod\ p) - x_1)\ \mod\ pq \\ &= r_1 - q ((r_1\mod\ p) - x_1)\ \mod\ pq \\ &= r_1 - (2p + 1) ((r_1\mod\ p) - x_1)\ \mod\ pq \\ &:\ \text{\{Under modulo p\}} \\ &= r_1 - (2p + 1) ((r_1\mod\ p) - x_1)\ \mod\ p \\ &= r_1 - 1 ((r_1\mod\ p) - x_1)\ \mod\ p \\ &= r_1 - (r_1\mod\ p) + x_1\ \mod\ p \\ &= x_1\ \mod\ p \\ \end{aligned}

Now xor those two integer to get the flag.

Additional Notes

Here's the solution from admin. It is stronger than my solution which doesn't need the assumption of safe prime on private key. Here's a proof about how it works:

Using extended gcd to get X, Y, such that: pX+qY=gcd(p,q)=1pX + qY = \text{gcd}(p, q) = 1

Using the equation above, we have following equation about multiplicative inverse: 1pX×pX=1=pX+qY 1pX=pX+qYpX=1+qYpX1qY×qY=1=pX+qY 1qY=pX+qYqY=1+pXqY\begin{aligned} &\frac{1}{pX} \times pX = 1 = pX + qY \\ \Rightarrow\ &\frac{1}{pX} = \frac{pX + qY}{pX} = 1 + \frac{qY}{pX} \\ \\ &\frac{1}{qY} \times qY = 1 = pX + qY \\ \Rightarrow\ &\frac{1}{qY} = \frac{pX + qY}{qY} = 1 + \frac{pX}{qY} \\ \end{aligned}

Select c=enc(α)c = \text{enc}(\alpha), where α=pXmodpq\alpha = pX \mod pq

So that: d0=dec(c0)=x0α(x0r0)modpq=x0pX(x0r0)modpq: {under modulo p}=x0pX(x0r0)modp=x0modp\begin{aligned} d_0 &= \text{dec}(c_0) \\ &= x_0 - \alpha (x_0 - r_0) \mod pq \\ &= x_0 - pX (x_0 - r_0) \mod pq \\ &:\ \text{\{under modulo p\}} \\ &= x_0 - pX (x_0 - r_0) \mod p \\ &= x_0 \mod p \\ \end{aligned}

However the script calculate x0x_0 using: x0:=d0qYmodpx_0 \coloneqq \frac{d_0}{qY} \mod p which is also true.

d0qY=x0qYmodp=x0(1+pXqY)modp=x0modp\begin{aligned} \frac{d_0}{qY} &= \frac{x_0}{qY} \mod p \\ &= x_0 (1 + \frac{pX}{qY}) \mod p \\ &= x_0 \mod p \\ \end{aligned}

We can calculate x1x_1 from d1d_1 in the similar way: d1=dec(c1)=r1α(r1x1)modpq=r1pX(r1x1)modpqd1pX=r1pXr1+x1modpq=r1(1+qYpX)r1+x1modpq: {under modulo q}=r1(1+qYpX)r1+x1modq=r1r1+x1modq=x1modq\begin{aligned} d_1 &= \text{dec}(c_1) \\ &= r_1 - \alpha (r_1 - x_1) \mod pq \\ &= r_1 - pX (r_1 - x_1) \mod pq \\ \\ \frac{d_1}{pX} &= \frac{r_1}{pX} - r_1 + x_1 \mod pq \\ &= r_1 (1 + \frac{qY}{pX}) - r_1 + x_1 \mod pq \\ &:\ \text{\{under modulo q\}} \\ &= r_1 (1 + \frac{qY}{pX}) - r_1 + x_1 \mod q \\ &= r_1 - r_1 + x_1 \mod q \\ &= x_1 \mod q \\ \end{aligned}