Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/content/docs/integrations/near-integration-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ description: Design document for integrating NEAR 1Click API with SIP Protocol S

# NEAR Intents Integration Design

:::note[Design proposal — not the shipped API]
This document describes a proposed high-level API design. The shipped SDK exposes the `SIP` client (`getQuotes()` / `execute()`) and `NEARIntentsAdapter` (`prepareSwap()` / `initiateSwap()`) — see [NEAR Intents](/integrations/near-intents/). Code below is illustrative of the design direction, not current API.
:::

Design document for integrating NEAR 1Click API with SIP Protocol SDK.

## Goals
Expand Down
8 changes: 4 additions & 4 deletions src/content/docs/security/audit-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const bytes = crypto.getRandomValues(new Uint8Array(32))
- [ ] No discrete log relation to G is known

```typescript
// Expected: H = hashToCurve("SIP_PEDERSEN_H_GENERATOR_V1")
// Expected: H = try-and-increment over SHA-256("SIP-PEDERSEN-GENERATOR-H-v1:<counter>")
```

#### 2.2 Commitment Creation
Expand Down Expand Up @@ -133,9 +133,9 @@ const bytes = crypto.getRandomValues(new Uint8Array(32))

- [ ] **File**: `stealth.ts:generateStealthAddress()`
- [ ] Ephemeral key is fresh random
- [ ] ECDH performed correctly: S = r·K_view
- [ ] ECDH performed correctly: S = r·K_spend
- [ ] Scalar derivation: s = H(S)
- [ ] Address computation: P = K_spend + s·G
- [ ] Address computation: P = K_view + s·G

#### 3.3 Address Checking

Expand All @@ -147,7 +147,7 @@ const bytes = crypto.getRandomValues(new Uint8Array(32))
#### 3.4 Private Key Recovery

- [ ] **File**: `stealth.ts:deriveStealthPrivateKey()`
- [ ] Correctly computes: p = k_spend + H(k_view·R)
- [ ] Correctly computes: p = k_view + H(k_spend·R)
- [ ] Result matches stealth address public key
- [ ] No timing variance based on input

Expand Down
42 changes: 28 additions & 14 deletions src/content/docs/security/crypto-assumptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@ Where:
### H Generator (NUMS Construction)

```typescript
// H is derived by hashing a fixed string to curve
const seed = sha256("SIP_PEDERSEN_H_GENERATOR_V1")
H = hashToCurve(seed)
// H is derived deterministically from a fixed domain string using a
// try-and-increment hash-to-curve, so nobody knows log_G(H).
const H_DOMAIN = 'SIP-PEDERSEN-GENERATOR-H-v1'
// For counter = 0, 1, 2, ...: hash `${H_DOMAIN}:${counter}` with SHA-256
// and attempt to decode the digest as a valid curve point; the first
// success becomes H.
H = tryAndIncrement(H_DOMAIN)

// Properties:
// 1. Nobody knows discrete log of H with respect to G
Expand Down Expand Up @@ -108,15 +112,22 @@ H = hashToCurve(seed)
Recipient publishes: (K_spend, K_view) - stealth meta-address
Sender generates: r (ephemeral private key)
R = r·G (ephemeral public key)
S = r·K_view (shared secret via ECDH)
S = r·K_spend (shared secret via ECDH)
s = H(S) (scalar derivation)
P = K_spend + s·G (stealth address)
P = K_view + s·G (stealth address)

Recipient computes: S' = k_view·R (same shared secret)
Recipient computes: S' = k_spend·R (same shared secret)
s' = H(S')
p = k_spend + s' (stealth private key)
p = k_view + s' (stealth private key)
```

Consistency: `S = r·K_spend = k_spend·R` (ECDH), and
`P = K_view + s·G = (k_view + s)·G = p·G`. Deriving the stealth private key
`p` therefore requires **both** recipient private keys (`k_spend` to recover
`S`, `k_view` as the base scalar). This matches the implementation in
`stealth/secp256k1.ts` and the formula `A = Q + H(r·P)·G` in
[security-properties](/security/security-properties/).

### Security Properties

1. **Unlinkability**
Expand Down Expand Up @@ -174,7 +185,7 @@ Properties:

- **Backend**: Barretenberg (Aztec)
- **Language**: Noir
- **Proof System**: UltraPlonk
- **Proof System**: UltraHonk

### Assumptions

Expand All @@ -192,11 +203,14 @@ Properties:

### Circuit Constraints

| Circuit | Constraints (approx) | Purpose |
|---------|---------------------|---------|
| Funding Proof | ~20 | Prove sufficient balance |
| Validity Proof | ~200 | Verify intent signature |
| Fulfillment Proof | ~200 | Verify delivery |
| Circuit | ACIR Opcodes | Tests | Purpose |
|---------|-------------|-------|---------|
| Funding Proof | 972 | 5 | Prove balance ≥ minimum |
| Validity Proof | 1,113 | 6 | Verify intent authorization |
| Fulfillment Proof | 1,691 | 8 | Verify fulfillment correctness |

> Counts are ACIR opcodes from the compiled Noir circuits (3,776 total). The
> Barretenberg gate count after lowering is higher and differs per backend.

## Random Number Generation

Expand Down Expand Up @@ -234,7 +248,7 @@ crypto.getRandomValues(new Uint8Array(32))
| Commitments | ∞ (perfect) | Hiding is information-theoretic |
| Stealth addresses | 128 bits | CDH assumption |
| SHA-256 | 128 bits | Collision resistance |
| ZK Proofs | ~128 bits | UltraPlonk soundness |
| ZK Proofs | ~128 bits | UltraHonk soundness |

## Implementation Notes

Expand Down
13 changes: 11 additions & 2 deletions src/content/docs/specs/fulfillment-proof.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ import { Badge, Card } from '@astrojs/starlight/components'
<div style="display: flex; gap: 0.5rem; margin-bottom: 1rem;">
<Badge text="Planned" variant="caution" />
<Badge text="Noir" variant="note" />
<Badge text="~80 constraints" variant="tip" />
<Badge text="1,691 ACIR opcodes" variant="tip" />
<Badge text="8 tests" variant="tip" />
</div>

<Card title="TL;DR">
Proves a solver correctly executed a swap **without revealing the exact amount or transaction path**. Verifies delivery to the correct stealth address and that output meets minimum requirements.
</Card>

:::note[Circuit metric: ACIR opcodes vs gate count]
The **1,691** figure is the **ACIR opcode** count reported by `nargo info` for the compiled circuit — not a Barretenberg gate count. After Noir lowers ACIR to the UltraHonk proving system (Barretenberg / `@aztec/bb.js`), the backend gate count is larger and backend-specific.
:::

# Fulfillment Proof Specification

The Fulfillment Proof demonstrates that a solver correctly executed a swap without revealing transaction details.
Expand Down Expand Up @@ -201,5 +206,9 @@ interface OracleAttestation {
| Metric | Mock | Noir (estimated) |
|--------|------|------------------|
| Proof generation | <1ms | 2-4s |
| Proof size | 64 bytes | ~200 bytes |
| Proof size | placeholder bytes (not a real proof) | multi-KB (real UltraHonk proof) |
| Verification | <1ms | ~10ms |

:::caution[Proof size]
`MockProofProvider` returns placeholder bytes for testing — it is **not** a real cryptographic proof and has no fixed 64-byte size. Real proofs are produced by the UltraHonk backend (Barretenberg / `@aztec/bb.js`) and are several KB, not ~200 bytes.
:::
13 changes: 11 additions & 2 deletions src/content/docs/specs/funding-proof.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ import { Badge, Card } from '@astrojs/starlight/components'
<div style="display: flex; gap: 0.5rem; margin-bottom: 1rem;">
<Badge text="Planned" variant="caution" />
<Badge text="Noir" variant="note" />
<Badge text="~50 constraints" variant="tip" />
<Badge text="972 ACIR opcodes" variant="tip" />
<Badge text="5 tests" variant="tip" />
</div>

<Card title="TL;DR">
Proves user has sufficient balance to cover a transaction **without revealing the actual balance**. Uses Pedersen commitments to hide amounts while proving `balance >= minimum`.
</Card>

:::note[Circuit metric: ACIR opcodes vs gate count]
The **972** figure is the **ACIR opcode** count reported by `nargo info` for the compiled circuit — not a Barretenberg gate count. After Noir lowers ACIR to the UltraHonk proving system (Barretenberg / `@aztec/bb.js`), the backend gate count is larger and backend-specific. The SDK JSDoc carries a separate, higher gate-count *estimate*; treat the two as different metrics — ACIR opcodes describe the circuit, gate count describes the proving cost.
:::

# Funding Proof Specification

The Funding Proof demonstrates that a user has sufficient balance to cover a transaction without revealing the actual balance.
Expand Down Expand Up @@ -159,5 +164,9 @@ if (!isValid) {
| Metric | Mock | Noir (estimated) |
|--------|------|------------------|
| Proof generation | <1ms | 2-3s |
| Proof size | 64 bytes | ~200 bytes |
| Proof size | placeholder bytes (not a real proof) | multi-KB (real UltraHonk proof) |
| Verification | <1ms | ~10ms |

:::caution[Proof size]
`MockProofProvider` returns placeholder bytes for testing — it is **not** a real cryptographic proof and has no fixed 64-byte size. Real proofs are produced by the UltraHonk backend (Barretenberg / `@aztec/bb.js`) and are several KB, not ~200 bytes.
:::
13 changes: 11 additions & 2 deletions src/content/docs/specs/validity-proof.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ import { Badge, Card } from '@astrojs/starlight/components'
<div style="display: flex; gap: 0.5rem; margin-bottom: 1rem;">
<Badge text="Planned" variant="caution" />
<Badge text="Noir" variant="note" />
<Badge text="~150 constraints" variant="tip" />
<Badge text="1,113 ACIR opcodes" variant="tip" />
<Badge text="6 tests" variant="tip" />
</div>

<Card title="TL;DR">
Proves an intent was authorized by a legitimate sender **without revealing their identity**. Uses ECDSA signature verification inside the circuit to prove "someone with spending authority signed this."
</Card>

:::note[Circuit metric: ACIR opcodes vs gate count]
The **1,113** figure is the **ACIR opcode** count reported by `nargo info` for the compiled circuit — not a Barretenberg gate count. After Noir lowers ACIR to the UltraHonk proving system (Barretenberg / `@aztec/bb.js`), the backend gate count is larger and backend-specific.
:::

# Validity Proof Specification

The Validity Proof demonstrates that an intent was authorized by a legitimate sender without revealing their identity.
Expand Down Expand Up @@ -184,5 +189,9 @@ interface ValidityProof {
| Metric | Mock | Noir (estimated) |
|--------|------|------------------|
| Proof generation | <1ms | 3-5s |
| Proof size | 64 bytes | ~250 bytes |
| Proof size | placeholder bytes (not a real proof) | multi-KB (real UltraHonk proof) |
| Verification | <1ms | ~15ms |

:::caution[Proof size]
`MockProofProvider` returns placeholder bytes for testing — it is **not** a real cryptographic proof and has no fixed 64-byte size. Real proofs are produced by the UltraHonk backend (Barretenberg / `@aztec/bb.js`) and are several KB, not ~250 bytes.
:::
8 changes: 3 additions & 5 deletions src/content/docs/specs/zk-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,13 @@ flowchart TB
NoirJS["Noir / NoirJS<br/>(Production)"]
end

NoirJS --> UP["UltraPlonk Backend"]
NoirJS --> G16["Groth16 Backend"]
NoirJS --> UH["UltraHonk Backend<br/>(Barretenberg / @aztec/bb.js)"]

style SDK fill:#312e81,stroke:#8b5cf6,stroke-width:2px
style PP fill:#4c1d95,stroke:#a78bfa
style TestPath fill:#1e1b4b,stroke:#8b5cf6
style ProdPath fill:#4c1d95,stroke:#a78bfa,stroke-width:2px
style UP fill:#22c55e,stroke:#86efac
style G16 fill:#22c55e,stroke:#86efac
style UH fill:#22c55e,stroke:#86efac
```

## SDK Integration
Expand Down Expand Up @@ -264,7 +262,7 @@ const proof = await prover.prove({
| Risk | Mitigation |
|------|------------|
| Less battle-tested | Simple circuits, formal verification |
| Performance gaps | Start with UltraPlonk, can switch |
| Performance gaps | Start with UltraHonk (Barretenberg), can switch |
| Smaller ecosystem | Core primitives well-supported |

## Roadmap
Expand Down