# Aṇu Astra Python SDK (v1.1.0)

The official Python SDK for the **Aṇu Astra Virtual Quantum Processor** and **Post-Quantum Cryptography (PQC)** API.

Build and evaluate path-integral quantum circuits locally, run native OpenQASM 2.0 payloads, and secure your applications against "Store Now, Decrypt Later" threats using NIST-standardized Kyber and Dilithium algorithms.

## Installation

Install the package via pip:

```bash
pip install anuastra
```

## Quick Start: Quantum Execution (Qiskit-Style)

The `QuantumCircuit` builder provides a declarative, strictly-typed interface mirroring industry standards like IBM Qiskit. 
In v1.1.0, we introduced a smart `QuantumResult` wrapper. You can simply print the result to see beautiful JSON, or use dot-notation (e.g., `result.states`) to access data directly!

```python
from anuastra import Client, QuantumCircuit

# Initialize with your Developer Key
astra = Client(api_key='YOUR_API_KEY_HERE')

def run_quantum():
    # Scaffold a 2-qubit circuit
    circuit = QuantumCircuit(2)
    
    # Create a Bell State (Superposition + Entanglement)
    circuit.h(0)
    circuit.cx(0, 1)

    # Execute the circuit using the Aṇu Astra path-integral engine
    result = astra.execute(circuit, shots=1)
    
    # The SDK automatically formats the result beautifully!
    print(result)

    # Or access specific properties easily:
    print(f"Engine: {result.engine}")
    print(f"Feynman Paths Explored: {result.telemetry['feynman_paths_explored']}")
    print(f"Collapsed measurement (Binary): {result.states[0]}")

if __name__ == "__main__":
    run_quantum()
```

## Supported Quantum Gates

Aṇu Astra natively supports a sprawling library of quantum operators. You can chain these directly onto your `QuantumCircuit` object.

| Category | Supported Gates & Method Shortcuts |
| :--- | :--- |
| **Pauli & Basic** | `h(q)`, `x(q)`, `y(q)`, `z(q)`, `id(q)` |
| **Phase & S/T** | `s(q)`, `sdg(q)`, `t(q)`, `tdg(q)`, `p(q, lambda)` |
| **Rotations** | `rx(q, theta)`, `ry(q, theta)`, `rz(q, theta)` |
| **Square Root** | `sx(q)`, `sxdg(q)` |
| **General Unitary** | `u1(q, l)`, `u2(q, p, l)`, `u3(q, t, p, l)` / `u(...)` |
| **2-Qubit (Controlled)** | `cnot(c, t)` / `cx(...)`, `cz(c, t)`, `cy(c, t)`, `ch(c, t)` |
| **2-Qubit (Advanced)** | `swap(q1, q2)`, `iswap(q1, q2)`, `ecr(q1, q2)`, `dcx(q1, q2)` |
| **2-Qubit (Rotations)**| `crx(c, t, theta)`, `cry(...)`, `crz(...)`, `cp(...)`, `cu(...)` |
| **2-Qubit (Ising/XX)** | `rxx(q1, q2, theta)`, `ryy(...)`, `rzz(...)`, `rzx(...)` |
| **3+ Qubit (Multi)** | `ccx(q1, q2, q3)` / `toffoli(...)`, `ccz(...)`, `cswap(...)` / `fredkin(...)`, `c3x(...)`, `c4x(...)` / `quadx(...)` |

## Quick Start: OpenQASM 2.0 Ingestion

For research teams migrating from legacy hardware (like IBM Quantum), Aṇu Astra natively ingests raw `.qasm` strings and executes them on the physics engine.

```python
from anuastra import Client

astra = Client(api_key='YOUR_API_KEY_HERE')

qasm_payload = """OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q[0] -> c[0];
measure q[1] -> c[1];
"""

# Execute the raw OpenQASM syntax natively
response = astra.execute_qasm(qasm_payload, shots=5)

# Output is wrapped in the QuantumResult object
print(response)
```

## API Endpoint Defaulting
*Note: As of v1.1.0, the SDK automatically points to the live production server at `https://astra.cryptopix.in/api/v1` out of the box.*

## Post-Quantum Cryptography (PQC)

The Aṇu Astra SDK exposes NIST FIPS-203 and FIPS-204 standardized algorithms.

### 1. Key Encapsulation (ML-KEM / Kyber)
Used for establishing symmetric quantum-resistant tunnels over public networks (TLS/TCP).

> [!IMPORTANT]
> **Zero-Trust Architecture (v1.0.2+)**: `keygen` and `decapsulate` are now executed entirely **locally** on your device using the pure-Python `fips203` distribution. Aṇu Astra never transmits or stores your private parameters.

```python
# 1. Generate keys LOCALLY (Server A)
# No private keys leave your device
keys = astra.kyber.keygen_local(level=768)
public_key = keys['public_key']
private_key = keys['private_key']

# 2. Encapsulate via VQP (Server B)
# Server B uses Public Key to create a Shared Secret + Ciphertext
capsule = astra.kyber.encapsulate(public_key)

# 3. Decapsulate LOCALLY (Server A)
# Server A uses Private Key + Ciphertext to derive the exact same Shared Secret
resolved = astra.kyber.decapsulate_local(capsule['ciphertext'], private_key)
```

### 2. Digital Signatures (ML-DSA / Dilithium)
Used for unbreakable document signing, firmware validation, and transaction authentication.

```python
# 1. Generate keys
keys = astra.dilithium.keygen(level=3)
public_key = keys['public_key']
private_key = keys['private_key']

# 2. Sign a payload
message = "Quantum Safe transaction payload"
signed = astra.dilithium.sign(message, private_key)

# 3. Verify the payload cryptographically
validation = astra.dilithium.verify(signed['signature'], message, public_key)
print(validation['is_valid']) # Returns True
```

## License
MIT
