nexus-crypt 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.
nexus/__init__.py ADDED
@@ -0,0 +1,14 @@
1
+
2
+ __version__ = "1.0.0"
3
+ __author__ = "Harshith Madhavaram"
4
+
5
+ from .core import NEXUSCipher, NEXUS
6
+ from .exceptions import NEXUSError, DecryptionError, SignatureVerificationError
7
+
8
+ __all__ = [
9
+ "NEXUS",
10
+ "NEXUSCipher",
11
+ "NEXUSError",
12
+ "DecryptionError",
13
+ "SignatureVerificationError",
14
+ ]
nexus/constants.py ADDED
@@ -0,0 +1,28 @@
1
+
2
+
3
+ STATE_SIZE = 512
4
+ WORD_SIZE = 128
5
+ NUM_WORDS = 4
6
+ BLOCK_SIZE = 64
7
+
8
+ ROUNDS_256 = 20
9
+ ROUNDS_384 = 22
10
+ ROUNDS_512 = 24
11
+
12
+ PRIME_ROTATIONS = [17, 31, 61, 127]
13
+
14
+ GF128_POLY = 0b10000111
15
+
16
+ LWE_MODULUS = 257
17
+ LWE_ERROR_SIGMA = 3.2
18
+ SBOX_COUNT = 8
19
+ SBOX_SIZE = 256
20
+
21
+ SBOX_REGEN_BYTES = 1024 * 1024
22
+
23
+
24
+ NTRU_N = 512
25
+ NTRU_Q = 2**128
26
+
27
+
28
+ NONCE_SIZE = 16
nexus/core.py ADDED
@@ -0,0 +1,232 @@
1
+ import secrets
2
+ import hashlib
3
+ from typing import List, Tuple
4
+ from .math_utils import *
5
+ from .constants import *
6
+ from .exceptions import *
7
+
8
+ class NEXUSCipher:
9
+
10
+ def __init__(self, key: bytes, key_size: int = 256):
11
+ if key_size not in [256, 384, 512]:
12
+ raise NEXUSError("Key size must be 256, 384, or 512 bits")
13
+
14
+ expected_len = key_size // 8
15
+ if len(key) != expected_len:
16
+ raise NEXUSError(f"Key must be {expected_len} bytes for {key_size}-bit security")
17
+
18
+ self.key = key
19
+ self.key_size = key_size
20
+ self.rounds = self._get_rounds()
21
+ self.round_keys = self._derive_round_keys()
22
+ self.sboxes = [generate_lwe_sbox(key, i, 0) for i in range(SBOX_COUNT)]
23
+ self.sbox_counter = 0
24
+ self.bytes_processed = 0
25
+ self.gf_matrices = self._generate_gf_matrices()
26
+
27
+ def _get_rounds(self) -> int:
28
+ return {256: ROUNDS_256, 384: ROUNDS_384, 512: ROUNDS_512}[self.key_size]
29
+
30
+ def _derive_round_keys(self) -> List[List[int]]:
31
+ key_material = hkdf_sha256(self.key, self.rounds * 64, b"NEXUS-ROUND-KEYS")
32
+ round_keys = []
33
+ for i in range(self.rounds):
34
+ round_key_bytes = key_material[i*64:(i+1)*64]
35
+ round_key_words = bytes_to_words(round_key_bytes)
36
+ round_keys.append(round_key_words)
37
+ return round_keys
38
+
39
+ def _generate_gf_matrices(self) -> List[int]:
40
+ matrices = []
41
+ for i in range(NUM_WORDS):
42
+ h = hashlib.sha256()
43
+ h.update(self.key)
44
+ h.update(b"GF-MATRIX")
45
+ h.update(i.to_bytes(1, 'big'))
46
+ matrix_element = int.from_bytes(h.digest()[:16], 'big')
47
+ matrices.append(matrix_element)
48
+ return matrices
49
+
50
+ def _regenerate_sboxes_if_needed(self):
51
+ if self.bytes_processed >= SBOX_REGEN_BYTES:
52
+ self.sbox_counter += 1
53
+ self.sboxes = [generate_lwe_sbox(self.key, i, self.sbox_counter) for i in range(SBOX_COUNT)]
54
+ self.bytes_processed = 0
55
+
56
+ def _nexus_round(self, state: List[int], round_num: int) -> List[int]:
57
+ for i in range(NUM_WORDS):
58
+ state[i] = (state[i] + self.round_keys[round_num][i]) & ((1 << 128) - 1)
59
+ state[i] = rol(state[i], PRIME_ROTATIONS[i], 128)
60
+ lattice_const = generate_lattice_constant(round_num, i)
61
+ state[i] ^= lattice_const
62
+
63
+ state_bytes = bytearray(words_to_bytes(state))
64
+ for byte_idx in range(len(state_bytes)):
65
+ sbox_id = byte_idx % SBOX_COUNT
66
+ state_bytes[byte_idx] = self.sboxes[sbox_id][state_bytes[byte_idx]]
67
+ state = bytes_to_words(bytes(state_bytes))
68
+
69
+ for i in range(NUM_WORDS):
70
+ state[i] = gf128_multiply(state[i], self.gf_matrices[i])
71
+
72
+ state_bits = []
73
+ for word in state:
74
+ for bit_pos in range(128):
75
+ state_bits.append((word >> bit_pos) & 1)
76
+
77
+ ntru_perm = generate_ntru_permutation(self.key, round_num)
78
+ permuted_bits = [state_bits[ntru_perm[i]] for i in range(NTRU_N)]
79
+
80
+ state = []
81
+ for word_idx in range(NUM_WORDS):
82
+ word = 0
83
+ for bit_idx in range(128):
84
+ bit_pos = word_idx * 128 + bit_idx
85
+ word |= (permuted_bits[bit_pos] << bit_idx)
86
+ state.append(word)
87
+
88
+ return state
89
+
90
+ def _generate_keystream(self, nonce: bytes) -> bytes:
91
+ state = [0] * NUM_WORDS
92
+ nonce_extended = nonce + nonce + nonce + nonce
93
+ nonce_words = bytes_to_words(nonce_extended)
94
+
95
+ for i in range(NUM_WORDS):
96
+ state[i] ^= nonce_words[i]
97
+
98
+ for round_num in range(self.rounds):
99
+ state = self._nexus_round(state, round_num)
100
+
101
+ return words_to_bytes(state)
102
+
103
+ def encrypt_block(self, plaintext: bytes, nonce: bytes) -> bytes:
104
+ if len(plaintext) != BLOCK_SIZE:
105
+ raise NEXUSError(f"Block must be {BLOCK_SIZE} bytes")
106
+ if len(nonce) != NONCE_SIZE:
107
+ raise NEXUSError(f"Nonce must be {NONCE_SIZE} bytes")
108
+
109
+ keystream = self._generate_keystream(nonce)
110
+ ciphertext = bytes([p ^ k for p, k in zip(plaintext, keystream)])
111
+ self.bytes_processed += BLOCK_SIZE
112
+ self._regenerate_sboxes_if_needed()
113
+ return ciphertext
114
+
115
+ def decrypt_block(self, ciphertext: bytes, nonce: bytes) -> bytes:
116
+ if len(ciphertext) != BLOCK_SIZE:
117
+ raise NEXUSError(f"Block must be {BLOCK_SIZE} bytes")
118
+ if len(nonce) != NONCE_SIZE:
119
+ raise NEXUSError(f"Nonce must be {NONCE_SIZE} bytes")
120
+
121
+ keystream = self._generate_keystream(nonce)
122
+ plaintext = bytes([c ^ k for c, k in zip(ciphertext, keystream)])
123
+ self.bytes_processed += BLOCK_SIZE
124
+ self._regenerate_sboxes_if_needed()
125
+ return plaintext
126
+
127
+ def encrypt(self, plaintext: bytes, nonce: bytes = None) -> Tuple[bytes, bytes]:
128
+ if nonce is None:
129
+ nonce = secrets.token_bytes(NONCE_SIZE)
130
+
131
+ pad_len = BLOCK_SIZE - (len(plaintext) % BLOCK_SIZE)
132
+ plaintext += bytes([pad_len] * pad_len)
133
+
134
+ ciphertext = b''
135
+ for i in range(0, len(plaintext), BLOCK_SIZE):
136
+ block = plaintext[i:i+BLOCK_SIZE]
137
+ block_nonce = nonce + i.to_bytes(16, 'big')
138
+ block_nonce = hashlib.sha256(block_nonce).digest()[:NONCE_SIZE]
139
+ encrypted_block = self.encrypt_block(block, block_nonce)
140
+ ciphertext += encrypted_block
141
+
142
+ return ciphertext, nonce
143
+
144
+ def decrypt(self, ciphertext: bytes, nonce: bytes) -> bytes:
145
+ if len(ciphertext) % BLOCK_SIZE != 0:
146
+ raise DecryptionError("Invalid ciphertext length")
147
+
148
+ plaintext = b''
149
+ for i in range(0, len(ciphertext), BLOCK_SIZE):
150
+ block = ciphertext[i:i+BLOCK_SIZE]
151
+ block_nonce = nonce + i.to_bytes(16, 'big')
152
+ block_nonce = hashlib.sha256(block_nonce).digest()[:NONCE_SIZE]
153
+ decrypted_block = self.decrypt_block(block, block_nonce)
154
+ plaintext += decrypted_block
155
+
156
+ pad_len = plaintext[-1]
157
+ if pad_len <= BLOCK_SIZE and pad_len > 0:
158
+ plaintext = plaintext[:-pad_len]
159
+
160
+ return plaintext
161
+
162
+
163
+ class NEXUS:
164
+
165
+ def __init__(self, key_size: int = 256):
166
+ self.key_size = key_size
167
+ self.cipher = None
168
+
169
+ try:
170
+ from pqcrypto.kem.ml_kem_768 import generate_keypair as kyber_keygen
171
+ from pqcrypto.kem.ml_kem_768 import encrypt as kyber_encrypt
172
+ from pqcrypto.kem.ml_kem_768 import decrypt as kyber_decrypt
173
+ from pqcrypto.sign.ml_dsa_65 import generate_keypair as dilithium_keygen
174
+ from pqcrypto.sign.ml_dsa_65 import sign as dilithium_sign
175
+ from pqcrypto.sign.ml_dsa_65 import verify as dilithium_verify
176
+
177
+ self.kyber_keygen = kyber_keygen
178
+ self.kyber_encrypt = kyber_encrypt
179
+ self.kyber_decrypt = kyber_decrypt
180
+ self.dilithium_keygen = dilithium_keygen
181
+ self.dilithium_sign = dilithium_sign
182
+ self.dilithium_verify = dilithium_verify
183
+ except ImportError:
184
+ raise NEXUSError("Please install pqcrypto: pip install pqcrypto")
185
+
186
+ def generate_kem_keypair(self) -> Tuple[bytes, bytes]:
187
+ public_key, secret_key = self.kyber_keygen()
188
+ return public_key, secret_key
189
+
190
+ def generate_signing_keypair(self) -> Tuple[bytes, bytes]:
191
+ public_key, secret_key = self.dilithium_keygen()
192
+ return public_key, secret_key
193
+
194
+ def establish_session(self, peer_public_key: bytes) -> Tuple[bytes, bytes]:
195
+ ciphertext, shared_secret = self.kyber_encrypt(peer_public_key)
196
+ enc_key = hkdf_sha256(shared_secret, self.key_size // 8, b"NEXUS-ENC")
197
+ self.cipher = NEXUSCipher(enc_key, self.key_size)
198
+ return ciphertext, shared_secret
199
+
200
+ def accept_session(self, ciphertext: bytes, secret_key: bytes) -> bytes:
201
+ shared_secret = self.kyber_decrypt(secret_key, ciphertext)
202
+ enc_key = hkdf_sha256(shared_secret, self.key_size // 8, b"NEXUS-ENC")
203
+ self.cipher = NEXUSCipher(enc_key, self.key_size)
204
+ return shared_secret
205
+
206
+ def hash(self, data: bytes) -> bytes:
207
+ return hashlib.sha256(data).digest()
208
+
209
+ def encrypt_and_sign(self, plaintext: bytes, signing_key: bytes) -> dict:
210
+ if self.cipher is None:
211
+ raise NEXUSError("Session not established. Call establish_session first.")
212
+
213
+ ciphertext, nonce = self.cipher.encrypt(plaintext)
214
+ digest = self.hash(ciphertext)
215
+ signature = self.dilithium_sign(signing_key, digest)
216
+
217
+ return {'ciphertext': ciphertext, 'nonce': nonce, 'signature': signature}
218
+
219
+ def verify_and_decrypt(self, package: dict, verify_key: bytes) -> bytes:
220
+ if self.cipher is None:
221
+ raise NEXUSError("Session not established.")
222
+
223
+ digest = self.hash(package['ciphertext'])
224
+ try:
225
+ is_valid = self.dilithium_verify(verify_key, digest, package['signature'])
226
+ if not is_valid:
227
+ raise SignatureVerificationError("Signature verification failed")
228
+ except Exception as e:
229
+ raise SignatureVerificationError(f"Signature verification failed: {e}")
230
+
231
+ plaintext = self.cipher.decrypt(package['ciphertext'], package['nonce'])
232
+ return plaintext
nexus/exceptions.py ADDED
@@ -0,0 +1,11 @@
1
+ class NEXUSError(Exception):
2
+ pass
3
+
4
+ class DecryptionError(NEXUSError):
5
+ pass
6
+
7
+ class SignatureVerificationError(NEXUSError):
8
+ pass
9
+
10
+ class KeyGenerationError(NEXUSError):
11
+ pass
nexus/kem.py ADDED
@@ -0,0 +1,25 @@
1
+ from typing import Tuple
2
+ class MLKEM:
3
+
4
+
5
+ def __init__(self):
6
+ try:
7
+ from pqcrypto.kem.kyber768 import (
8
+ generate_keypair,
9
+ encrypt,
10
+ decrypt
11
+ )
12
+ self.generate_keypair = generate_keypair
13
+ self.encrypt = encrypt
14
+ self.decrypt = decrypt
15
+ except ImportError:
16
+ raise ImportError("pqcrypto not installed")
17
+
18
+ def keygen(self) -> Tuple[bytes, bytes]:
19
+ return self.generate_keypair()
20
+
21
+ def encapsulate(self, public_key: bytes) -> Tuple[bytes, bytes]:
22
+ return self.encrypt(public_key)
23
+
24
+ def decapsulate(self, ciphertext: bytes, secret_key: bytes) -> bytes:
25
+ return self.decrypt(ciphertext, secret_key)
nexus/math_utils.py ADDED
@@ -0,0 +1,124 @@
1
+ import secrets
2
+ import hashlib
3
+ import numpy as np
4
+ from typing import List, Tuple
5
+ from .constants import *
6
+
7
+ def rol(value: int, shift: int, bits: int = 128) -> int:
8
+ shift %= bits
9
+ mask = (1 << bits) - 1
10
+ return ((value << shift) | (value >> (bits - shift))) & mask
11
+
12
+ def ror(value: int, shift: int, bits: int = 128) -> int:
13
+ return rol(value, bits - shift, bits)
14
+
15
+ def bytes_to_words(data: bytes) -> List[int]:
16
+ words = []
17
+ for i in range(0, len(data), 16):
18
+ word = int.from_bytes(data[i:i+16], 'big')
19
+ words.append(word)
20
+ return words
21
+
22
+ def words_to_bytes(words: List[int]) -> bytes:
23
+ result = b''
24
+ for word in words:
25
+ result += word.to_bytes(16, 'big')
26
+ return result
27
+
28
+ def gf128_multiply(a: int, b: int) -> int:
29
+ result = 0
30
+ for i in range(128):
31
+ if b & (1 << i):
32
+ result ^= a
33
+
34
+ carry = a >> 127
35
+ a = (a << 1) & ((1 << 128) - 1)
36
+ if carry:
37
+ a ^= GF128_POLY
38
+
39
+ return result
40
+
41
+ def gaussian_sample(sigma: float) -> int:
42
+ return int(np.random.normal(0, sigma))
43
+
44
+ def generate_lwe_matrix(seed: bytes, size: int) -> List[List[int]]:
45
+ rng = np.random.RandomState(int.from_bytes(seed[:4], 'big'))
46
+ return [[int(rng.randint(0, LWE_MODULUS)) for _ in range(size)]
47
+ for _ in range(size)]
48
+
49
+ def generate_lwe_sbox(master_key: bytes, sbox_index: int, counter: int) -> List[int]:
50
+ h = hashlib.sha256()
51
+ h.update(master_key)
52
+ h.update(sbox_index.to_bytes(1, 'big'))
53
+ h.update(counter.to_bytes(8, 'big'))
54
+ seed = h.digest()
55
+
56
+ rng = np.random.RandomState(int.from_bytes(seed[:4], 'big'))
57
+ A = [[int(rng.randint(0, LWE_MODULUS)) for _ in range(SBOX_SIZE)]
58
+ for _ in range(SBOX_SIZE)]
59
+
60
+ sbox = []
61
+ for x in range(SBOX_SIZE):
62
+ error_seed = hashlib.sha256(seed + x.to_bytes(2, 'big')).digest()
63
+ error = int.from_bytes(error_seed[:2], 'big') % LWE_MODULUS
64
+
65
+ ax_sum = sum(A[x]) % LWE_MODULUS
66
+ value = (ax_sum * x + error) % LWE_MODULUS
67
+
68
+ sbox.append(value % 256)
69
+
70
+ return ensure_bijection(sbox)
71
+ def ensure_bijection(sbox: List[int]) -> List[int]:
72
+ used = set()
73
+ result = []
74
+ available = list(range(256))
75
+
76
+ for val in sbox:
77
+ if val not in used:
78
+ result.append(val)
79
+ used.add(val)
80
+ if val in available:
81
+ available.remove(val)
82
+ else:
83
+ replacement = available.pop(0)
84
+ result.append(replacement)
85
+ used.add(replacement)
86
+
87
+ return result
88
+
89
+ def generate_ntru_permutation(round_key: bytes, round_num: int) -> List[int]:
90
+ h = hashlib.sha256()
91
+ h.update(round_key)
92
+ h.update(round_num.to_bytes(1, 'big'))
93
+ seed = int.from_bytes(h.digest(), 'big')
94
+
95
+ rng = np.random.RandomState(seed % (2**32))
96
+ permutation = list(range(NTRU_N))
97
+ rng.shuffle(permutation)
98
+
99
+ return permutation
100
+
101
+ def generate_lattice_constant(round_num: int, word_idx: int) -> int:
102
+ h = hashlib.sha256()
103
+ h.update(b"NEXUS-LATTICE")
104
+ h.update(round_num.to_bytes(1, 'big'))
105
+ h.update(word_idx.to_bytes(1, 'big'))
106
+ return int.from_bytes(h.digest()[:16], 'big')
107
+
108
+ def hkdf_sha256(input_key: bytes, length: int, info: bytes = b"") -> bytes:
109
+ h = hashlib.sha256()
110
+ h.update(input_key)
111
+ prk = h.digest()
112
+
113
+ okm = b""
114
+ t = b""
115
+ for i in range((length + 31) // 32):
116
+ h = hashlib.sha256()
117
+ h.update(t)
118
+ h.update(prk)
119
+ h.update(info)
120
+ h.update(bytes([i + 1]))
121
+ t = h.digest()
122
+ okm += t
123
+
124
+ return okm[:length]
nexus/signature.py ADDED
@@ -0,0 +1,26 @@
1
+ class MLDSA:
2
+ def __init__(self):
3
+ try:
4
+ from pqcrypto.sign.dilithium3 import (
5
+ generate_keypair,
6
+ sign,
7
+ verify
8
+ )
9
+ self.generate_keypair = generate_keypair
10
+ self.sign = sign
11
+ self.verify = verify
12
+ except ImportError:
13
+ raise ImportError("pqcrypto not installed")
14
+
15
+ def keygen(self):
16
+ return self.generate_keypair()
17
+
18
+ def sign_message(self, message: bytes, secret_key: bytes) -> bytes:
19
+
20
+ return self.sign(message, secret_key)
21
+ def verify_signature(self, signature: bytes, message: bytes, public_key: bytes) -> bool:
22
+ try:
23
+ self.verify(signature, message, public_key)
24
+ return True
25
+ except:
26
+ return False
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: nexus-crypt
3
+ Version: 1.0.0
4
+ Summary: Post-quantum cryptographic suite with PFS, encryption, signatures, and hashing
5
+ Home-page: https://github.com/Harshith2412/nexus-crypt
6
+ Author: Harshith Madhavaram
7
+ Author-email: madhavaram.harshith2412@gmail.com
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Security :: Cryptography
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: pycryptodome>=3.19.0
20
+ Requires-Dist: pqcrypto>=0.1.0
21
+ Requires-Dist: numpy>=1.24.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=7.0; extra == "dev"
24
+ Requires-Dist: black; extra == "dev"
25
+ Requires-Dist: mypy; extra == "dev"
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: license-file
33
+ Dynamic: provides-extra
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
37
+
38
+ NEXUS-Crypt
39
+
40
+ Post-Quantum Cryptographic Suite with Perfect Forward Secrecy
41
+
42
+ NEXUS-Crypt is a unified cryptographic library combining:
43
+ - NEXUS-Cipher: Custom lattice based symmetric encryption
44
+ - ML-KEM (Kyber): Key encapsulation for Perfect Forward Secrecy
45
+ - ML-DSA (Dilithium): Post-quantum digital signatures
46
+ - SHA-256: Cryptographic hashing
47
+
48
+ Features
49
+
50
+ Post-quantum secure (resistant to quantum computer attacks)
51
+ Perfect Forward Secrecy (PFS) via ML-KEM
52
+ Authenticated encryption with ML-DSA signatures
53
+ Constant time operations (side-channel resistant)
54
+ Easy to use API
55
+
56
+ ## Installation
57
+ ```bash
58
+ pip install nexus-crypt
59
+ ```
60
+
61
+ ## Quick Start
62
+ ```python
63
+ from nexus import NEXUS
64
+
65
+ nexus = NEXUS(key_size=256)
66
+
67
+ kem_pk, kem_sk = nexus.generate_kem_keypair()
68
+ sign_pk, sign_sk = nexus.generate_signing_keypair()
69
+
70
+ ciphertext, shared_secret = nexus.establish_session(kem_pk)
71
+
72
+ message = b"Secret data"
73
+ package = nexus.encrypt_and_sign(message, sign_sk)
74
+
75
+ plaintext = nexus.verify_and_decrypt(package, sign_pk)
76
+ ```
77
+
78
+ ## Security Properties
79
+
80
+ - Quantum Resistance: Based on lattice problems (LWE, NTRU)
81
+ - Key Sizes: 256, 384, or 512 bits
82
+ - Block Size: 512 bits (64 bytes)
83
+ - Rounds: 20-24 depending on key size
84
+
85
+ ## Use Cases
86
+
87
+ - Automotive CAN bus encryption
88
+ - OTA firmware updates
89
+ - V2X communication
90
+ - IoT device security
91
+ - Secure messaging
92
+
93
+ ## License
94
+
95
+ MIT License
96
+
97
+ ## Author
98
+
99
+ Harshith Madhavaram
100
+ MS Cybersecurity '2027
101
+ Northeastern University, Boston
102
+ ```
103
+
104
+ ---
105
+
106
+ ## `.gitignore`**
107
+ ```
108
+ __pycache__/
109
+ *.py[cod]
110
+ *$py.class
111
+ *.so
112
+ .Python
113
+ build/
114
+ develop-eggs/
115
+ dist/
116
+ downloads/
117
+ eggs/
118
+ .eggs/
119
+ lib/
120
+ lib64/
121
+ parts/
122
+ sdist/
123
+ var/
124
+ wheels/
125
+ *.egg-info/
126
+ .installed.cfg
127
+ *.egg
128
+ .pytest_cache/
129
+ .coverage
130
+ htmlcov/
131
+ .env
132
+ venv/
133
+ ENV/
@@ -0,0 +1,18 @@
1
+ nexus/__init__.py,sha256=Us12WiiAK6aCVEN3xn6ewbzxhqb3XHuwD6gWqeTr4a0,297
2
+ nexus/constants.py,sha256=u1QoANPkuYrkERTTqJiAc5siluDFFe_iUe8H3D-RrLc,340
3
+ nexus/core.py,sha256=RfMCbq5dS9rJms92cxub2vT3NJfwkBs2pJiAddc2mPo,9575
4
+ nexus/exceptions.py,sha256=uX2uYvSZwbbp8jg1J6IPa37SU0akhmBFsat6ZUQ8kcA,186
5
+ nexus/kem.py,sha256=zwjJpc5Z59NM3ESPJDkAMb4BqF1J2iVTpHhrpJO3ty8,766
6
+ nexus/math_utils.py,sha256=S24NR190beP-X7vuFDimLhzSWYzA7ALKWZgDAlNL1qs,3585
7
+ nexus/signature.py,sha256=08YOIIMBd3khwnbokO2hi5l5CDSXo9HN18movEU0x5g,809
8
+ nexus_crypt-1.0.0.dist-info/licenses/LICENSE,sha256=TQCc2TWKUr36KWq83fjK1TIuhNoGk4fr153g4rYud0s,1076
9
+ tests/__init__.py,sha256=H5Bln6YMuVEElGdgeU52LCz8AA6gIj8H10p_kfa7_1w,94
10
+ tests/test_cipher.py,sha256=UZo6r_wH6hR5qADhLbp1lFzgimK56MOJN29NYa1QRwo,8696
11
+ tests/test_integrations.py,sha256=HkACbXCB0U8PmlocT4iYqpAAtiUBnRx3dPGLSJ750HQ,10376
12
+ tests/test_kem.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ tests/test_math_utils.py,sha256=AhBG1NWCHGXThMmAVhwbGlhfg6zKUERBTUGEorx7Cyk,7388
14
+ tests/test_signature.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ nexus_crypt-1.0.0.dist-info/METADATA,sha256=V7MKeX_3fHlNofQvN9HhSjgAhdRvDWcp1jQueius8y4,2918
16
+ nexus_crypt-1.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
17
+ nexus_crypt-1.0.0.dist-info/top_level.txt,sha256=RuVf2FBa2z0GmWkRU398fLOJkqhsP_8MktKlqSd-3gc,12
18
+ nexus_crypt-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Harshith Madhavaram
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.
@@ -0,0 +1,2 @@
1
+ nexus
2
+ tests
tests/__init__.py ADDED
@@ -0,0 +1 @@
1
+ __all__ = ["test_cipher", "test_kem", "test_signature", "test_integration", "test_math_utils"]