lemonade-cryptography 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.
- lemonade/__init__.py +9 -0
- lemonade/crypto.py +112 -0
- lemonade/exceptions.py +10 -0
- lemonade/version.py +1 -0
- lemonade_cryptography-1.0.0.dist-info/METADATA +225 -0
- lemonade_cryptography-1.0.0.dist-info/RECORD +9 -0
- lemonade_cryptography-1.0.0.dist-info/WHEEL +5 -0
- lemonade_cryptography-1.0.0.dist-info/licenses/LICENSE +19 -0
- lemonade_cryptography-1.0.0.dist-info/top_level.txt +1 -0
lemonade/__init__.py
ADDED
lemonade/crypto.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import binascii
|
|
3
|
+
import secrets
|
|
4
|
+
|
|
5
|
+
from . import exceptions as e
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def encrypt(msg: str) -> tuple[str, str]:
|
|
9
|
+
"""Encrypts a message using Lemonade Encryption.
|
|
10
|
+
|
|
11
|
+
Generates a random key with the same byte length as the message.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
msg (str): Text to be encrypted.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
tuple[str, str]: Encrypted message and its key.
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
LemonadeError: When the message is invalid.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
if not isinstance(msg, str):
|
|
24
|
+
raise e.LemonadeError("Message must be a string.")
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
msg_bytes = msg.encode("utf-8")
|
|
28
|
+
except UnicodeEncodeError as error:
|
|
29
|
+
raise e.LemonadeError(
|
|
30
|
+
"Unable to encode message as UTF-8."
|
|
31
|
+
) from error
|
|
32
|
+
|
|
33
|
+
key_bytes = secrets.token_bytes(len(msg_bytes))
|
|
34
|
+
|
|
35
|
+
crypt_bytes = bytes(
|
|
36
|
+
(msg_bytes[i] - key_bytes[i]) % 256
|
|
37
|
+
for i in range(len(msg_bytes))
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
crypt = base64.b64encode(crypt_bytes).decode("ascii")
|
|
41
|
+
key = base64.b64encode(key_bytes).decode("ascii")
|
|
42
|
+
|
|
43
|
+
return crypt, key
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def decrypt(crypt: str, key: str) -> str:
|
|
47
|
+
"""Decrypts a Lemonade encrypted message.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
crypt (str): Encrypted message in Base64.
|
|
51
|
+
key (str): Encryption key in Base64.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
str: Decrypted original message.
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
InvalidCipherError: When the encrypted message is invalid.
|
|
58
|
+
InvalidKeyError: When the key is invalid.
|
|
59
|
+
LemonadeError: When decryption fails.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
if not isinstance(crypt, str):
|
|
63
|
+
raise e.InvalidCipherError(
|
|
64
|
+
"Cipher must be a string."
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if not isinstance(key, str):
|
|
68
|
+
raise e.InvalidKeyError(
|
|
69
|
+
"Key must be a string."
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
crypt_bytes = base64.b64decode(
|
|
74
|
+
crypt,
|
|
75
|
+
validate=True
|
|
76
|
+
)
|
|
77
|
+
except (binascii.Error, ValueError) as error:
|
|
78
|
+
raise e.InvalidCipherError(
|
|
79
|
+
"Invalid cryptography."
|
|
80
|
+
) from error
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
key_bytes = base64.b64decode(
|
|
84
|
+
key,
|
|
85
|
+
validate=True
|
|
86
|
+
)
|
|
87
|
+
except (binascii.Error, ValueError) as error:
|
|
88
|
+
raise e.InvalidKeyError(
|
|
89
|
+
"Invalid encryption key."
|
|
90
|
+
) from error
|
|
91
|
+
|
|
92
|
+
if len(key_bytes) != len(crypt_bytes):
|
|
93
|
+
raise e.InvalidKeyError(
|
|
94
|
+
"Encryption key length does not match cipher length."
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
msg_bytes = bytes(
|
|
99
|
+
(crypt_bytes[i] + key_bytes[i]) % 256
|
|
100
|
+
for i in range(len(crypt_bytes))
|
|
101
|
+
)
|
|
102
|
+
except IndexError as error:
|
|
103
|
+
raise e.LemonadeError(
|
|
104
|
+
"Error while decrypting cipher."
|
|
105
|
+
) from error
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
return msg_bytes.decode("utf-8")
|
|
109
|
+
except UnicodeDecodeError as error:
|
|
110
|
+
raise e.LemonadeError(
|
|
111
|
+
"Decrypted data is not valid UTF-8."
|
|
112
|
+
) from error
|
lemonade/exceptions.py
ADDED
lemonade/version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lemonade-cryptography
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Lightweight byte-oriented encryption library.
|
|
5
|
+
Author: Vlinho
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright 2026 Vlinho
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the “Software”), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
|
25
|
+
Keywords: cryptography,encryption,experimental
|
|
26
|
+
Classifier: Programming Language :: Python :: 3
|
|
27
|
+
Classifier: Operating System :: OS Independent
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# 🍋 Lemonade Cryptography
|
|
34
|
+
|
|
35
|
+
**Lemonade Cryptography** is a lightweight byte-oriented encryption library based on modular arithmetic and symmetric key transformations.
|
|
36
|
+
|
|
37
|
+
Lemonade transforms readable messages into encrypted data by converting text into bytes and applying mathematical operations using a cryptographic key.
|
|
38
|
+
|
|
39
|
+
The core concept is:
|
|
40
|
+
|
|
41
|
+
> Each byte of the message is encrypted by subtracting it from a corresponding byte of a secret key.
|
|
42
|
+
|
|
43
|
+
The original message can be recovered by applying the reverse operation using the same key.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
# Installation
|
|
48
|
+
|
|
49
|
+
Install Lemonade Cryptography using pip:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install lemonade-cryptography
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
# Quick Start
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from lemonade import encrypt, decrypt
|
|
61
|
+
|
|
62
|
+
message = "Hello. We are looking for highly intelligent individuals."
|
|
63
|
+
|
|
64
|
+
crypt, key = encrypt(message)
|
|
65
|
+
|
|
66
|
+
print("Encrypted:")
|
|
67
|
+
print(crypt)
|
|
68
|
+
|
|
69
|
+
print("\nKey:")
|
|
70
|
+
print(key)
|
|
71
|
+
|
|
72
|
+
original = decrypt(crypt, key)
|
|
73
|
+
|
|
74
|
+
print("\nDecrypted:")
|
|
75
|
+
print(original)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Output:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
Encrypted:
|
|
82
|
+
<encrypted data>
|
|
83
|
+
|
|
84
|
+
Key:
|
|
85
|
+
<secret key>
|
|
86
|
+
|
|
87
|
+
Decrypted:
|
|
88
|
+
Hello. We are looking for highly intelligent individuals.
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
# Features
|
|
94
|
+
|
|
95
|
+
- Symmetric key encryption
|
|
96
|
+
- Byte-oriented processing
|
|
97
|
+
- UTF-8 message support
|
|
98
|
+
- Random cryptographic key generation
|
|
99
|
+
- Base64 encoded output
|
|
100
|
+
- Simple Python API
|
|
101
|
+
- Lightweight implementation
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
# API Reference
|
|
106
|
+
|
|
107
|
+
## `encrypt()`
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
encrypt(msg: str) -> tuple[str, str]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Encrypts a message and generates a random key.
|
|
114
|
+
|
|
115
|
+
### Arguments
|
|
116
|
+
|
|
117
|
+
| Argument | Type | Description |
|
|
118
|
+
|-|-|-|
|
|
119
|
+
| `msg` | `str` | Message to encrypt |
|
|
120
|
+
|
|
121
|
+
### Returns
|
|
122
|
+
|
|
123
|
+
A tuple containing:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
(
|
|
127
|
+
encrypted_message,
|
|
128
|
+
encryption_key
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Both values are encoded using Base64.
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
crypt, key = encrypt("Hello")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## `decrypt()`
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
decrypt(crypt: str, key: str) -> str
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Decrypts a Lemonade encrypted message using its key.
|
|
149
|
+
|
|
150
|
+
### Arguments
|
|
151
|
+
|
|
152
|
+
| Argument | Type | Description |
|
|
153
|
+
|-|-|-|
|
|
154
|
+
| `crypt` | `str` | Encrypted message in Base64 |
|
|
155
|
+
| `key` | `str` | Encryption key in Base64 |
|
|
156
|
+
|
|
157
|
+
### Returns
|
|
158
|
+
|
|
159
|
+
The original message:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
str
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Example:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
message = decrypt(crypt, key)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
# How It Works
|
|
174
|
+
|
|
175
|
+
Lemonade operates directly on byte values.
|
|
176
|
+
|
|
177
|
+
Example:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
A = 65
|
|
181
|
+
B = 66
|
|
182
|
+
C = 67
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The encryption operation is:
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
C = (M - K) mod 256
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Where:
|
|
192
|
+
|
|
193
|
+
| Symbol | Meaning |
|
|
194
|
+
|-|-|
|
|
195
|
+
| `C` | Encrypted byte |
|
|
196
|
+
| `M` | Original message byte |
|
|
197
|
+
| `K` | Key byte |
|
|
198
|
+
|
|
199
|
+
The decryption operation reverses the transformation:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
M = (C + K) mod 256
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
More technical details can be found in:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
docs/algorithm.md
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
# Security Notice
|
|
214
|
+
|
|
215
|
+
Lemonade Cryptography is an experimental encryption library created for educational purposes and lightweight applications.
|
|
216
|
+
|
|
217
|
+
It is not intended to replace modern cryptographic standards such as AES or ChaCha20 in security-critical systems.
|
|
218
|
+
|
|
219
|
+
Always protect your encryption keys. Without the correct key, encrypted messages cannot be recovered.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
# License
|
|
224
|
+
|
|
225
|
+
Lemonade Cryptography is licensed under the MIT License.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
lemonade/__init__.py,sha256=7fU4uiX0nSTbP1hW_gIkwSOqaxCjiqDfaRABov0Bk_s,143
|
|
2
|
+
lemonade/crypto.py,sha256=LlhNpTekOQRTqlOXqWwi0PEBSfnN0Q9b5tQEl-TNT7Y,2912
|
|
3
|
+
lemonade/exceptions.py,sha256=WLwGW5Ek1NhPa-gpmeNvUeTRyCHN_CThcmp9IGPR0yE,150
|
|
4
|
+
lemonade/version.py,sha256=Aj77VL1d5Mdku7sgCgKQmPuYavPpAHuZuJcy6bygQZE,21
|
|
5
|
+
lemonade_cryptography-1.0.0.dist-info/licenses/LICENSE,sha256=olw0lONhY29sK92XqrhDmVelyv71gOz-WJujJIGr-Iw,1082
|
|
6
|
+
lemonade_cryptography-1.0.0.dist-info/METADATA,sha256=snLot0liX9SkYw26NRSNgIa8fBTYgop0zy9kzr8mlcQ,4811
|
|
7
|
+
lemonade_cryptography-1.0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
8
|
+
lemonade_cryptography-1.0.0.dist-info/top_level.txt,sha256=hpUhSlZTjtT-LauOFVflT6n2Z7v795Pe8R-j7J6oIpY,9
|
|
9
|
+
lemonade_cryptography-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright 2026 Vlinho
|
|
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
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
lemonade
|