128 lines
5.9 KiB
Markdown
128 lines
5.9 KiB
Markdown
# The p.ari.lt API
|
|
|
|
This API provides access to a database of safe prime numbers computed by people. Most endpoints requires a Time-based One-Time Password (TOTP) for authentication and performs various operations on prime numbers.
|
|
|
|
## Errors
|
|
|
|
- Errors have codes of non-2xx responses.
|
|
- They return JSON: `{"error": "human-readable message", "ident": "identifier"}`.
|
|
|
|
## API Endpoints
|
|
|
|
All endpoints are in context of /api (for example /totp => /api/totp).
|
|
|
|
### GET /totp
|
|
|
|
- **Description**: Retrieves the server's TOTP key and timestamp.
|
|
- **Returns**: JSON object containing the TOTP key and timestamp.
|
|
- Example: `{"key": "base85-encoded-key", "ts": 1594857600}`
|
|
|
|
### GET /requirements/all & GET /requirements/\<bits\>
|
|
|
|
- **Description**: Fetches the global prime or prime in range of `[2^floor(log2(bits)); 2^(floor(log2(bits)) + 1))` requirements.
|
|
- **Requires**: JSON containing a valid TOTP.
|
|
- **Parameters**:
|
|
- `totp`: TOTP value based off the server's TOTP information.
|
|
- **Returns**: On success, JSON object containing scaled mid-mean of all bits and transitional values.
|
|
- Example: `{"bits": 1024, "trans": 512}`
|
|
- **Errors**:
|
|
- `totp`: Returned on TOTP validation errors.
|
|
|
|
### POST /add
|
|
|
|
- **Description**: Adds a new prime to the database.
|
|
- **Requires**: JSON containing the prime number, TOTP, and optional metadata.
|
|
- **Parameters**:
|
|
- `prime`: The prime number to add.
|
|
- `totp`: TOTP for authentication.
|
|
- **Returns**: On success, JSON object containing cryptographic keys and TOTP information for the added prime.
|
|
- Example: `{"key": "encrypted-key", "subkey": "base85-encoded-subkey", "totp_key": "encrypted-totp-key", "totp_ts": 1594857600}`
|
|
- **Errors**:
|
|
- `totp`: Returned on TOTP validation errors.
|
|
- `json`: Returned if there is an issue with the provided JSON data.
|
|
- `registered`: Returned if the prime is already registered.
|
|
- `notprime`: Returned if the provided number is not an accepted prime.
|
|
- `requirements`: Returned if the prime does not meet the local requirements in the bit range.
|
|
|
|
### POST /note
|
|
|
|
- **Description**: Adds or updates a note on an existing prime record.
|
|
- **Requires**: JSON containing the prime number, cryptographic key, note content, and TOTP.
|
|
- **Parameters**:
|
|
- `prime`: The prime number to annotate.
|
|
- `key`: Encrypted cryptographic key associated with the prime.
|
|
- `note`: Content of the note to add or update.
|
|
- `totp`: TOTP for authentication.
|
|
- **Returns**: On success, JSON object confirming the note change and showing the previous note.
|
|
- Example: `{"success": "Note changed.", "prev_note": "Old note content"}`
|
|
- **Errors**:
|
|
- `totp`: Returned on TOTP validation errors.
|
|
- `json`: Returned if there is an issue with the provided JSON data.
|
|
- `notexist`: Returned if the specified prime does not exist.
|
|
|
|
### GET /prime/\<prime\>?totp=\<totp\>
|
|
|
|
- **Description**: Retrieves detailed information about a specific prime.
|
|
- **Parameters**:
|
|
- `prime`: The prime number to retrieve.
|
|
- **Returns**: JSON object containing details about the prime, such as bit length, transitional values, and optional notes.
|
|
- Example: `{"bits": 1024, "trans": 512, "old_mbits": 1000, "old_mtrans": 500, "note": "Detailed note", "claimed": 1594857600, "next": "next-prime", "prev": "prev-prime"}`
|
|
- **Errors**:
|
|
- `totp`: Returned on TOTP validation errors.
|
|
|
|
### POST /rekey
|
|
|
|
- **Description**: Re-keys the cryptographic details associated with a prime.
|
|
- **Requires**: JSON containing the prime number and TOTP.
|
|
- **Parameters**:
|
|
- `prime`: The prime number to rekey.
|
|
- `totp`: TOTP for authentication.
|
|
- `key`: Encrypted cryptographic key associated with the prime.
|
|
- **Returns**: On success, JSON object containing new cryptographic keys and TOTP information.
|
|
- Example: `{"key": "new-encrypted-key", "subkey": "new-base85-encoded-subkey", "totp_key": "new-encrypted-totp-key", "totp_ts": 1594857600}`
|
|
- **Errors**:
|
|
- `totp`: Returned on TOTP validation errors (not specified or invalid `totp` GET parameter).
|
|
- `json`: Returned if there is an issue with the provided JSON data.
|
|
- `notexist`: Returned if the specified prime does not exist.
|
|
|
|
### GET /ranges?totp=\<totp\>
|
|
|
|
- **Description**: Retrieves the range of prime numbers stored in the database, from the smallest to the largest.
|
|
- **Requires**: JSON containing a valid TOTP.
|
|
- **Parameters**:
|
|
- `totp`: TOTP value based off the server's TOTP information.
|
|
- **Returns**: On success, JSON object containing the smallest and largest prime numbers.
|
|
- Example: `{"from": "smallest-prime", "to": "largest-prime"}`
|
|
- **Errors**:
|
|
- `totp`: Returned on TOTP validation errors.
|
|
|
|
## Cryptography
|
|
|
|
p.ari.lt uses ChaCha20-Poly1305 to encrypt keys using nonces and subkeys. A cypher-text is valid for only 256 seconds due to how the keys are derived: First 48 bytes of the subkey are used in key derivation, last 16 - for authentication. An example implementation in Python could look like this:
|
|
|
|
```py
|
|
def chacha20_encrypt(data: bytes, subkey: bytes) -> str:
|
|
"""Encrypt data using a subkey"""
|
|
nonce: bytes = os.urandom(12)
|
|
key: bytes = hashlib.sha3_256(
|
|
nonce + subkey[:48] + int(time.time() / 256).to_bytes(8, "big")
|
|
).digest()
|
|
return base64.b85encode(
|
|
nonce + ChaCha20Poly1305(key).encrypt(nonce, data, subkey[48:])
|
|
).decode("ascii")
|
|
|
|
|
|
def chacha20_decrypt(ct: str, subkey: bytes) -> bytes:
|
|
"""Decrypt data using a subkey"""
|
|
cb: bytes = base64.b85decode(ct.encode("ascii"))
|
|
key: bytes = hashlib.sha3_256(
|
|
cb[:12] + subkey[:48] + int(time.time() / 256).to_bytes(8, "big")
|
|
).digest()
|
|
return ChaCha20Poly1305(key).decrypt(cb[:12], cb[12:], subkey[48:])
|
|
```
|
|
|
|
## TOTP algorithm parameters
|
|
|
|
- Hashing function: SHA3-512
|
|
- Interval: 256 seconds
|
|
- Reference timestamp and key as specified.
|