Metadata-Version: 2.4
Name: coinrandom
Version: 0.3.0
Summary: True random numbers sourced from live cryptocurrency market data
Author-email: dglst <woo9910203626@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/LETUED/coinrandom
Project-URL: Repository, https://github.com/LETUED/coinrandom
Project-URL: Bug Tracker, https://github.com/LETUED/coinrandom/issues
Project-URL: Changelog, https://github.com/LETUED/coinrandom/blob/main/CHANGELOG.md
Keywords: random,entropy,cryptocurrency,bitcoin,randomness,cryptography,DRBG,verifiable-random,proof
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28
Requires-Dist: argon2-cffi>=21.0
Provides-Extra: superheavy
Requires-Dist: numpy>=1.24; extra == "superheavy"
Requires-Dist: scipy>=1.10; extra == "superheavy"
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: pytest; extra == "dev"

# coinrandom

[한국어](README.ko.md) | English

> True random numbers sourced from live cryptocurrency market data.

```python
import coinrandom

coinrandom.random()        # 0.7182818...
coinrandom.randint(1, 100) # 42
coinrandom.choice(["a", "b", "c"])
```

---

## Why coinrandom?

Cryptocurrency markets trade 24/7 globally. At the tick level — individual trade prices, quantities, timestamps, and buyer/seller direction — the data is highly unpredictable. The Efficient Market Hypothesis (EMH) says no one can consistently predict short-term market movements. **coinrandom uses this unpredictability as an entropy source.**

### Trust Model

> Even with the full source code published, no one can predict the output in advance — because no one can predict the coin market.

This is an application of **Kerckhoffs's principle**: security depends on the unpredictability of the market, not on keeping the algorithm secret. Each value generated by Heavy/SuperHeavy comes with a `RandomProof` — a verifiable audit trail showing exactly which market data produced the result.

**Honest limits:** coinrandom provides *computational security* (like AES/RSA), not *information-theoretic security* (like Chainlink VRF). The trust model is economic, not mathematical. For cryptographic key generation, use `secrets`. For smart contract RNG, use Chainlink VRF.

---

## Installation

```bash
pip install coinrandom                     # Light + Heavy
pip install "coinrandom[superheavy]"       # + SuperHeavy (numpy, scipy)
```

No API keys. No configuration.

---

## Three Tiers

| Tier | Speed | Entropy source | Proof | Use case |
|------|-------|---------------|-------|----------|
| **Light** | ~1ms | Binance tick + Argon2 | No | High-volume generation |
| **Heavy** | ~2s | 3 exchanges + ETH + BTC block hash + Argon2 | Yes | Raffles, NFT mints, DAO votes |
| **SuperHeavy** | ~30s | Portfolio-optimized coins + Heavy pipeline (ETH + BTC) | Yes | Maximum entropy, auditable |

All tiers return the same API — drop-in replacement for Python's `random` module.

---

## Usage

### Light (default)

```python
import coinrandom

coinrandom.random()              # float in [0.0, 1.0)
coinrandom.uniform(1.5, 9.5)
coinrandom.randint(1, 100)
coinrandom.choice(["a", "b", "c"])
coinrandom.choices(["a", "b", "c"], k=5)
coinrandom.sample(range(100), k=10)

lst = [1, 2, 3, 4, 5]
coinrandom.shuffle(lst)

coinrandom.gauss(mu=0.0, sigma=1.0)
```

### Heavy — with proof

```python
from coinrandom.heavy import HeavyEngine

engine = HeavyEngine()
proof = engine.random_with_proof()

print(proof.value)              # 0.3571428...
print(proof.exchanges)          # [{"exchange": "binance", "symbol": "BTCUSDT", ...}, ...]
print(proof.block_hashes)       # {"ETH": "0xabc123...", "BTC": "000000000000..."}
print(proof.block_hashes["ETH"])
print(proof.block_hashes["BTC"])
print(proof.final_hash)         # SHA-256 of the Argon2-stretched entropy
```

### SuperHeavy — portfolio-optimized entropy

```python
from coinrandom.superheavy import SuperHeavyEngine

engine = SuperHeavyEngine()
proof = engine.random_with_proof()

print(proof.selected_symbols)       # coins selected by inverse portfolio optimization
print(proof.correlation_matrix)     # correlation matrix of candidates
print(proof.optimization_result)    # scipy SLSQP result
```

### Saving proof as JSON

`RandomProof` and `SuperProof` are plain dataclasses — save them with the standard library:

```python
import dataclasses, json

proof = engine.random_with_proof()

with open("proof.json", "w") as f:
    json.dump(dataclasses.asdict(proof), f, indent=2)
```

SuperHeavy runs inverse Markowitz portfolio optimization to select the **least-correlated coins** as entropy sources — maximizing entropy diversity.

### Async API

All tiers expose async versions of every function — same names, prefixed with `a`.

```python
import asyncio
import coinrandom
from coinrandom import heavy, superheavy  # superheavy requires [superheavy] extra

async def main():
    # Light
    val = await coinrandom.arandom()
    n   = await coinrandom.arandint(1, 100)
    c   = await coinrandom.achoice(["a", "b", "c"])
    lst = [1, 2, 3]
    await coinrandom.ashuffle(lst)

    # Heavy
    val   = await heavy.arandom()
    proof = await heavy.arandom_with_proof()
    print(proof.block_hash)

    # SuperHeavy
    val   = await superheavy.arandom()
    proof = await superheavy.arandom_with_proof()
    print(proof.selected_symbols)

asyncio.run(main())
```

Async methods offload blocking I/O to a thread pool via `asyncio.run_in_executor` — no new dependencies.

---

## Design Principles

1. **No API keys** — works out of the box with `pip install`
2. **Uniform API** — every tier exposes the same functions as `random`
3. **No stdlib random** — custom HashDRBG (SHA-512 counter-based), Mersenne Twister not used anywhere
4. **Open-source safe** — Kerckhoffs's principle: publishing the algorithm doesn't compromise security
5. **Intentionally heavy** — Heavy/SuperHeavy: each call runs the full entropy pipeline. "Slow = costly to manipulate."

---

## Internals

```
coinrandom/
├── __init__.py          # Light tier as default API
├── core.py              # fetch_binance_entropy, mix_entropy
├── proof.py             # RandomProof, SuperProof dataclasses
├── light/               # HashDRBG + Argon2 (t=1, m=8MB) reseed cache
├── heavy/               # 3 exchanges parallel + ETH block hash + Argon2 (t=4, m=64MB)
└── superheavy/          # Inverse portfolio optimization → Heavy pipeline
```

### HashDRBG

Custom SHA-512 counter-based DRBG. No `import random` anywhere in the codebase.

```python
# Simplified
state = argon2(mix_entropy(coin_data, os.urandom(32)))
output = sha512(state + counter)  # per call
```

### Manipulation resistance

Heavy mode requires simultaneously moving 32+ coins across Binance, Upbit, and Coinbase in the exact direction needed — estimated cost: billions of dollars. SuperHeavy additionally hides the target coins until optimization runs.

---

## Versioning

This project follows [Semantic Versioning](https://semver.org/):

- `PATCH` — bug fixes, internal improvements
- `MINOR` — new features, backward-compatible
- `MAJOR` — stable API declaration or breaking changes

Current status: `0.x` (API stabilizing, not yet guaranteed stable)

---

## License

MIT
