qpher 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.
qpher-0.1.0/.gitignore ADDED
@@ -0,0 +1,82 @@
1
+ # ============================================================
2
+ # Qpher PQC Security Cloud — .gitignore
3
+ # ============================================================
4
+
5
+ # --- Python ---
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ *.so
10
+ *.egg-info/
11
+ dist/
12
+ build/
13
+ *.egg
14
+ .eggs/
15
+
16
+ # --- Virtual Environments ---
17
+ venv/
18
+ .venv/
19
+ env/
20
+ ENV/
21
+
22
+ # --- IDE ---
23
+ .vscode/
24
+ .idea/
25
+ *.swp
26
+ *.swo
27
+ *~
28
+ .DS_Store
29
+ Thumbs.db
30
+
31
+ # --- Testing ---
32
+ .coverage
33
+ .coverage.*
34
+ htmlcov/
35
+ .pytest_cache/
36
+ .mypy_cache/
37
+ .ruff_cache/
38
+
39
+ # --- Environment / Secrets ---
40
+ .env
41
+ .env.local
42
+ .env.production
43
+ .env.staging
44
+ # NOTE: .env.example IS tracked (template only, no real secrets)
45
+
46
+ # --- Database ---
47
+ *.db
48
+ *.sqlite3
49
+
50
+ # --- Logs ---
51
+ logs/
52
+ *.log
53
+ audit_logs/
54
+
55
+ # --- Docker ---
56
+ docker-compose.override.yml
57
+
58
+ # --- Node.js (frontend apps) ---
59
+ node_modules/
60
+ .next/
61
+ .docusaurus/
62
+ out/
63
+ .turbo/
64
+ .vercel/
65
+
66
+ # --- KMS Key Files (NEVER commit private keys) ---
67
+ kms_keys/
68
+ *.pem
69
+ *.key
70
+
71
+ # --- OS ---
72
+ Desktop.ini
73
+
74
+ # --- Build artifacts ---
75
+ *.tar.gz
76
+ *.whl
77
+
78
+ # --- Jupyter ---
79
+ .ipynb_checkpoints/
80
+
81
+ # --- Claude Code ---
82
+ .claude/
qpher-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Qpher
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
qpher-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,265 @@
1
+ Metadata-Version: 2.4
2
+ Name: qpher
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for the Qpher Post-Quantum Cryptography API
5
+ Project-URL: Homepage, https://qpher.ai
6
+ Project-URL: Documentation, https://docs.qpher.ai/sdks/python
7
+ Project-URL: Repository, https://github.com/qpher/qpher-python
8
+ Project-URL: Issues, https://github.com/qpher/qpher-python/issues
9
+ Author-email: Qpher <sdk@qpher.ai>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: cryptography,dilithium,encryption,kyber,post-quantum,pqc,signatures
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: requests>=2.31.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
26
+ Requires-Dist: pytest>=7.4.0; extra == 'dev'
27
+ Requires-Dist: responses>=0.24.0; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Qpher Python SDK
31
+
32
+ Official Python SDK for the [Qpher](https://qpher.ai) Post-Quantum Cryptography API.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install qpher
38
+ ```
39
+
40
+ ## Requirements
41
+
42
+ - Python 3.9+
43
+
44
+ ## Quick Start
45
+
46
+ ```python
47
+ from qpher import Qpher
48
+
49
+ # Initialize the client
50
+ client = Qpher(api_key="qph_live_your_api_key")
51
+
52
+ # Encrypt data using Kyber768 KEM
53
+ result = client.kem.encrypt(
54
+ plaintext=b"Hello, Quantum World!",
55
+ key_version=1,
56
+ )
57
+ print(f"Ciphertext: {result.ciphertext.hex()}")
58
+
59
+ # Decrypt data
60
+ decrypted = client.kem.decrypt(
61
+ ciphertext=result.ciphertext,
62
+ key_version=result.key_version,
63
+ )
64
+ print(f"Plaintext: {decrypted.plaintext}")
65
+
66
+ # Sign a message using Dilithium3
67
+ sig_result = client.signatures.sign(
68
+ message=b"Invoice #12345",
69
+ key_version=1,
70
+ )
71
+ print(f"Signature: {sig_result.signature.hex()}")
72
+
73
+ # Verify a signature
74
+ verify_result = client.signatures.verify(
75
+ message=b"Invoice #12345",
76
+ signature=sig_result.signature,
77
+ key_version=sig_result.key_version,
78
+ )
79
+ print(f"Valid: {verify_result.valid}")
80
+ ```
81
+
82
+ ## API Reference
83
+
84
+ ### Client Initialization
85
+
86
+ ```python
87
+ from qpher import Qpher
88
+
89
+ client = Qpher(
90
+ api_key="qph_live_your_api_key", # Required
91
+ base_url="https://api.qpher.ai", # Optional, default
92
+ timeout=30, # Optional, seconds
93
+ max_retries=3, # Optional
94
+ )
95
+ ```
96
+
97
+ ### KEM Operations (Kyber768)
98
+
99
+ #### Encrypt
100
+
101
+ ```python
102
+ result = client.kem.encrypt(
103
+ plaintext=b"secret data",
104
+ key_version=1,
105
+ mode="standard", # Optional: "standard" or "deterministic"
106
+ salt=b"...", # Required if mode="deterministic" (min 32 bytes)
107
+ )
108
+ # result.ciphertext: bytes
109
+ # result.key_version: int
110
+ # result.algorithm: str ("Kyber768")
111
+ # result.request_id: str
112
+ ```
113
+
114
+ #### Decrypt
115
+
116
+ ```python
117
+ result = client.kem.decrypt(
118
+ ciphertext=encrypted_data,
119
+ key_version=1,
120
+ )
121
+ # result.plaintext: bytes
122
+ # result.key_version: int
123
+ # result.algorithm: str
124
+ # result.request_id: str
125
+ ```
126
+
127
+ ### Signature Operations (Dilithium3)
128
+
129
+ #### Sign
130
+
131
+ ```python
132
+ result = client.signatures.sign(
133
+ message=b"document to sign",
134
+ key_version=1,
135
+ )
136
+ # result.signature: bytes (3,293 bytes)
137
+ # result.key_version: int
138
+ # result.algorithm: str ("Dilithium3")
139
+ # result.request_id: str
140
+ ```
141
+
142
+ #### Verify
143
+
144
+ ```python
145
+ result = client.signatures.verify(
146
+ message=b"document to sign",
147
+ signature=signature_bytes,
148
+ key_version=1,
149
+ )
150
+ # result.valid: bool
151
+ # result.key_version: int
152
+ # result.algorithm: str
153
+ # result.request_id: str
154
+ ```
155
+
156
+ ### Key Management
157
+
158
+ #### Generate Key
159
+
160
+ ```python
161
+ result = client.keys.generate(algorithm="Kyber768")
162
+ # result.key_version: int
163
+ # result.algorithm: str
164
+ # result.status: str ("active")
165
+ # result.public_key: bytes
166
+ # result.created_at: str
167
+ ```
168
+
169
+ #### Rotate Key
170
+
171
+ ```python
172
+ result = client.keys.rotate(algorithm="Kyber768")
173
+ # result.key_version: int (new)
174
+ # result.old_key_version: int
175
+ # result.algorithm: str
176
+ # result.public_key: bytes
177
+ ```
178
+
179
+ #### Get Active Key
180
+
181
+ ```python
182
+ key_info = client.keys.get_active(algorithm="Kyber768")
183
+ # key_info.key_version: int
184
+ # key_info.algorithm: str
185
+ # key_info.status: str
186
+ # key_info.public_key: bytes
187
+ # key_info.created_at: str
188
+ ```
189
+
190
+ #### List Keys
191
+
192
+ ```python
193
+ result = client.keys.list(
194
+ algorithm="Kyber768", # Optional filter
195
+ status="active", # Optional filter: "active", "retired", "archived"
196
+ )
197
+ # result.keys: List[KeyInfo]
198
+ # result.total: int
199
+ ```
200
+
201
+ #### Retire Key
202
+
203
+ ```python
204
+ result = client.keys.retire(algorithm="Kyber768", key_version=1)
205
+ # result.key_version: int
206
+ # result.status: str ("retired")
207
+ ```
208
+
209
+ ## Error Handling
210
+
211
+ ```python
212
+ from qpher import (
213
+ Qpher,
214
+ QpherError,
215
+ AuthenticationError,
216
+ ValidationError,
217
+ NotFoundError,
218
+ RateLimitError,
219
+ )
220
+
221
+ try:
222
+ result = client.kem.encrypt(plaintext=b"data", key_version=99)
223
+ except NotFoundError as e:
224
+ print(f"Key not found: {e.message}")
225
+ print(f"Error code: {e.error_code}")
226
+ print(f"Request ID: {e.request_id}")
227
+ except RateLimitError as e:
228
+ print("Rate limit exceeded, please retry later")
229
+ except AuthenticationError as e:
230
+ print("Invalid API key")
231
+ except ValidationError as e:
232
+ print(f"Invalid input: {e.message}")
233
+ except QpherError as e:
234
+ print(f"API error: {e.message}")
235
+ ```
236
+
237
+ ## Error Types
238
+
239
+ | Exception | HTTP Status | Description |
240
+ |-----------|-------------|-------------|
241
+ | `AuthenticationError` | 401 | Invalid or missing API key |
242
+ | `ValidationError` | 400 | Invalid request parameters |
243
+ | `ForbiddenError` | 403 | Operation not allowed |
244
+ | `NotFoundError` | 404 | Resource not found |
245
+ | `RateLimitError` | 429 | Rate limit exceeded |
246
+ | `ServerError` | 500+ | Server-side errors |
247
+ | `TimeoutError` | 504 | Request timed out |
248
+ | `ConnectionError` | 503 | Connection failed |
249
+
250
+ ## Supported Algorithms
251
+
252
+ | Algorithm | Type | Security Level |
253
+ |-----------|------|----------------|
254
+ | Kyber768 | KEM (Encryption) | NIST Level 3 |
255
+ | Dilithium3 | Digital Signatures | NIST Level 3 |
256
+
257
+ ## License
258
+
259
+ MIT License - see [LICENSE](LICENSE) for details.
260
+
261
+ ## Links
262
+
263
+ - [Qpher Website](https://qpher.ai)
264
+ - [API Documentation](https://docs.qpher.ai)
265
+ - [GitHub Repository](https://github.com/qpher/qpher-python)
qpher-0.1.0/README.md ADDED
@@ -0,0 +1,236 @@
1
+ # Qpher Python SDK
2
+
3
+ Official Python SDK for the [Qpher](https://qpher.ai) Post-Quantum Cryptography API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install qpher
9
+ ```
10
+
11
+ ## Requirements
12
+
13
+ - Python 3.9+
14
+
15
+ ## Quick Start
16
+
17
+ ```python
18
+ from qpher import Qpher
19
+
20
+ # Initialize the client
21
+ client = Qpher(api_key="qph_live_your_api_key")
22
+
23
+ # Encrypt data using Kyber768 KEM
24
+ result = client.kem.encrypt(
25
+ plaintext=b"Hello, Quantum World!",
26
+ key_version=1,
27
+ )
28
+ print(f"Ciphertext: {result.ciphertext.hex()}")
29
+
30
+ # Decrypt data
31
+ decrypted = client.kem.decrypt(
32
+ ciphertext=result.ciphertext,
33
+ key_version=result.key_version,
34
+ )
35
+ print(f"Plaintext: {decrypted.plaintext}")
36
+
37
+ # Sign a message using Dilithium3
38
+ sig_result = client.signatures.sign(
39
+ message=b"Invoice #12345",
40
+ key_version=1,
41
+ )
42
+ print(f"Signature: {sig_result.signature.hex()}")
43
+
44
+ # Verify a signature
45
+ verify_result = client.signatures.verify(
46
+ message=b"Invoice #12345",
47
+ signature=sig_result.signature,
48
+ key_version=sig_result.key_version,
49
+ )
50
+ print(f"Valid: {verify_result.valid}")
51
+ ```
52
+
53
+ ## API Reference
54
+
55
+ ### Client Initialization
56
+
57
+ ```python
58
+ from qpher import Qpher
59
+
60
+ client = Qpher(
61
+ api_key="qph_live_your_api_key", # Required
62
+ base_url="https://api.qpher.ai", # Optional, default
63
+ timeout=30, # Optional, seconds
64
+ max_retries=3, # Optional
65
+ )
66
+ ```
67
+
68
+ ### KEM Operations (Kyber768)
69
+
70
+ #### Encrypt
71
+
72
+ ```python
73
+ result = client.kem.encrypt(
74
+ plaintext=b"secret data",
75
+ key_version=1,
76
+ mode="standard", # Optional: "standard" or "deterministic"
77
+ salt=b"...", # Required if mode="deterministic" (min 32 bytes)
78
+ )
79
+ # result.ciphertext: bytes
80
+ # result.key_version: int
81
+ # result.algorithm: str ("Kyber768")
82
+ # result.request_id: str
83
+ ```
84
+
85
+ #### Decrypt
86
+
87
+ ```python
88
+ result = client.kem.decrypt(
89
+ ciphertext=encrypted_data,
90
+ key_version=1,
91
+ )
92
+ # result.plaintext: bytes
93
+ # result.key_version: int
94
+ # result.algorithm: str
95
+ # result.request_id: str
96
+ ```
97
+
98
+ ### Signature Operations (Dilithium3)
99
+
100
+ #### Sign
101
+
102
+ ```python
103
+ result = client.signatures.sign(
104
+ message=b"document to sign",
105
+ key_version=1,
106
+ )
107
+ # result.signature: bytes (3,293 bytes)
108
+ # result.key_version: int
109
+ # result.algorithm: str ("Dilithium3")
110
+ # result.request_id: str
111
+ ```
112
+
113
+ #### Verify
114
+
115
+ ```python
116
+ result = client.signatures.verify(
117
+ message=b"document to sign",
118
+ signature=signature_bytes,
119
+ key_version=1,
120
+ )
121
+ # result.valid: bool
122
+ # result.key_version: int
123
+ # result.algorithm: str
124
+ # result.request_id: str
125
+ ```
126
+
127
+ ### Key Management
128
+
129
+ #### Generate Key
130
+
131
+ ```python
132
+ result = client.keys.generate(algorithm="Kyber768")
133
+ # result.key_version: int
134
+ # result.algorithm: str
135
+ # result.status: str ("active")
136
+ # result.public_key: bytes
137
+ # result.created_at: str
138
+ ```
139
+
140
+ #### Rotate Key
141
+
142
+ ```python
143
+ result = client.keys.rotate(algorithm="Kyber768")
144
+ # result.key_version: int (new)
145
+ # result.old_key_version: int
146
+ # result.algorithm: str
147
+ # result.public_key: bytes
148
+ ```
149
+
150
+ #### Get Active Key
151
+
152
+ ```python
153
+ key_info = client.keys.get_active(algorithm="Kyber768")
154
+ # key_info.key_version: int
155
+ # key_info.algorithm: str
156
+ # key_info.status: str
157
+ # key_info.public_key: bytes
158
+ # key_info.created_at: str
159
+ ```
160
+
161
+ #### List Keys
162
+
163
+ ```python
164
+ result = client.keys.list(
165
+ algorithm="Kyber768", # Optional filter
166
+ status="active", # Optional filter: "active", "retired", "archived"
167
+ )
168
+ # result.keys: List[KeyInfo]
169
+ # result.total: int
170
+ ```
171
+
172
+ #### Retire Key
173
+
174
+ ```python
175
+ result = client.keys.retire(algorithm="Kyber768", key_version=1)
176
+ # result.key_version: int
177
+ # result.status: str ("retired")
178
+ ```
179
+
180
+ ## Error Handling
181
+
182
+ ```python
183
+ from qpher import (
184
+ Qpher,
185
+ QpherError,
186
+ AuthenticationError,
187
+ ValidationError,
188
+ NotFoundError,
189
+ RateLimitError,
190
+ )
191
+
192
+ try:
193
+ result = client.kem.encrypt(plaintext=b"data", key_version=99)
194
+ except NotFoundError as e:
195
+ print(f"Key not found: {e.message}")
196
+ print(f"Error code: {e.error_code}")
197
+ print(f"Request ID: {e.request_id}")
198
+ except RateLimitError as e:
199
+ print("Rate limit exceeded, please retry later")
200
+ except AuthenticationError as e:
201
+ print("Invalid API key")
202
+ except ValidationError as e:
203
+ print(f"Invalid input: {e.message}")
204
+ except QpherError as e:
205
+ print(f"API error: {e.message}")
206
+ ```
207
+
208
+ ## Error Types
209
+
210
+ | Exception | HTTP Status | Description |
211
+ |-----------|-------------|-------------|
212
+ | `AuthenticationError` | 401 | Invalid or missing API key |
213
+ | `ValidationError` | 400 | Invalid request parameters |
214
+ | `ForbiddenError` | 403 | Operation not allowed |
215
+ | `NotFoundError` | 404 | Resource not found |
216
+ | `RateLimitError` | 429 | Rate limit exceeded |
217
+ | `ServerError` | 500+ | Server-side errors |
218
+ | `TimeoutError` | 504 | Request timed out |
219
+ | `ConnectionError` | 503 | Connection failed |
220
+
221
+ ## Supported Algorithms
222
+
223
+ | Algorithm | Type | Security Level |
224
+ |-----------|------|----------------|
225
+ | Kyber768 | KEM (Encryption) | NIST Level 3 |
226
+ | Dilithium3 | Digital Signatures | NIST Level 3 |
227
+
228
+ ## License
229
+
230
+ MIT License - see [LICENSE](LICENSE) for details.
231
+
232
+ ## Links
233
+
234
+ - [Qpher Website](https://qpher.ai)
235
+ - [API Documentation](https://docs.qpher.ai)
236
+ - [GitHub Repository](https://github.com/qpher/qpher-python)
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "qpher"
7
+ version = "0.1.0"
8
+ description = "Official Python SDK for the Qpher Post-Quantum Cryptography API"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "Qpher", email = "sdk@qpher.ai" }]
13
+ keywords = ["post-quantum", "cryptography", "pqc", "kyber", "dilithium", "encryption", "signatures"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.9",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Topic :: Security :: Cryptography",
24
+ ]
25
+ dependencies = ["requests>=2.31.0"]
26
+
27
+ [project.optional-dependencies]
28
+ dev = [
29
+ "pytest>=7.4.0",
30
+ "pytest-cov>=4.1.0",
31
+ "responses>=0.24.0",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://qpher.ai"
36
+ Documentation = "https://docs.qpher.ai/sdks/python"
37
+ Repository = "https://github.com/qpher/qpher-python"
38
+ Issues = "https://github.com/qpher/qpher-python/issues"
39
+
40
+ [tool.pytest.ini_options]
41
+ testpaths = ["tests"]
42
+ asyncio_mode = "auto"
43
+
44
+ [tool.hatch.build.targets.wheel]
45
+ packages = ["qpher"]
@@ -0,0 +1,53 @@
1
+ """Qpher Python SDK - Official client for the Qpher Post-Quantum Cryptography API."""
2
+
3
+ from qpher.client import Qpher
4
+ from qpher.errors import (
5
+ QpherError,
6
+ AuthenticationError,
7
+ RateLimitError,
8
+ NotFoundError,
9
+ ValidationError,
10
+ ForbiddenError,
11
+ ServerError,
12
+ TimeoutError,
13
+ ConnectionError,
14
+ )
15
+ from qpher.types import (
16
+ EncryptResult,
17
+ DecryptResult,
18
+ SignResult,
19
+ VerifyResult,
20
+ KeyInfo,
21
+ KeyListResult,
22
+ RotateResult,
23
+ GenerateResult,
24
+ RetireResult,
25
+ )
26
+ from qpher._version import __version__
27
+
28
+ __all__ = [
29
+ # Main client
30
+ "Qpher",
31
+ # Errors
32
+ "QpherError",
33
+ "AuthenticationError",
34
+ "RateLimitError",
35
+ "NotFoundError",
36
+ "ValidationError",
37
+ "ForbiddenError",
38
+ "ServerError",
39
+ "TimeoutError",
40
+ "ConnectionError",
41
+ # Types
42
+ "EncryptResult",
43
+ "DecryptResult",
44
+ "SignResult",
45
+ "VerifyResult",
46
+ "KeyInfo",
47
+ "KeyListResult",
48
+ "RotateResult",
49
+ "GenerateResult",
50
+ "RetireResult",
51
+ # Version
52
+ "__version__",
53
+ ]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"