Skip to main content

Python client for the Big Bang Entropy API.

Project description

bigbangentropy

Python client for the Big Bang Entropy API.

Big Bang Entropy is a public physical entropy project. Its entropy stream is derived from cosmic radio noise captured by an antenna and SDR hardware, then processed by the Big Bang Entropy generator and exposed through simple binary HTTP endpoints.

At a high level, the source pipeline looks like this:

antenna -> SDR (e.g. PlutoSDR, RTL-SDR) -> sdr-node -> UDP -> generator -> entropy pool -> HTTP/TCP clients

This package makes that API easy to use from Python. It can fetch raw entropy bytes, return them as text, mix remote entropy with the local Python RNG, and generate tokens or passwords.

The recommended API is get_mixed_entropy(): it fetches entropy from Big Bang Entropy, reads local entropy with secrets.token_bytes(), and mixes both sources with SHA-512.

This library does not replace the operating system RNG. It lets you add an external physical entropy source to your local randomness pipeline. Do not use the raw API signal directly for security-sensitive work without mixing it with local RNG unless you have a very specific threat model.

Why Physical Entropy?

Physical entropy gives your application an independent randomness source outside the host operating system and cloud runtime. Mixing it with Python secrets.token_bytes() adds source diversity, which is useful as a defense-in-depth measure when tokens, secrets, test vectors, or long-lived cryptographic material matter. Cosmic radio noise is not deterministic application state, not a PRNG seed, and not generated by the same machine that consumes it. The safest pattern is still to combine it with local RNG, so security does not depend on any single source.

Installation

pip install bigbangentropy

Quick Start

from bigbangentropy import get_mixed_entropy, generate_token

entropy = get_mixed_entropy(32)
token = generate_token()

print(entropy.hex())
print(token)

Default Endpoints

Default base_url:

https://entropy.sparksome.pl

Default entropy endpoints:

https://entropy.sparksome.pl/raw
https://entropy.sparksome.pl/raw/stream?bytes=1048576

For direct unbuffered small requests, the client can use /raw. For larger requests and buffer refills, it uses /raw/stream?bytes=<bytes>. The default threshold is 1024 bytes and can be changed with stream_threshold_bytes.

By default, the client keeps a small on-demand local entropy buffer of 4096 bytes to avoid one HTTP request per token in loops. It does not download entropy in the background. The buffer is filled only when needed, consumed once, and never reused. Set entropy_buffer_size_bytes=0 to disable buffering entirely.

Examples

Fetch Entropy as Hex

from bigbangentropy import get_entropy_hex

hex_entropy = get_entropy_hex(32)
print(hex_entropy)

Fetch 1 MB of Entropy

from bigbangentropy import get_entropy

one_megabyte = get_entropy(1_048_576)
print(len(one_megabyte))

With the default configuration, this call uses:

/raw/stream?bytes=1048576

Generate a Token

from bigbangentropy import generate_token

token = generate_token()
print(token)

generate_token(32) returns a 64-character hex token by default.

Generate a Password

from bigbangentropy import generate_password

password = generate_password({
    "length": 24,
    "uppercase": True,
    "lowercase": True,
    "numbers": True,
    "symbols": True,
})

print(password)

The password generator does not use random.random(). Its randomness comes from get_mixed_entropy().

Use a Custom base_url

from bigbangentropy import create_client

entropy = create_client({
    "base_url": "https://entropy.example.com",
    "timeout_sec": 5,
    "retries": 2,
    "user_agent": "my-service/1.0.0",
    "stream_threshold_bytes": 1_024,
})

token = entropy.generate_token(32)
print(token)

You can also use keyword arguments:

from bigbangentropy import create_client

entropy = create_client(base_url="https://entropy.example.com")

Health Check

from bigbangentropy import create_client

entropy = create_client({
    "health_url": "/health",
})

health = entropy.get_health()

if not health["ok"]:
    print("Big Bang Entropy API unavailable", health)

If a dedicated health endpoint is not available, get_health() checks /raw by default. You can later pass health_url without changing the calling code.

Fetch Entropy as Base64

from bigbangentropy import get_entropy_base64

base64_entropy = get_entropy_base64(48)
print(base64_entropy)

Base64 output is convenient when entropy needs to be passed through JSON, environment variables, or text-only storage.

Generate Mixed Bytes for Your Own Crypto Flow

from bigbangentropy import get_mixed_entropy

seed_material = get_mixed_entropy(64)

# Use seed_material with your own KDF, envelope encryption, or key rotation flow.
print(seed_material.hex())

Use this when you need bytes instead of a formatted token. The returned bytes are already mixed with local Python RNG.

Handle API Errors

from bigbangentropy import BigBangEntropyError, get_mixed_entropy

try:
    entropy = get_mixed_entropy(32)
    print(entropy.hex())
except BigBangEntropyError as error:
    print(f"Entropy request failed: {error.code}", error)

The client fails loudly when the API is unavailable, times out, or returns too little data.

Explicit Local Fallback

from bigbangentropy import create_client

entropy = create_client({
    "allow_local_fallback": True,
    "timeout_sec": 2,
})

raw_bytes = entropy.get_entropy(32)
print(raw_bytes.hex())

This mode is intentionally opt-in. Use it only when your application can continue with local RNG alone and you are comfortable knowing that external physical entropy may not have been used for that call.

Optimize Token Loops with an Entropy Buffer

from bigbangentropy import create_client

entropy = create_client({
    "entropy_buffer_size_bytes": 65_536,
})

tokens = []

for _ in range(1_000):
    tokens.append(entropy.generate_token())

print(len(tokens))

The client already uses a 4096 byte buffer by default. Raising it can reduce HTTP requests further in larger loops. The client fetches entropy chunks on demand, stores unused API bytes locally, and consumes them once across later calls. There is no background polling and no repeated use of buffered bytes.

Async API

import asyncio
from bigbangentropy import create_async_client


async def main() -> None:
    async with create_async_client() as entropy:
        token = await entropy.generate_token()
        print(token)


asyncio.run(main())

API

create_client(options)

from bigbangentropy import create_client

client = create_client({
    "base_url": "https://entropy.sparksome.pl",
    "timeout_sec": 5,
    "retries": 2,
    "user_agent": "bigbangentropy/0.1.0",
    "stream_threshold_bytes": 1_024,
    "entropy_buffer_size_bytes": 4_096,
    "allow_local_fallback": False,
})

Options:

  • base_url - defaults to https://entropy.sparksome.pl
  • timeout_sec - defaults to 5
  • retries - defaults to 2
  • user_agent - defaults to bigbangentropy/0.1.0
  • stream_threshold_bytes - defaults to 1024
  • entropy_buffer_size_bytes - defaults to 4096; small calls consume a local one-time-use API entropy buffer; set to 0 to disable buffering
  • health_url - optional health endpoint, for example /health
  • allow_local_fallback - defaults to False; when set to True, the client may explicitly use local RNG if the API is unavailable

Sync Methods

  • get_entropy(byte_count: int) -> bytes
  • get_entropy_hex(byte_count: int) -> str
  • get_entropy_base64(byte_count: int) -> str
  • get_mixed_entropy(byte_count: int) -> bytes
  • generate_token(byte_count: int = 32) -> str
  • generate_password(options: PasswordOptions | None = None) -> str
  • get_health() -> HealthResult

Async Methods

The async client exposes the same method names, but they are awaitable:

from bigbangentropy import create_async_client

async with create_async_client() as client:
    data = await client.get_mixed_entropy(32)

Error Handling

The client does not silently fall back to local RNG. If the API is unavailable, the call fails unless you explicitly set allow_local_fallback=True.

Exported error classes:

  • InvalidBytesError
  • EntropyApiError
  • EntropyTimeoutError
  • InsufficientEntropyError
  • InvalidPasswordOptionsError

All exported errors extend BigBangEntropyError and expose a code field, such as API_UNAVAILABLE, TIMEOUT, INSUFFICIENT_ENTROPY, or INVALID_BYTES.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bigbangentropy-0.1.0.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bigbangentropy-0.1.0-py3-none-any.whl (15.3 kB view details)

Uploaded Python 3

File details

Details for the file bigbangentropy-0.1.0.tar.gz.

File metadata

  • Download URL: bigbangentropy-0.1.0.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for bigbangentropy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d02aa32c4431484a8957fc306ebcce98d54d78b2f68c6597e7f0dd2151d9b4a
MD5 413ed746c90bd478d0f3cbb308d23e46
BLAKE2b-256 04b26afc87dbdb4d64fb0394f2a433041fa88f150f7b21336e022cc05b42ec10

See more details on using hashes here.

File details

Details for the file bigbangentropy-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: bigbangentropy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for bigbangentropy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fada0d85effae38d1741c7fd484c081e29a51d75ae9a5bf7975de013957e1d69
MD5 964579f6432e7b5c5826f2bc74d53351
BLAKE2b-256 5f888a300a99dc058ba156d527b180120f2a12bf09a50fe073e8a2c84dc3d416

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page