Metadata-Version: 2.4
Name: fibcrypt
Version: 1.0.0
Summary: A fast Fibonacci-based cryptographic toolkit
Author: Hakan Damar
Author-email: hakan.damar@linux.com
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: pycryptodomex>=3.22.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# fibcrypt

`fibcrypt` is an open-source, edge-oriented encryption toolkit that combines a Fibonacci-based key derivation design with AES-256-CBC and HMAC-SHA256 authentication.

It is designed for applications that need many low-latency encryption/decryption operations and want to evaluate an alternative, transparent cryptographic construction. It is **not** presented as a replacement for Argon2, scrypt, or other independently reviewed password KDFs.

## What It Provides

- Fibonacci-based key derivation using modular fast-doubling arithmetic
- A 256-bit default modulus and full SHA-256-derived seed
- AES-256-CBC encryption with PKCS#7 padding
- Encrypt-then-MAC using HMAC-SHA256
- A fresh random salt and IV for every encryption
- A required deployment secret (`pepper`) kept outside the ciphertext
- Versioned `FC2` ciphertext payloads

## Security Model

Each encryption requires four inputs:

- `plaintext`: the data to encrypt
- `password`: the user/application password
- `salt`: caller-provided context; it may be public, but must be supplied again for decryption
- `pepper`: a secret deployment value that must not be stored in the ciphertext or source code

The ciphertext contains the version marker, random salt, IV, encrypted data, and authentication tag:

```text
FC2 + random_salt + iv + ciphertext + HMAC-SHA256 tag
```

Decryption authenticates the tag before attempting CBC decryption. Modified or truncated ciphertexts, wrong passwords, wrong salts, and wrong peppers are rejected.

For a ciphertext-only attacker who has no password, caller salt, or pepper, the payload and public source code are not sufficient to derive the keys. This assumes the deployment pepper is a high-entropy secret and is not embedded in application source, test configuration, logs, or the payload.

Important limitations:

- The Fibonacci KDF is custom and has not received an independent cryptographic audit.
- `iterations=128` is selected for latency, not as a claim of equivalence to a memory-hard password KDF.
- Weak or reused passwords remain vulnerable to dictionary attacks if the attacker also knows or can guess the salt and obtains the pepper.
- The pepper must be managed as a deployment secret. If an attacker compromises the application host and reads its secrets, this model no longer applies.
- Do not use this package for high-assurance or regulated cryptographic requirements without an independent review.

## Installation

```bash
pip install fibcrypt
```

## Usage

Set the pepper through a secret manager or environment variable. Do not commit it to source control.

```bash
export FIBCRYPT_PEPPER="your-long-random-deployment-secret"
```

```python
import os

from fibcrypt.crypto_utils import decrypt, encrypt

message = "This is a secret message"
password = "my-strong-password"
salt = "application-context"
pepper = os.environ["FIBCRYPT_PEPPER"]

ciphertext = encrypt(message, password, salt, pepper)
print("Encrypted:", ciphertext.hex())

plaintext = decrypt(ciphertext, password, salt, pepper)
print("Decrypted:", plaintext)
```

`encrypt` returns `bytes`. Store or transmit those bytes directly, or encode them as hexadecimal/base64. Keep the `salt` and `pepper` available to the decrypting service; only the pepper must remain secret.

Wrong credentials and tampered ciphertext raise `ValueError` during authentication.

## Parameters

The default public API uses:

- `iterations=128`
- `prime=2**256 - 2**32 - 977`

Both can be overridden explicitly for experiments and benchmarks. Changing these values changes the derived keys, so the parameters must remain consistent between encryption and decryption.

## Performance

On the development benchmark machine (Python 3.14, Apple Silicon, 7 samples after one warmup), v8 measured approximately:

| Payload | Encrypt | Decrypt |
| ---: | ---: | ---: |
| 16 B | 67.8 ms | 68.4 ms |
| 1 KiB | 68.5 ms | 69.0 ms |
| 1 MiB | 73.4 ms | 72.8 ms |

These are reference measurements, not performance guarantees. Benchmark the target edge hardware before deployment.

### PyPI 0.1.5 vs v1.0

The following comparison was run on the same machine against the published PyPI `0.1.5` wheel and the current v1.0 implementation. The legacy release used its original `iterations=20` default and unauthenticated AES-CBC format; v1.0 uses `iterations=128`, full-seed derivation, a secret pepper, random salt, and HMAC authentication. This is therefore a release comparison, not an equal-security-configuration comparison.

| Payload | 0.1.5 Encrypt | v1.0 Encrypt | Speedup | 0.1.5 Decrypt | v1.0 Decrypt | Speedup |
| ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 16 B | 3443 ms | 67.8 ms | 50.8x | 3446 ms | 68.4 ms | 50.4x |
| 1 KiB | 3471 ms | 68.5 ms | 50.7x | 3497 ms | 69.0 ms | 50.7x |
| 1 MiB | 3524 ms | 73.4 ms | 48.0x | 3507 ms | 72.8 ms | 48.2x |

The legacy values used three timed samples after one warmup; v1.0 values used seven timed samples after one warmup. Values are rounded and will vary by hardware.

## Security Improvements

Compared with the original PyPI `fibcrypt 0.1.5` release, `fibcrypt 1.0` includes:

- Modular fast-doubling Fibonacci arithmetic instead of unbounded intermediate matrix growth
- A 256-bit default modulus instead of `65537`
- The full SHA-256-derived seed instead of a directly enumerable `seed % 10**6` space
- A required deployment pepper kept outside the ciphertext and source code
- A fresh random salt for every encryption
- Separate encryption and authentication key derivation domains
- HMAC-SHA256 authentication verified before CBC decryption
- Versioned `FC2` payloads with explicit format boundaries
- Approximately 48-51x lower measured latency than the published `0.1.5` artifact on the benchmark machine

## Upgrading From 0.1.5

Version 1.0 changes both the API and ciphertext format. Existing systems must not be upgraded blindly:

1. Provision one high-entropy pepper through a secret manager or environment variable and make it available to every service that encrypts or decrypts the shared data.
2. Update calls from `encrypt(plaintext, password, salt)` and `decrypt(ciphertext, password, salt)` to include the same pepper value.
3. Keep the original `0.1.5` runtime available while migrating existing data.
4. Decrypt each `0.1.5` ciphertext with the original package and credentials, then re-encrypt it with v1.0 and the managed pepper.
5. Verify the migrated plaintext or application record before replacing the old ciphertext.
6. Test the migration on a backup or staging copy before rolling it out to production.

The v0.1.5 format was `iv + ciphertext` and used different key derivation defaults. It has no authentication tag and is not readable by the v1.0 `FC2` decoder. Conversely, v1.0 ciphertexts require the v1.0 parameters and the correct pepper. Losing the pepper makes v1.0 ciphertexts unrecoverable.

## Development

```bash
python3 -m pip install -r requirements-dev.txt
python3 -m pytest
ruff check .
mypy
PYTHONPATH=. python3 test/main.py
```

## License

This project is licensed under the MIT License.
