|
15 | 15 | "source": [ |
16 | 16 | "The Discrete Logarithm Problem [[1](#DiscreteLog)] was shown by Shor [[2](#Shor)] to be solved in a polynomial time using quantum computers, while the fastest classical algorithms take a superpolynomial time. The problem is at least as hard as the factoring problem. In fact, the hardness of the problem is the basis for the Diffie-Hellman [[3](#DiffieHellman)] protocol for key exchange. \n", |
17 | 17 | "\n", |
18 | | - "### Problem formulation\n", |
| 18 | + "## Formulating the Problem\n", |
19 | 19 | "\n", |
20 | 20 | "* **Input:** A cyclic group $G = \\langle g \\rangle$ with $g$ as a generator, and an element $x\\in G$.\n", |
21 | 21 | "\n", |
22 | 22 | "* **Promise:** There is a number $s$ such that $g^s = x$.\n", |
23 | 23 | "\n", |
24 | | - "* **Output:** $s$, the discrete logarithm: $s = \\log_gx$\n", |
| 24 | + "* **Output:** $s$, the discrete logarithm: $s = \\log_gx$.\n", |
25 | 25 | "\n", |
26 | 26 | "*** \n", |
27 | 27 | "\n", |
28 | | - "In Shor's implementation the order of $g$ is assumed to be known beforehand (for example using the order finding algorithm). We will also assume it in the demonstration. \n", |
| 28 | + "In Shor's implementation, the order of $g$ is assumed to be known beforehand (for example, using the order finding algorithm). We also assume it in the demonstration. \n", |
29 | 29 | "\n", |
30 | | - "The Discrete Log problem is a specific example for the Abelian Hidden Subgroup Problem [[4](#HSP)], for the case of an additive group, with the function:\n", |
| 30 | + "The Discrete Log problem is a specific example of the Abelian Hidden Subgroup Problem [[4](#HSP)] for the case of an additive group, with this function:\n", |
31 | 31 | "$$\n", |
32 | 32 | "f: \\mathbb{Z}_N \\times \\mathbb{Z}_N \\rightarrow G\n", |
33 | 33 | "$$\n", |
|
41 | 41 | "id": "8ab4be3d-dbd8-41d4-be9d-d025deebf713", |
42 | 42 | "metadata": {}, |
43 | 43 | "source": [ |
44 | | - "## How to build the Algorithm with Classiq" |
| 44 | + "## Building the Algorithm with Classiq" |
45 | 45 | ] |
46 | 46 | }, |
47 | 47 | { |
48 | 48 | "cell_type": "markdown", |
49 | 49 | "id": "b14cfda4-29fa-45e5-a59c-f4c798f09172", |
50 | 50 | "metadata": {}, |
51 | 51 | "source": [ |
52 | | - "The heart of the algorithm's logic is the implementation of the function:\n", |
| 52 | + "The heart of the algorithm's logic is the implementation of the function\n", |
53 | 53 | "$$\n", |
54 | | - "|x_1\\rangle|x_2\\rangle|1\\rangle \\rightarrow |x_1\\rangle|x_2\\rangle|x^{x_1} g^{x_2}\\rangle \n", |
| 54 | + "|x_1\\rangle|x_2\\rangle|1\\rangle \\rightarrow |x_1\\rangle|x_2\\rangle|x^{x_1} g^{x_2}\\rangle. \n", |
55 | 55 | "$$\n", |
56 | 56 | "\n", |
57 | | - "This is done using 2 applications of the modular exponentiation function, which was described in detail in the [Shor's Factoring Algorithm](https://github.com/Classiq/classiq-library/blob/main/algorithms/algebraic/shor/shor_modular_exponentiation.ipynb) notebook. So here we will just import it from the classiq's library.\n", |
| 57 | + "This is done using two applications of the modular exponentiation function, described in detail in the [Shor's Factoring Algorithm](https://github.com/Classiq/classiq-library/blob/main/algorithms/algebraic/shor/shor_modular_exponentiation.ipynb) notebook. So here we import it from the Classiq library.\n", |
58 | 58 | "\n", |
59 | | - "The function `modular_exp` accepts the following arguments:\n", |
| 59 | + "The `modular_exp` function accepts these arguments:\n", |
60 | 60 | "- `n: CInt` - modulo number\n", |
61 | 61 | "- `a: CInt` - base of the exponentiation\n", |
62 | | - "- `x: QArray[QBit]` - unsigned integer to multiply be the exponentiation\n", |
| 62 | + "- `x: QArray[QBit]` - unsigned integer to multiply by the exponentiation\n", |
63 | 63 | "- `power: QArray[QBit]`- power of the exponentiation\n", |
64 | 64 | "\n", |
65 | | - "So that the function implements:\n", |
66 | | - "$|power\\rangle|x\\rangle \\rightarrow |power\\rangle|x \\cdot a ^ {power}\\mod n\\rangle$" |
| 65 | + "So the function implements \n", |
| 66 | + "$|power\\rangle|x\\rangle \\rightarrow |power\\rangle|x \\cdot a ^ {power}\\mod n\\rangle$." |
67 | 67 | ] |
68 | 68 | }, |
69 | 69 | { |
|
97 | 97 | "id": "23cf730e-17d2-4a76-b4d6-d39d4c9b865a", |
98 | 98 | "metadata": {}, |
99 | 99 | "source": [ |
100 | | - "### The full algorithm:\n", |
101 | | - "1. Prepare uniform superposition over the first 2 quantum variables `x1`, `x2`. Each variable should be with size $\\lceil \\log r\\rceil + \\log({1/{\\epsilon}})$. In the special case where $r$ is a power of 2, $\\log r$ is enough.\n", |
102 | | - "3. Compute `discrete_log_oracle` on the `func_res` variable. `func_res` should be of size $\\lceil \\log N\\rceil$.\n", |
103 | | - "4. Apply inverse Fourier transform `x1`, `x2`.\n", |
| 100 | + "### Full Algorithm\n", |
| 101 | + "1. Prepare uniform superposition over the first two quantum variables `x1`, `x2`. Each variable has size $\\lceil \\log r\\rceil + \\log({1/{\\epsilon}})$. In the special case where $r$ is a power of 2, $\\log r$ is enough.\n", |
| 102 | + "3. Compute `discrete_log_oracle` on the `func_res` variable. `func_res` is of size $\\lceil \\log N\\rceil$.\n", |
| 103 | + "4. Apply the inverse Fourier transform `x1`, `x2`.\n", |
104 | 104 | "5. Measure." |
105 | 105 | ] |
106 | 106 | }, |
|
142 | 142 | "id": "56b2c254-8894-4b05-9cf1-deded6ab15cc", |
143 | 143 | "metadata": {}, |
144 | 144 | "source": [ |
145 | | - "After the inverse QFTs, we get in the variables (under the assumption of $r=2^m$ for some $m$):\n", |
146 | | - "$$|\\psi\\rangle = \\sum_{\\nu\\in\\mathbb{Z}_r, \\delta\\in G}\\omega^{\\nu\\delta}|\\nu\\cdot log_gx\\rangle_{x_1}|\\nu\\rangle_{x_2}|\\delta>_{func\\_res}$$\n", |
| 145 | + "After the inverse QFTs (under the assumption of $r=2^m$ for some $m$), the variables become\n", |
| 146 | + "$$|\\psi\\rangle = \\sum_{\\nu\\in\\mathbb{Z}_r, \\delta\\in G}\\omega^{\\nu\\delta}|\\nu\\cdot log_gx\\rangle_{x_1}|\\nu\\rangle_{x_2}|\\delta>_{func\\_res}$$.\n", |
147 | 147 | "\n", |
148 | | - "For every $\\nu$ that has a mutplicative inverse in $\\mathbb{Z}_r$, we can extract $s=\\log_xg$ by multiplying the first variable result by its inverse.\n", |
| 148 | + "For every $\\nu$ that has a multiplicative inverse in $\\mathbb{Z}_r$, we can extract $s=\\log_xg$ by multiplying the first variable result by its inverse.\n", |
149 | 149 | "\n", |
150 | | - "In the case where $r$ is not a power of 2, we get in the variables and approximation of: |$\\log_g(x)\\cdot \\nu/ r\\rangle_{x_1} |\\nu / r\\rangle_{x_2}$. So we can use the continued fractions algorithm [[5](#ContinuedFraction)] to compute $\\nu/r$, then using the same technique to calculate $\\log_gx$.\n", |
| 150 | + "If $r$ is not a power of 2, the variables get an approximation of |$\\log_g(x)\\cdot \\nu/ r\\rangle_{x_1} |\\nu / r\\rangle_{x_2}$. So we can use the continued fractions algorithm [[5](#ContinuedFraction)] to compute $\\nu/r$, then use the same technique to calculate $\\log_gx$.\n", |
151 | 151 | "\n", |
152 | | - "*Note: Alternatively, one might implement the $QFT_{\\mathbb{Z}_r}$ over general $r$, and instead of the uniform superposition prepare the states: $\\frac{1}{\\sqrt{r}}\\sum_{x\\in\\mathbb{r}}|x\\rangle$ in `x1`, `x2`. Then again no continued fractions post-process is required.*" |
| 152 | + "*Note: Alternatively, you could implement the $QFT_{\\mathbb{Z}_r}$ over general $r$, and instead of the uniform superposition, prepare the states: $\\frac{1}{\\sqrt{r}}\\sum_{x\\in\\mathbb{r}}|x\\rangle$ in `x1`, `x2`. Then, again, no continued fractions postprocessing is required.*" |
153 | 153 | ] |
154 | 154 | }, |
155 | 155 | { |
|
178 | 178 | "id": "c8c1edc5-0271-48c6-ac7d-7bdc17598568", |
179 | 179 | "metadata": {}, |
180 | 180 | "source": [ |
181 | | - "For this specific demonstration, we choose $G = \\mathbb{Z}_5^\\times$, with $g=3$ and $x=2$. Under this setting, $log_gx=3$.\n", |
| 181 | + "For this specific demonstration, we choose $G = \\mathbb{Z}_5^\\times$, with $g=3$ and $x=2$. With this setting, $log_gx=3$.\n", |
182 | 182 | "\n", |
183 | | - "We choose this specific example as the order of of the group $r=4$ is a power of $2$, and so we can get exactly the discrete logarithm, without continued-fractions post processing. In other cases, one has to use larger quantum variable for the exponents so the continued fractions post-processing will converge." |
| 183 | + "We choose this specific example because the order of the group $r=4$ is a power of $2$, so we can get the exact discrete logarithm without continued-fractions postprocessing. In other cases, we use a larger quantum variable for the exponents so the continued fractions postprocessing converges." |
184 | 184 | ] |
185 | 185 | }, |
186 | 186 | { |
|
248 | 248 | "id": "c405feed-408f-4d91-a22c-0b445b2ff6c2", |
249 | 249 | "metadata": {}, |
250 | 250 | "source": [ |
251 | | - "Notice that `func_res` is uncorrelated to the other variables, and we get uniform distribution, as expected. \n", |
| 251 | + "Note that `func_res` is uncorrelated to the other variables, and we get uniform distribution, as expected. \n", |
252 | 252 | "\n", |
253 | 253 | "We take only the `x2` that are co-prime to $r=4$, so they have a multiplicative-inverse. Hence `x2=1,3` are the relevant results.\n", |
254 | | - "So we get 2 relevant results (for all different $\\delta$s): $|1\\rangle|3\\rangle$, $|3\\rangle|1\\rangle$. All left to do to get the logarithm is to multiply `x1` by the inverse of `x2`:" |
| 254 | + "So we get two relevant results (for all different $\\delta$s): $|1\\rangle|3\\rangle$, $|3\\rangle|1\\rangle$. All that remains to get the logarithm is to multiply `x1` by the inverse of `x2`:" |
255 | 255 | ] |
256 | 256 | }, |
257 | 257 | { |
|
295 | 295 | "id": "a83324a1-202e-4589-b663-e4b0e631e680", |
296 | 296 | "metadata": {}, |
297 | 297 | "source": [ |
298 | | - "Verify we got the correct discrete logarithm:" |
| 298 | + "Verify we received the correct discrete logarithm:" |
299 | 299 | ] |
300 | 300 | }, |
301 | 301 | { |
|
321 | 321 | "id": "3fd236be-032d-4513-806c-086a8623a40d", |
322 | 322 | "metadata": {}, |
323 | 323 | "source": [ |
324 | | - "And indeed in both cases the same result, which is exactly the discrete logarithm: $\\log_32 \\mod 5 = 3$" |
| 324 | + "And, indeed, both cases give the same result, which is exactly the discrete logarithm: $\\log_32 \\mod 5 = 3$." |
325 | 325 | ] |
326 | 326 | }, |
327 | 327 | { |
|
337 | 337 | "id": "1702d0f8-bca1-4e00-bffd-4b8c0ec4ddcb", |
338 | 338 | "metadata": {}, |
339 | 339 | "source": [ |
340 | | - "Here we take the case were the order is not a power of 2. In the circuit creation, we will need to change the state preparation. Instead of creating the entire uniform distribution on the `x1`, `x2` variables, we will load them with the uniform superposition of only the first `#ORDER` states.\n", |
| 340 | + "In this case the order is not a power of 2. During circuit creation, we change the state preparation: instead of creating the entire uniform distribution on the `x1`, `x2` variables, we load them with the uniform superposition of only the first `#ORDER` states.\n", |
341 | 341 | "\n", |
342 | | - "In order to do that we can use the library function `prepare_uniform_trimmed_state` which prepare such a state efficiently." |
| 342 | + "We do that using the `prepare_uniform_trimmed_state` library function, which efficiently prepares such a state." |
343 | 343 | ] |
344 | 344 | }, |
345 | 345 | { |
|
367 | 367 | ") -> None:\n", |
368 | 368 | " reg_len = ceiling(log(order, 2)) + 1\n", |
369 | 369 | "\n", |
370 | | - " # we define the variables with fraction places in order to ease the post-processing\n", |
| 370 | + " # we define the variables with fraction places to ease the postprocessing\n", |
371 | 371 | " allocate_num(reg_len, False, reg_len, x1)\n", |
372 | 372 | " allocate_num(reg_len, False, reg_len, x2)\n", |
373 | 373 | "\n", |
|
453 | 453 | "id": "89ea05c0-7939-42a3-8cdf-4e46989ce401", |
454 | 454 | "metadata": {}, |
455 | 455 | "source": [ |
456 | | - "#### Post process" |
| 456 | + "#### Postprocessing" |
457 | 457 | ] |
458 | 458 | }, |
459 | 459 | { |
460 | 460 | "cell_type": "markdown", |
461 | 461 | "id": "74e6acb6-43c0-41ad-a0dc-eac9c9f5f5cc", |
462 | 462 | "metadata": {}, |
463 | 463 | "source": [ |
464 | | - "We now have additional step in post-process. We translate each result to the closest fraction with denominator which is the order:" |
| 464 | + "We now have an additional step in postprocessing. We translate each result to the closest fraction with a denominator, which is the order:" |
465 | 465 | ] |
466 | 466 | }, |
467 | 467 | { |
|
526 | 526 | "id": "e2e15760-1bbb-4d79-8499-d111a2009135", |
527 | 527 | "metadata": {}, |
528 | 528 | "source": [ |
529 | | - "Now take a sample where `x2` is co-prime to the order, such that we can get the logarithm by multiplying `x1` by the modular inverse. If the the `x1`, `x2` registers are large enough, we are guaranteed to sample it with a good probability:" |
| 529 | + "Now, we take a sample where `x2` is co-prime to the order, such that we can get the logarithm by multiplying `x1` by the modular inverse. If the `x1`, `x2` registers are large enough, we are guaranteed to sample it with a good probability:" |
530 | 530 | ] |
531 | 531 | }, |
532 | 532 | { |
|
578 | 578 | "\n", |
579 | 579 | "<a id='DiscreteLog'>[1]</a>: [Discrete Logarithm (Wikipedia)](https://en.wikipedia.org/wiki/Discrete_logarithm)\n", |
580 | 580 | "\n", |
581 | | - "<a id='Shor94'>[2]</a>: [Shor, Peter W. \"Algorithms for quantum computation: discrete logarithms and factoring.\" Proceedings 35th annual symposium on foundations of computer science. Ieee, 1994.](https://ieeexplore.ieee.org/abstract/document/365700)\n", |
| 581 | + "<a id='Shor94'>[2]</a>: [Shor, Peter W. \"Algorithms for quantum computation: discrete logarithms and factoring.\" Proceedings 35th annual symposium on foundations of computer science. IEEE, 1994.](https://ieeexplore.ieee.org/abstract/document/365700)\n", |
582 | 582 | "\n", |
583 | 583 | "<a id='DiffieHellman'>[3]</a>: [Diffie-Hellman Key Exchange (Wikipedia)](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)\n", |
584 | 584 | "\n", |
|
0 commit comments