---
# System prepended metadata

title: e000p

---

# e000p

Author. EggRoll (Discord ID. 蛋捲鯛魚燒#5393)

## Overview

We are asked to solve dlog on Edwards Curve41417 with equation of the form $$x^2+y^2 = 1+dx^2y^2\pmod{p}$$ The curve is secure as the order is a prime number. Fortunately, we are also given most bit values of the exponent. 

## Motivation

First of all, notice that there are **only** `45` unknown bits according to the hint. 

```python
bm = (1 << 412) - 1
bm ^= ((1 << 22) -1) << 313    # 22-bit mask
bm ^= ((1 << 22) -1) << 13     # 22-bit mask
bm ^= 1 << 196                 #  1-bit mask
hint = bm & pow(msg, -1, order)
```

Though it's impoosible to test all $2^{45}$ possibilties, we aware of that $2^{\lfloor\frac{45}{2}\rfloor}$ is brute-forcable. This motivates us to apply meet-in-the-middle (MITM). 

## Exploit

To clearly explain the attack, let's identitfy the problem more mathematically. So basically, there are two points $P, Q$ on the curve satisfying $$mP = Q$$ where $m$ is the secret exponent (`m = pow(msg, -1, order)` in our case). We also know that $$m \oplus bm = hint$$ Here $bm$ has only $45$ bits being $0$. In other words, there are only $45$ bits of $m$ that we don't know. We may assume $$m = hint +i_{1}\cdot 2^{e_{1}}+\cdots+i_{45}\cdot 2^{e_{45}} = hint+\sum\limits_{k=1}^{45}{i_{k}2^{e_{k}}}$$ for some $i_{1}, \dots, i_{45} \in\{0, 1\}$ and different integers $e_{1}, \dots, e_{45}$ (they are $13\sim 34$, $313\sim 334$ and $196$). The attack consists of two main steps

1. Bulid a lookup table or dictionary $T$ such that $$T\left[\left(hint+\sum\limits_{k=1}^{23}{j_{k}2^{e_{k}}}\right)P\right] = \sum\limits_{k=1}^{23}{j_{k}2^{k}}$$ In fact, the right-hand-side (RHS) can be other number, it's only required that $j_{1},\dots,j_{23}$ can be recovered.
2. Try the other $22$ bits and check whether the following point: $$\left(m-\sum\limits_{k=24}^{45}{j_{k}2^{e_{k}}}\right)P$$is a key of $T$. Once the key is found, the exponent is revealed.

## Remark

### Too Slow?!

As the curve operations could be slow, there are some ways to speed-up our computations:

1. Pre-computing the points $\{2^{e_{j}}P,\quad j = 1,\dots,45\}$
2. Transform the curve into Weierstrass form [Sage code](https://neuromancer.sk/std/other/Curve41417) and there are libraries optimizing such things 

### Highlight

When the number of unknowns is small enough (less than $50$), then it's possible to apply MITM. For instance, the following problems could be solved using this technique.

* *Fault* from TetCTF 2022
* *Corrupted-Curve+* from corCTF 2022 [Official Repo](https://github.com/Crusaders-of-Rust/corCTF-2022-public-challenge-archive/tree/master/crypto/corruptedcurvesplus)

## Quick Implementation

```python
# MITM 1st Step
lookup = {}

# Pre-processing for speed-up
tmp = mul(hint, base)
points = [mul(1 << (313 + i), base) for i in range(22)]

for i in range(1 << 22):
	
	res = tmp
	for j in range(22):
		if i & (1 << j):
			res = add(points[j], res)
	lookup[res] = i

# MTIM 2nd Step

# Pre-processing for speed-up
points = [inverse(mul(1 << (13 + i), base)) for i in range(22)]
points += [inverse(mul(1 << 196, base))]

for i in range(1 << 22):
	
	res = enc
	for j in range(22):
		if i & (1 << j):
			res = add(points[j], res)
            
	if res in lookup:
		print(i)
		print(lookup[res])

	if add(points[-1], res) in lookup:
		print("+")
		print(i)
		print(lookup[res])

```

You should be able to find the flag from here :P 

:::success
maple{th3_3dw4rd_cu12ve_and_kn0wn_bits_dlp}
:::

Sorry for my ugly code, you may also refer [maple3142 and vishiswoz's scripts](https://gist.github.com/maple3142/39cface48563d01dc90607344c6bcad9)




