Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggested English changes to Discrete Logarithm #679

Merged
merged 1 commit into from
Jan 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 34 additions & 34 deletions algorithms/algebraic/discrete_log/discrete_log.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
"source": [
"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",
"\n",
"### Problem formulation\n",
"## Formulating the Problem\n",
"\n",
"* **Input:** A cyclic group $G = \\langle g \\rangle$ with $g$ as a generator, and an element $x\\in G$.\n",
"\n",
"* **Promise:** There is a number $s$ such that $g^s = x$.\n",
"\n",
"* **Output:** $s$, the discrete logarithm: $s = \\log_gx$\n",
"* **Output:** $s$, the discrete logarithm: $s = \\log_gx$.\n",
"\n",
"*** \n",
"\n",
"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",
"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",
"\n",
"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",
"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",
"$$\n",
"f: \\mathbb{Z}_N \\times \\mathbb{Z}_N \\rightarrow G\n",
"$$\n",
Expand All @@ -41,29 +41,29 @@
"id": "8ab4be3d-dbd8-41d4-be9d-d025deebf713",
"metadata": {},
"source": [
"## How to build the Algorithm with Classiq"
"## Building the Algorithm with Classiq"
]
},
{
"cell_type": "markdown",
"id": "b14cfda4-29fa-45e5-a59c-f4c798f09172",
"metadata": {},
"source": [
"The heart of the algorithm's logic is the implementation of the function:\n",
"The heart of the algorithm's logic is the implementation of the function\n",
"$$\n",
"|x_1\\rangle|x_2\\rangle|1\\rangle \\rightarrow |x_1\\rangle|x_2\\rangle|x^{x_1} g^{x_2}\\rangle \n",
"|x_1\\rangle|x_2\\rangle|1\\rangle \\rightarrow |x_1\\rangle|x_2\\rangle|x^{x_1} g^{x_2}\\rangle. \n",
"$$\n",
"\n",
"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",
"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",
"\n",
"The function `modular_exp` accepts the following arguments:\n",
"The `modular_exp` function accepts these arguments:\n",
"- `n: CInt` - modulo number\n",
"- `a: CInt` - base of the exponentiation\n",
"- `x: QArray[QBit]` - unsigned integer to multiply be the exponentiation\n",
"- `x: QArray[QBit]` - unsigned integer to multiply by the exponentiation\n",
"- `power: QArray[QBit]`- power of the exponentiation\n",
"\n",
"So that the function implements:\n",
"$|power\\rangle|x\\rangle \\rightarrow |power\\rangle|x \\cdot a ^ {power}\\mod n\\rangle$"
"So the function implements \n",
"$|power\\rangle|x\\rangle \\rightarrow |power\\rangle|x \\cdot a ^ {power}\\mod n\\rangle$."
]
},
{
Expand Down Expand Up @@ -97,10 +97,10 @@
"id": "23cf730e-17d2-4a76-b4d6-d39d4c9b865a",
"metadata": {},
"source": [
"### The full algorithm:\n",
"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",
"3. Compute `discrete_log_oracle` on the `func_res` variable. `func_res` should be of size $\\lceil \\log N\\rceil$.\n",
"4. Apply inverse Fourier transform `x1`, `x2`.\n",
"### Full Algorithm\n",
"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",
"3. Compute `discrete_log_oracle` on the `func_res` variable. `func_res` is of size $\\lceil \\log N\\rceil$.\n",
"4. Apply the inverse Fourier transform `x1`, `x2`.\n",
"5. Measure."
]
},
Expand Down Expand Up @@ -142,14 +142,14 @@
"id": "56b2c254-8894-4b05-9cf1-deded6ab15cc",
"metadata": {},
"source": [
"After the inverse QFTs, we get in the variables (under the assumption of $r=2^m$ for some $m$):\n",
"$$|\\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",
"After the inverse QFTs (under the assumption of $r=2^m$ for some $m$), the variables become\n",
"$$|\\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",
"\n",
"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",
"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",
"\n",
"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",
"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",
"\n",
"*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.*"
"*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.*"
]
},
{
Expand Down Expand Up @@ -178,9 +178,9 @@
"id": "c8c1edc5-0271-48c6-ac7d-7bdc17598568",
"metadata": {},
"source": [
"For this specific demonstration, we choose $G = \\mathbb{Z}_5^\\times$, with $g=3$ and $x=2$. Under this setting, $log_gx=3$.\n",
"For this specific demonstration, we choose $G = \\mathbb{Z}_5^\\times$, with $g=3$ and $x=2$. With this setting, $log_gx=3$.\n",
"\n",
"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."
"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."
]
},
{
Expand Down Expand Up @@ -248,10 +248,10 @@
"id": "c405feed-408f-4d91-a22c-0b445b2ff6c2",
"metadata": {},
"source": [
"Notice that `func_res` is uncorrelated to the other variables, and we get uniform distribution, as expected. \n",
"Note that `func_res` is uncorrelated to the other variables, and we get uniform distribution, as expected. \n",
"\n",
"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",
"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`:"
"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`:"
]
},
{
Expand Down Expand Up @@ -295,7 +295,7 @@
"id": "a83324a1-202e-4589-b663-e4b0e631e680",
"metadata": {},
"source": [
"Verify we got the correct discrete logarithm:"
"Verify we received the correct discrete logarithm:"
]
},
{
Expand All @@ -321,7 +321,7 @@
"id": "3fd236be-032d-4513-806c-086a8623a40d",
"metadata": {},
"source": [
"And indeed in both cases the same result, which is exactly the discrete logarithm: $\\log_32 \\mod 5 = 3$"
"And, indeed, both cases give the same result, which is exactly the discrete logarithm: $\\log_32 \\mod 5 = 3$."
]
},
{
Expand All @@ -337,9 +337,9 @@
"id": "1702d0f8-bca1-4e00-bffd-4b8c0ec4ddcb",
"metadata": {},
"source": [
"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",
"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",
"\n",
"In order to do that we can use the library function `prepare_uniform_trimmed_state` which prepare such a state efficiently."
"We do that using the `prepare_uniform_trimmed_state` library function, which efficiently prepares such a state."
]
},
{
Expand Down Expand Up @@ -367,7 +367,7 @@
") -> None:\n",
" reg_len = ceiling(log(order, 2)) + 1\n",
"\n",
" # we define the variables with fraction places in order to ease the post-processing\n",
" # we define the variables with fraction places to ease the postprocessing\n",
" allocate_num(reg_len, False, reg_len, x1)\n",
" allocate_num(reg_len, False, reg_len, x2)\n",
"\n",
Expand Down Expand Up @@ -453,15 +453,15 @@
"id": "89ea05c0-7939-42a3-8cdf-4e46989ce401",
"metadata": {},
"source": [
"#### Post process"
"#### Postprocessing"
]
},
{
"cell_type": "markdown",
"id": "74e6acb6-43c0-41ad-a0dc-eac9c9f5f5cc",
"metadata": {},
"source": [
"We now have additional step in post-process. We translate each result to the closest fraction with denominator which is the order:"
"We now have an additional step in postprocessing. We translate each result to the closest fraction with a denominator, which is the order:"
]
},
{
Expand Down Expand Up @@ -526,7 +526,7 @@
"id": "e2e15760-1bbb-4d79-8499-d111a2009135",
"metadata": {},
"source": [
"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:"
"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:"
]
},
{
Expand Down Expand Up @@ -578,7 +578,7 @@
"\n",
"<a id='DiscreteLog'>[1]</a>: [Discrete Logarithm (Wikipedia)](https://en.wikipedia.org/wiki/Discrete_logarithm)\n",
"\n",
"<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",
"<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",
"\n",
"<a id='DiffieHellman'>[3]</a>: [Diffie-Hellman Key Exchange (Wikipedia)](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)\n",
"\n",
Expand Down
Loading