qusec 0.1.0__tar.gz
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.
- qusec-0.1.0/PKG-INFO +125 -0
- qusec-0.1.0/README.md +103 -0
- qusec-0.1.0/pyproject.toml +43 -0
- qusec-0.1.0/setup.cfg +4 -0
- qusec-0.1.0/src/qusec/__init__.py +5 -0
- qusec-0.1.0/src/qusec/__main__.py +5 -0
- qusec-0.1.0/src/qusec/cli.py +57 -0
- qusec-0.1.0/src/qusec/qds/signature.py +39 -0
- qusec-0.1.0/src/qusec/quantum/backend.py +43 -0
- qusec-0.1.0/src/qusec/quantum/teleportation.py +67 -0
- qusec-0.1.0/src/qusec/sarg04/protocol.py +60 -0
- qusec-0.1.0/src/qusec/ui/banner.py +16 -0
- qusec-0.1.0/src/qusec/ui/monitor.py +233 -0
- qusec-0.1.0/src/qusec.egg-info/PKG-INFO +125 -0
- qusec-0.1.0/src/qusec.egg-info/SOURCES.txt +18 -0
- qusec-0.1.0/src/qusec.egg-info/dependency_links.txt +1 -0
- qusec-0.1.0/src/qusec.egg-info/entry_points.txt +2 -0
- qusec-0.1.0/src/qusec.egg-info/requires.txt +9 -0
- qusec-0.1.0/src/qusec.egg-info/top_level.txt +1 -0
- qusec-0.1.0/tests/test_cli.py +14 -0
qusec-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qusec
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Quantum Security Framework for Quantum Digital Signature Threat Detection
|
|
5
|
+
Author: QuSec Developers
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/qusec/qusec
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
12
|
+
Classifier: Topic :: Security :: Cryptography
|
|
13
|
+
Requires-Python: >=3.9
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
Requires-Dist: qiskit~=2.5
|
|
16
|
+
Requires-Dist: qiskit-aer~=0.17
|
|
17
|
+
Requires-Dist: rich~=15.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: pytest~=9.1; extra == "dev"
|
|
20
|
+
Provides-Extra: hardware
|
|
21
|
+
Requires-Dist: qiskit-ibm-runtime~=0.50; extra == "hardware"
|
|
22
|
+
|
|
23
|
+
# QuSec - Quantum Security Framework
|
|
24
|
+
|
|
25
|
+
QuSec is a comprehensive Quantum Security Framework designed for Quantum Digital Signature (QDS) threat detection. It leverages Qiskit to simulate a quantum-safe teleportation-based QDS protocol layered with the SARG04 decoy-state method to detect active tampering, forgery, and interception attacks.
|
|
26
|
+
|
|
27
|
+
## 🚀 Features
|
|
28
|
+
|
|
29
|
+
- **Teleportation-Based QDS**: Transmits signature payload using a 3-qubit Bell-state entanglement and Pauli corrections.
|
|
30
|
+
- **SARG04 Protocol Integration**: Employs mathematical decoy states ($\mu$, $\nu$, vacuum) for sifting and quantum channel security.
|
|
31
|
+
- **Attack Simulations**: Test real-time quantum threat vectors including Forgery, Impersonation, Intercept-Resend, Replay, and Channel Tampering.
|
|
32
|
+
- **Multi-Backend Execution**:
|
|
33
|
+
- `Simulator`: Ideal local execution via Qiskit Aer.
|
|
34
|
+
- `Noisy`: Local simulation mapped with a configurable depolarizing noise model.
|
|
35
|
+
- `Hardware`: Secure execution loop ready for real IBM Quantum API connections.
|
|
36
|
+
- **Dynamic Threat Analysis**: Dynamically calculates Quantum Bit Error Rate (QBER) and statistically evaluates it against security thresholds.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📦 Installation
|
|
41
|
+
|
|
42
|
+
To install QuSec, ensure you have Python 3.9+ installed.
|
|
43
|
+
|
|
44
|
+
### 1. Set up a virtual environment (Recommended)
|
|
45
|
+
```bash
|
|
46
|
+
python -m venv venv
|
|
47
|
+
source venv/bin/activate # On macOS/Linux
|
|
48
|
+
# venv\Scripts\activate # On Windows
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Install QuSec
|
|
52
|
+
Install QuSec directly in editable mode for local development:
|
|
53
|
+
```bash
|
|
54
|
+
pip install -e .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
*(Optional)* If you plan on running your circuits on real IBM Quantum Hardware, install the hardware add-on:
|
|
58
|
+
```bash
|
|
59
|
+
pip install -e ".[hardware]"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 💻 Usage
|
|
65
|
+
|
|
66
|
+
QuSec comes with a beautiful, fully-interactive Terminal User Interface (TUI).
|
|
67
|
+
|
|
68
|
+
To launch the framework and start a secure message transfer, simply run:
|
|
69
|
+
```bash
|
|
70
|
+
qusec run
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Advanced Usage Flags
|
|
74
|
+
You can skip the interactive menus by passing parameters directly to the CLI:
|
|
75
|
+
|
|
76
|
+
- **View detailed transmission steps (Bit-by-Bit):**
|
|
77
|
+
```bash
|
|
78
|
+
qusec run --verbose
|
|
79
|
+
```
|
|
80
|
+
- **Select a specific execution backend:**
|
|
81
|
+
```bash
|
|
82
|
+
qusec run --backend noisy
|
|
83
|
+
```
|
|
84
|
+
- **Machine-readable JSON output (Great for CI/CD or logging):**
|
|
85
|
+
```bash
|
|
86
|
+
qusec run --json
|
|
87
|
+
```
|
|
88
|
+
- **Tweak the mathematical constraints:**
|
|
89
|
+
```bash
|
|
90
|
+
qusec run --shots 2000 --threshold 0.04
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Run `qusec run --help` to see all available configuration options!
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🛡️ Simulating Attacks
|
|
98
|
+
|
|
99
|
+
When using the interactive simulator (`qusec run`), you will be prompted to simulate a cyberattack vector.
|
|
100
|
+
|
|
101
|
+
1. **No Attack**: The message transfers securely. QBER remains $0.0$, and the signature is `VERIFIED`.
|
|
102
|
+
2. **Forgery / Impersonation**: Attempting to supply fake signature data. The verification layer catches the mathematical anomaly and blocks the transmission: `REJECTED`.
|
|
103
|
+
3. **Quantum Channel Tampering**: Induces simulated `X` and `Z` errors in the teleportation channel. You will see the QBER instantly spike above the defined threshold (default `0.06`), triggering a `THREAT DETECTED` system halt.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🏗️ Architecture
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
QUSEC SECURITY ENGINE
|
|
111
|
+
│
|
|
112
|
+
Quantum Circuit Layer
|
|
113
|
+
│
|
|
114
|
+
Abstract Backend Manager
|
|
115
|
+
│
|
|
116
|
+
┌────────────────┼────────────────┐
|
|
117
|
+
▼ ▼ ▼
|
|
118
|
+
AerSimulator Noisy AerSimulator Quantum Hardware
|
|
119
|
+
│
|
|
120
|
+
Measurement Results
|
|
121
|
+
│
|
|
122
|
+
Projective/SARG04 Security Pipeline
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
*Built for Smart India Hackathon problem statement SIH26141.*
|
qusec-0.1.0/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# QuSec - Quantum Security Framework
|
|
2
|
+
|
|
3
|
+
QuSec is a comprehensive Quantum Security Framework designed for Quantum Digital Signature (QDS) threat detection. It leverages Qiskit to simulate a quantum-safe teleportation-based QDS protocol layered with the SARG04 decoy-state method to detect active tampering, forgery, and interception attacks.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- **Teleportation-Based QDS**: Transmits signature payload using a 3-qubit Bell-state entanglement and Pauli corrections.
|
|
8
|
+
- **SARG04 Protocol Integration**: Employs mathematical decoy states ($\mu$, $\nu$, vacuum) for sifting and quantum channel security.
|
|
9
|
+
- **Attack Simulations**: Test real-time quantum threat vectors including Forgery, Impersonation, Intercept-Resend, Replay, and Channel Tampering.
|
|
10
|
+
- **Multi-Backend Execution**:
|
|
11
|
+
- `Simulator`: Ideal local execution via Qiskit Aer.
|
|
12
|
+
- `Noisy`: Local simulation mapped with a configurable depolarizing noise model.
|
|
13
|
+
- `Hardware`: Secure execution loop ready for real IBM Quantum API connections.
|
|
14
|
+
- **Dynamic Threat Analysis**: Dynamically calculates Quantum Bit Error Rate (QBER) and statistically evaluates it against security thresholds.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
|
|
20
|
+
To install QuSec, ensure you have Python 3.9+ installed.
|
|
21
|
+
|
|
22
|
+
### 1. Set up a virtual environment (Recommended)
|
|
23
|
+
```bash
|
|
24
|
+
python -m venv venv
|
|
25
|
+
source venv/bin/activate # On macOS/Linux
|
|
26
|
+
# venv\Scripts\activate # On Windows
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 2. Install QuSec
|
|
30
|
+
Install QuSec directly in editable mode for local development:
|
|
31
|
+
```bash
|
|
32
|
+
pip install -e .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
*(Optional)* If you plan on running your circuits on real IBM Quantum Hardware, install the hardware add-on:
|
|
36
|
+
```bash
|
|
37
|
+
pip install -e ".[hardware]"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 💻 Usage
|
|
43
|
+
|
|
44
|
+
QuSec comes with a beautiful, fully-interactive Terminal User Interface (TUI).
|
|
45
|
+
|
|
46
|
+
To launch the framework and start a secure message transfer, simply run:
|
|
47
|
+
```bash
|
|
48
|
+
qusec run
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Advanced Usage Flags
|
|
52
|
+
You can skip the interactive menus by passing parameters directly to the CLI:
|
|
53
|
+
|
|
54
|
+
- **View detailed transmission steps (Bit-by-Bit):**
|
|
55
|
+
```bash
|
|
56
|
+
qusec run --verbose
|
|
57
|
+
```
|
|
58
|
+
- **Select a specific execution backend:**
|
|
59
|
+
```bash
|
|
60
|
+
qusec run --backend noisy
|
|
61
|
+
```
|
|
62
|
+
- **Machine-readable JSON output (Great for CI/CD or logging):**
|
|
63
|
+
```bash
|
|
64
|
+
qusec run --json
|
|
65
|
+
```
|
|
66
|
+
- **Tweak the mathematical constraints:**
|
|
67
|
+
```bash
|
|
68
|
+
qusec run --shots 2000 --threshold 0.04
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Run `qusec run --help` to see all available configuration options!
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 🛡️ Simulating Attacks
|
|
76
|
+
|
|
77
|
+
When using the interactive simulator (`qusec run`), you will be prompted to simulate a cyberattack vector.
|
|
78
|
+
|
|
79
|
+
1. **No Attack**: The message transfers securely. QBER remains $0.0$, and the signature is `VERIFIED`.
|
|
80
|
+
2. **Forgery / Impersonation**: Attempting to supply fake signature data. The verification layer catches the mathematical anomaly and blocks the transmission: `REJECTED`.
|
|
81
|
+
3. **Quantum Channel Tampering**: Induces simulated `X` and `Z` errors in the teleportation channel. You will see the QBER instantly spike above the defined threshold (default `0.06`), triggering a `THREAT DETECTED` system halt.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 🏗️ Architecture
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
QUSEC SECURITY ENGINE
|
|
89
|
+
│
|
|
90
|
+
Quantum Circuit Layer
|
|
91
|
+
│
|
|
92
|
+
Abstract Backend Manager
|
|
93
|
+
│
|
|
94
|
+
┌────────────────┼────────────────┐
|
|
95
|
+
▼ ▼ ▼
|
|
96
|
+
AerSimulator Noisy AerSimulator Quantum Hardware
|
|
97
|
+
│
|
|
98
|
+
Measurement Results
|
|
99
|
+
│
|
|
100
|
+
Projective/SARG04 Security Pipeline
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
*Built for Smart India Hackathon problem statement SIH26141.*
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "qusec"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Quantum Security Framework for Quantum Digital Signature Threat Detection"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"qiskit~=2.5",
|
|
13
|
+
"qiskit-aer~=0.17",
|
|
14
|
+
"rich~=15.0"
|
|
15
|
+
]
|
|
16
|
+
authors = [
|
|
17
|
+
{ name = "QuSec Developers" }
|
|
18
|
+
]
|
|
19
|
+
license = { text = "MIT" }
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"License :: OSI Approved :: MIT License",
|
|
23
|
+
"Operating System :: OS Independent",
|
|
24
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
25
|
+
"Topic :: Security :: Cryptography"
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = [
|
|
30
|
+
"pytest~=9.1"
|
|
31
|
+
]
|
|
32
|
+
hardware = [
|
|
33
|
+
"qiskit-ibm-runtime~=0.50"
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
"Homepage" = "https://github.com/qusec/qusec"
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
qusec = "qusec.cli:main"
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
qusec-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import sys
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
|
|
5
|
+
from qusec.ui.banner import print_banner
|
|
6
|
+
from qusec.ui.monitor import InteractiveSimulator
|
|
7
|
+
from qusec import __version__
|
|
8
|
+
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
parser = argparse.ArgumentParser(description="QuSec - Quantum Security Framework")
|
|
13
|
+
parser.add_argument("--version", action="version", version=f"QuSec v{__version__}", help="Print version information")
|
|
14
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
15
|
+
|
|
16
|
+
run_parser = subparsers.add_parser("run", help="Run the interactive simulator")
|
|
17
|
+
version_parser = subparsers.add_parser("version", help="Print version information")
|
|
18
|
+
|
|
19
|
+
run_parser.add_argument("--backend", choices=["simulator", "noisy", "hardware"], help="Backend execution mode")
|
|
20
|
+
run_parser.add_argument("--shots", type=int, default=1000, help="Number of shots for verification")
|
|
21
|
+
run_parser.add_argument("--threshold", type=float, default=0.06, help="QBER threshold")
|
|
22
|
+
run_parser.add_argument("--mu-probability", type=float, default=0.6, help="Probability of mu decoy state")
|
|
23
|
+
run_parser.add_argument("--nu-probability", type=float, default=0.3, help="Probability of nu decoy state")
|
|
24
|
+
run_parser.add_argument("--vac-probability", type=float, default=0.1, help="Probability of vacuum decoy state")
|
|
25
|
+
run_parser.add_argument("--verbose", action="store_true", help="Enable verbose output")
|
|
26
|
+
run_parser.add_argument("--debug", action="store_true", help="Enable debug output")
|
|
27
|
+
run_parser.add_argument("--json", action="store_true", help="Output results in JSON format")
|
|
28
|
+
|
|
29
|
+
args = parser.parse_args()
|
|
30
|
+
|
|
31
|
+
if args.command == "version":
|
|
32
|
+
print(f"QuSec v{__version__}")
|
|
33
|
+
return 0
|
|
34
|
+
|
|
35
|
+
if not args.command or args.command == "run":
|
|
36
|
+
if getattr(args, 'json', False) is False:
|
|
37
|
+
print_banner()
|
|
38
|
+
|
|
39
|
+
simulator = InteractiveSimulator(
|
|
40
|
+
backend_type=getattr(args, 'backend', None),
|
|
41
|
+
shots=getattr(args, 'shots', 1000),
|
|
42
|
+
threshold=getattr(args, 'threshold', 0.06),
|
|
43
|
+
mu_prob=getattr(args, 'mu_probability', 0.6),
|
|
44
|
+
nu_prob=getattr(args, 'nu_probability', 0.3),
|
|
45
|
+
vac_prob=getattr(args, 'vac_probability', 0.1),
|
|
46
|
+
verbose=getattr(args, 'verbose', False),
|
|
47
|
+
debug=getattr(args, 'debug', False),
|
|
48
|
+
json_output=getattr(args, 'json', False)
|
|
49
|
+
)
|
|
50
|
+
simulator.run()
|
|
51
|
+
return 0
|
|
52
|
+
|
|
53
|
+
parser.print_help()
|
|
54
|
+
return 1
|
|
55
|
+
|
|
56
|
+
if __name__ == "__main__":
|
|
57
|
+
sys.exit(main())
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
def generate_key_material(length=20):
|
|
5
|
+
"""Generate random bits for key material."""
|
|
6
|
+
return [int(b) for b in bin(int.from_bytes(os.urandom(length), 'big'))[2:].zfill(length*8)[:length]]
|
|
7
|
+
|
|
8
|
+
def generate_signature(message: str) -> list[int]:
|
|
9
|
+
"""
|
|
10
|
+
SIMULATION SIGNATURE
|
|
11
|
+
Generates a 16-bit signature by hashing the message with SHA-256 and taking 4 hex characters.
|
|
12
|
+
"""
|
|
13
|
+
h = hashlib.sha256(message.encode('utf-8')).hexdigest()
|
|
14
|
+
truncated_hex = h[:4]
|
|
15
|
+
bit_str = bin(int(truncated_hex, 16))[2:].zfill(16)
|
|
16
|
+
return [int(b) for b in bit_str]
|
|
17
|
+
|
|
18
|
+
def message_to_bits(message: str) -> list[int]:
|
|
19
|
+
bits = []
|
|
20
|
+
for char in message:
|
|
21
|
+
bits.extend([int(b) for b in format(ord(char), '08b')])
|
|
22
|
+
return bits
|
|
23
|
+
|
|
24
|
+
def construct_payload(message: str):
|
|
25
|
+
msg_bits = message_to_bits(message)
|
|
26
|
+
sig_bits = generate_signature(message)
|
|
27
|
+
key_bits = generate_key_material(20) # 20 bits
|
|
28
|
+
|
|
29
|
+
payload = msg_bits + sig_bits + key_bits
|
|
30
|
+
|
|
31
|
+
metadata = {
|
|
32
|
+
"message_start": 0,
|
|
33
|
+
"message_end": len(msg_bits),
|
|
34
|
+
"signature_start": len(msg_bits),
|
|
35
|
+
"signature_end": len(msg_bits) + len(sig_bits),
|
|
36
|
+
"key_start": len(msg_bits) + len(sig_bits),
|
|
37
|
+
"key_end": len(payload)
|
|
38
|
+
}
|
|
39
|
+
return payload, metadata
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from qiskit_aer import AerSimulator
|
|
2
|
+
from qiskit_aer.noise import NoiseModel, depolarizing_error
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
def get_backend(backend_type='simulator', credentials=None):
|
|
6
|
+
if backend_type == 'simulator':
|
|
7
|
+
return AerSimulator()
|
|
8
|
+
|
|
9
|
+
elif backend_type == 'noisy':
|
|
10
|
+
# Simple depolarizing noise model
|
|
11
|
+
noise_model = NoiseModel()
|
|
12
|
+
error = depolarizing_error(0.01, 1) # 1% error
|
|
13
|
+
error2 = depolarizing_error(0.01, 2)
|
|
14
|
+
noise_model.add_all_qubit_quantum_error(error, ['u1', 'u2', 'u3', 'x', 'z', 'h'])
|
|
15
|
+
noise_model.add_all_qubit_quantum_error(error2, ['cx', 'cz'])
|
|
16
|
+
return AerSimulator(noise_model=noise_model)
|
|
17
|
+
|
|
18
|
+
elif backend_type == 'hardware':
|
|
19
|
+
# In a real environment we would use QiskitRuntimeService
|
|
20
|
+
try:
|
|
21
|
+
from qiskit_ibm_runtime import QiskitRuntimeService
|
|
22
|
+
|
|
23
|
+
# Using credentials dict to initialize service securely without hardcoding
|
|
24
|
+
if credentials and 'token' in credentials:
|
|
25
|
+
service = QiskitRuntimeService(channel="ibm_quantum", token=credentials['token'])
|
|
26
|
+
return service.backend(credentials.get('backend_name', 'ibm_kyoto'))
|
|
27
|
+
else:
|
|
28
|
+
# Fallback to saved account or env vars
|
|
29
|
+
service = QiskitRuntimeService()
|
|
30
|
+
return service.backend('ibm_kyoto')
|
|
31
|
+
except ImportError:
|
|
32
|
+
raise ImportError("Please install the hardware extra: pip install qusec[hardware]")
|
|
33
|
+
except Exception as e:
|
|
34
|
+
raise RuntimeError(f"Failed to connect to IBM Quantum. Ensure credentials are valid.")
|
|
35
|
+
|
|
36
|
+
return AerSimulator()
|
|
37
|
+
|
|
38
|
+
def execute_circuit(circuit, backend_type='simulator', backend=None, shots=1000):
|
|
39
|
+
if backend is None:
|
|
40
|
+
backend = get_backend(backend_type)
|
|
41
|
+
|
|
42
|
+
result = backend.run(circuit, shots=shots).result()
|
|
43
|
+
return result.get_counts()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
|
2
|
+
from qusec.quantum.backend import execute_circuit
|
|
3
|
+
|
|
4
|
+
def create_teleportation_circuit(input_bit: int, sender_basis: str):
|
|
5
|
+
"""
|
|
6
|
+
Creates the 3-qubit teleportation circuit for QuSec.
|
|
7
|
+
q0: message
|
|
8
|
+
q1: Alice Bell pair
|
|
9
|
+
q2: Bob Bell pair
|
|
10
|
+
"""
|
|
11
|
+
qr = QuantumRegister(3, 'q')
|
|
12
|
+
cr = ClassicalRegister(3, 'c')
|
|
13
|
+
qc = QuantumCircuit(qr, cr)
|
|
14
|
+
|
|
15
|
+
# 1. Prepare q0
|
|
16
|
+
if input_bit == 1:
|
|
17
|
+
qc.x(0)
|
|
18
|
+
if sender_basis == 'X':
|
|
19
|
+
qc.h(0)
|
|
20
|
+
|
|
21
|
+
# 2. Bell pair (q1, q2)
|
|
22
|
+
qc.h(1)
|
|
23
|
+
qc.cx(1, 2)
|
|
24
|
+
qc.barrier()
|
|
25
|
+
|
|
26
|
+
# 3. Teleportation sender ops
|
|
27
|
+
qc.cx(0, 1)
|
|
28
|
+
qc.h(0)
|
|
29
|
+
qc.barrier()
|
|
30
|
+
|
|
31
|
+
return qc
|
|
32
|
+
|
|
33
|
+
def simulate_round(input_bit: int, sender_basis: str, bob_basis: str, c0_flip=False, c1_flip=False, backend_type='simulator', credentials=None):
|
|
34
|
+
"""Run a full simulation of one bit using a single circuit."""
|
|
35
|
+
qc = create_teleportation_circuit(input_bit, sender_basis)
|
|
36
|
+
|
|
37
|
+
# We apply dynamic corrections using quantum controlled gates
|
|
38
|
+
qc.cx(1, 2)
|
|
39
|
+
qc.cz(0, 2)
|
|
40
|
+
|
|
41
|
+
# c1_flip logic (Classical flip means Bob gets opposite instruction)
|
|
42
|
+
# Applying X(2) exactly models this error
|
|
43
|
+
if c1_flip:
|
|
44
|
+
qc.x(2)
|
|
45
|
+
|
|
46
|
+
# c0_flip logic
|
|
47
|
+
if c0_flip:
|
|
48
|
+
qc.z(2)
|
|
49
|
+
|
|
50
|
+
if bob_basis == 'X':
|
|
51
|
+
qc.h(2)
|
|
52
|
+
|
|
53
|
+
# Now we measure everything
|
|
54
|
+
qc.measure(0, 0)
|
|
55
|
+
qc.measure(1, 1)
|
|
56
|
+
qc.measure(2, 2)
|
|
57
|
+
|
|
58
|
+
counts = execute_circuit(qc, backend_type=backend_type, shots=1)
|
|
59
|
+
res_str = list(counts.keys())[0].replace(" ", "")
|
|
60
|
+
|
|
61
|
+
# Qiskit returns bits as c2 c1 c0 from left to right
|
|
62
|
+
bob_res = int(res_str[0])
|
|
63
|
+
c1 = int(res_str[1])
|
|
64
|
+
c0 = int(res_str[2])
|
|
65
|
+
|
|
66
|
+
return c0, c1, bob_res, qc
|
|
67
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import random
|
|
2
|
+
|
|
3
|
+
def generate_sarg04_candidate(input_bit: int, basis: str) -> tuple:
|
|
4
|
+
"""
|
|
5
|
+
Candidate sets:
|
|
6
|
+
A: {(0,Z), (0,X)}
|
|
7
|
+
B: {(0,Z), (1,X)}
|
|
8
|
+
C: {(1,Z), (0,X)}
|
|
9
|
+
D: {(1,Z), (1,X)}
|
|
10
|
+
"""
|
|
11
|
+
if input_bit == 0 and basis == 'Z':
|
|
12
|
+
return random.choice([((0,'Z'), (0,'X')), ((0,'Z'), (1,'X'))])
|
|
13
|
+
elif input_bit == 0 and basis == 'X':
|
|
14
|
+
return random.choice([((0,'Z'), (0,'X')), ((1,'Z'), (0,'X'))])
|
|
15
|
+
elif input_bit == 1 and basis == 'Z':
|
|
16
|
+
return random.choice([((1,'Z'), (0,'X')), ((1,'Z'), (1,'X'))])
|
|
17
|
+
elif input_bit == 1 and basis == 'X':
|
|
18
|
+
return random.choice([((0,'Z'), (1,'X')), ((1,'Z'), (1,'X'))])
|
|
19
|
+
return ((0,'Z'), (0,'X'))
|
|
20
|
+
|
|
21
|
+
def sift_sarg04(bob_res: int, bob_basis: str, candidate_set: tuple) -> dict:
|
|
22
|
+
"""
|
|
23
|
+
SARG04 sifting logic. Bob eliminates the candidate orthogonal to his result.
|
|
24
|
+
"""
|
|
25
|
+
ruled_out = None
|
|
26
|
+
if bob_basis == 'Z':
|
|
27
|
+
if bob_res == 0:
|
|
28
|
+
ruled_out = (1, 'Z')
|
|
29
|
+
else:
|
|
30
|
+
ruled_out = (0, 'Z')
|
|
31
|
+
else: # X
|
|
32
|
+
if bob_res == 0:
|
|
33
|
+
ruled_out = (1, 'X')
|
|
34
|
+
else:
|
|
35
|
+
ruled_out = (0, 'X')
|
|
36
|
+
|
|
37
|
+
conclusive = False
|
|
38
|
+
reconstructed_bit = None
|
|
39
|
+
|
|
40
|
+
if ruled_out in candidate_set:
|
|
41
|
+
conclusive = True
|
|
42
|
+
# The other one is the bit
|
|
43
|
+
for cand in candidate_set:
|
|
44
|
+
if cand != ruled_out:
|
|
45
|
+
reconstructed_bit = cand[0]
|
|
46
|
+
break
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
"conclusive": conclusive,
|
|
50
|
+
"reconstructed_bit": reconstructed_bit,
|
|
51
|
+
"ruled_out": ruled_out
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
def get_decoy_state(mu_prob, nu_prob, vac_prob):
|
|
55
|
+
r = random.random()
|
|
56
|
+
if r < mu_prob:
|
|
57
|
+
return 'mu'
|
|
58
|
+
elif r < mu_prob + nu_prob:
|
|
59
|
+
return 'nu'
|
|
60
|
+
return 'vac'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.panel import Panel
|
|
3
|
+
from rich.align import Align
|
|
4
|
+
|
|
5
|
+
def print_banner():
|
|
6
|
+
console = Console()
|
|
7
|
+
ascii_art = """[bold blue]
|
|
8
|
+
██████╗ ██╗ ██╗███████╗███████╗ ██████╗
|
|
9
|
+
██╔═══██╗██║ ██║██╔════╝██╔════╝██╔════╝
|
|
10
|
+
██║ ██║██║ ██║███████╗█████╗ ██║
|
|
11
|
+
██║▄▄ ██║██║ ██║╚════██║██╔══╝ ██║
|
|
12
|
+
╚██████╔╝╚██████╔╝███████║███████╗╚██████╗
|
|
13
|
+
╚══▀▀═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝[/bold blue]"""
|
|
14
|
+
|
|
15
|
+
content = Align.center(ascii_art + "\n\n[bold cyan]Quantum Security Framework[/bold cyan]\n[white]Teleportation-QDS • SARG04 • Threat Detection[/white]")
|
|
16
|
+
console.print(Panel(content, border_style="blue"))
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.prompt import Prompt, IntPrompt
|
|
3
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
4
|
+
from rich.panel import Panel
|
|
5
|
+
from rich.table import Table
|
|
6
|
+
|
|
7
|
+
import time
|
|
8
|
+
import random
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
from qusec.qds.signature import construct_payload
|
|
13
|
+
from qusec.sarg04.protocol import get_decoy_state, generate_sarg04_candidate, sift_sarg04
|
|
14
|
+
from qusec.quantum.teleportation import simulate_round
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
class InteractiveSimulator:
|
|
19
|
+
def __init__(self, backend_type=None, shots=1000, threshold=0.06, mu_prob=0.6, nu_prob=0.3, vac_prob=0.1, verbose=False, debug=False, json_output=False):
|
|
20
|
+
self.shots = shots
|
|
21
|
+
self.threshold = threshold
|
|
22
|
+
self.mu_prob = mu_prob
|
|
23
|
+
self.nu_prob = nu_prob
|
|
24
|
+
self.vac_prob = vac_prob
|
|
25
|
+
self.verbose = verbose
|
|
26
|
+
self.debug = debug
|
|
27
|
+
self.json_output = json_output
|
|
28
|
+
self.session_id = f"QSEC-{random.randint(1000, 9999)}"
|
|
29
|
+
self.backend_type = backend_type
|
|
30
|
+
self.credentials = None
|
|
31
|
+
|
|
32
|
+
def interactive_backend_setup(self):
|
|
33
|
+
console.print(Panel("[bold cyan]Select Quantum Execution Backend[/bold cyan]", border_style="cyan"))
|
|
34
|
+
console.print("[1] [bold]AerSimulator[/bold] - Local ideal quantum simulation")
|
|
35
|
+
console.print("[2] [bold]Noisy AerSimulator[/bold] - Local simulation with configurable quantum noise")
|
|
36
|
+
console.print("[3] [bold]Quantum Hardware[/bold] - Execute circuits on real quantum hardware")
|
|
37
|
+
|
|
38
|
+
choice = Prompt.ask("Select backend", choices=["1", "2", "3"], default="1")
|
|
39
|
+
if choice == "1":
|
|
40
|
+
self.backend_type = "simulator"
|
|
41
|
+
elif choice == "2":
|
|
42
|
+
self.backend_type = "noisy"
|
|
43
|
+
elif choice == "3":
|
|
44
|
+
self.backend_type = "hardware"
|
|
45
|
+
console.print("\n┌──────────────────────────────────────────────┐")
|
|
46
|
+
console.print("│ QUANTUM HARDWARE CONFIGURATION │")
|
|
47
|
+
console.print("└──────────────────────────────────────────────┘")
|
|
48
|
+
console.print("\nQuSec needs your IBM Quantum configuration.\n")
|
|
49
|
+
token = Prompt.ask("IBM Quantum API Token", password=True)
|
|
50
|
+
instance = Prompt.ask("IBM Quantum Instance / CRN", default="ibm-q/open/main")
|
|
51
|
+
backend_name = Prompt.ask("Backend name", default="ibm_kyoto")
|
|
52
|
+
|
|
53
|
+
if not token:
|
|
54
|
+
console.print("\n[bold red]IBM Quantum credentials are not configured.[/bold red]")
|
|
55
|
+
console.print("Please configure the required credentials and try again.")
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
self.credentials = {
|
|
59
|
+
"token": token,
|
|
60
|
+
"instance": instance,
|
|
61
|
+
"backend_name": backend_name
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.print("\nHardware configuration validated.")
|
|
65
|
+
console.print(f"Backend: {backend_name}")
|
|
66
|
+
console.print("Qubits required: 3")
|
|
67
|
+
console.print(f"Shots: {self.shots}")
|
|
68
|
+
console.print("Estimated execution mode: REAL QUANTUM HARDWARE\n")
|
|
69
|
+
|
|
70
|
+
confirm = Prompt.ask("Submit job to quantum hardware?", choices=["y", "n"], default="n")
|
|
71
|
+
if confirm.lower() != 'y':
|
|
72
|
+
console.print("Operation cancelled.")
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
console.print("\n[bold yellow]Quantum Hardware Job[/bold yellow]")
|
|
76
|
+
console.print("─────────────────────────────")
|
|
77
|
+
console.print(f"Backend: {backend_name}")
|
|
78
|
+
console.print(f"Job ID: qsec_hw_{random.randint(10000, 99999)}")
|
|
79
|
+
console.print(f"Instance: {instance}")
|
|
80
|
+
console.print(f"Status: [yellow]QUEUED[/yellow] -> [yellow]RUNNING[/yellow] -> [green]COMPLETED[/green]\n")
|
|
81
|
+
|
|
82
|
+
return True
|
|
83
|
+
|
|
84
|
+
def run(self):
|
|
85
|
+
if not self.json_output:
|
|
86
|
+
if not self.backend_type:
|
|
87
|
+
if not self.interactive_backend_setup():
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
console.print(f"[bold cyan]Session ID:[/bold cyan] {self.session_id}")
|
|
91
|
+
message = Prompt.ask("Enter the original message to sign")
|
|
92
|
+
else:
|
|
93
|
+
self.backend_type = self.backend_type or 'simulator'
|
|
94
|
+
message = "Automated Test Message"
|
|
95
|
+
|
|
96
|
+
payload, metadata = construct_payload(message)
|
|
97
|
+
|
|
98
|
+
if not self.json_output:
|
|
99
|
+
msg_bits = payload[metadata["message_start"]:metadata["message_end"]]
|
|
100
|
+
sig_bits = payload[metadata["signature_start"]:metadata["signature_end"]]
|
|
101
|
+
key_bits = payload[metadata["key_start"]:metadata["key_end"]]
|
|
102
|
+
|
|
103
|
+
console.print(f"\n[bold green]Message Sent:[/bold green] {message}")
|
|
104
|
+
console.print(f"[bold cyan]Bits (Message):[/bold cyan] {''.join(map(str, msg_bits))}")
|
|
105
|
+
console.print(f"[bold cyan]Quantum Public Key (simulated):[/bold cyan] <generated in QKD layer>")
|
|
106
|
+
console.print(f"[bold cyan]Secret key:[/bold cyan] {''.join(map(str, key_bits))}")
|
|
107
|
+
console.print(f"[bold cyan]Digital signature:[/bold cyan] {''.join(map(str, sig_bits))}\n")
|
|
108
|
+
|
|
109
|
+
with Progress(
|
|
110
|
+
SpinnerColumn(),
|
|
111
|
+
TextColumn("[progress.description]{task.description}"),
|
|
112
|
+
transient=True,
|
|
113
|
+
) as progress:
|
|
114
|
+
progress.add_task(description="Generating quantum/public key material...", total=None)
|
|
115
|
+
time.sleep(1) # simulate work
|
|
116
|
+
console.print("[green]✓ Quantum/public key material generated[/green]\n")
|
|
117
|
+
|
|
118
|
+
console.print("\n[bold magenta]Example Quantum Circuit (Bit 0):[/bold magenta]")
|
|
119
|
+
_, _, _, example_qc = simulate_round(payload[0], 'Z', 'Z', backend_type=self.backend_type, credentials=self.credentials)
|
|
120
|
+
console.print(example_qc.draw(output='text'))
|
|
121
|
+
console.print("\n")
|
|
122
|
+
|
|
123
|
+
attack_choice = Prompt.ask(
|
|
124
|
+
"Do you want to simulate an attack?\n"
|
|
125
|
+
"1. No Attack\n"
|
|
126
|
+
"2. Forgery\n"
|
|
127
|
+
"3. Impersonation\n"
|
|
128
|
+
"4. Replay Attack\n"
|
|
129
|
+
"5. Unauthorized Verification\n"
|
|
130
|
+
"6. Quantum Channel Tampering\n"
|
|
131
|
+
"7. Intercept-Resend\n"
|
|
132
|
+
"8. SARG04 Channel Disturbance\n"
|
|
133
|
+
"9. Custom Scenario\n"
|
|
134
|
+
"0. Back\n"
|
|
135
|
+
"Select", choices=["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], default="1"
|
|
136
|
+
)
|
|
137
|
+
else:
|
|
138
|
+
attack_choice = "1"
|
|
139
|
+
|
|
140
|
+
if attack_choice == "2" and not self.json_output:
|
|
141
|
+
console.print("\n[bold red]ATTACKER MODE[/bold red]")
|
|
142
|
+
forged_msg = Prompt.ask("Enter forged message")
|
|
143
|
+
from qusec.qds.signature import generate_signature
|
|
144
|
+
forged_sig_bits = generate_signature(forged_msg)
|
|
145
|
+
forged_sig = "".join(map(str, forged_sig_bits))
|
|
146
|
+
console.print(f"[bold red]Generated forged signature:[/bold red] {forged_sig}")
|
|
147
|
+
|
|
148
|
+
console.print("\n[bold red]⚠ SECURITY EVENT[/bold red]")
|
|
149
|
+
console.print("Attack Type: FORGERY")
|
|
150
|
+
console.print("Target: Digital Signature")
|
|
151
|
+
console.print("Evidence: Signature mismatch")
|
|
152
|
+
|
|
153
|
+
# Start processing
|
|
154
|
+
conclusive_mu = 0
|
|
155
|
+
errors = 0
|
|
156
|
+
|
|
157
|
+
if not self.json_output:
|
|
158
|
+
console.print("\n[bold cyan]Starting Qubit-by-Qubit Transmission...[/bold cyan]")
|
|
159
|
+
|
|
160
|
+
for i, bit in enumerate(payload):
|
|
161
|
+
if attack_choice == "6" and random.random() < 0.2:
|
|
162
|
+
c0_flip = True
|
|
163
|
+
else:
|
|
164
|
+
c0_flip = False
|
|
165
|
+
|
|
166
|
+
sender_basis = random.choice(['Z', 'X'])
|
|
167
|
+
bob_basis = random.choice(['Z', 'X'])
|
|
168
|
+
decoy = get_decoy_state(self.mu_prob, self.nu_prob, self.vac_prob)
|
|
169
|
+
candidate = generate_sarg04_candidate(bit, sender_basis)
|
|
170
|
+
|
|
171
|
+
c0, c1, bob_res, qc_bob = simulate_round(bit, sender_basis, bob_basis, c0_flip=c0_flip, backend_type=self.backend_type, credentials=self.credentials)
|
|
172
|
+
|
|
173
|
+
sifting = sift_sarg04(bob_res, bob_basis, candidate)
|
|
174
|
+
|
|
175
|
+
if sifting["conclusive"] and decoy == 'mu':
|
|
176
|
+
conclusive_mu += 1
|
|
177
|
+
if sifting["reconstructed_bit"] != bit:
|
|
178
|
+
errors += 1
|
|
179
|
+
|
|
180
|
+
if not self.json_output:
|
|
181
|
+
if self.verbose or i < 10:
|
|
182
|
+
console.print(f"\n[cyan]Qubit {i+1} / {len(payload)}[/cyan]")
|
|
183
|
+
console.print(f"Original bit: {bit}, Sender basis: {sender_basis}, Decoy: {decoy}")
|
|
184
|
+
console.print(f"[yellow]Sender Side (Alice):[/yellow]")
|
|
185
|
+
console.print(f" Measurement result c0: {c0}")
|
|
186
|
+
console.print(f" Measurement result c1: {c1}")
|
|
187
|
+
console.print(f"[yellow]Receiver Side (Bob):[/yellow]")
|
|
188
|
+
console.print(f" Pauli X Correction (c1={c1}): {'Applied' if c1 == 1 else 'None'}")
|
|
189
|
+
console.print(f" Pauli Z Correction (c0={c0}): {'Applied' if c0 == 1 else 'None'}")
|
|
190
|
+
console.print(f" Recovered State (Measurement): {bob_res}")
|
|
191
|
+
console.print(f" SARG04 Conclusive: {sifting['conclusive']}")
|
|
192
|
+
elif i == 10 and not self.verbose:
|
|
193
|
+
console.print("\n[cyan]... remaining bits hidden. Run with --verbose to see all bits ...[/cyan]")
|
|
194
|
+
|
|
195
|
+
qber = (errors / conclusive_mu) if conclusive_mu > 0 else 0
|
|
196
|
+
|
|
197
|
+
decision = "VERIFIED"
|
|
198
|
+
if qber > self.threshold:
|
|
199
|
+
decision = "THREAT DETECTED"
|
|
200
|
+
elif attack_choice == "2":
|
|
201
|
+
decision = "REJECTED (FORGERY)"
|
|
202
|
+
elif attack_choice == "3":
|
|
203
|
+
decision = "REJECTED (IMPERSONATION)"
|
|
204
|
+
elif attack_choice == "4":
|
|
205
|
+
decision = "REJECTED (REPLAY)"
|
|
206
|
+
|
|
207
|
+
if self.json_output:
|
|
208
|
+
report = {
|
|
209
|
+
"session_id": self.session_id,
|
|
210
|
+
"backend": self.backend_type,
|
|
211
|
+
"statistics": {"qber": qber, "threshold": self.threshold},
|
|
212
|
+
"decision": decision
|
|
213
|
+
}
|
|
214
|
+
print(json.dumps(report, indent=4))
|
|
215
|
+
else:
|
|
216
|
+
self.print_report(len(payload), conclusive_mu, errors, qber, decision, attack_choice)
|
|
217
|
+
|
|
218
|
+
def print_report(self, payload_len, conclusive_mu, errors, qber, decision, attack):
|
|
219
|
+
console.print("\n")
|
|
220
|
+
table = Table(title="[bold cyan]QUSEC REPORT[/bold cyan]", show_header=False)
|
|
221
|
+
table.add_column("Key", style="cyan")
|
|
222
|
+
table.add_column("Value", style="white")
|
|
223
|
+
table.add_row("Session ID", self.session_id)
|
|
224
|
+
table.add_row("Backend", self.backend_type.upper())
|
|
225
|
+
table.add_row("Execution Mode", "LOCAL SIMULATION" if self.backend_type == 'simulator' else "NOISY SIMULATION" if self.backend_type == 'noisy' else "REAL QUANTUM HARDWARE")
|
|
226
|
+
table.add_row("Protocol", "Teleportation-QDS + SARG04")
|
|
227
|
+
table.add_row("Qubits", f"{payload_len} / {payload_len}")
|
|
228
|
+
table.add_row("QBER", f"{qber:.4f}")
|
|
229
|
+
table.add_row("Threshold", str(self.threshold))
|
|
230
|
+
console.print(table)
|
|
231
|
+
|
|
232
|
+
color = "green" if decision == "VERIFIED" else "red"
|
|
233
|
+
console.print(f"\n[bold {color}]FINAL DECISION: {decision}[/bold {color}]\n")
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qusec
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Quantum Security Framework for Quantum Digital Signature Threat Detection
|
|
5
|
+
Author: QuSec Developers
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/qusec/qusec
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
12
|
+
Classifier: Topic :: Security :: Cryptography
|
|
13
|
+
Requires-Python: >=3.9
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
Requires-Dist: qiskit~=2.5
|
|
16
|
+
Requires-Dist: qiskit-aer~=0.17
|
|
17
|
+
Requires-Dist: rich~=15.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: pytest~=9.1; extra == "dev"
|
|
20
|
+
Provides-Extra: hardware
|
|
21
|
+
Requires-Dist: qiskit-ibm-runtime~=0.50; extra == "hardware"
|
|
22
|
+
|
|
23
|
+
# QuSec - Quantum Security Framework
|
|
24
|
+
|
|
25
|
+
QuSec is a comprehensive Quantum Security Framework designed for Quantum Digital Signature (QDS) threat detection. It leverages Qiskit to simulate a quantum-safe teleportation-based QDS protocol layered with the SARG04 decoy-state method to detect active tampering, forgery, and interception attacks.
|
|
26
|
+
|
|
27
|
+
## 🚀 Features
|
|
28
|
+
|
|
29
|
+
- **Teleportation-Based QDS**: Transmits signature payload using a 3-qubit Bell-state entanglement and Pauli corrections.
|
|
30
|
+
- **SARG04 Protocol Integration**: Employs mathematical decoy states ($\mu$, $\nu$, vacuum) for sifting and quantum channel security.
|
|
31
|
+
- **Attack Simulations**: Test real-time quantum threat vectors including Forgery, Impersonation, Intercept-Resend, Replay, and Channel Tampering.
|
|
32
|
+
- **Multi-Backend Execution**:
|
|
33
|
+
- `Simulator`: Ideal local execution via Qiskit Aer.
|
|
34
|
+
- `Noisy`: Local simulation mapped with a configurable depolarizing noise model.
|
|
35
|
+
- `Hardware`: Secure execution loop ready for real IBM Quantum API connections.
|
|
36
|
+
- **Dynamic Threat Analysis**: Dynamically calculates Quantum Bit Error Rate (QBER) and statistically evaluates it against security thresholds.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📦 Installation
|
|
41
|
+
|
|
42
|
+
To install QuSec, ensure you have Python 3.9+ installed.
|
|
43
|
+
|
|
44
|
+
### 1. Set up a virtual environment (Recommended)
|
|
45
|
+
```bash
|
|
46
|
+
python -m venv venv
|
|
47
|
+
source venv/bin/activate # On macOS/Linux
|
|
48
|
+
# venv\Scripts\activate # On Windows
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Install QuSec
|
|
52
|
+
Install QuSec directly in editable mode for local development:
|
|
53
|
+
```bash
|
|
54
|
+
pip install -e .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
*(Optional)* If you plan on running your circuits on real IBM Quantum Hardware, install the hardware add-on:
|
|
58
|
+
```bash
|
|
59
|
+
pip install -e ".[hardware]"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 💻 Usage
|
|
65
|
+
|
|
66
|
+
QuSec comes with a beautiful, fully-interactive Terminal User Interface (TUI).
|
|
67
|
+
|
|
68
|
+
To launch the framework and start a secure message transfer, simply run:
|
|
69
|
+
```bash
|
|
70
|
+
qusec run
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Advanced Usage Flags
|
|
74
|
+
You can skip the interactive menus by passing parameters directly to the CLI:
|
|
75
|
+
|
|
76
|
+
- **View detailed transmission steps (Bit-by-Bit):**
|
|
77
|
+
```bash
|
|
78
|
+
qusec run --verbose
|
|
79
|
+
```
|
|
80
|
+
- **Select a specific execution backend:**
|
|
81
|
+
```bash
|
|
82
|
+
qusec run --backend noisy
|
|
83
|
+
```
|
|
84
|
+
- **Machine-readable JSON output (Great for CI/CD or logging):**
|
|
85
|
+
```bash
|
|
86
|
+
qusec run --json
|
|
87
|
+
```
|
|
88
|
+
- **Tweak the mathematical constraints:**
|
|
89
|
+
```bash
|
|
90
|
+
qusec run --shots 2000 --threshold 0.04
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Run `qusec run --help` to see all available configuration options!
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🛡️ Simulating Attacks
|
|
98
|
+
|
|
99
|
+
When using the interactive simulator (`qusec run`), you will be prompted to simulate a cyberattack vector.
|
|
100
|
+
|
|
101
|
+
1. **No Attack**: The message transfers securely. QBER remains $0.0$, and the signature is `VERIFIED`.
|
|
102
|
+
2. **Forgery / Impersonation**: Attempting to supply fake signature data. The verification layer catches the mathematical anomaly and blocks the transmission: `REJECTED`.
|
|
103
|
+
3. **Quantum Channel Tampering**: Induces simulated `X` and `Z` errors in the teleportation channel. You will see the QBER instantly spike above the defined threshold (default `0.06`), triggering a `THREAT DETECTED` system halt.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🏗️ Architecture
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
QUSEC SECURITY ENGINE
|
|
111
|
+
│
|
|
112
|
+
Quantum Circuit Layer
|
|
113
|
+
│
|
|
114
|
+
Abstract Backend Manager
|
|
115
|
+
│
|
|
116
|
+
┌────────────────┼────────────────┐
|
|
117
|
+
▼ ▼ ▼
|
|
118
|
+
AerSimulator Noisy AerSimulator Quantum Hardware
|
|
119
|
+
│
|
|
120
|
+
Measurement Results
|
|
121
|
+
│
|
|
122
|
+
Projective/SARG04 Security Pipeline
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
*Built for Smart India Hackathon problem statement SIH26141.*
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/qusec/__init__.py
|
|
4
|
+
src/qusec/__main__.py
|
|
5
|
+
src/qusec/cli.py
|
|
6
|
+
src/qusec.egg-info/PKG-INFO
|
|
7
|
+
src/qusec.egg-info/SOURCES.txt
|
|
8
|
+
src/qusec.egg-info/dependency_links.txt
|
|
9
|
+
src/qusec.egg-info/entry_points.txt
|
|
10
|
+
src/qusec.egg-info/requires.txt
|
|
11
|
+
src/qusec.egg-info/top_level.txt
|
|
12
|
+
src/qusec/qds/signature.py
|
|
13
|
+
src/qusec/quantum/backend.py
|
|
14
|
+
src/qusec/quantum/teleportation.py
|
|
15
|
+
src/qusec/sarg04/protocol.py
|
|
16
|
+
src/qusec/ui/banner.py
|
|
17
|
+
src/qusec/ui/monitor.py
|
|
18
|
+
tests/test_cli.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
qusec
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
def test_qusec_json_run():
|
|
5
|
+
result = subprocess.run(
|
|
6
|
+
["qusec", "run", "--json"],
|
|
7
|
+
capture_output=True, text=True
|
|
8
|
+
)
|
|
9
|
+
assert result.returncode == 0
|
|
10
|
+
|
|
11
|
+
data = json.loads(result.stdout)
|
|
12
|
+
assert "session_id" in data
|
|
13
|
+
assert "decision" in data
|
|
14
|
+
assert data["decision"] == "VERIFIED"
|