unitarylab-algorithms 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. unitarylab_algorithms/__init__.py +79 -0
  2. unitarylab_algorithms/algo_base.py +129 -0
  3. unitarylab_algorithms/cryptology/__init__.py +17 -0
  4. unitarylab_algorithms/cryptology/discrete_log/README_en.md +104 -0
  5. unitarylab_algorithms/cryptology/discrete_log/README_zh.md +104 -0
  6. unitarylab_algorithms/cryptology/discrete_log/__init__.py +13 -0
  7. unitarylab_algorithms/cryptology/discrete_log/algorithm.py +223 -0
  8. unitarylab_algorithms/cryptology/discrete_log/parameters.json +42 -0
  9. unitarylab_algorithms/cryptology/shor/README_en.md +106 -0
  10. unitarylab_algorithms/cryptology/shor/README_zh.md +107 -0
  11. unitarylab_algorithms/cryptology/shor/__init__.py +13 -0
  12. unitarylab_algorithms/cryptology/shor/algorithm.py +329 -0
  13. unitarylab_algorithms/cryptology/shor/parameters.json +30 -0
  14. unitarylab_algorithms/cryptology/simon/README_en.md +100 -0
  15. unitarylab_algorithms/cryptology/simon/README_zh.md +100 -0
  16. unitarylab_algorithms/cryptology/simon/__init__.py +13 -0
  17. unitarylab_algorithms/cryptology/simon/algorithm.py +173 -0
  18. unitarylab_algorithms/cryptology/simon/parameters.json +20 -0
  19. unitarylab_algorithms/fundamental_algorithm/__init__.py +22 -0
  20. unitarylab_algorithms/fundamental_algorithm/amplitude_amplification/README_en.md +79 -0
  21. unitarylab_algorithms/fundamental_algorithm/amplitude_amplification/README_zh.md +83 -0
  22. unitarylab_algorithms/fundamental_algorithm/amplitude_amplification/__init__.py +13 -0
  23. unitarylab_algorithms/fundamental_algorithm/amplitude_amplification/algorithm.py +231 -0
  24. unitarylab_algorithms/fundamental_algorithm/amplitude_amplification/parameters.json +31 -0
  25. unitarylab_algorithms/fundamental_algorithm/amplitude_estimation/README_en.md +77 -0
  26. unitarylab_algorithms/fundamental_algorithm/amplitude_estimation/README_zh.md +78 -0
  27. unitarylab_algorithms/fundamental_algorithm/amplitude_estimation/__init__.py +14 -0
  28. unitarylab_algorithms/fundamental_algorithm/amplitude_estimation/algorithm.py +251 -0
  29. unitarylab_algorithms/fundamental_algorithm/amplitude_estimation/parameters.json +32 -0
  30. unitarylab_algorithms/fundamental_algorithm/grover/README_en.md +87 -0
  31. unitarylab_algorithms/fundamental_algorithm/grover/README_zh.md +116 -0
  32. unitarylab_algorithms/fundamental_algorithm/grover/__init__.py +14 -0
  33. unitarylab_algorithms/fundamental_algorithm/grover/algorithm.py +206 -0
  34. unitarylab_algorithms/fundamental_algorithm/grover/parameters.json +30 -0
  35. unitarylab_algorithms/fundamental_algorithm/hadamard_test/README_en.md +77 -0
  36. unitarylab_algorithms/fundamental_algorithm/hadamard_test/README_zh.md +81 -0
  37. unitarylab_algorithms/fundamental_algorithm/hadamard_test/__init__.py +13 -0
  38. unitarylab_algorithms/fundamental_algorithm/hadamard_test/algorithm.py +263 -0
  39. unitarylab_algorithms/fundamental_algorithm/hadamard_test/parameters.json +36 -0
  40. unitarylab_algorithms/fundamental_algorithm/hadamard_transform/README_en.md +73 -0
  41. unitarylab_algorithms/fundamental_algorithm/hadamard_transform/README_zh.md +78 -0
  42. unitarylab_algorithms/fundamental_algorithm/hadamard_transform/__init__.py +12 -0
  43. unitarylab_algorithms/fundamental_algorithm/hadamard_transform/algorithm.py +176 -0
  44. unitarylab_algorithms/fundamental_algorithm/hadamard_transform/parameters.json +22 -0
  45. unitarylab_algorithms/fundamental_algorithm/qpe/README_en.md +78 -0
  46. unitarylab_algorithms/fundamental_algorithm/qpe/README_zh.md +80 -0
  47. unitarylab_algorithms/fundamental_algorithm/qpe/__init__.py +14 -0
  48. unitarylab_algorithms/fundamental_algorithm/qpe/algorithm.py +159 -0
  49. unitarylab_algorithms/fundamental_algorithm/qpe/parameters.json +32 -0
  50. unitarylab_algorithms/hamiltonian_simulation/__init__.py +18 -0
  51. unitarylab_algorithms/hamiltonian_simulation/cartan/README_en.md +93 -0
  52. unitarylab_algorithms/hamiltonian_simulation/cartan/README_zh.md +93 -0
  53. unitarylab_algorithms/hamiltonian_simulation/cartan/__init__.py +14 -0
  54. unitarylab_algorithms/hamiltonian_simulation/cartan/algorithm.py +133 -0
  55. unitarylab_algorithms/hamiltonian_simulation/cartan/parameters.json +39 -0
  56. unitarylab_algorithms/hamiltonian_simulation/qdrift/README_en.md +103 -0
  57. unitarylab_algorithms/hamiltonian_simulation/qdrift/README_zh.md +103 -0
  58. unitarylab_algorithms/hamiltonian_simulation/qdrift/__init__.py +5 -0
  59. unitarylab_algorithms/hamiltonian_simulation/qdrift/algorithm.py +227 -0
  60. unitarylab_algorithms/hamiltonian_simulation/qdrift/parameters.json +39 -0
  61. unitarylab_algorithms/hamiltonian_simulation/qsp/README_en.md +103 -0
  62. unitarylab_algorithms/hamiltonian_simulation/qsp/README_zh.md +103 -0
  63. unitarylab_algorithms/hamiltonian_simulation/qsp/__init__.py +5 -0
  64. unitarylab_algorithms/hamiltonian_simulation/qsp/algorithm.py +230 -0
  65. unitarylab_algorithms/hamiltonian_simulation/qsp/parameters.json +39 -0
  66. unitarylab_algorithms/hamiltonian_simulation/taylor/README_en.md +101 -0
  67. unitarylab_algorithms/hamiltonian_simulation/taylor/README_zh.md +97 -0
  68. unitarylab_algorithms/hamiltonian_simulation/taylor/__init__.py +5 -0
  69. unitarylab_algorithms/hamiltonian_simulation/taylor/algorithm.py +266 -0
  70. unitarylab_algorithms/hamiltonian_simulation/taylor/parameters.json +39 -0
  71. unitarylab_algorithms/hamiltonian_simulation/trotter/README_en.md +106 -0
  72. unitarylab_algorithms/hamiltonian_simulation/trotter/README_zh.md +106 -0
  73. unitarylab_algorithms/hamiltonian_simulation/trotter/__init__.py +14 -0
  74. unitarylab_algorithms/hamiltonian_simulation/trotter/algorithm.py +253 -0
  75. unitarylab_algorithms/hamiltonian_simulation/trotter/parameters.json +49 -0
  76. unitarylab_algorithms/linear_algebra/__init__.py +22 -0
  77. unitarylab_algorithms/linear_algebra/hhl/README_en.md +95 -0
  78. unitarylab_algorithms/linear_algebra/hhl/README_zh.md +95 -0
  79. unitarylab_algorithms/linear_algebra/hhl/__init__.py +18 -0
  80. unitarylab_algorithms/linear_algebra/hhl/algorithm.py +282 -0
  81. unitarylab_algorithms/linear_algebra/hhl/parameters.json +38 -0
  82. unitarylab_algorithms/linear_algebra/lcu/README_en.md +99 -0
  83. unitarylab_algorithms/linear_algebra/lcu/README_zh.md +99 -0
  84. unitarylab_algorithms/linear_algebra/lcu/__init__.py +16 -0
  85. unitarylab_algorithms/linear_algebra/lcu/algorithm.py +232 -0
  86. unitarylab_algorithms/linear_algebra/lcu/parameters.json +38 -0
  87. unitarylab_algorithms/linear_algebra/qft/README_en.md +87 -0
  88. unitarylab_algorithms/linear_algebra/qft/README_zh.md +87 -0
  89. unitarylab_algorithms/linear_algebra/qft/__init__.py +14 -0
  90. unitarylab_algorithms/linear_algebra/qft/algorithm.py +140 -0
  91. unitarylab_algorithms/linear_algebra/qft/parameters.json +36 -0
  92. unitarylab_algorithms/linear_algebra/qsp/README_en.md +98 -0
  93. unitarylab_algorithms/linear_algebra/qsp/README_zh.md +98 -0
  94. unitarylab_algorithms/linear_algebra/qsp/__init__.py +10 -0
  95. unitarylab_algorithms/linear_algebra/qsp/algorithm.py +144 -0
  96. unitarylab_algorithms/linear_algebra/qsp/parameters.json +42 -0
  97. unitarylab_algorithms/linear_algebra/qsvt_qlsa/README_en.md +89 -0
  98. unitarylab_algorithms/linear_algebra/qsvt_qlsa/README_zh.md +89 -0
  99. unitarylab_algorithms/linear_algebra/qsvt_qlsa/__init__.py +17 -0
  100. unitarylab_algorithms/linear_algebra/qsvt_qlsa/algorithm.py +90 -0
  101. unitarylab_algorithms/linear_algebra/qsvt_qlsa/parameters.json +38 -0
  102. unitarylab_algorithms/linear_algebra/vqls/README.md +382 -0
  103. unitarylab_algorithms/linear_algebra/vqls/README_en.md +92 -0
  104. unitarylab_algorithms/linear_algebra/vqls/README_zh.md +93 -0
  105. unitarylab_algorithms/linear_algebra/vqls/__init__.py +8 -0
  106. unitarylab_algorithms/linear_algebra/vqls/algorithm.py +386 -0
  107. unitarylab_algorithms/linear_algebra/vqls/parameters.json +40 -0
  108. unitarylab_algorithms/quantum_machine_learning/__init__.py +21 -0
  109. unitarylab_algorithms/quantum_machine_learning/cvqnn/README_en.md +81 -0
  110. unitarylab_algorithms/quantum_machine_learning/cvqnn/README_zh.md +82 -0
  111. unitarylab_algorithms/quantum_machine_learning/cvqnn/__init__.py +7 -0
  112. unitarylab_algorithms/quantum_machine_learning/cvqnn/algorithm.py +281 -0
  113. unitarylab_algorithms/quantum_machine_learning/cvqnn/parameters.json +50 -0
  114. unitarylab_algorithms/quantum_machine_learning/qaoa/README_en.md +89 -0
  115. unitarylab_algorithms/quantum_machine_learning/qaoa/README_zh.md +90 -0
  116. unitarylab_algorithms/quantum_machine_learning/qaoa/__init__.py +6 -0
  117. unitarylab_algorithms/quantum_machine_learning/qaoa/algorithm.py +188 -0
  118. unitarylab_algorithms/quantum_machine_learning/qaoa/parameters.json +50 -0
  119. unitarylab_algorithms/quantum_machine_learning/qcbm/README_en.md +89 -0
  120. unitarylab_algorithms/quantum_machine_learning/qcbm/README_zh.md +90 -0
  121. unitarylab_algorithms/quantum_machine_learning/qcbm/__init__.py +7 -0
  122. unitarylab_algorithms/quantum_machine_learning/qcbm/algorithm.py +194 -0
  123. unitarylab_algorithms/quantum_machine_learning/qcbm/parameters.json +50 -0
  124. unitarylab_algorithms/quantum_machine_learning/vqc/README_en.md +77 -0
  125. unitarylab_algorithms/quantum_machine_learning/vqc/README_zh.md +78 -0
  126. unitarylab_algorithms/quantum_machine_learning/vqc/__init__.py +7 -0
  127. unitarylab_algorithms/quantum_machine_learning/vqc/algorithm.py +527 -0
  128. unitarylab_algorithms/quantum_machine_learning/vqc/parameters.json +50 -0
  129. unitarylab_algorithms/quantum_machine_learning/vqe/README_en.md +84 -0
  130. unitarylab_algorithms/quantum_machine_learning/vqe/README_zh.md +85 -0
  131. unitarylab_algorithms/quantum_machine_learning/vqe/__init__.py +6 -0
  132. unitarylab_algorithms/quantum_machine_learning/vqe/algorithm.py +212 -0
  133. unitarylab_algorithms/quantum_machine_learning/vqe/parameters.json +42 -0
  134. unitarylab_algorithms/schrodingerization/__init__.py +21 -0
  135. unitarylab_algorithms/schrodingerization/base.py +441 -0
  136. unitarylab_algorithms/schrodingerization/equation_advection/__init__.py +20 -0
  137. unitarylab_algorithms/schrodingerization/equation_advection/algorithm.py +281 -0
  138. unitarylab_algorithms/schrodingerization/equation_advection/setup.json +195 -0
  139. unitarylab_algorithms/schrodingerization/equation_heat/__init__.py +20 -0
  140. unitarylab_algorithms/schrodingerization/equation_heat/algorithm.py +311 -0
  141. unitarylab_algorithms/schrodingerization/equation_heat/setup.json +172 -0
  142. unitarylab_algorithms/schrodingerization/equation_heat2d/__init__.py +20 -0
  143. unitarylab_algorithms/schrodingerization/equation_heat2d/algorithm.py +360 -0
  144. unitarylab_algorithms/schrodingerization/equation_heat2d/setup.json +171 -0
  145. unitarylab_algorithms/template.py +87 -0
  146. unitarylab_algorithms-1.0.0.dist-info/METADATA +81 -0
  147. unitarylab_algorithms-1.0.0.dist-info/RECORD +150 -0
  148. unitarylab_algorithms-1.0.0.dist-info/WHEEL +5 -0
  149. unitarylab_algorithms-1.0.0.dist-info/licenses/LICENSE +7 -0
  150. unitarylab_algorithms-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,79 @@
1
+ """
2
+ Quantum Algorithms
3
+ =========================
4
+
5
+ This module provides quantum algorithms including:
6
+ - Cryptology algorithms
7
+ - Discrete Logarithm Algorithm
8
+ - Shor's Algorithm
9
+ - Simon's Algorithm
10
+ - Fundamental algorithms
11
+ - Hadamard Test Algorithm
12
+ - Hadamard Transform Algorithm
13
+ - Grover's Algorithm
14
+ - Amplitude Amplification Algorithm
15
+ - Amplitude Estimation Algorithm
16
+ - Quantum Phase Estimation Algorithm
17
+ - Linear Algebra algorithms
18
+ - HHL Algorithm
19
+ - LCU Algorithm
20
+ - QFT Algorithm
21
+ - QSP Algorithm
22
+ - QSVT(QLSA) Algorithm
23
+ - VQLS Algorithm
24
+ - Hamiltonian Simulation algorithms
25
+ - Trotter Algorithm
26
+ - QDRIFT Algorithm
27
+ - Taylor Series Algorithm
28
+ - QSP Algorithm
29
+ - Quantum Machine Learning algorithms
30
+ - VQE Algorithm
31
+ - QAOA Algorithm
32
+ - QCBM Algorithm
33
+ - VQC Algorithm
34
+ - CVQNN Algorithm
35
+ """
36
+
37
+ from .cryptology import *
38
+ from .fundamental_algorithm import *
39
+ from .linear_algebra import *
40
+ from .hamiltonian_simulation import *
41
+ from .quantum_machine_learning import *
42
+ from .schrodingerization import *
43
+
44
+ __all__ = [
45
+ "DiscreteLogAlgorithm",
46
+ "ShorAlgorithm",
47
+ "SimonAlgorithm",
48
+
49
+ "HadamardTransformAlgorithm",
50
+ "HadamardTestAlgorithm",
51
+ "AmplitudeAmplificationAlgorithm",
52
+ "AmplitudeEstimationAlgorithm",
53
+ "GroverAlgorithm",
54
+ "QPEAlgorithm",
55
+
56
+ "TrotterAlgorithm",
57
+ "QDriftAlgorithm",
58
+ "TaylorAlgorithm",
59
+ "QSPHSAlgorithm",
60
+ "CartanDecompositionAlgorithm",
61
+
62
+ "HHLAlgorithm",
63
+ "LCUAlgorithm",
64
+ "QFTAlgorithm",
65
+ "QSPAlgorithm",
66
+ "QSVTLinearSolverAlgorithm",
67
+ "VQLSAlgorithm",
68
+
69
+ "VQEAlgorithm",
70
+ "QAOAAlgorithm",
71
+ "CVQNNAlgorithm",
72
+ "QCBMAlgorithm",
73
+ "VQCAlgorithm",
74
+
75
+ "HeatEquationAlgorithm",
76
+ "AdvectionEquationAlgorithm",
77
+ "Heat2dEquationAlgorithm",
78
+ ]
79
+
@@ -0,0 +1,129 @@
1
+ from typing import Any, Dict, List, Optional
2
+ import os
3
+
4
+
5
+ class BaseAlgorithm:
6
+ """Shared base class for algorithm result/log formatting."""
7
+
8
+ def __init__(self, name: str, prefix: str = "", text_mode: str = "plain", algo_dir: Optional[str] = None):
9
+ self.name = self.__class__.__name__ if name == "" else name
10
+ self.prefix = self.name[:3].upper() if prefix == "" else prefix
11
+ self.prefix = '[' + self.prefix + ']' if not self.prefix.startswith('[') else self.prefix
12
+
13
+ self.text_mode = text_mode
14
+ self.algo_dir = algo_dir
15
+ self.status = ""
16
+ self.input: Dict[str, Any] = {}
17
+ self.output: Dict[str, Any] = {}
18
+ self.info: list = []
19
+ self.summary: str = ""
20
+
21
+ def run(self, *args, **kwargs) -> Dict[str, Any]:
22
+ """Run the algorithm with given parameters. To be implemented by subclasses."""
23
+ raise NotImplementedError("Subclasses must implement the run() method.")
24
+
25
+ def _auxiliary_method(self, *args, **kwargs) -> Any:
26
+ """An example auxiliary method that can be used by subclasses."""
27
+ pass
28
+
29
+ def log(self, message) -> None:
30
+ """Print a message and save it into info logs."""
31
+ if isinstance(message, str):
32
+ msg = self.prefix + ": " + message
33
+ print(msg)
34
+ self.info.append(message)
35
+ elif isinstance(message, dict):
36
+ for key, value in message.items():
37
+ msg = f" - {key} = {value}"
38
+ print(msg)
39
+
40
+ def update_input(self, input_dict: Dict[str, Any]) -> None:
41
+ """Update the input parameters dictionary."""
42
+ self.input.update(input_dict)
43
+ print(f"{self.prefix}: Starting {self.name}")
44
+ print(f"{self.prefix}: Input parameters: ")
45
+ self.log(self.input)
46
+
47
+ def update_output(self, output_dict: Dict[str, Any]) -> None:
48
+ """Update the output information dictionary."""
49
+ self.output.update(output_dict)
50
+ print(f"{self.prefix}: Output information: ")
51
+ self.log(self.output)
52
+
53
+ def save_circuit(self, circuit, name=None) -> str:
54
+ """Save the circuit into a file."""
55
+ if name is None:
56
+ filename = f"{self.name.replace(' ', '_').lower()}_circuit.svg"
57
+ else:
58
+ filename = f"{name}.svg"
59
+
60
+ filepath = f"{self.algo_dir}/{filename}"
61
+ circuit.draw(filename=filepath, title=f"{self.name} Circuit")
62
+ self.log(f" Circuit diagram saved: {filepath}")
63
+ return filepath
64
+
65
+ def save_txt(self) -> None:
66
+ """Save the algorithm result into a file."""
67
+ filename = f"{self.name.replace(' ', '_').lower()}_result.txt"
68
+ filepath = f"{self.algo_dir}/{filename}"
69
+ with open(filepath, "w", encoding="utf-8") as f:
70
+ f.write(self.format_result_ascii())
71
+ self.log(f" Result saved: {filepath}")
72
+ return filename
73
+
74
+ def _build_return_dict(self, success: bool, circuit_path, filepath, circuit=None) -> Dict[str, Any]:
75
+ """Build a dictionary containing all relevant information for returning."""
76
+ success = 'ok' if success else 'failed'
77
+ if isinstance(filepath, str):
78
+ filepath = [filepath]
79
+ files = []
80
+ for filename in filepath:
81
+ files.append({"format": filename[-3:], "filename": filename})
82
+
83
+ result = {"status": success, "circuit_path": circuit_path, "plot": files, "circuit": circuit}
84
+ return result.update(self.output) or result
85
+
86
+ def format_result_ascii(self) -> str:
87
+ """Format the most recent algorithm result as text output."""
88
+ result = ""
89
+ # Algorithm start
90
+ if self.text_mode == "plain":
91
+ result += '\n' + f'{"=" * 25}\n{self.name} Algorithm Result\n{"=" * 25}\n'
92
+ elif self.text_mode == "legacy":
93
+ result += '=' * 70 + '\n' + f"{' ' * 10}⚛️ {self.name} Algorithm Result ⚛️\n" + '=' * 70 + '\n'
94
+
95
+ # Solve status
96
+ if self.text_mode == "plain":
97
+ result += f"Status: {self.status}\n\n"
98
+ elif self.text_mode == "legacy":
99
+ result += f"📊 Status: {self.status}\n\n"
100
+
101
+ # Input parameters
102
+ if self.text_mode == "plain":
103
+ result += "Input parameters:\n"
104
+ elif self.text_mode == "legacy":
105
+ result += "-" * 70 + '\n' + "📥 Input parameters:\n" + "-" * 70 + "\n"
106
+ result += "\n".join([f" - {key}: {value}" for key, value in self.input.items()]) + "\n\n"
107
+
108
+ # Runtime logs
109
+ if self.text_mode == "plain":
110
+ result += "Runtime logs:\n"
111
+ elif self.text_mode == "legacy":
112
+ result += "-" * 70 + '\n' + "📝 Runtime logs:\n" + "-" * 70 + "\n"
113
+ result += "\n".join([f" - {line}" for line in self.info]) + "\n\n"
114
+
115
+ # Output information
116
+ if self.text_mode == "plain":
117
+ result += "Output information:\n"
118
+ elif self.text_mode == "legacy":
119
+ result += "-" * 70 + '\n' + "📤 Output information:\n" + "-" * 70 + "\n"
120
+ result += "\n".join([f" - {key}: {value}" for key, value in self.output.items()]) + "\n\n"
121
+
122
+ # Summary
123
+ if self.text_mode == "plain":
124
+ result += "Summary:\n"
125
+ elif self.text_mode == "legacy":
126
+ result += "-" * 70 + '\n' + "🔍 Summary:\n" + "-" * 70 + "\n"
127
+ result += f" {self.summary}\n"
128
+
129
+ return result
@@ -0,0 +1,17 @@
1
+ """
2
+ Quantum Cryptology Algorithm
3
+ =========================
4
+
5
+ This module provides quantum algorithms including:
6
+ - dlg: Discrete Logarithm Problem (DLP) algorithm
7
+ """
8
+
9
+ from .discrete_log import DiscreteLogAlgorithm
10
+ from .shor import ShorAlgorithm
11
+ from .simon import SimonAlgorithm
12
+
13
+ __all__ = [
14
+ "DiscreteLogAlgorithm",
15
+ "ShorAlgorithm",
16
+ "SimonAlgorithm",
17
+ ]
@@ -0,0 +1,104 @@
1
+ # Discrete Logarithm Algorithm Explained
2
+
3
+ ## Parameter Settings
4
+
5
+ - `g`: Base, default value is `3`.
6
+ - `y`: Target value, default value is `13`.
7
+ - `P`: Modulus (typically a prime number), default value is `17`.
8
+
9
+ > **Summary**: The discrete logarithm algorithm is used to find the unknown $x$ in $g^x \equiv y \pmod P$ in polynomial time. Given the inputs $g$, $y$, and $P$, it encodes the period information using Quantum Phase Estimation, combines classical continued fractions with modular arithmetic techniques, and ultimately outputs the computed discrete logarithm $x$.
10
+
11
+ ---
12
+
13
+ ## Table of Contents
14
+
15
+ - [Execution Flow](#execution-flow)
16
+ - [Core Idea](#core-idea)
17
+ - [Mathematical Principles](#mathematical-principles)
18
+ - [Algorithm Steps](#algorithm-steps)
19
+ - [Quantum Advantage](#quantum-advantage)
20
+ - [Complexity Analysis](#complexity-analysis)
21
+ - [Applications and Impact](#applications-and-impact)
22
+
23
+ ---
24
+
25
+ ## Execution Flow
26
+
27
+ 1. **Parameter Preparation**:
28
+ - Verify that $g$ and $y$ must be coprime with $P$.
29
+ - Based on the bit length of $P$, calculate the count register size $n_{\text{count}}$ and work register size $n_{\text{work}}$ (a total of $2n_{\text{count}} + n_{\text{work}}$ qubits).
30
+ 2. **Quantum Circuit Construction**:
31
+ - Initialize two control (count) registers (corresponding to the powers of $g$ and $y^{-1}$) and one work register.
32
+ - Apply a Hadamard layer to the control registers to prepare a uniform superposition state.
33
+ - Initialize the work register to $|1\rangle$.
34
+ - For the first control register, apply controlled modular multiplication operators with multipliers $g^{2^i}$ (simulated by matrices).
35
+ - For the second control register, apply controlled modular multiplication operators with multipliers $(y^{-1})^{2^j}$ where $y^{-1}$ is the inverse in $\pmod P$ (simulated by matrices).
36
+ - Apply the **Inverse Quantum Fourier Transform (IQFT)** to both control registers.
37
+ 3. **Quantum Simulation and Measurement**:
38
+ - Execute the quantum circuit simulation.
39
+ - Extract the probability distribution of the respective quantum state components for further analysis.
40
+ 4. **Classical Post-processing (Continued Fractions & Congruences)**:
41
+ - Extract the most probable sets of observational values $(c_1, c_2)$ from the measured probability spectrum.
42
+ - Use classical continued fraction algorithms to analyze the ratio $c_1/N$ and extract the possible group order (period) $r$.
43
+ - Based on the extracted results for $x_1/r$ and $x_2/r$, formulate the linear modular equation $x \cdot x_1 + x_2 \equiv 0 \pmod r$ and solve for $x$.
44
+ - Verify if the result satisfies $g^x \equiv y \pmod P$.
45
+ 5. **Result Output**: Export the SVG chart of the quantum circuit, output the computation time, the detected period $r$, and the found result $x$.
46
+
47
+ ---
48
+
49
+ ## Core Idea
50
+
51
+ To solve the discrete logarithm problem $g^x \equiv y \pmod P$ over a finite cyclic group, Peter Shor demonstrated that it could be reduced to a Hidden Subgroup Problem (a 2D period-finding problem).
52
+ Define a function:
53
+ $$f(a,b) = g^a y^{-b} \bmod P$$
54
+ Evidently, if a pair $(a,b)$ is found such that $f(a,b) = 1$, since $y = g^x$, this implies:
55
+ $$g^a (g^x)^{-b} = g^{a - bx} \equiv 1 \pmod P$$
56
+ This equality holds when $a - bx \equiv 0 \pmod r$ (where $r$ is the multiplicative order of $g$). The unknown $x$ can then be classically computed using the modular inverse: $x = ab^{-1} \bmod r$. Thus, by locating the group's order and the function's implicit 2-dimensional period via quantum superposition and phase estimation, the variable $x$ can be successfully resolved.
57
+
58
+ ---
59
+
60
+ ## Mathematical Principles
61
+
62
+ ### Controlled Group Operations and Joint State
63
+ Using two registers each of size $N$ to represent the superposition state $(a,b)$, the joint state represents:
64
+ $$\frac{1}{N}\sum_{a=0}^{N-1}\sum_{b=0}^{N-1}|a\rangle|b\rangle|g^ay^{-b}\bmod P\rangle$$
65
+ This implicitly computes and encapsulates the periodic information across a 2D grid defined by $x$.
66
+
67
+ ### Two-Dimensional Quantum Fourier Transform
68
+ After applying two independent Quantum Fourier Transforms, the system's amplitudes will constructively interfere (forming peaks) around specific coordinate pairs $(c_1, c_2)$ satisfying:
69
+ $$\frac{c_1}{N} \approx \frac{k}{r} \quad \text{and} \quad \frac{c_2}{N} \approx \frac{kx}{r}$$
70
+ where $r$ is the period (the order of $g$ modulo $P$). By doing so, $r$ can be extracted from $c_1$, and subsequently $x$ can be derived by calculating $c_2/c_1 \approx x \pmod r$.
71
+
72
+ ---
73
+
74
+ ## Algorithm Steps
75
+
76
+ 1. **Classical Pre-check**: Check the coprime conditions and calculate the required sizes for the control and work registers.
77
+ 2. **State Preparation**: Prepare $|0\rangle^{\otimes 2n} |1\rangle$, then apply a Hadamard layer to obtain $|+\rangle^{\otimes 2n} |1\rangle$.
78
+ 3. **Quantum Period Mapping**: Apply the two-dimensional black-box controlled operator $U|a\rangle|b\rangle|z\rangle = |a\rangle|b\rangle|z \cdot g^a y^{-b} \bmod P\rangle$.
79
+ 4. **IQFT Phase Extraction**: Apply IQFT to the first two registers to concentrate the amplitudes toward $c_1, c_2$.
80
+ 5. **Classical Measurement and Parsing**: Extract the period and $x$ using the continued fractions theorem. Verify the answer via back substitution over the original congruence until success.
81
+
82
+ ---
83
+
84
+ ## Quantum Advantage
85
+
86
+ | Task | Classical Complexity | Quantum Complexity (Shor DLP) |
87
+ |------|-----------|----------------|
88
+ | Solving Discrete Logarithm | Sub-exponential time (e.g., General Number Field Sieve) | $O((\log P)^3)$ |
89
+
90
+ Note: Just as with prime factorization, Shor's treatment of the discrete logarithm problem achieved an exponential quantum speedup. This effectively undermines the foundation of traditional cryptographic systems like Diffie-Hellman and Elliptic Curves.
91
+
92
+ ---
93
+
94
+ ## Complexity Analysis
95
+
96
+ - **Quantum Part**: $O(\log P)$ qubit footprint; polynomial grade $O((\log P)^3)$ quantum gate operations are required to establish the grid of controlled modular multiplications and IQFTs.
97
+ - **Overall Computation Time**: Stemming from the high likelihood of sampling correct states and the efficiency of classical post-processing (finding large inverse numbers and continued fractions), the overall time complexity is $O((\log P)^3)$.
98
+
99
+ ---
100
+
101
+ ## Applications and Impact
102
+
103
+ - **Breaking Public-Key Cryptography Foundations**: Beyond RSA (based on integer factorization), the security of modern cryptographic architectures—such as the Diffie-Hellman (DH) key exchange protocol, Digital Signature Algorithm (DSA), ElGamal, and Elliptic Curve Cryptography (ECC) variations—is constructed entirely on the intractability of the classical discrete logarithm problem, all of which fall to this algorithm model.
104
+ - **Driving the Next-Generation Security Formats**: Because quantum algorithms can crack these protocols in polynomial time, this algorithm serves as a forceful catalyst, pushing the global computer industry toward Post-Quantum Cryptography (PQC), such as lattice-based and hash-based cryptography.
@@ -0,0 +1,104 @@
1
+ # 离散对数算法详解
2
+
3
+ ## 参数设置
4
+
5
+ - `g`: 底数 (Base),默认值为 `3`。
6
+ - `y`: 目标值 (Target value),默认值为 `13`。
7
+ - `P`: 模数 (Modulus,通常为素数),默认值为 `17`。
8
+
9
+ > **总结**:离散对数算法用于在多项式时间内求解 $g^x \equiv y \pmod P$ 中的未知数 $x$。输入底数 $g$、目标值 $y$ 和模数 $P$,通过量子相位估计编码周期信息,结合经典连分数与同余方程技术,最终输出计算得到的离散对数 $x$。
10
+
11
+ ---
12
+
13
+ ## 目录
14
+
15
+ - [运行流程](#运行流程)
16
+ - [核心思想](#核心思想)
17
+ - [数学原理](#数学原理)
18
+ - [算法步骤](#算法步骤)
19
+ - [量子优势](#量子优势)
20
+ - [复杂度分析](#复杂度分析)
21
+ - [应用与影响](#应用与影响)
22
+
23
+ ---
24
+
25
+ ## 运行流程
26
+
27
+ 1. **参数制备**:
28
+ - 验证 $g$ 和 $y$ 必须与 $P$ 互素。
29
+ - 根据 $P$ 的位长,计算出计数寄存器位长 $n_{\text{count}}$ 和工作寄存器位长 $n_{\text{work}}$(总计耗费 $2n_{\text{count}} + n_{\text{work}}$ 个量子比特)。
30
+ 2. **量子电路构建**:
31
+ - 初始化两个控制(计数)寄存器(分别对应 $g$ 的幂次与 $y^{-1}$ 的幂次)和工作寄存器。
32
+ - 对控制寄存器施加 Hadamard 层制备均匀叠加态。
33
+ - 设置工作寄存器初始状态为 $|1\rangle$。
34
+ - 对第一个控制寄存器,依次施加以 $g^{2^i}$ 为乘数的受控模乘算子(矩阵模拟)。
35
+ - 对第二个控制寄存器,依次施加以 $y^{-1}$(在 $\pmod P$ 下的逆元)的对应幂次为乘数的受控模乘算子(矩阵模拟)。
36
+ - 对两个控制寄存器分别施加**逆量子傅里叶变换 (IQFT)**。
37
+ 3. **量子模拟与测量**:
38
+ - 执行量子电路模拟。
39
+ - 提取执行后各量子态分量的概率分布用于下一阶段分析。
40
+ 4. **经典后处理(连分数与同余方程)**:
41
+ - 从测得概率图谱中提取最可能的几组观测值 $(c_1, c_2)$。
42
+ - 运用经典连分数算法分析 $c_1/N$ 等比值,提取可能的群阶(周期)$r$。
43
+ - 根据 $x_1/r$ 和 $x_2/r$ 的提取结果构建模线性方程 $x \cdot x_1 + x_2 \equiv 0 \pmod r$,反解得到 $x$。
44
+ - 验证代入 $g^x \equiv y \pmod P$ 是否成立。
45
+ 5. **结果输出**:导出量子电路 SVG 图表,并输出计算耗时、检测到的周期 $r$ 及求得的结果 $x$。
46
+
47
+ ---
48
+
49
+ ## 核心思想
50
+
51
+ 求解有限循环群上的离散对数问题 $g^x \equiv y \pmod P$,Peter Shor 提出可以将其转化为一种隐子群问题(二维周期查找问题)。
52
+ 定义一个函数:
53
+ $$f(a,b) = g^a y^{-b} \bmod P$$
54
+ 显然,如果找到了 $(a,b)$ 使得 $f(a,b) = 1$,由于 $y = g^x$,这意味着:
55
+ $$g^a (g^x)^{-b} = g^{a - bx} \equiv 1 \pmod P$$
56
+ 当 $a - bx \equiv 0 \pmod r$($r$ 为 $g$ 的阶)时等式成立,此时即可通过经典模逆元求出 $x = ab^{-1} \bmod r$。因此,通过量子叠加及相位估计来寻找群的阶与函数的隐式二维周期,便能解出变量 $x$。
57
+
58
+ ---
59
+
60
+ ## 数学原理
61
+
62
+ ### 受控群运算与联合态
63
+ 用两个大小分别为 $N$ 的寄存器表示叠加状态 $(a,b)$,其联合状态可表示为:
64
+ $$\frac{1}{N}\sum_{a=0}^{N-1}\sum_{b=0}^{N-1}|a\rangle|b\rangle|g^ay^{-b}\bmod P\rangle$$
65
+ 此状态通过隐式计算封装了由 $x$ 建立的 $(a,b)$ 网格上的周期信息。
66
+
67
+ ### 二维量子傅里叶变换
68
+ 应用两次相互独立的量子傅里叶变换后,系统状态的振幅在满足如下条件的特定 $(c_1, c_2)$ 点会发生相长干涉(出现波峰):
69
+ $$\frac{c_1}{N} \approx \frac{k}{r} \quad \text{且} \quad \frac{c_2}{N} \approx \frac{kx}{r}$$
70
+ 其中 $r$ 为周期($g$ 在 $\pmod P$ 的阶)。借由此可以分别从 $c_1$ 算出 $r$,再通过 $c_2/c_1 \approx x \pmod r$ 提取 $x$ 自身。
71
+
72
+ ---
73
+
74
+ ## 算法步骤
75
+
76
+ 1. **经典预检查**:判定参数互素条件,算出用于量子阶段的具体控制/工作寄存器尺寸。
77
+ 2. **状态制备**:制备 $|0\rangle^{\otimes 2n} |1\rangle$,然后施加 Hadamard 层得到 $|+\rangle^{\otimes 2n} |1\rangle$。
78
+ 3. **量子周期映射**:施加二维黑盒控制算子 $U|a\rangle|b\rangle|z\rangle = |a\rangle|b\rangle|z \cdot g^a y^{-b} \bmod P\rangle$。
79
+ 4. **傅里叶逆变换提取相位**:对前两个寄存器施加 IQFT,将振幅集中指向 $c_1, c_2$ 附近。
80
+ 5. **经典测量与解析**:测量第一个和第二个寄存器,用连分数定理提取周期并求取 $x$。通过同余反代校验直至结果正确。
81
+
82
+ ---
83
+
84
+ ## 量子优势
85
+
86
+ | 任务 | 经典复杂度 | 量子复杂度 (Shor DLP) |
87
+ |------|-----------|----------------|
88
+ | 离散对数求解 | 次指数时间(通用数域筛法 GNFS 等) | $O((\log P)^3)$ |
89
+
90
+ 注:与对于单纯的素数分解算法相同,Shor 针对离散对数的问题同样取得了指数量级的算法加速,使得传统的 Diffie-Hellman 与椭圆曲线等密码体系变得脆弱。
91
+
92
+ ---
93
+
94
+ ## 复杂度分析
95
+
96
+ - **量子部分**:$O(\log P)$ 的比特开销,多项式级 $O((\log P)^3)$ 量子门操作以实现受控模乘累加运算与 IQFT 网格。
97
+ - **整体计算时间**:由于测量结果高频命中以及只需要常规的经典后处理(大数求逆和连分数),预期整体时间复杂度同为 $O((\log P)^3)$。
98
+
99
+ ---
100
+
101
+ ## 应用与影响
102
+
103
+ - **打破公钥密码体系基础**:除了基于素数分解的 RSA;现代诸多密码协议如 Diffie-Hellman (DH) 密钥交换协议、数字签名标准 (DSA)、ElGamal 算法以及基于椭圆曲线 (ECC) 的等价方案,其安全性统统奠立于经典离散对数问题的难解性之上,均可被该算法模型所攻破。
104
+ - **推动新一代安全策略**:因为量子技术能以多项式时间降维打击这些协议,此算法强力助推了全球计算机产业向后量子密码学 (PQC) 如格密码、哈希密码过渡的浪潮。
@@ -0,0 +1,13 @@
1
+ """
2
+ discrete log Algorithm Module
3
+ ========================
4
+
5
+ Implementation of Simon's algorithm for finding hidden periods.
6
+ """
7
+
8
+ from .algorithm import DiscreteLogAlgorithm, test
9
+
10
+ __all__ = [
11
+ 'DiscreteLogAlgorithm',
12
+ 'test'
13
+ ]
@@ -0,0 +1,223 @@
1
+ import time
2
+ import os
3
+ import math
4
+ import numpy as np
5
+ from fractions import Fraction
6
+ from typing import Dict, Any
7
+
8
+ # Import core project components
9
+ from unitarylab import Circuit, Register
10
+ from unitarylab.library import IQFT
11
+
12
+ try:
13
+ from ...algo_base import BaseAlgorithm
14
+ except ImportError:
15
+ # 单独运行时,将上级目录加入 sys.path,使 base 模块可被找到
16
+ import sys
17
+ _algorithms_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
18
+ if _algorithms_dir not in sys.path:
19
+ sys.path.insert(0, _algorithms_dir)
20
+ from algo_base import BaseAlgorithm
21
+
22
+ class DiscreteLogAlgorithm(BaseAlgorithm):
23
+ """
24
+ Discrete Logarithm Algorithm Module
25
+
26
+ Computes x in g^x ≡ y (mod P).
27
+ Based on quantum phase estimation and classical post-processing
28
+ (continued fraction period extraction and congruence equation solving).
29
+ """
30
+ def __init__(self, text_mode: str = "plain", algo_dir: str = None):
31
+ if algo_dir is None:
32
+ _this = os.path.abspath(__file__)
33
+ _directory = os.path.dirname(_this)
34
+ algo_dir = os.path.join(os.getcwd(), "results", os.path.basename(os.path.dirname(_directory)), os.path.basename(_directory))
35
+ os.makedirs(algo_dir, exist_ok=True)
36
+
37
+ super().__init__(name="Discrete Logarithm Algorithm", prefix="DLG", text_mode=text_mode, algo_dir=algo_dir)
38
+
39
+ def run(self, g: int, y: int, P: int) -> Dict[str, Any]:
40
+ """
41
+ Run the discrete logarithm algorithm to solve g^x ≡ y (mod P).
42
+
43
+ Args:
44
+ g: Base
45
+ y: Target value
46
+ P: Modulus (typically prime)
47
+
48
+ Returns:
49
+ Dictionary containing algorithm results with fields:
50
+ - status: Execution status, 'ok' on success
51
+ - circuit_path: Local path to saved quantum circuit diagram
52
+ - file_path: Local path to saved result text file
53
+ """
54
+ input = {"Base number": g, "Target value": y, "Modulus": P}
55
+ self.update_input(input)
56
+
57
+ # Stage 1: Parameter preparation
58
+ self.log(f"Stage 1: Parameter preparation")
59
+
60
+ if math.gcd(g, P) != 1 or math.gcd(y, P) != 1:
61
+ raise ValueError("g and y must be coprime with P")
62
+
63
+ n_count = 2*P.bit_length()
64
+ n_work = P.bit_length()
65
+ N_size = 2**n_count
66
+
67
+ self.log(f" Count register size: {n_count}")
68
+ self.log(f" Work register size: {n_work}")
69
+ self.log(f" Total qubits: {2 * n_count + n_work}")
70
+
71
+ # Stage 2: Quantum circuit construction
72
+ self.log(f"Stage 2: Building quantum circuit")
73
+
74
+ ra = Register("reg_a", n_count)
75
+ rb = Register("reg_b", n_count)
76
+ rw = Register("reg_work", n_work)
77
+ gs = Circuit(ra, rb, rw, name=f'DLP_{g}^{{x}}_{y}')
78
+
79
+ def get_p(reg_slice):
80
+ reg, idxs = reg_slice[0]
81
+ if reg.name == "reg_a": offset = 0
82
+ elif reg.name == "reg_b": offset = n_count
83
+ else: offset = 2 * n_count
84
+ return [i + offset for i in idxs]
85
+
86
+ gs.h(get_p(ra[:]))
87
+ gs.h(get_p(rb[:]))
88
+ gs.x(get_p(rw[0]))
89
+ for i in range(n_count):
90
+ mult = pow(g, 2**i, P)
91
+ matrix = self._get_modular_matrix(mult, P, n_work)
92
+ gs.unitary(matrix, get_p(rw[:]), get_p(ra[i])[0], '1')
93
+
94
+ y_inv = pow(y, -1, P)
95
+ for j in range(n_count):
96
+ mult = pow(y_inv, 2**j, P)
97
+ matrix = self._get_modular_matrix(mult, P, n_work)
98
+ gs.unitary(matrix, get_p(rw[:]), get_p(rb[j])[0], '1')
99
+
100
+ gs.append(IQFT(n_count), get_p(ra[:]))
101
+ gs.append(IQFT(n_count), get_p(rb[:]))
102
+
103
+ # Stage 3: Quantum simulation
104
+ self.log(f"Stage 3: Running quantum simulation")
105
+
106
+ start_time = time.time()
107
+ res_vec = gs.execute()
108
+ probs_dict = res_vec.calculate_state(range(2 * n_count))
109
+ end_time = time.time()
110
+ comp_time = end_time - start_time
111
+
112
+ self.log(f" Computation time: {comp_time:.4f} s")
113
+
114
+ # Stage 4: Classical post-processing
115
+ self.log(f"Stage 4: Classical post-processing (continued fractions and congruences)")
116
+
117
+ found_x, found_r, info_msg = self._classical_post_processing(probs_dict, g, y, P, n_count, N_size)
118
+ is_success = found_x is not None
119
+
120
+ self.log(f" Detected period r: {found_r if found_r else 'unknown'}")
121
+ self.log(f" Result x: {found_x if is_success else 'not found'}")
122
+ self.log(f" Verification: {'success' if is_success else 'failed'}")
123
+
124
+ # Stage 5: Export circuit diagram
125
+ self.log(f"Stage 5: Exporting circuit diagram")
126
+
127
+ output = {"Computation time (s)": round(comp_time, 4), "Detected period r": found_r, "Found x": found_x}
128
+ self.update_output(output)
129
+ self.status = 'success' if is_success else 'failed'
130
+ self.summary = f"Discrete logarithm x found with x={found_x}" if is_success else "Solution failed"
131
+
132
+ # Save results
133
+ circuit_path = self.save_circuit(gs)
134
+ filename = self.save_txt()
135
+
136
+ return self._build_return_dict(is_success, circuit_path, filename, gs)
137
+
138
+ def _get_modular_matrix(self, a, N, n_qubits):
139
+ """Build modular multiplication unitary: z -> (a * z) mod N."""
140
+ dim = 2**n_qubits
141
+ matrix = np.zeros((dim, dim))
142
+ for z in range(dim):
143
+ if z < N: target = (a * z) % N
144
+ else: target = z
145
+ matrix[target, z] = 1.0
146
+ return matrix
147
+
148
+ def _classical_post_processing(self, probs, g, y, P, n, N_size):
149
+ """Classical post-processing: extract period via continued fractions and solve congruence equations."""
150
+ sorted_probs = sorted(probs.items(), key=lambda x: x[1]['prob'], reverse=True)
151
+
152
+ for bitstring, data in sorted_probs:
153
+ if data['prob'] < 0.02: continue
154
+
155
+ v_bin, u_bin = bitstring[:n], bitstring[n:]
156
+ u, v = int(u_bin, 2), int(v_bin, 2)
157
+ if u == 0: continue
158
+
159
+ frac = Fraction(u, N_size).limit_denominator(P)
160
+ r_base, s_base = frac.denominator, frac.numerator
161
+
162
+ real_r = None
163
+ for k in range(1, 10):
164
+ if pow(g, r_base * k, P) == 1:
165
+ real_r = r_base * k
166
+ real_s = s_base * k
167
+ break
168
+
169
+ if real_r is None: continue
170
+
171
+ target = int(round((v * real_r) / N_size))
172
+
173
+ d = math.gcd(real_s, real_r)
174
+ if (-target) % d == 0:
175
+ s_red = real_s // d
176
+ r_red = real_r // d
177
+ t_red = (-target) // d
178
+
179
+
180
+ try:
181
+ x0 = (t_red * pow(s_red, -1, r_red)) % r_red
182
+ for i in range(d):
183
+ x_test = (x0 + i * r_red) % real_r
184
+ if pow(g, x_test, P) == (y % P):
185
+ final_x = x_test % real_r
186
+ return final_x, real_r, "Success"
187
+ except ValueError:
188
+ continue
189
+ return None, None, "No solution found"
190
+
191
+ def test(g=3, y=6, P=7):
192
+ """
193
+ Run the discrete logarithm algorithm to solve g^x ≡ y (mod P).
194
+
195
+ Args:
196
+ g: Base
197
+ y: Target value
198
+ P: Modulus (typically prime)
199
+
200
+ Returns:
201
+ Dictionary containing algorithm results with fields:
202
+ - status: Execution status, 'ok' on success
203
+ - circuit_path: Local path to saved quantum circuit diagram (SVG)
204
+ - file_path: Local path to saved text file with results
205
+ """
206
+ if not isinstance(g, int):
207
+ g = int(g)
208
+ if not isinstance(y, int):
209
+ y = int(y)
210
+ if not isinstance(P, int):
211
+ P = int(P)
212
+
213
+ dlg = DiscreteLogAlgorithm(text_mode="legacy")
214
+ result = dlg.run(g=g, y=y, P=P)
215
+ return result
216
+
217
+
218
+ if __name__ == "__main__":
219
+ g = 3 # [PARAM]
220
+ y = 6 # [PARAM]
221
+ P = 7 # [PARAM]
222
+
223
+ test(g=g, y=y, P=P)