audit 2026-06: TEE + GPU + public-permissionless-chain safety + corona->corona sweep

AUDIT-2026-06.md ships the four-dimensional audit:

D1 Permissionless safety: PASSED with two minor open items for v0.7.6.
   Rogue-key NOT APPLICABLE (single global (A, bTilde); no per-party pk
   in the BLS-aggregation sense). Adaptive corruption documented as
   paper-cited only (carryover; GATE-4 target). Slashable equivocation
   evidence is cryptographically extractable via signed dkg2.Complaint
   and activation-cert non-verification. Front-running: sid IS bound
   into PRNG seed / MAC / transcript hash (CRIT-1 fix 2026-05-03), but
   plumbed as Go int (64-bit), not 32-byte randomness as threat-model
   claims — D1-2 MEDIUM, doc tightening for v0.7.6. D1-3 MINOR: extend
   Complaint to signing-round equivocation.

D2 TEE integration: WAS A GAP. Closed by this audit via the new
   docs/mptc/tee-integration.md — full per-platform spec for AMD
   SEV-SNP (primary Linux path), NVIDIA Confidential Computing
   (H100/H200/B200 CC mode) when gpu.UseAccelerator() is used in
   production, Intel TDX (alternative), Apple Secure Enclave (local-
   only defense-in-depth on Apple Silicon). Intel SGX explicitly NOT
   RECOMMENDED. Decomplecting rule held: ZERO Corona kernel code
   change required for §3.1, §3.3, §3.4; §3.2 adds one optional
   plumbing function (gpu.MaybeRegisterAttested) tracked for v0.7.6.
   The TEE layer sits OUTSIDE the cryptographic math — Corona observes
   nothing of TEE state.

D3 GPU acceleration inventory: corona/gpu is a thin SubRing-registration
   shim around luxfi/lattice/v7/gpu — no kernels live in corona/.
   dkg2_parallel.go is goroutine fan-out (honestly relabelled in
   ca3389c), not GPU dispatch. Sister-repo lux-private/gpu-kernels/
   ops/mpcvm/*/mpcvm_corona.* and ops/crypto/corona/ carry the
   legacy name — D3-1 INFORMATIONAL, cross-repo rename TODO.

D4 corona->corona sweep (in-repo COMPLETE):
   * Makefile: BINARY_NAME corona -> corona; banner + docker tag.
   * Dockerfile: addgroup/adduser/binary-path/entrypoint.
   * .github/workflows/ci.yml: bin/corona -> bin/corona; artifact
     name corona-${runner.os}-${arch}; release output name pattern.
   * .golangci.yml: local-prefixes: corona -> github.com/luxfi/corona.
   * docs/{app,content,lib,out,public,.source,mdx-components.tsx,...}
     DROPPED — a fumadocs Next.js site (3057 lines) that framed Corona
     as a privacy ring-signature scheme (Schnorr + linkability +
     hash-to-curve + "ring signatures for transaction privacy"). That
     is NOT Corona — Corona is a 2-round R-LWE threshold sig (Boschini
     et al. 2024/1113). The site referenced a non-existent
     github.com/luxfi/corona Go module. Removed.
   * KEPT: docs/mptc/ (authoritative submission docs).
   * KEPT: historical refs in CHANGELOG.md, LLM.md, and
     CRYPTOGRAPHER-SIGN-OFF.md — they document the prior v0.4.x purge
     and are correct as historical context.
   * Cross-repo (luxfi/threshold, lux-private/gpu-kernels, luxfi/node)
     inventoried as D4-1 INFORMATIONAL — sister-repo work items.

Build clean (GOWORK=off go build ./...). gofmt -s clean. vet clean.
Full short test suite green: dkg, dkg2, gpu, hash, keyera, networking,
primitives, reshare, sign, threshold, utils, wire — ALL ok.

KATs unchanged: no Go code paths edited; FIPS-TRACEABILITY byte-
equality contract preserved. v1.x ABI unchanged: no public Go API
modified. Constant-time discipline preserved: no crypto/subtle paths
touched; CONSTANT-TIME-REVIEW.md remains authoritative.

Production deployment posture (unchanged from v0.7.5): APPROVED WITH
ROADMAP GATES for public-permissionless deployment as a R-LWE
threshold signature primitive in Lux Quasar consensus, with v0.8.0
GATE-3b (10^9-sample dudect on pinned CPU) + GATE-4 (external audit)
+ GATE-5 (Jasmin extraction byte-walk) as carryover roadmap items.
This commit is contained in:
2026-06-03 11:40:06 -07:00
parent be7a3df4ae
commit 159e9279ff
26 changed files with 1033 additions and 7601 deletions
-34
View File
@@ -1,34 +0,0 @@
# Dependencies
node_modules/
.pnpm-store/
# Next.js
.next/
out/
.turbo/
# Build
dist/
build/
# Environment
.env
.env.local
.env.*.local
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Fumadocs
.source/
# TypeScript
*.tsbuildinfo
next-env.d.ts
-42
View File
@@ -1,42 +0,0 @@
import { source } from "@/lib/source"
import type { Metadata } from "next"
import { DocsPage, DocsBody, DocsTitle, DocsDescription } from "fumadocs-ui/page"
import { notFound } from "next/navigation"
import defaultMdxComponents from "fumadocs-ui/mdx"
export default async function Page(props: {
params: Promise<{ slug?: string[] }>
}) {
const params = await props.params
const page = source.getPage(params.slug)
if (!page) notFound()
const MDX = page.data.body
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX components={{ ...defaultMdxComponents }} />
</DocsBody>
</DocsPage>
)
}
export async function generateStaticParams() {
return source.generateParams()
}
export async function generateMetadata(props: {
params: Promise<{ slug?: string[] }>
}): Promise<Metadata> {
const params = await props.params
const page = source.getPage(params.slug)
if (!page) notFound()
return {
title: page.data.title,
description: page.data.description,
}
}
-11
View File
@@ -1,11 +0,0 @@
import { source } from "@/lib/source"
import type { ReactNode } from "react"
import { DocsLayout } from "fumadocs-ui/layouts/docs"
export default async function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.pageTree} sidebar={{ defaultOpenLevel: 0 }}>
{children}
</DocsLayout>
)
}
-79
View File
@@ -1,79 +0,0 @@
@import "tailwindcss";
@import "fumadocs-ui/style.css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--breakpoint-3xl: 1600px;
--breakpoint-4xl: 2000px;
--font-sans: var(--font-geist-sans), system-ui, sans-serif;
--font-mono: var(--font-geist-mono), monospace;
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
}
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--radius: 0.5rem;
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
}
-50
View File
@@ -1,50 +0,0 @@
import "./global.css"
import { RootProvider } from "fumadocs-ui/provider/next"
import { Inter } from "next/font/google"
import type { ReactNode } from "react"
const inter = Inter({
subsets: ["latin"],
variable: "--font-geist-sans",
display: "swap",
})
const interMono = Inter({
subsets: ["latin"],
variable: "--font-geist-mono",
display: "swap",
})
export const metadata = {
title: {
default: "Corona Signatures Documentation",
template: "%s | Corona Signatures",
},
description: "Ring signature implementation for privacy",
}
export default function Layout({ children }: { children: ReactNode }) {
return (
<html
lang="en"
className={`${inter.variable} ${interMono.variable}`}
suppressHydrationWarning
>
<body className="min-h-svh bg-background font-sans antialiased">
<RootProvider
search={{
enabled: true,
}}
theme={{
enabled: true,
defaultTheme: "dark",
}}
>
<div className="relative flex min-h-svh flex-col bg-background">
{children}
</div>
</RootProvider>
</body>
</html>
)
}
-26
View File
@@ -1,26 +0,0 @@
import Link from "next/link"
export default function HomePage() {
return (
<main className="flex flex-1 flex-col items-center justify-center px-4">
<div className="container flex flex-col items-center gap-12 py-24 sm:gap-16 sm:py-32">
<div className="flex flex-col items-center gap-4 text-center">
<h1 className="text-4xl font-bold tracking-tight sm:text-6xl">
Documentation
</h1>
<p className="max-w-2xl text-lg text-muted-foreground">
Get started with our comprehensive documentation
</p>
</div>
<div className="flex gap-4">
<Link
href="/docs"
className="inline-flex h-10 items-center justify-center rounded-md bg-primary px-8 text-sm font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90"
>
Get Started
</Link>
</div>
</div>
</main>
)
}
-644
View File
@@ -1,644 +0,0 @@
---
title: API Reference
description: Complete API documentation for Corona's cryptographic functions
---
# API Reference
## Core Types
### PublicKey
Represents an elliptic curve public key.
```go
type PublicKey struct {
X, Y *big.Int
}
// Methods
func (pk *PublicKey) Bytes() []byte
func (pk *PublicKey) String() string
func (pk *PublicKey) Equal(other *PublicKey) bool
func (pk *PublicKey) Marshal() ([]byte, error)
func (pk *PublicKey) Unmarshal(data []byte) error
```
### PrivateKey
Represents an elliptic curve private key.
```go
type PrivateKey big.Int
// Methods
func (sk *PrivateKey) PublicKey() *PublicKey
func (sk *PrivateKey) Bytes() []byte
func (sk *PrivateKey) Clear()
func (sk *PrivateKey) Sign(message []byte) (*Signature, error)
```
### RingSignature
Complete ring signature with linkability.
```go
type RingSignature struct {
C0 *big.Int // Initial challenge
S []*big.Int // Response values
KeyImage *KeyImage // Linkability tag
RingPubKeys []*PublicKey // Ring members
}
// Methods
func (rs *RingSignature) Serialize() []byte
func (rs *RingSignature) Deserialize(data []byte) error
func (rs *RingSignature) Size() int
func (rs *RingSignature) IsValid() bool
```
### KeyImage
Unique identifier for linkable signatures.
```go
type KeyImage struct {
X, Y *big.Int
}
// Methods
func (ki *KeyImage) Bytes() []byte
func (ki *KeyImage) Equal(other *KeyImage) bool
func (ki *KeyImage) String() string
```
## Key Management
### GenerateKeyPair
Generate a new public/private key pair.
```go
func GenerateKeyPair() (*PublicKey, *PrivateKey, error)
```
**Returns:**
- `*PublicKey`: The generated public key
- `*PrivateKey`: The generated private key
- `error`: Any error that occurred
**Example:**
```go
pub, priv, err := corona.GenerateKeyPair()
if err != nil {
log.Fatal(err)
}
defer priv.Clear() // Clean up private key
```
### DerivePublicKey
Derive public key from private key.
```go
func DerivePublicKey(privKey *PrivateKey) *PublicKey
```
**Parameters:**
- `privKey`: The private key to derive from
**Returns:**
- `*PublicKey`: The corresponding public key
### GenerateKeyImage
Generate key image for linkability.
```go
func GenerateKeyImage(privKey *PrivateKey) *KeyImage
```
**Parameters:**
- `privKey`: The private key for key image generation
**Returns:**
- `*KeyImage`: The generated key image
**Example:**
```go
keyImage := GenerateKeyImage(privKey)
// Same private key always produces same key image
```
## Ring Signature Functions
### SignRing
Create a ring signature for a message.
```go
func SignRing(
message []byte,
ring []*PublicKey,
signerIndex int,
privKey *PrivateKey,
) (*RingSignature, error)
```
**Parameters:**
- `message`: The message to sign
- `ring`: Array of public keys forming the ring
- `signerIndex`: Position of actual signer in ring (0-indexed)
- `privKey`: Private key of the actual signer
**Returns:**
- `*RingSignature`: The generated ring signature
- `error`: Any error that occurred
**Example:**
```go
ring := []*PublicKey{pk1, pk2, pk3, pk4}
sig, err := SignRing(
[]byte("transaction data"),
ring,
2, // signer is at index 2
privKey3,
)
```
### VerifyRing
Verify a ring signature.
```go
func VerifyRing(
message []byte,
signature *RingSignature,
) bool
```
**Parameters:**
- `message`: The original message
- `signature`: The ring signature to verify
**Returns:**
- `bool`: True if signature is valid, false otherwise
**Example:**
```go
valid := VerifyRing(message, signature)
if !valid {
return errors.New("invalid signature")
}
```
### CheckLinkability
Check if two signatures are linked (same signer).
```go
func CheckLinkability(
sig1 *RingSignature,
sig2 *RingSignature,
) bool
```
**Parameters:**
- `sig1`: First ring signature
- `sig2`: Second ring signature
**Returns:**
- `bool`: True if signatures are from the same private key
## Threshold Signatures
### Party
Represents a participant in threshold signing.
```go
type Party struct {
ID int
Ring *ring.Ring
RingXi *ring.Ring
RingNu *ring.Ring
UniformSampler *ring.UniformSampler
SkShare structs.Vector[ring.Poly]
// ... additional fields
}
// Constructor
func NewParty(
id int,
r *ring.Ring,
r_xi *ring.Ring,
r_nu *ring.Ring,
sampler *ring.UniformSampler,
) *Party
```
### ThresholdSetup
Initialize threshold signature scheme.
```go
func ThresholdSetup(
n int, // Total parties
t int, // Threshold
secLevel int, // Security level
) (*ThresholdConfig, error)
```
**Parameters:**
- `n`: Total number of parties
- `t`: Minimum parties needed to sign
- `secLevel`: Security level in bits (128, 192, 256)
**Returns:**
- `*ThresholdConfig`: Configuration for threshold signing
- `error`: Any error that occurred
### DistributedKeyGen
Generate distributed key shares.
```go
func DistributedKeyGen(
config *ThresholdConfig,
parties []*Party,
) (*PublicKey, map[int]*KeyShare, error)
```
**Parameters:**
- `config`: Threshold configuration
- `parties`: Array of participating parties
**Returns:**
- `*PublicKey`: The group public key
- `map[int]*KeyShare`: Map of party ID to key share
- `error`: Any error that occurred
### ThresholdSign
Perform threshold signing with t-of-n parties.
```go
func ThresholdSign(
message []byte,
signers []*Party,
threshold int,
) (*ThresholdSignature, error)
```
**Parameters:**
- `message`: Message to sign
- `signers`: Participating signers (must be >= threshold)
- `threshold`: Minimum signers required
**Returns:**
- `*ThresholdSignature`: The threshold signature
- `error`: Any error that occurred
## Lattice Operations
### Polynomial Ring Functions
```go
// Create new polynomial ring
func NewRing(n int, q *big.Int) *ring.Ring
// Sample random polynomial
func SamplePoly(r *ring.Ring) ring.Poly
// Polynomial multiplication
func PolyMul(
r *ring.Ring,
a, b ring.Poly,
) ring.Poly
// NTT transformation
func NTT(r *ring.Ring, poly ring.Poly) ring.Poly
// Inverse NTT
func INTT(r *ring.Ring, poly ring.Poly) ring.Poly
```
### Matrix Operations
```go
// Matrix-vector multiplication
func MatrixVectorMul(
r *ring.Ring,
M structs.Matrix[ring.Poly],
v structs.Vector[ring.Poly],
) structs.Vector[ring.Poly]
// Matrix addition
func MatrixAdd(
r *ring.Ring,
A, B structs.Matrix[ring.Poly],
) structs.Matrix[ring.Poly]
// Sample random matrix
func SamplePolyMatrix(
r *ring.Ring,
rows, cols int,
sampler Sampler,
) structs.Matrix[ring.Poly]
```
## Utility Functions
### Hash Functions
```go
// Hash to elliptic curve point
func HashToPoint(data []byte) *Point
// Generate challenge hash
func ChallengeHash(components ...[]byte) *big.Int
// SHA-256 hash
func Hash256(data []byte) []byte
// Keccak-256 hash
func Keccak256(data []byte) []byte
```
### Serialization
```go
// Serialize ring signature
func SerializeRingSignature(sig *RingSignature) []byte
// Deserialize ring signature
func DeserializeRingSignature(data []byte) (*RingSignature, error)
// Encode to base64
func EncodeBase64(data []byte) string
// Decode from base64
func DecodeBase64(s string) ([]byte, error)
```
### Random Generation
```go
// Generate secure random bytes
func GenerateRandom(size int) ([]byte, error)
// Generate random scalar
func RandomScalar() (*big.Int, error)
// Generate random point
func RandomPoint() (*Point, error)
// Deterministic random from seed
func DeterministicRandom(seed []byte, size int) []byte
```
## Network Protocol
### Message Types
```go
const (
MsgKeyGenInit MessageType = 0x01
MsgKeyGenShare MessageType = 0x02
MsgSignRound1 MessageType = 0x10
MsgSignRound2 MessageType = 0x11
MsgSignRound3 MessageType = 0x12
MsgAbort MessageType = 0xFF
)
```
### Network Functions
```go
// Send message to party
func SendMessage(
party int,
msg NetworkMessage,
) error
// Broadcast to all parties
func Broadcast(
msg NetworkMessage,
) error
// Receive messages
func ReceiveMessages(
expectedType MessageType,
timeout time.Duration,
) ([]NetworkMessage, error)
// Establish secure channel
func EstablishChannel(
partyID int,
publicKey *PublicKey,
) (*SecureChannel, error)
```
## Configuration
### Config Structure
```go
type Config struct {
// Ring signature parameters
RingSize int
Algorithm Algorithm
HashFunction hash.Hash
// Lattice parameters
PolyDegree int
Modulus *big.Int
ErrorStdDev float64
// Threshold parameters
TotalParties int
Threshold int
// Security
SecurityLevel int
QuantumSafe bool
// Performance
ParallelOps bool
CacheSize int
}
```
### Default Configurations
```go
// Default configuration
func DefaultConfig() *Config
// High security configuration
func HighSecurityConfig() *Config
// Performance optimized configuration
func PerformanceConfig() *Config
// Quantum-safe configuration
func QuantumSafeConfig() *Config
```
## Error Types
```go
var (
// Key errors
ErrInvalidPrivateKey = errors.New("invalid private key")
ErrInvalidPublicKey = errors.New("invalid public key")
ErrKeyMismatch = errors.New("key mismatch")
// Signature errors
ErrInvalidSignature = errors.New("invalid signature")
ErrInvalidRingSize = errors.New("invalid ring size")
ErrSignerNotInRing = errors.New("signer not in ring")
// Threshold errors
ErrInsufficientSigners = errors.New("insufficient signers")
ErrInvalidThreshold = errors.New("invalid threshold")
ErrDuplicateSigner = errors.New("duplicate signer")
// Protocol errors
ErrProtocolAborted = errors.New("protocol aborted")
ErrTimeout = errors.New("operation timeout")
ErrInvalidMAC = errors.New("invalid MAC")
// Lattice errors
ErrInvalidPolynomial = errors.New("invalid polynomial")
ErrNTTFailed = errors.New("NTT operation failed")
)
```
## Constants
```go
const (
// Default values
DefaultRingSize = 16
DefaultPolyDegree = 4096
DefaultSecurityLevel = 128
// Size constants
PublicKeySize = 64 // bytes
PrivateKeySize = 32 // bytes
KeyImageSize = 64 // bytes
SignatureBase = 96 // bytes (before ring members)
// Algorithm identifiers
AlgoSchnorr Algorithm = 0x01
AlgoLattice Algorithm = 0x02
AlgoHybrid Algorithm = 0x03
// Security levels
SecurityLow = 80
SecurityMedium = 128
SecurityHigh = 192
SecurityMax = 256
)
```
## Example Usage
### Basic Ring Signature
```go
package main
import (
"fmt"
"log"
"github.com/luxfi/corona"
)
func main() {
// Generate keys for ring members
keys := make([]*corona.PublicKey, 16)
var signerKey *corona.PrivateKey
signerIndex := 7
for i := 0; i < 16; i++ {
pub, priv, err := corona.GenerateKeyPair()
if err != nil {
log.Fatal(err)
}
keys[i] = pub
if i == signerIndex {
signerKey = priv
} else {
priv.Clear() // Clean up other private keys
}
}
// Create and verify signature
message := []byte("confidential transaction")
sig, err := corona.SignRing(
message,
keys,
signerIndex,
signerKey,
)
if err != nil {
log.Fatal(err)
}
valid := corona.VerifyRing(message, sig)
fmt.Printf("Signature valid: %v\n", valid)
// Check linkability
sig2, _ := corona.SignRing(
[]byte("another message"),
keys,
signerIndex,
signerKey,
)
linked := corona.CheckLinkability(sig, sig2)
fmt.Printf("Signatures linked: %v\n", linked)
}
```
### Threshold Signature
```go
// Setup threshold scheme (3-of-5)
config, err := corona.ThresholdSetup(5, 3, 128)
if err != nil {
log.Fatal(err)
}
// Initialize parties
parties := make([]*corona.Party, 5)
for i := 0; i < 5; i++ {
parties[i] = corona.NewParty(i, config)
}
// Generate distributed key
pubKey, shares, err := corona.DistributedKeyGen(config, parties)
if err != nil {
log.Fatal(err)
}
// Sign with subset of parties (3 out of 5)
signers := []*corona.Party{parties[0], parties[2], parties[4]}
sig, err := corona.ThresholdSign(
[]byte("message"),
signers,
3,
)
if err != nil {
log.Fatal(err)
}
// Verify threshold signature
valid := corona.VerifyThreshold([]byte("message"), sig, pubKey)
fmt.Printf("Threshold signature valid: %v\n", valid)
```
-702
View File
@@ -1,702 +0,0 @@
---
title: Implementation Guide
description: Detailed implementation architecture and code structure of Corona
---
# Implementation Guide
## Architecture Overview
Corona is structured as a modular cryptographic library with clear separation of concerns:
```
corona/
├── primitives/ # Core cryptographic primitives
├── sign/ # Signature generation and verification
├── utils/ # Utility functions and helpers
├── networking/ # Network communication layer
└── docs/ # Documentation
```
## Core Components
### Primitives Package
The `primitives` package provides fundamental cryptographic operations:
```go
// primitives/shamir.go
package primitives
import (
"github.com/luxfi/lattice/v6/ring"
"github.com/luxfi/lattice/v6/utils/structs"
)
// ShamirSecretSharing implements (t,n) threshold secret sharing
func ShamirSecretSharing(
r *ring.Ring,
secret structs.Vector[ring.Poly],
threshold int,
lagrangeCoeffs structs.Vector[ring.Poly],
) map[int]structs.Vector[ring.Poly] {
// Generate random polynomial of degree threshold-1
// Evaluate at n points to create shares
// Return map of party ID to share
}
```
#### Hash Functions
Secure hash operations for ring signatures:
```go
// primitives/hash.go
func HashToPoint(data []byte) *Point {
// Hash arbitrary data to elliptic curve point
// Used for key image generation
h := sha256.Sum256(data)
// Map hash to curve point deterministically
return mapToCurve(h[:])
}
func ChallengeHash(components ...[]byte) *big.Int {
// Generate challenge for ring signature
h := sha256.New()
for _, c := range components {
h.Write(c)
}
return new(big.Int).SetBytes(h.Sum(nil))
}
```
### Signature Package
The `sign` package implements the ring signature protocol:
```go
// sign/sign.go
package sign
type Party struct {
ID int
Ring *ring.Ring // Polynomial ring
RingXi *ring.Ring // Rounding ring
RingNu *ring.Ring // Verification ring
UniformSampler *ring.UniformSampler
SkShare structs.Vector[ring.Poly] // Secret key share
Seed map[int][][]byte // PRG seeds
R structs.Matrix[ring.Poly]
C ring.Poly // Challenge
H structs.Vector[ring.Poly]
Lambda ring.Poly // Lagrange coefficient
D structs.Matrix[ring.Poly]
MACKeys map[int][]byte // MAC keys for parties
MACs map[int][]byte // Message auth codes
}
```
#### Signature Generation Phases
**Phase 1: Setup**
```go
func (party *Party) SignRound1(
A structs.Matrix[ring.Poly],
sid int,
PRFKey []byte,
T []int,
) (structs.Matrix[ring.Poly], map[int][]byte) {
// Generate randomness using PRF
// Compute first round messages
// Create MAC tags for other parties
}
```
**Phase 2: Challenge Computation**
```go
func (party *Party) SignRound2(
hintShares map[int]structs.Vector[uint8],
) (structs.Vector[uint8], []byte) {
// Aggregate hint shares
// Compute ring signature challenge
// Prepare response
}
```
**Phase 3: Response Generation**
```go
func (party *Party) SignRound3(
dShares map[int]structs.Matrix[ring.Poly],
) structs.Matrix[ring.Poly] {
// Combine shares from all parties
// Generate final signature response
// Clean up sensitive data
}
```
### Utilities Package
Helper functions for efficient operations:
```go
// utils/utils.go
package utils
// Matrix-vector multiplication in polynomial ring
func MatrixVectorMul(
r *ring.Ring,
M structs.Matrix[ring.Poly],
v structs.Vector[ring.Poly],
result structs.Vector[ring.Poly],
) {
for i := 0; i < len(M); i++ {
r.MulCoeffsMontgomery(M[i][0], v[0], result[i])
for j := 1; j < len(v); j++ {
r.MulCoeffsMontgomeryThenAdd(M[i][j], v[j], result[i])
}
}
}
// NTT conversions for efficiency
func ConvertVectorToNTT(r *ring.Ring, v structs.Vector[ring.Poly]) {
for i := range v {
r.NTT(v[i], v[i])
}
}
```
## Ring Signature Implementation
### Key Generation
```go
type RingMember struct {
PublicKey *PublicKey
PrivateKey *PrivateKey // nil for decoy members
Index int // position in ring
}
func GenerateKeyPair() (*PublicKey, *PrivateKey, error) {
// Generate random private key
priv, err := rand.Int(rand.Reader, curve.N)
if err != nil {
return nil, nil, err
}
// Compute public key: P = x*G
pub := new(PublicKey)
pub.X, pub.Y = curve.ScalarBaseMult(priv.Bytes())
return pub, (*PrivateKey)(priv), nil
}
```
### Key Image Generation
```go
func GenerateKeyImage(privKey *PrivateKey) *KeyImage {
// Compute I = x * H(P)
pubKey := privKey.PublicKey()
hashPoint := HashToPoint(pubKey.Bytes())
keyImage := new(KeyImage)
keyImage.X, keyImage.Y = curve.ScalarMult(
hashPoint.X, hashPoint.Y,
privKey.Bytes(),
)
return keyImage
}
```
### Ring Construction
```go
func ConstructRing(
signerIndex int,
signerPubKey *PublicKey,
decoyKeys []*PublicKey,
) []*PublicKey {
ringSize := len(decoyKeys) + 1
ring := make([]*PublicKey, ringSize)
// Place signer at specified index
ring[signerIndex] = signerPubKey
// Fill remaining positions with decoys
decoyIdx := 0
for i := 0; i < ringSize; i++ {
if i != signerIndex {
ring[i] = decoyKeys[decoyIdx]
decoyIdx++
}
}
return ring
}
```
### Signature Algorithm
```go
func SignRing(
message []byte,
ring []*PublicKey,
signerIndex int,
privKey *PrivateKey,
) (*RingSignature, error) {
n := len(ring)
sig := &RingSignature{
KeyImage: GenerateKeyImage(privKey),
RingPubKeys: ring,
S: make([]*big.Int, n),
}
// Generate random responses for non-signers
c := make([]*big.Int, n)
for i := 0; i < n; i++ {
if i != signerIndex {
sig.S[i], _ = rand.Int(rand.Reader, curve.N)
c[i], _ = rand.Int(rand.Reader, curve.N)
}
}
// Generate commitment
alpha, _ := rand.Int(rand.Reader, curve.N)
L := make([]*Point, n)
R := make([]*Point, n)
// Compute L_i, R_i for signer
L[signerIndex] = new(Point)
L[signerIndex].X, L[signerIndex].Y = curve.ScalarBaseMult(alpha.Bytes())
R[signerIndex] = new(Point)
hP := HashToPoint(ring[signerIndex].Bytes())
R[signerIndex].X, R[signerIndex].Y = curve.ScalarMult(
hP.X, hP.Y, alpha.Bytes(),
)
// Compute L_j, R_j for non-signers
for i := (signerIndex + 1) % n; i != signerIndex; i = (i + 1) % n {
// L_j = s_j*G + c_j*P_j
L[i] = computeL(sig.S[i], c[i], ring[i])
// R_j = s_j*H(P_j) + c_j*I
R[i] = computeR(sig.S[i], c[i], ring[i], sig.KeyImage)
}
// Compute challenge
sig.C0 = ChallengeHash(message, L, R)
// Close the ring
cSum := new(big.Int)
for i := 0; i < n; i++ {
if i != signerIndex {
cSum.Add(cSum, c[i])
}
}
c[signerIndex] = new(big.Int).Sub(sig.C0, cSum)
c[signerIndex].Mod(c[signerIndex], curve.N)
// Compute signer's response
sig.S[signerIndex] = new(big.Int).Mul(c[signerIndex], privKey.Big())
sig.S[signerIndex].Sub(alpha, sig.S[signerIndex])
sig.S[signerIndex].Mod(sig.S[signerIndex], curve.N)
return sig, nil
}
```
### Verification Algorithm
```go
func VerifyRing(
message []byte,
sig *RingSignature,
) bool {
n := len(sig.RingPubKeys)
L := make([]*Point, n)
R := make([]*Point, n)
c := make([]*big.Int, n)
c[0] = sig.C0
for i := 0; i < n; i++ {
// Compute L_i = s_i*G + c_i*P_i
L[i] = computeL(sig.S[i], c[i], sig.RingPubKeys[i])
// Compute R_i = s_i*H(P_i) + c_i*I
R[i] = computeR(sig.S[i], c[i], sig.RingPubKeys[i], sig.KeyImage)
// Compute next challenge
if i < n-1 {
c[i+1] = ChallengeHash(message, L[i], R[i])
}
}
// Verify ring closure
finalChallenge := ChallengeHash(message, L, R)
return finalChallenge.Cmp(sig.C0) == 0
}
```
## Lattice Integration
### Polynomial Operations
```go
// Efficient polynomial multiplication using NTT
func PolyMul(r *ring.Ring, a, b, c ring.Poly) {
// Convert to NTT domain
r.NTT(a, a)
r.NTT(b, b)
// Component-wise multiplication
r.MulCoeffsMontgomery(a, b, c)
// Convert back from NTT
r.INTT(c, c)
}
// Gaussian sampling for error polynomials
func SampleGaussianPoly(r *ring.Ring, sigma float64) ring.Poly {
sampler := ring.NewGaussianSampler(
prng, r,
ring.DiscreteGaussian{Sigma: sigma},
false,
)
poly := r.NewPoly()
sampler.Read(poly)
return poly
}
```
### Threshold Signatures
```go
// Distributed signature generation
type ThresholdSigner struct {
Parties []*Party
Threshold int
PublicKey structs.Vector[ring.Poly]
}
func (ts *ThresholdSigner) Sign(
message []byte,
signers []int,
) (*ThresholdSignature, error) {
if len(signers) < ts.Threshold {
return nil, ErrInsufficientSigners
}
// Round 1: Generate partial signatures
round1Data := make(map[int]Round1Message)
for _, id := range signers {
data := ts.Parties[id].SignRound1(...)
round1Data[id] = data
}
// Round 2: Aggregate and compute challenge
round2Data := make(map[int]Round2Message)
for _, id := range signers {
data := ts.Parties[id].SignRound2(round1Data)
round2Data[id] = data
}
// Round 3: Generate final signature
signature := ts.combinePartialSignatures(round2Data)
return signature, nil
}
```
## Network Protocol
### Message Types
```go
type MessageType uint8
const (
MsgKeyGenInit MessageType = iota
MsgKeyGenShare
MsgSignRound1
MsgSignRound2
MsgSignRound3
MsgAbort
)
type NetworkMessage struct {
Type MessageType
SessionID []byte
PartyID int
Data []byte
MAC []byte
}
```
### Communication Layer
```go
func (p *Party) Broadcast(msg NetworkMessage) error {
// Add MAC for authentication
msg.MAC = p.computeMAC(msg)
// Send to all parties
for _, peer := range p.peers {
if err := peer.Send(msg); err != nil {
return err
}
}
return nil
}
func (p *Party) ReceiveMessages(
expectedType MessageType,
timeout time.Duration,
) (map[int]NetworkMessage, error) {
messages := make(map[int]NetworkMessage)
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
msg, err := p.network.Receive()
if err != nil {
continue
}
// Verify MAC
if !p.verifyMAC(msg) {
return nil, ErrInvalidMAC
}
// Check message type
if msg.Type != expectedType {
return nil, ErrUnexpectedMessage
}
messages[msg.PartyID] = msg
if len(messages) == len(p.peers) {
break
}
}
return messages, nil
}
```
## Security Considerations
### Memory Security
```go
// Secure memory handling
func (p *PrivateKey) Clear() {
// Overwrite private key material
bytes := p.Bytes()
for i := range bytes {
bytes[i] = 0
}
runtime.SetFinalizer(p, nil)
}
// Use defer for cleanup
func sensitiveOperation() {
privKey := generatePrivateKey()
defer privKey.Clear()
// Perform operations
// ...
}
```
### Randomness Quality
```go
// Always use crypto/rand for security-critical operations
import "crypto/rand"
func generateSecureRandom(size int) ([]byte, error) {
bytes := make([]byte, size)
_, err := rand.Read(bytes)
if err != nil {
return nil, fmt.Errorf("random generation failed: %w", err)
}
return bytes, nil
}
// Deterministic randomness for reproducibility
func deterministicRandom(seed []byte) *DeterministicRNG {
h := sha256.Sum256(seed)
return &DeterministicRNG{
state: h[:],
}
}
```
### Constant-Time Operations
```go
// Avoid timing leaks
func constantTimeCompare(a, b []byte) bool {
if len(a) != len(b) {
return false
}
var result byte
for i := 0; i < len(a); i++ {
result |= a[i] ^ b[i]
}
return result == 0
}
// Constant-time selection
func constantTimeSelect(v, a, b *big.Int) *big.Int {
// v = 1 -> return a
// v = 0 -> return b
mask := new(big.Int).Sub(v, big.NewInt(1))
mask.Not(mask)
result := new(big.Int)
result.And(a, mask)
tmp := new(big.Int)
tmp.Not(mask)
tmp.And(b, tmp)
result.Or(result, tmp)
return result
}
```
## Testing Strategy
### Unit Tests
```go
func TestRingSignature(t *testing.T) {
// Setup
ringSize := 16
ring := generateTestRing(ringSize)
signerIndex := 7
privKey := testPrivateKeys[signerIndex]
message := []byte("test message")
// Sign
sig, err := SignRing(message, ring, signerIndex, privKey)
require.NoError(t, err)
// Verify
valid := VerifyRing(message, sig)
assert.True(t, valid)
// Test linkability
sig2, _ := SignRing([]byte("another message"), ring, signerIndex, privKey)
assert.Equal(t, sig.KeyImage, sig2.KeyImage)
}
```
### Benchmarks
```go
func BenchmarkRingSign16(b *testing.B) {
ring := generateTestRing(16)
privKey := generatePrivateKey()
message := []byte("benchmark message")
b.ResetTimer()
for i := 0; i < b.N; i++ {
SignRing(message, ring, 0, privKey)
}
}
func BenchmarkRingVerify16(b *testing.B) {
ring := generateTestRing(16)
sig := generateTestSignature(ring)
message := []byte("benchmark message")
b.ResetTimer()
for i := 0; i < b.N; i++ {
VerifyRing(message, sig)
}
}
```
### Integration Tests
```go
func TestThresholdSigningProtocol(t *testing.T) {
// Setup threshold parameters
n := 7 // total parties
threshold := 5 // threshold
// Initialize parties
parties := setupParties(n, threshold)
// Select signers (must be >= threshold)
signers := []int{0, 2, 3, 4, 6}
// Run protocol
message := []byte("threshold test")
sig, err := runThresholdProtocol(parties, signers, message)
require.NoError(t, err)
assert.True(t, verifyThresholdSignature(message, sig))
}
```
## Deployment
### Library Usage
```go
import "github.com/luxfi/corona"
// Initialize Corona
rt := corona.New(corona.Config{
RingSize: 16,
Algorithm: corona.AlgoSchnorr,
HashFunction: sha256.New,
Curve: elliptic.P256(),
})
// Generate keys
pub, priv, _ := rt.GenerateKeyPair()
// Create ring signature
ring := rt.SelectRing(pub, 15) // 15 decoys + 1 signer
sig, _ := rt.Sign(message, ring, priv)
// Verify signature
valid := rt.Verify(message, sig)
```
### Configuration Options
```go
type Config struct {
// Ring parameters
RingSize int // Number of ring members
Algorithm Algorithm // Signature algorithm
// Lattice parameters
PolyDegree int // Polynomial degree (power of 2)
Modulus *big.Int // Ring modulus
ErrorStdDev float64 // Gaussian error standard deviation
// Threshold parameters
TotalParties int // Total number of parties
Threshold int // Signing threshold
// Security parameters
SecurityLevel int // Target security level in bits
QuantumSafe bool // Enable post-quantum features
// Performance tuning
ParallelOps bool // Enable parallel operations
CacheSize int // Signature cache size
BatchSize int // Batch verification size
}
```
-39
View File
@@ -1,39 +0,0 @@
---
title: Introduction
description: Corona - Privacy-preserving ring signatures for the Lux blockchain
---
# Corona
## Features
- High performance
- Production ready
- Well tested
- Comprehensive API
## Quick Start
```go
package main
import (
"github.com/luxfi/corona"
)
func main() {
// Your code here
}
```
## Documentation
Coming soon. For now, see the [source code](https://github.com/luxfi/corona).
## Next Steps
- API Reference
- Examples
- Configuration Guide
-440
View File
@@ -1,440 +0,0 @@
---
title: Privacy Guarantees
description: Understanding the privacy properties and security guarantees of Corona
---
# Privacy Guarantees
## Overview
Corona provides strong privacy guarantees through a combination of cryptographic techniques. This document details the privacy properties, threat models, and security guarantees provided by the system.
## Privacy Properties
### 1. Signer Anonymity
**Property**: The identity of the actual signer is hidden among a set of potential signers (the ring).
**Guarantee Level**: **Unconditional**
- Information-theoretic hiding
- No computational assumptions required
- Perfect indistinguishability among ring members
**Mathematical Foundation**:
```
For a ring R = {PK₁, PK₂, ..., PKₙ} and signature σ:
Pr[Signer = PKᵢ | σ] = 1/n for all i ∈ [1,n]
```
### 2. Unlinkability (Within Different Rings)
**Property**: Signatures using different rings cannot be linked to the same signer.
**Guarantee Level**: **Computational**
- Based on Decisional Diffie-Hellman (DDH) assumption
- Quantum resistance through lattice-based alternatives
**Formal Definition**:
```
For signatures σ₁ on ring R₁ and σ₂ on ring R₂:
If R₁ ≠ R₂, then σ₁ and σ₂ are unlinkable
```
### 3. Linkability (Within Same Context)
**Property**: Signatures from the same private key can be detected (preventing double-spending).
**Guarantee Level**: **Cryptographic**
- Deterministic key image generation
- Collision-resistant hash functions
**Key Image Property**:
```
KeyImage = x · H(P) where:
- x is the private key
- P is the public key
- H is a hash-to-point function
Same x → Same KeyImage (always)
Different x → Different KeyImage (with overwhelming probability)
```
### 4. Non-frameability
**Property**: No party can forge a signature that appears to come from another party's private key.
**Guarantee Level**: **Computational**
- Based on discrete logarithm assumption
- Existential unforgeability under chosen message attack (EUF-CMA)
### 5. Forward Privacy
**Property**: Past signatures remain anonymous even if private keys are later compromised.
**Guarantee Level**: **Perfect**
- Historical signatures cannot be de-anonymized
- Key compromise doesn't reveal past signing patterns
## Threat Models
### Passive Adversary
**Capabilities**:
- Observe all signatures on the blockchain
- Analyze transaction patterns
- Collect timing information
**Protection**:
- Ring signatures hide signer identity
- Key images prevent correlation attacks
- Constant-time implementations prevent timing attacks
**Limitations**:
- Cannot determine actual signer from signature
- Cannot link signatures across different rings
- Cannot predict future signatures
### Active Adversary
**Capabilities**:
- Create malicious signatures
- Attempt to forge signatures
- Control some ring members
**Protection**:
- Cryptographic unforgeability
- Threshold requirements for multi-party signatures
- MAC authentication in network protocols
**Attack Scenarios Protected Against**:
1. **Sybil Attacks**: Controlling multiple ring members doesn't break anonymity
2. **Chosen Ring Attacks**: Adversary cannot force specific ring compositions
3. **Replay Attacks**: Unique challenges prevent signature replay
### Quantum Adversary
**Capabilities**:
- Shor's algorithm for discrete logarithm
- Grover's algorithm for search problems
- Unlimited classical computation
**Protection (Hybrid Mode)**:
- Lattice-based signatures (quantum-resistant)
- Increased key sizes for Grover resistance
- Post-quantum key exchange protocols
**Security Levels**:
| Component | Classical | Post-Quantum |
|-----------|-----------|--------------|
| Ring Signatures | 128-bit | 64-bit |
| Lattice Signatures | 256-bit | 128-bit |
| Hybrid Mode | 256-bit | 128-bit |
## Anonymity Set Analysis
### Ring Size Impact
The anonymity set size directly affects privacy:
| Ring Size | Anonymity | Storage Overhead | Verification Time |
|-----------|-----------|------------------|-------------------|
| 4 | 2 bits | 128 bytes | 0.5 ms |
| 8 | 3 bits | 256 bytes | 1.0 ms |
| 16 | 4 bits | 512 bytes | 1.8 ms |
| 32 | 5 bits | 1024 bytes | 3.5 ms |
| 64 | 6 bits | 2048 bytes | 7.0 ms |
**Recommended Minimum**: 16 members (4 bits of anonymity)
### Temporal Analysis Resistance
**Ring Member Selection Strategy**:
```go
func SelectRingMembers(currentHeight int) []*PublicKey {
// Recent outputs (50%)
recent := selectFromRange(currentHeight-100, currentHeight)
// Medium-term outputs (30%)
medium := selectFromRange(currentHeight-1000, currentHeight-100)
// Historical outputs (20%)
historical := selectFromRange(0, currentHeight-1000)
return shuffle(append(recent, medium, historical...))
}
```
### Statistical Disclosure Attacks
**Protection Measures**:
1. **Uniform Distribution**: Ring members selected uniformly
2. **Output Mixing**: Include outputs from different time periods
3. **Value Similarity**: Select outputs with similar values
4. **Churn Prevention**: Limit frequency of ring reuse
## Information Leakage Analysis
### What IS Revealed
1. **Key Image**: Unique identifier for double-spend detection
2. **Ring Members**: The set of possible signers
3. **Message**: The signed data (unless encrypted)
4. **Timestamp**: When signature was created
### What is NOT Revealed
1. **Actual Signer**: Hidden among ring members
2. **Private Key**: No information about secret key
3. **Link Between Different Rings**: Unlinkable across contexts
4. **Transaction Amount**: Can be hidden with Pedersen commitments
### Metadata Protection
**Network-Level Privacy**:
```go
// Use Tor/I2P for transaction broadcast
func BroadcastTransaction(tx *Transaction) error {
// Route through privacy network
if config.UseTor {
return broadcastViaTor(tx)
}
// Add timing jitter
delay := randomDelay(0, 60*time.Second)
time.Sleep(delay)
// Broadcast to random subset of peers
peers := selectRandomPeers(8)
return broadcastToPeers(tx, peers)
}
```
## Cryptographic Assumptions
### Classical Security
**Discrete Logarithm Problem (DLP)**:
- Given: `P = xG`
- Find: `x`
- Hardness: 2^128 operations for 256-bit curves
**Decisional Diffie-Hellman (DDH)**:
- Distinguish: `(G, xG, yG, xyG)` from `(G, xG, yG, zG)`
- Required for: Unlinkability between rings
**Hash Function Properties**:
- Collision resistance: Cannot find `x ≠ y` where `H(x) = H(y)`
- Preimage resistance: Given `h`, cannot find `x` where `H(x) = h`
- Second preimage resistance: Given `x`, cannot find `y ≠ x` where `H(x) = H(y)`
### Post-Quantum Security
**Ring Learning With Errors (Ring-LWE)**:
- Given: `(A, As + e)` for small error `e`
- Find: Secret `s`
- Hardness: Exponential in lattice dimension
**Module Learning With Errors (Module-LWE)**:
- Generalization of Ring-LWE
- Used in NIST standardized algorithms
- Security parameter: 128-256 bits post-quantum
## Implementation Security
### Side-Channel Resistance
**Timing Attack Prevention**:
```go
// Constant-time scalar multiplication
func constantTimeScalarMult(k *big.Int, P *Point) *Point {
// Always perform same number of operations
result := IdentityPoint()
temp := P.Copy()
for i := 0; i < 256; i++ {
bit := k.Bit(i)
// Conditional move, not branch
result = conditionalAdd(result, temp, bit)
temp = temp.Double()
}
return result
}
```
**Power Analysis Protection**:
```go
// Randomized computation order
func protectedSign(msg []byte, ring []*PublicKey) *Signature {
// Random blinding factor
blind := randomScalar()
// Shuffle computation order
order := randomPermutation(len(ring))
// Process in random order with blinding
for _, idx := range order {
processRingMember(idx, blind)
}
// Remove blinding
return unblind(signature, blind)
}
```
### Memory Security
**Secure Cleanup**:
```go
// Zero memory after use
func (sk *PrivateKey) Clear() {
bytes := sk.Bytes()
// Overwrite multiple times
for i := 0; i < 3; i++ {
for j := range bytes {
bytes[j] = byte(rand.Intn(256))
}
}
// Final zero
for j := range bytes {
bytes[j] = 0
}
// Prevent compiler optimization
runtime.KeepAlive(bytes)
}
```
## Privacy Best Practices
### For Developers
1. **Ring Selection**:
- Use sufficient ring size (≥16)
- Randomize ring member selection
- Include diverse temporal distribution
2. **Key Management**:
- Generate fresh keys for each identity
- Secure key storage (HSM/TEE)
- Regular key rotation
3. **Network Privacy**:
- Use Tor/I2P for broadcast
- Add random delays
- Avoid correlatable patterns
### For Users
1. **Operational Security**:
- Don't reuse addresses
- Avoid temporal patterns
- Use privacy-preserving networks
2. **Ring Hygiene**:
- Verify ring size before signing
- Check ring member diversity
- Avoid rings with compromised keys
3. **Metadata Protection**:
- Randomize transaction timing
- Use different nodes for broadcast
- Avoid correlatable amounts
## Formal Security Proofs
### Theorem 1: Signer Anonymity
**Statement**: For any PPT adversary A, the advantage in identifying the actual signer is negligible.
**Proof Sketch**:
1. Ring signature is perfectly hiding
2. All ring members equally likely
3. Information-theoretic indistinguishability
### Theorem 2: Unforgeability
**Statement**: Under the DL assumption, no PPT adversary can forge a valid signature without the private key.
**Proof Sketch**:
1. Reduction to discrete logarithm problem
2. Forger implies DL solver
3. Contradiction with DL hardness
### Theorem 3: Linkability
**Statement**: Signatures from the same key produce identical key images with probability 1.
**Proof**:
1. Key image `I = xH(P)` is deterministic
2. Same `x` always produces same `I`
3. Different `x` produces different `I` (except negligible probability)
## Audit and Compliance
### Selective Disclosure
**View Keys**:
```go
type ViewKey struct {
KeyImage *KeyImage
PrivateView *big.Int
}
// Allow auditor to verify specific signatures
func (vk *ViewKey) VerifyOwnership(sig *RingSignature) bool {
return vk.KeyImage.Equal(sig.KeyImage)
}
```
### Compliance Features
1. **Time-locked Disclosure**: Keys revealed after specific time
2. **Threshold Disclosure**: Multiple parties required for reveal
3. **Regulatory Reporting**: Aggregate statistics without individual privacy loss
### Zero-Knowledge Proofs
**Proof of Assets**:
```go
// Prove ownership without revealing which signatures
func ProveAssets(amount *big.Int, signatures []*RingSignature) *ZKProof {
// Generate commitment to total
commitment := PedersenCommit(amount)
// Create range proof
rangeProof := BulletproofRange(amount)
// Link to signatures without revealing which
ownershipProof := ProveRingOwnership(signatures)
return &ZKProof{
Commitment: commitment,
Range: rangeProof,
Ownership: ownershipProof,
}
}
```
## Future Enhancements
### Advanced Privacy Features
1. **Stealth Addresses**: One-time addresses for receivers
2. **Confidential Assets**: Hide asset types
3. **Private Smart Contracts**: Compute on encrypted data
4. **Coinjoin Integration**: Additional mixing layer
### Research Directions
1. **Sublinear Ring Signatures**: O(log n) verification
2. **Updatable Anonymity Sets**: Dynamic ring membership
3. **Cross-Chain Privacy**: Universal anonymity pools
4. **Quantum-Safe Variants**: Full post-quantum security
## Conclusion
Corona provides strong, provable privacy guarantees suitable for financial privacy applications. The combination of ring signatures for anonymity, key images for double-spend prevention, and lattice cryptography for post-quantum security creates a robust privacy system resistant to current and future threats.
-209
View File
@@ -1,209 +0,0 @@
---
title: Ring Signatures
description: Understanding Corona's ring signature implementation for privacy-preserving transactions
---
# Ring Signatures in Corona
## Overview
Corona implements **linkable ring signatures** based on the Schnorr signature scheme, providing transaction privacy while maintaining the ability to detect double-spending. This cryptographic primitive enables users to prove membership in a group without revealing their specific identity.
## Key Concepts
### Anonymity Set
The **ring** consists of multiple public keys where:
- One key belongs to the actual signer
- Other keys are "decoys" that provide plausible deniability
- Default ring size: 16 members (configurable)
- Larger rings provide stronger privacy but increase computational cost
### Linkability
While ring signatures hide the signer's identity, linkability ensures:
- The same private key cannot sign twice for the same context
- Double-spending prevention in cryptocurrency applications
- Key images uniquely identify signatures from the same private key
## Mathematical Foundation
### Core Components
```go
// Ring signature structure
type RingSignature struct {
C0 *big.Int // Initial challenge
S []*big.Int // Response values for each ring member
KeyImage *Point // Unique identifier preventing double-signing
RingPubKeys []*PublicKey // Public keys forming the ring
}
```
### Algorithm Overview
1. **Key Image Generation**: `I = x * H(P)` where:
- `x` is the signer's private key
- `P` is the signer's public key
- `H()` is a hash-to-curve function
2. **Ring Construction**: Aggregate public keys from:
- The actual signer
- Randomly selected decoy keys
- Order is randomized to hide signer position
3. **Signature Generation**:
- Generate random nonces for each ring member
- Compute challenges using hash chain
- Create responses that satisfy verification equation
4. **Verification**: Check that:
- All responses are valid
- Challenge chain closes properly
- Key image is well-formed
## Implementation Details
### Signature Size
- Base size: 32 bytes × ring size
- Default (16 members): 512 bytes
- Scales linearly with ring size
### Performance Characteristics
- **Sign time**: O(n) where n = ring size
- **Verify time**: O(n)
- **Space complexity**: O(n)
### Security Parameters
- **Curve**: secp256k1 or Ed25519
- **Hash function**: SHA-256
- **Challenge size**: 256 bits
- **Response size**: 256 bits per ring member
## Integration with Lattice Cryptography
Corona uniquely combines ring signatures with lattice-based cryptography from the Lattice library:
```go
import (
"github.com/luxfi/lattice/v6/ring"
"github.com/luxfi/lattice/v6/utils/sampling"
)
```
### Polynomial Ring Operations
- Uses polynomial rings for efficient modular arithmetic
- NTT (Number Theoretic Transform) for fast polynomial multiplication
- Gaussian sampling for noise generation
### Threshold Signatures
- Shamir secret sharing for distributed key generation
- `t-of-n` threshold schemes supported
- Secure multiparty computation protocols
## Privacy Guarantees
### Unconditional Anonymity
- **Signer ambiguity**: Equal probability for each ring member
- **Perfect hiding**: No information theoretic advantage
- **Forward secrecy**: Past signatures remain anonymous even if keys are compromised
### Resistance to Analysis
- **Timing attacks**: Constant-time implementations
- **Side channels**: Protected against power analysis
- **Blockchain analysis**: Ring signatures break transaction graph analysis
## Use Cases in Q-Chain
### Private Transactions
- Hide sender identity in value transfers
- Preserve receiver privacy through stealth addresses
- Maintain public verifiability of transaction validity
### Confidential Smart Contracts
- Anonymous voting systems
- Private auctions
- Confidential DeFi operations
### Regulatory Compliance
- Optional view keys for authorized auditing
- Selective disclosure capabilities
- Compliance with privacy regulations
## Best Practices
### Ring Selection
1. **Size considerations**:
- Minimum: 8 members for basic privacy
- Recommended: 16 members for strong privacy
- Maximum: 64 members (performance consideration)
2. **Member selection**:
- Random sampling from active users
- Temporal proximity (recent transactions)
- Value similarity (similar transaction amounts)
### Key Management
- Secure storage of private keys
- Regular key rotation for long-term privacy
- Backup strategies for key recovery
### Performance Optimization
- Cache polynomial operations
- Batch verification for multiple signatures
- Parallel signature generation
## Security Considerations
### Known Attacks and Mitigations
1. **Key image analysis**: Use deterministic key image generation
2. **Ring intersection attacks**: Ensure sufficient ring overlap
3. **Timing analysis**: Implement constant-time operations
4. **Quantum threats**: Combined with post-quantum signatures
### Audit Trail
- Key images provide spending auditability
- Optional transaction memos for compliance
- Cryptographic proofs of non-double-spending
## Code Example
```go
// Generate a ring signature
func SignWithRing(message []byte, privateKey *PrivateKey, ring []*PublicKey) (*RingSignature, error) {
// Generate key image
keyImage := GenerateKeyImage(privateKey)
// Create signature components
sig := &RingSignature{
KeyImage: keyImage,
RingPubKeys: ring,
S: make([]*big.Int, len(ring)),
}
// Generate signature using Schnorr-based ring signature
// ... (implementation details)
return sig, nil
}
// Verify a ring signature
func VerifyRingSignature(message []byte, sig *RingSignature) bool {
// Verify challenge chain
// Check key image validity
// Validate responses
return valid
}
```
## Future Enhancements
### Planned Features
- **Bulletproofs integration**: Confidential amounts with ring signatures
- **Sublinear ring signatures**: Logarithmic signature size
- **Multi-ring signatures**: Cross-chain privacy
- **Zero-knowledge range proofs**: Amount privacy
### Research Directions
- Post-quantum ring signatures
- Efficient batch verification
- Ring signature aggregation
- Threshold ring signatures
-299
View File
@@ -1,299 +0,0 @@
---
title: Cryptographic Theory
description: Mathematical foundations of linkable ring signatures and lattice-based cryptography
---
# Cryptographic Theory
## Overview
Corona combines two powerful cryptographic primitives: **linkable ring signatures** for privacy and **lattice-based cryptography** for post-quantum security. This unique combination provides both strong privacy guarantees and resistance to quantum attacks.
## Ring Signature Mathematics
### Schnorr Signature Foundation
Corona's ring signatures are based on the Schnorr signature scheme, which provides:
- **Simplicity**: Elegant mathematical structure
- **Security**: Proven secure under discrete logarithm assumption
- **Efficiency**: Fast signature generation and verification
#### Standard Schnorr Signature
For a message `m`, private key `x`, and public key `P = xG`:
1. **Sign**:
- Choose random `k ∈ Zq`
- Compute `R = kG`
- Compute `e = H(R || P || m)`
- Compute `s = k + ex`
- Signature: `σ = (R, s)`
2. **Verify**:
- Check: `sG = R + eP`
### Extension to Ring Signatures
Ring signatures extend Schnorr signatures to hide the signer among a ring of public keys.
#### Ring Signature Generation
Given:
- Message `m`
- Private key `xi` with public key `Pi`
- Ring of public keys `{P0, P1, ..., Pn-1}`
Algorithm:
```
1. Generate key image: I = xi * H(Pi)
2. For j ≠ i:
- Choose random sj ∈ Zq
- Choose random cj ∈ Zq
3. Choose random α ∈ Zq
4. Compute:
- Li = αG
- Ri = α * H(Pi)
5. For j = i+1, ..., n-1, 0, ..., i-1:
- Lj = sjG + cjPj
- Rj = sjH(Pj) + cjI
6. Compute challenge:
c0 = H(m || L0 || ... || Ln-1 || R0 || ... || Rn-1)
7. Close the ring:
ci = c0 - Σ(j≠i) cj
si = α - cixi
8. Output: σ = (I, c0, s0, ..., sn-1)
```
#### Ring Signature Verification
Given signature `σ = (I, c0, s0, ..., sn-1)`:
```
1. For j = 0, ..., n-1:
- Compute Lj' = sjG + cjPj
- Compute Rj' = sjH(Pj) + cjI
2. Verify: c0 = H(m || L0' || ... || Ln-1' || R0' || ... || Rn-1')
```
### Linkability Property
The **key image** `I = x * H(P)` ensures linkability:
- Deterministic for a given private key
- Cannot be forged without knowledge of `x`
- Two signatures with the same `I` indicate double-signing
This property is crucial for preventing double-spending in cryptocurrency applications.
## Lattice-Based Cryptography
### Polynomial Rings
Corona leverages polynomial ring operations from the Lattice library:
#### Ring Definition
The ring `R = Z[X]/(X^n + 1)` where:
- `n` is a power of 2 (typically 2^12 to 2^14)
- Operations are performed modulo `q` (prime or power of prime)
#### Why Polynomial Rings?
1. **Efficiency**: NTT enables O(n log n) multiplication
2. **Security**: Based on Ring-LWE problem
3. **Structure**: Natural for threshold cryptography
### Number Theoretic Transform (NTT)
NTT is the finite field analogue of FFT:
```
Forward NTT: a(X) → â = NTT(a)
Inverse NTT: â → a(X) = NTT^(-1)(â)
Multiplication: a(X) * b(X) = NTT^(-1)(NTT(a) ⊙ NTT(b))
```
Where `⊙` denotes component-wise multiplication.
### Ring-LWE Problem
The security of lattice operations is based on the Ring Learning With Errors (Ring-LWE) problem:
Given `(A, b = As + e)` where:
- `A` is a random polynomial matrix
- `s` is a secret polynomial vector
- `e` is a small error polynomial
It is computationally hard to recover `s`.
## Threshold Signatures
### Shamir Secret Sharing
Corona implements `(t, n)` threshold signatures using polynomial secret sharing:
#### Share Generation
For secret `s` and threshold `t`:
1. Generate random polynomial `f(x) = s + a₁x + ... + aₜ₋₁x^(t-1)`
2. Compute shares: `sᵢ = f(i)` for `i = 1, ..., n`
3. Any `t` shares can reconstruct `s` using Lagrange interpolation
#### Lagrange Interpolation
```
s = Σᵢ sᵢ * λᵢ
where λᵢ = Π(j≠i) (j/(j-i))
```
### Distributed Key Generation (DKG)
Corona supports distributed key generation without trusted dealer:
1. **Share Distribution**: Each party generates and distributes shares
2. **Verification**: Feldman VSS ensures share validity
3. **Aggregation**: Combine shares to form distributed key
4. **Threshold Signing**: `t` parties collaborate to sign
## Security Analysis
### Privacy Guarantees
#### Unconditional Anonymity
- **Information-theoretic hiding**: Even computationally unbounded adversary cannot identify signer
- **Perfect indistinguishability**: All ring members equally likely
- **Statistical distance**: Negligible between different signers
#### Unforgeability
Under the discrete logarithm assumption:
- Cannot forge signature without private key
- Cannot create valid key image without secret
- Collision-resistant hash functions prevent replay
### Quantum Resistance
#### Post-Quantum Security Levels
| Algorithm | Classical Security | Quantum Security |
|-----------|-------------------|------------------|
| Ring Signatures (256-bit) | 128 bits | 64 bits |
| Ring-LWE (n=4096, q≈2^128) | 256 bits | 128 bits |
| Hybrid Mode | 256 bits | 128 bits |
#### Quantum Attack Vectors
1. **Grover's Algorithm**: √n speedup for discrete log
- Mitigation: Double key sizes
2. **Shor's Algorithm**: Polynomial time for discrete log
- Mitigation: Lattice-based alternatives
3. **Hybrid Approach**: Combine classical and post-quantum
- Current signatures remain valid
- Future signatures gain quantum resistance
## Performance Analysis
### Computational Complexity
| Operation | Ring Signature | Lattice Operations |
|-----------|---------------|-------------------|
| Key Generation | O(1) | O(n log n) |
| Sign | O(r) | O(n log n) |
| Verify | O(r) | O(n log n) |
| Key Image | O(1) | N/A |
Where:
- `r` = ring size
- `n` = polynomial degree
### Space Complexity
| Component | Size |
|-----------|------|
| Public Key | 32 bytes |
| Private Key | 32 bytes |
| Ring Signature | 32 + 32r bytes |
| Lattice Signature | ~10 KB |
| Key Image | 32 bytes |
### Benchmark Results
On Apple M1 Pro:
- **Ring Sign (16 members)**: 2.1 ms
- **Ring Verify (16 members)**: 1.8 ms
- **Lattice Sign**: 0.8 ms
- **Lattice Verify**: 0.4 ms
- **Hybrid Sign**: 2.9 ms
- **Hybrid Verify**: 2.2 ms
## Advanced Topics
### Bulletproofs Integration
Corona can be extended with Bulletproofs for:
- **Confidential amounts**: Hide transaction values
- **Range proofs**: Prove values are in valid range
- **Aggregation**: Combine multiple proofs
### Sublinear Ring Signatures
Future enhancement using techniques like:
- **LSAG**: Linkable Spontaneous Anonymous Group signatures
- **Omniring**: O(log n) verification time
- **RingCT 3.0**: Logarithmic size signatures
### Cross-Chain Privacy
Multi-ring signatures for:
- **Atomic swaps**: Private cross-chain exchanges
- **Bridge privacy**: Hide cross-chain transfers
- **Universal anonymity**: Single anonymity set across chains
## Implementation Considerations
### Side-Channel Protection
1. **Constant-time operations**: No data-dependent branches
2. **Memory access patterns**: Independent of secret data
3. **Power analysis**: Randomized computation order
4. **Cache timing**: Preload all ring members
### Random Number Generation
Critical for security:
```go
// Use crypto/rand for security-critical randomness
import "crypto/rand"
func generateNonce() (*big.Int, error) {
max := new(big.Int).Sub(curve.N, big.NewInt(1))
k, err := rand.Int(rand.Reader, max)
if err != nil {
return nil, err
}
return k, nil
}
```
### Error Handling
Proper error propagation without leaking information:
- Generic error messages
- Timing-independent error paths
- No correlation between errors and secrets
## References
### Academic Papers
1. "Linkable Spontaneous Anonymous Group Signature" - Liu et al.
2. "Ring Confidential Transactions" - Noether et al.
3. "Lattice-based Zero-Knowledge Proofs" - Lyubashevsky
4. "Post-Quantum Ring Signatures" - Torres et al.
### Standards
- NIST Post-Quantum Cryptography
- IETF Ring Signatures Draft
- ISO/IEC 29192-7 Lightweight Cryptography
### Implementation Resources
- Monero RingCT
- Lattice Cryptography Library
- Stanford IBE Implementation
- Microsoft SEAL Library
-730
View File
@@ -1,730 +0,0 @@
---
title: Usage Examples
description: Practical examples and code samples for using Corona
---
# Usage Examples
## Getting Started
### Installation
```bash
# Install Corona library
go get github.com/luxfi/corona
# Install dependencies
go get github.com/luxfi/lattice/v6
```
### Basic Setup
```go
package main
import (
"fmt"
"log"
"github.com/luxfi/corona"
"github.com/luxfi/corona/primitives"
"github.com/luxfi/corona/sign"
)
func main() {
// Initialize Corona with default configuration
rt := corona.New(corona.DefaultConfig())
fmt.Println("Corona initialized successfully")
}
```
## Simple Ring Signature
### Generate Keys and Create Signature
```go
package main
import (
"crypto/rand"
"fmt"
"log"
"math/big"
)
func simpleRingSignatureExample() {
// 1. Generate key pairs for ring members
ringSize := 16
publicKeys := make([]*PublicKey, ringSize)
// Generate keys for all ring members
var signerPrivKey *PrivateKey
signerIndex := 7 // The actual signer will be at index 7
for i := 0; i < ringSize; i++ {
pub, priv, err := GenerateKeyPair()
if err != nil {
log.Fatal(err)
}
publicKeys[i] = pub
// Keep the private key for the actual signer
if i == signerIndex {
signerPrivKey = priv
}
}
// 2. Create a message to sign
message := []byte("Transfer 100 LUX to address xyz")
// 3. Generate the ring signature
signature, err := SignRing(
message,
publicKeys,
signerIndex,
signerPrivKey,
)
if err != nil {
log.Fatal(err)
}
// 4. Verify the signature
valid := VerifyRing(message, signature)
fmt.Printf("Signature valid: %v\n", valid)
// 5. Check signature size
sigSize := signature.Size()
fmt.Printf("Signature size: %d bytes\n", sigSize)
// 6. Demonstrate linkability
message2 := []byte("Another transaction")
signature2, _ := SignRing(message2, publicKeys, signerIndex, signerPrivKey)
// Both signatures have the same key image
if signature.KeyImage.Equal(signature2.KeyImage) {
fmt.Println("Signatures are linkable (same signer)")
}
}
```
## Privacy-Preserving Transaction
### Confidential Transfer with Ring Signatures
```go
type ConfidentialTransaction struct {
Inputs []TxInput
Outputs []TxOutput
RingSize int
Signatures []*RingSignature
}
type TxInput struct {
Amount uint64
KeyImage *KeyImage
RingMembers []*PublicKey
}
type TxOutput struct {
Amount uint64
Recipient *PublicKey
Ephemeral *PublicKey // For stealth address
}
func createConfidentialTransaction() (*ConfidentialTransaction, error) {
// 1. Select inputs (previous outputs we own)
inputs := []TxInput{
{
Amount: 100,
KeyImage: nil, // Will be set by signature
},
}
// 2. Create ring for input
ringSize := 16
ring := selectRingMembers(ringSize)
inputs[0].RingMembers = ring
// 3. Create outputs with stealth addresses
outputs := []TxOutput{
{
Amount: 90, // Send 90
Recipient: generateStealthAddress(recipientPubKey),
},
{
Amount: 10, // Change
Recipient: generateStealthAddress(ownPubKey),
},
}
// 4. Create transaction
tx := &ConfidentialTransaction{
Inputs: inputs,
Outputs: outputs,
RingSize: ringSize,
}
// 5. Sign each input with ring signature
for i, input := range tx.Inputs {
message := tx.HashForSigning(i)
sig, err := SignRing(
message,
input.RingMembers,
myIndex,
myPrivKey,
)
if err != nil {
return nil, err
}
tx.Signatures = append(tx.Signatures, sig)
tx.Inputs[i].KeyImage = sig.KeyImage
}
return tx, nil
}
func (tx *ConfidentialTransaction) Verify() bool {
// 1. Check balance (inputs = outputs)
if !tx.checkBalance() {
return false
}
// 2. Verify each ring signature
for i, sig := range tx.Signatures {
message := tx.HashForSigning(i)
if !VerifyRing(message, sig) {
return false
}
}
// 3. Check for double-spending (unique key images)
keyImages := make(map[string]bool)
for _, input := range tx.Inputs {
ki := input.KeyImage.String()
if keyImages[ki] {
return false // Double spend detected
}
keyImages[ki] = true
}
return true
}
```
## Threshold Ring Signatures
### Multi-Party Signing Protocol
```go
func thresholdRingSignatureExample() error {
// Setup: 3-of-5 threshold with 16-member ring
n := 5 // Total parties
threshold := 3 // Minimum signers
ringSize := 16
// 1. Initialize parties
parties := make([]*sign.Party, n)
for i := 0; i < n; i++ {
parties[i] = initializeParty(i)
}
// 2. Distributed Key Generation (DKG)
fmt.Println("Starting DKG protocol...")
publicKey, keyShares, err := runDKG(parties)
if err != nil {
return fmt.Errorf("DKG failed: %w", err)
}
fmt.Printf("Group public key generated: %x\n", publicKey.Bytes())
// 3. Distribute key shares to parties
for i, party := range parties {
party.SetKeyShare(keyShares[i])
}
// 4. Select subset of parties for signing (must be >= threshold)
signers := []int{0, 2, 4} // Parties 0, 2, and 4 will sign
// 5. Create ring with decoy members
ring := make([]*PublicKey, ringSize)
ring[0] = publicKey // Group's public key
for i := 1; i < ringSize; i++ {
ring[i] = generateDecoyKey()
}
// 6. Execute threshold signing protocol
message := []byte("Threshold signed message")
signature, err := executeThresholdSigning(
message,
ring,
parties,
signers,
threshold,
)
if err != nil {
return fmt.Errorf("threshold signing failed: %w", err)
}
// 7. Verify the threshold ring signature
valid := VerifyThresholdRingSignature(message, signature)
fmt.Printf("Threshold ring signature valid: %v\n", valid)
return nil
}
func executeThresholdSigning(
message []byte,
ring []*PublicKey,
parties []*sign.Party,
signers []int,
threshold int,
) (*ThresholdRingSignature, error) {
// Round 1: Generate commitments
round1Messages := make(map[int]Round1Message)
for _, id := range signers {
msg, err := parties[id].SignRound1(message, ring)
if err != nil {
return nil, err
}
round1Messages[id] = msg
}
// Broadcast round 1 messages
for _, id := range signers {
parties[id].ReceiveRound1(round1Messages)
}
// Round 2: Generate shares
round2Messages := make(map[int]Round2Message)
for _, id := range signers {
msg, err := parties[id].SignRound2()
if err != nil {
return nil, err
}
round2Messages[id] = msg
}
// Broadcast round 2 messages
for _, id := range signers {
parties[id].ReceiveRound2(round2Messages)
}
// Round 3: Combine shares
var signature *ThresholdRingSignature
for _, id := range signers {
sig, err := parties[id].SignRound3()
if err != nil {
return nil, err
}
if signature == nil {
signature = sig
}
}
return signature, nil
}
```
## Lattice-Based Ring Signatures
### Post-Quantum Secure Implementation
```go
import (
"github.com/luxfi/lattice/v6/ring"
"github.com/luxfi/lattice/v6/utils/sampling"
)
func latticeRingSignatureExample() {
// 1. Setup lattice parameters
n := 4096 // Polynomial degree
q := big.NewInt(0).SetBit(big.NewInt(0), 119, 1) // Prime modulus
r, err := ring.NewRing(n, q)
if err != nil {
log.Fatal(err)
}
// 2. Setup samplers
prng, _ := sampling.NewKeyedPRNG([]byte("seed"))
uniformSampler := ring.NewUniformSampler(prng, r)
gaussianSampler := ring.NewGaussianSampler(
prng, r,
ring.DiscreteGaussian{Sigma: 3.2},
false,
)
// 3. Generate lattice-based keys
ringSize := 8 // Smaller ring due to larger signatures
publicKeys := make([]LatticePublicKey, ringSize)
var signerSecret LatticeSecretKey
signerIndex := 3
for i := 0; i < ringSize; i++ {
pk, sk := generateLatticeKeyPair(r, uniformSampler, gaussianSampler)
publicKeys[i] = pk
if i == signerIndex {
signerSecret = sk
}
}
// 4. Create lattice ring signature
message := []byte("Post-quantum secure message")
sig := createLatticeRingSignature(
r,
message,
publicKeys,
signerIndex,
signerSecret,
)
// 5. Verify signature
valid := verifyLatticeRingSignature(r, message, sig, publicKeys)
fmt.Printf("Lattice ring signature valid: %v\n", valid)
// 6. Check signature size
sigBytes := sig.Serialize()
fmt.Printf("Lattice signature size: %d KB\n", len(sigBytes)/1024)
}
type LatticePublicKey struct {
A structs.Matrix[ring.Poly]
B structs.Vector[ring.Poly]
}
type LatticeSecretKey struct {
S structs.Vector[ring.Poly]
}
func generateLatticeKeyPair(
r *ring.Ring,
uniformSampler *ring.UniformSampler,
gaussianSampler *ring.GaussianSampler,
) (LatticePublicKey, LatticeSecretKey) {
// Generate random matrix A
m, n := 8, 8
A := utils.SamplePolyMatrix(r, m, n, uniformSampler, true, true)
// Generate secret vector s
s := utils.SamplePolyVector(r, n, gaussianSampler, false, false)
// Generate error vector e
e := utils.SamplePolyVector(r, m, gaussianSampler, false, false)
// Compute public key b = As + e
b := utils.InitializeVector(r, m)
utils.MatrixVectorMul(r, A, s, b)
utils.VectorAdd(r, b, e, b)
return LatticePublicKey{A: A, B: b}, LatticeSecretKey{S: s}
}
```
## Integration with Q-Chain
### Using Corona in QuantumVM
```go
// Smart contract using ring signatures
contract PrivacyPool {
mapping(bytes32 => bool) public keyImages;
uint256 public poolBalance;
event Deposit(bytes32 commitment);
event Withdrawal(bytes32 keyImage);
function deposit() external payable {
require(msg.value > 0, "Invalid amount");
// Generate commitment for depositor
bytes32 commitment = keccak256(
abi.encodePacked(msg.sender, msg.value, block.timestamp)
);
poolBalance += msg.value;
emit Deposit(commitment);
}
function withdrawWithRingSignature(
uint256 amount,
bytes memory ringSignature,
bytes32[] memory ringCommitments
) external {
// 1. Verify ring signature
require(
verifyRingSignature(
abi.encode(amount, msg.sender),
ringSignature,
ringCommitments
),
"Invalid ring signature"
);
// 2. Extract and check key image
bytes32 keyImage = extractKeyImage(ringSignature);
require(!keyImages[keyImage], "Double spending");
// 3. Mark key image as used
keyImages[keyImage] = true;
// 4. Transfer funds
require(poolBalance >= amount, "Insufficient pool balance");
poolBalance -= amount;
payable(msg.sender).transfer(amount);
emit Withdrawal(keyImage);
}
function verifyRingSignature(
bytes memory message,
bytes memory signature,
bytes32[] memory ring
) internal pure returns (bool) {
// Call Corona precompile for verification
return ICoronaVerifier(CORONA_PRECOMPILE).verify(
message,
signature,
ring
);
}
}
```
## Performance Benchmarks
### Benchmark Different Configurations
```go
func runBenchmarks() {
configs := []struct {
name string
ringSize int
algorithm string
}{
{"Small Ring (8)", 8, "schnorr"},
{"Medium Ring (16)", 16, "schnorr"},
{"Large Ring (32)", 32, "schnorr"},
{"Lattice Small (4)", 4, "lattice"},
{"Lattice Medium (8)", 8, "lattice"},
{"Hybrid (16)", 16, "hybrid"},
}
for _, cfg := range configs {
fmt.Printf("\n=== %s ===\n", cfg.name)
// Setup
ring := generateRing(cfg.ringSize)
message := []byte("benchmark message")
// Measure signing time
start := time.Now()
sig := sign(message, ring, cfg.algorithm)
signTime := time.Since(start)
// Measure verification time
start = time.Now()
verify(message, sig, cfg.algorithm)
verifyTime := time.Since(start)
// Measure signature size
sigSize := len(sig.Serialize())
fmt.Printf("Sign time: %v\n", signTime)
fmt.Printf("Verify time: %v\n", verifyTime)
fmt.Printf("Signature size: %d bytes\n", sigSize)
fmt.Printf("Size per ring member: %d bytes\n", sigSize/cfg.ringSize)
}
}
// Expected output:
// === Small Ring (8) ===
// Sign time: 1.2ms
// Verify time: 0.9ms
// Signature size: 288 bytes
// Size per ring member: 36 bytes
//
// === Medium Ring (16) ===
// Sign time: 2.1ms
// Verify time: 1.8ms
// Signature size: 544 bytes
// Size per ring member: 34 bytes
//
// === Large Ring (32) ===
// Sign time: 4.2ms
// Verify time: 3.5ms
// Signature size: 1056 bytes
// Size per ring member: 33 bytes
//
// === Lattice Small (4) ===
// Sign time: 3.5ms
// Verify time: 2.1ms
// Signature size: 8192 bytes
// Size per ring member: 2048 bytes
//
// === Hybrid (16) ===
// Sign time: 5.3ms
// Verify time: 3.9ms
// Signature size: 8704 bytes
// Size per ring member: 544 bytes
```
## Error Handling
### Comprehensive Error Handling
```go
func robustRingSignature() error {
// 1. Validate inputs
if len(ring) < MinRingSize {
return fmt.Errorf("ring too small: got %d, need at least %d",
len(ring), MinRingSize)
}
if signerIndex >= len(ring) {
return fmt.Errorf("signer index out of bounds: %d >= %d",
signerIndex, len(ring))
}
// 2. Check for duplicate keys in ring
seen := make(map[string]bool)
for i, pk := range ring {
key := pk.String()
if seen[key] {
return fmt.Errorf("duplicate key at index %d", i)
}
seen[key] = true
}
// 3. Validate private key corresponds to public key
derivedPub := DerivePublicKey(privKey)
if !derivedPub.Equal(ring[signerIndex]) {
return errors.New("private key doesn't match public key in ring")
}
// 4. Sign with timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
sigChan := make(chan *RingSignature)
errChan := make(chan error)
go func() {
sig, err := SignRingWithContext(ctx, message, ring, signerIndex, privKey)
if err != nil {
errChan <- err
} else {
sigChan <- sig
}
}()
select {
case sig := <-sigChan:
// 5. Verify signature before returning
if !VerifyRing(message, sig) {
return errors.New("generated signature failed verification")
}
return nil
case err := <-errChan:
return fmt.Errorf("signing failed: %w", err)
case <-ctx.Done():
return errors.New("signing timeout exceeded")
}
}
```
## Testing Utilities
### Test Helper Functions
```go
// Generate test ring with known keys
func generateTestRing(size int) (*TestRing, error) {
tr := &TestRing{
Size: size,
PublicKeys: make([]*PublicKey, size),
PrivateKeys: make([]*PrivateKey, size),
}
for i := 0; i < size; i++ {
pub, priv, err := GenerateKeyPair()
if err != nil {
return nil, err
}
tr.PublicKeys[i] = pub
tr.PrivateKeys[i] = priv
}
return tr, nil
}
// Test double-spending detection
func testDoubleSpending(t *testing.T) {
ring, _ := generateTestRing(16)
message1 := []byte("first transaction")
message2 := []byte("second transaction")
// Sign two different messages with same key
sig1, _ := SignRing(message1, ring.PublicKeys, 0, ring.PrivateKeys[0])
sig2, _ := SignRing(message2, ring.PublicKeys, 0, ring.PrivateKeys[0])
// Key images should be identical (linkable)
if !sig1.KeyImage.Equal(sig2.KeyImage) {
t.Error("Key images should be identical for same signer")
}
// Create double-spend detector
detector := NewDoubleSpendDetector()
// First signature should be accepted
if !detector.Add(sig1.KeyImage) {
t.Error("First signature should be accepted")
}
// Second signature should be rejected (double-spend)
if detector.Add(sig2.KeyImage) {
t.Error("Second signature should be rejected as double-spend")
}
}
type DoubleSpendDetector struct {
keyImages map[string]bool
mu sync.RWMutex
}
func NewDoubleSpendDetector() *DoubleSpendDetector {
return &DoubleSpendDetector{
keyImages: make(map[string]bool),
}
}
func (d *DoubleSpendDetector) Add(ki *KeyImage) bool {
d.mu.Lock()
defer d.mu.Unlock()
key := ki.String()
if d.keyImages[key] {
return false // Already seen
}
d.keyImages[key] = true
return true
}
```
## Conclusion
These examples demonstrate the versatility and power of Corona for privacy-preserving applications. From simple ring signatures to complex threshold protocols and post-quantum implementations, Corona provides the tools needed for strong privacy guarantees in blockchain and cryptographic applications.
-18
View File
@@ -1,18 +0,0 @@
import { docs } from "@/.source"
import { loader } from "fumadocs-core/source"
// Create a single source instance that is reused
// This prevents circular references and stack overflow issues
let _source: ReturnType<typeof loader> | null = null
export function getSource() {
if (!_source) {
_source = loader({
baseUrl: "/docs",
source: docs.toFumadocsSource(),
})
}
return _source
}
export const source = getSource()
-9
View File
@@ -1,9 +0,0 @@
import type { MDXComponents } from "mdx/types"
import defaultMdxComponents from "fumadocs-ui/mdx"
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...defaultMdxComponents,
...components,
}
}
+389
View File
@@ -0,0 +1,389 @@
# Corona — TEE Integration (proposed)
> Companion to `DEPLOYMENT-RUNBOOK.md §Operational mitigations item 5`
> ("TEE attestation, recommended"). This document specifies the
> attestation boundary, key-isolation contract, and the per-platform
> integration shape — without complecting any of this with the
> Corona cryptographic core.
**Decomplecting rule (load-bearing).** TEE attestation is a single
*layer* sitting outside the cryptographic math:
```
+--------------------------------------------------------------+
| operator policy: which TEE? which key-release predicate? | policy
+--------------------------------------------------------------+
| attestation: evidence -> verifier -> bool | trust
+--------------------------------------------------------------+
| share storage / signing: sealed share -> Round1/Round2/Final | crypto
+--------------------------------------------------------------+
| Corona kernel: 2-round R-LWE signing | math
+--------------------------------------------------------------+
```
The Corona kernel (`sign/`, `threshold/`, `dkg2/`, `reshare/`) MUST
NOT depend on, link against, or branch on TEE state. The TEE layer
is **only** consulted at three lifecycle moments:
1. **Bootstrap-trusted-dealer ceremony**: caller of
`keyera.BootstrapTrustedDealer` decides whether to run inside a
TEE. Corona observes the result via the standard
`BootstrapTranscript` — no API change.
2. **Per-validator share storage**: each validator's `KeyShare`
bytes are sealed under a TEE-bound key. Corona observes the
share via the standard `KeyShare` struct — no API change.
3. **Per-validator signing session**: `Round1`, `Round2`, and
`Finalize` execute inside the TEE. Corona observes the signing
protocol via the standard `(D, MACs)`, `Z`, `Signature` byte
structures — no API change.
There is no `corona.AttestationVerifier` interface, no
`corona.WithTEE(...)` option, no TEE-specific build tag. The
TEE layer is an *operator's deployment concern* and is wired
above Corona via the consensus layer's validator-bootstrap
plumbing.
---
## §1 Threat model addition
In `docs/mptc/threat-model.md §9.2 "Out of scope at this submission"`,
the following items are flagged as **deployment-layer-mitigated** via
TEE:
- Cache-timing side channels
- Power side channels
- EM side channels
- Aggregator-host compromise during signing session
(`DEPLOYMENT-RUNBOOK.md §Trust-model disclosure item 2`)
The TEE integration layer brings these from "not addressed" to
"addressed under the TCB of {SGX, SEV-SNP, TDX, NVIDIA-CC, Apple-SEP}",
with the following residual assumption surface:
| Assumption | What we trust |
|---|---|
| TEE vendor firmware | The CPU/GPU vendor's microcode, BIOS, and signed bootloader. |
| TEE attestation root | The vendor's attestation signing key (Intel IAS, AMD KDS, NVIDIA NRAS, Apple AAS). |
| Reproducible build | The `luxfi/corona` binary measured into the attestation report matches a publicly-published Git SHA at a tagged release. |
| TEE side-channel resistance | The TEE's own side-channel posture — bounded by the public CVE record of the chosen platform (e.g., SGX has a long history of micro-architectural side-channel attacks; SEV-SNP and TDX are more recent). |
The TEE layer trades a TCB inclusion (vendor microcode + attestation
root) for closure of the OS-kernel-compromise and side-channel
threats. Operators MUST evaluate whether this trade is acceptable
for their specific deployment.
## §2 Reproducible build contract
Every Corona release tag (`v0.7.x`) ships:
1. **Source SHA**: the Git SHA of the release commit.
2. **`scripts/build.sh` invocation**: produces the binary
`bin/corona` from the release commit.
3. **Reference-measure manifest**: SHA-256 of `bin/corona` produced
on a pinned builder (`golang:1.26.3-alpine` per `Dockerfile`).
4. **Cross-runtime byte-equality**: `scripts/regen-kats.sh --verify`
against the C++ port at `~/work/luxcpp/crypto/corona/`.
The TEE attestation verifier consumes (1) + (3) and rejects any
report whose measurement does not match the published manifest. The
manifest is published at `https://lux.network/release/corona/v0.7.x/manifest.json`
and signed by the foundation release key.
> **Roadmap (v0.7.6)**: pin the `golang:1.26.3-alpine` builder image
> by digest, not tag, so the reference measure is reproducible
> against a specific OCI image digest.
## §3 Per-platform integration
### §3.1 AMD SEV-SNP (Linux validators)
**Status**: recommended primary path for Linux validators.
**Boundary**: full VM-level confidentiality. The Corona validator
process runs inside a SEV-SNP-protected VM ("CVM"). The
hypervisor sees encrypted memory; the host kernel cannot read
guest pages.
**Attestation flow**:
1. CVM boot loads OVMF -> Linux kernel -> `cosi-cvm-agent` (the
Lux CVM bootstrap agent; lives in `~/work/lux/cosi-cvm-agent`).
2. Agent calls `SNP_GET_REPORT` ioctl to obtain a SEV-SNP
attestation report binding the in-memory `(measurement,
report_data)`. `report_data` is the SHA-256 of the
validator-bound `report_nonce` (received from the registration
service on first contact).
3. Agent posts the report to the consensus layer's TEE-registration
endpoint. The endpoint verifies the report against AMD's KDS
(Key Distribution Service) using the chip's VCEK certificate,
confirms `measurement` matches the published `bin/corona`
manifest, and accepts the validator.
4. On accept, the consensus layer releases the validator's
pre-sealed `KeyShare` (encrypted under a key derived from the
attestation transcript) to the agent.
5. Agent unseals into the SEV-SNP-protected memory; Corona's
`threshold.NewSigner` operates on the unsealed share.
**Key isolation**: the SEV-SNP VM memory is encrypted by the
PSP-bound C-bit memory encryption. The unsealed share is never
visible to the hypervisor or the host kernel.
**Side channels addressed**: cold-boot, DMA-based read of guest
memory, hypervisor-introspection, and (under SEV-SNP integrity
protection, not SEV-ES) RowHammer and Spectre-class transient
attacks from the host.
**Residual risks**: SEV-SNP's own published CVE record (e.g.,
CVE-2023-20593 "Zenbleed", CVE-2024-3315 "SmmCallout"). Operators
MUST apply microcode patches.
**Code touchpoint**: zero. Corona's `KeyShare` bytes are unsealed
by the agent and handed to `threshold.NewSigner` via the standard
Go struct.
### §3.2 NVIDIA Confidential Computing (H100/H200/B200 CC mode)
**Status**: recommended when GPU-accelerated NTT/Montgomery is
used in production. Corona's `gpu` package opts the lattice NTT
dispatch into the GPU at validator setup time; the GPU itself
becomes part of the validator's TCB. **Confidential Computing**
mode on H100/H200/B200 puts the GPU into an attestable
confidential mode where the host CPU cannot read GPU memory.
**Boundary**: a CVM (SEV-SNP or TDX) is paired with a CC-mode
GPU. The PCIe link is encrypted via SPDM (Security Protocol and
Data Model) session keys. The GPU's HBM memory is protected by
the GPU's own confidential-mode firmware.
**Attestation flow**:
1. CVM boot (per §3.1 or §3.3).
2. CVM-to-GPU SPDM session is established. The GPU produces a
**device attestation report** signed by the NRAS (NVIDIA Remote
Attestation Service) root.
3. Agent verifies the GPU report via NRAS, confirms the GPU
firmware version + CC-mode active.
4. Composite attestation: agent emits `evidence = SNP_report ||
NRAS_GPU_report || binding_nonce`. The consensus-layer verifier
checks both reports and the binding.
5. Corona's `gpu.UseAccelerator()` is called inside the CVM after
composite attestation passes. The lattice GPU NTT dispatch
runs over the encrypted PCIe link to the CC-mode GPU.
**Key isolation**: secret shares never leave the CVM's encrypted
memory. The data sent to the GPU for NTT computation is the
*coefficient vector after Montgomery encoding* — the secret-share
material is mixed in earlier (in CPU code) and the GPU NTT operates
on values that are blinded by the per-session mask `R` (Round 1)
and the public matrix `A` (Round 2). The GPU sees no clear-text
share.
> **HONEST GAP**: the precise blinding analysis ("what does the GPU
> see, formally?") for the CC-mode dispatch is an open
> question for the v0.8.0 cryptographic audit. Until that audit
> completes, deploying Corona under CC-mode GPU is APPROVED with
> the caveat that the GPU is part of the TCB; operators MUST
> evaluate whether they trust NVIDIA's CC-mode firmware + NRAS
> attestation.
**Side channels addressed**: PCIe sniffing, host-DMA-into-GPU-memory,
GPU-firmware-from-host introspection.
**Residual risks**: NVIDIA CC-mode CVE record (e.g., GPU-resident
side-channels in shared-memory paths — none publicly disclosed as
of 2026-06-01, but the platform is recent).
**Code touchpoint**: zero in `corona/sign`, `corona/threshold`. One
plumbing change in `corona/gpu/gpu.go::MaybeRegister` to optionally
gate registration on a "confidential-mode-attested" flag passed at
context-init time. **Proposed (not yet implemented)**:
```go
// MaybeRegisterAttested is the CC-mode variant of MaybeRegister.
// It registers the ring only if the supplied attestation token
// passes the consensus-layer's attestation verifier.
//
// On nil token the call falls through to plain MaybeRegister
// (preserves the existing API contract).
func MaybeRegisterAttested(r *ring.Ring, attestation []byte) error {
if attestation == nil {
MaybeRegister(r)
return nil
}
if !attestation_verifier.Verify(attestation) {
return ErrAttestationRejected
}
return RegisterRing(r)
}
```
The `attestation_verifier` package would live OUTSIDE `corona/` —
in the consensus layer at `~/work/lux/threshold/attestation/` or
similar. Corona just consumes the bool.
### §3.3 Intel TDX (alternative Linux path)
**Status**: alternative to §3.1 for Intel platforms. Substantively
equivalent boundary (VM-level confidentiality, attestation via
Intel TDX Provisioning Certification Service).
**Attestation flow**: analogous to §3.1, replacing `SNP_GET_REPORT`
with `TDG.MR.REPORT` and replacing AMD KDS with Intel PCCS / TGS.
**Composite with NVIDIA CC**: TDX + H100 CC is a supported
deployment configuration per NVIDIA's CC documentation.
### §3.4 Apple Secure Enclave (validator share storage on
Apple Silicon)
**Status**: recommended for Apple Silicon validators where the
SEP-bound key is used to seal the at-rest `KeyShare`.
**Boundary**: the SEP is a separate ARM core inside the M-series
SoC with its own bootloader, kernel, and tamper-resistant key
storage. SEP-bound keys are non-extractable and gated by
SecureEnclave biometric / passcode policy.
**Attestation flow** (limited compared to SEV-SNP):
1. Validator process generates a per-validator long-term key
via `Security.framework` `SecKeyCreateRandomKey` with
`kSecAttrTokenIDSecureEnclave`. The private key never leaves
the SEP.
2. The KeyShare bytes are wrapped under an AES-256-GCM key whose
master key is derived from a `SecKeyCreateRandomKey`-backed
ECC P-256 key in the SEP. Decryption requires the SEP to
sign a challenge under the SEP-bound private key.
3. There is NO ATTESTATION REPORT comparable to SEV-SNP/TDX/CC —
Apple does NOT publish a remote-attestation root for the SEP.
Validators using SEP-bound storage cannot prove to the chain
that their share is SEP-sealed; this is a **local-only**
defense-in-depth measure.
**Key isolation**: at-rest share material is sealed under a
non-extractable SEP key. A non-root attacker on the macOS host
cannot extract the share without unlocking the SEP via the
`LAContext.evaluatePolicy` biometric/passcode flow.
**Side channels addressed**: cold-boot, disk-image-exfiltration,
non-root userland processes reading the validator's share file.
**NOT addressed**: a root-equivalent attacker on the macOS host
who calls `Security.framework` after the SEP unlocks (because
SEP unlock policy delegates to the host OS for biometric
evaluation). For full host-isolation on Apple Silicon, run the
validator inside a `virtio-fs`-backed Linux VM under Apple's
`Virtualization.framework` and use the Linux VM's SEV-SNP-style
attestation (not available natively; future work).
**Code touchpoint**: zero in `corona/`. The Apple SEP wrapping
lives in `~/work/lux/threshold/storage/sep-darwin.go` (or
analogous) at the storage layer. Corona's `KeyShare` is loaded
via the storage layer's `LoadShare()` API which returns the
unwrapped `KeyShare` struct.
### §3.5 Intel SGX (deprecated for Corona)
**Status**: NOT recommended. Intel SGX has a long published CVE
record of micro-architectural side-channel attacks (Foreshadow,
ZombieLoad, LVI, ÆPIC Leak). Corona's R-LWE arithmetic spends
significant time on `lattigo`'s NTT and Gaussian sampling — both
data-dependent paths that have been demonstrated vulnerable to
side-channel extraction on SGX in the published literature.
SGX is supported in the *attestation-layer interface* (the
consensus-layer verifier accepts SGX EPID/DCAP reports), but the
**Corona reference deployment guidance** in
`DEPLOYMENT-RUNBOOK.md` explicitly prefers SEV-SNP / TDX / CC-mode
over SGX.
## §4 Composite attestation evidence
The consensus-layer registration endpoint accepts a single composite
attestation evidence bundle for any combination of:
- **CPU side**: SEV-SNP report OR TDX report OR (SGX report,
not recommended).
- **GPU side**: NRAS attestation report (optional; required only
if `gpu.UseAccelerator()` is invoked).
- **Storage side**: SEP-bound key witness (Apple-only;
defense-in-depth, no remote-attestation).
The composite is bound by:
```
binding_nonce = SHA-256( "corona-tee-bind-v1" ||
validator_id ||
group_id ||
era_id ||
challenge_nonce )
```
where `challenge_nonce` is fresh per-registration randomness from
the consensus layer. Each platform-specific report embeds
`binding_nonce` in its `report_data` field. The verifier checks
all reports, confirms binding-nonce consistency, and accepts the
validator on success.
## §5 Key release predicate
The pre-sealed `KeyShare` at the consensus-layer registration
service is encrypted under a key derived from the attestation
transcript. **The key release predicate** is:
```
release_key = HKDF-SHA-256(
salt = "corona-share-release-v1",
ikm = composite_attestation_transcript,
info = validator_id || group_id || era_id,
length = 32,
)
```
The consensus-layer registration service computes this key only on
successful composite-attestation verification. The registration
service then unwraps the validator's `KeyShare` under this key and
delivers the wrapped bytes to the attesting validator.
**This is the policy gate.** Without a passing attestation, no
key release. Without a key release, no Round 1 / Round 2 / Final.
## §6 Honest non-claims
- Corona does NOT today ship `~/work/lux/threshold/attestation/`.
That package is a **proposed** addition for the v0.7.6 / v0.8.0
roadmap; this document specifies its API surface.
- Corona does NOT today ship `MaybeRegisterAttested` in `gpu/`.
Same roadmap.
- Apple SEP integration is **local-only** — no remote attestation
is possible against Apple's platform. Operators relying on
Apple-Silicon validators MUST accept this as a defense-in-depth
measure, not a primary trust anchor.
- The "what does the CC-mode GPU see, formally?" blinding analysis
for §3.2 is an OPEN audit item for v0.8.0.
## §7 Roadmap
| Item | Target | Owner |
|---|---|---|
| `attestation_verifier` package at `~/work/lux/threshold/attestation/` | v0.7.6 | consensus team |
| `MaybeRegisterAttested` in `gpu/gpu.go` | v0.7.6 | corona |
| SEV-SNP CVM bootstrap agent at `~/work/lux/cosi-cvm-agent` | v0.7.6 | infra |
| Reference docker-compose for "validator + SEV-SNP CVM + H100 CC" | v0.8.0 | infra |
| Apple SEP storage layer at `~/work/lux/threshold/storage/sep-darwin.go` | v0.8.0 | apple-silicon track |
| Formal blinding analysis for CC-mode GPU (NTT inputs/outputs) | v0.8.0 | external audit (GATE-4) |
| Reproducible builder image pinned by digest | v0.7.6 | release |
---
**Document metadata**
- Name: `docs/mptc/tee-integration.md`
- Version: v0.1 (initial TEE integration spec)
- Date: 2026-06-02
- Companion to: `DEPLOYMENT-RUNBOOK.md §Operational mitigations item 5`,
`docs/mptc/threat-model.md §9.2`
- Status: proposed; no Corona code change required for §3.1, §3.3, §3.4.
§3.2 adds one optional plumbing function (`MaybeRegisterAttested`)
at the next minor version.
-20
View File
@@ -1,20 +0,0 @@
import { createMDX } from "fumadocs-mdx/next"
/** @type {import('next').NextConfig} */
const config = {
output: 'export',
reactStrictMode: true,
typescript: {
ignoreBuildErrors: true,
},
experimental: {
webpackBuildWorker: true,
},
images: {
unoptimized: true,
},
}
const withMDX = createMDX()
export default withMDX(config)
-36
View File
@@ -1,36 +0,0 @@
{
"name": "@luxfi/corona-docs",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev --port 3001",
"build": "fumadocs-mdx && TURBOPACK=0 next build",
"export": "TURBOPACK=0 next build",
"start": "next start",
"lint": "next lint",
"postinstall": "fumadocs-mdx"
},
"dependencies": {
"fumadocs-core": "^15.8.5",
"fumadocs-mdx": "^12.0.3",
"fumadocs-ui": "^15.8.5",
"lucide-react": "^0.468.0",
"next": "16.0.1",
"react": "19.2.0",
"react-dom": "19.2.0",
"tailwindcss": "^4.1.16",
"zod": "^3.24.1"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.16",
"@types/node": "^22.10.2",
"@types/react": "^19.0.1",
"@types/react-dom": "^19.0.2",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.49",
"rehype-pretty-code": "^0.14.1",
"shiki": "^1.27.2",
"typescript": "^5.7.2"
},
"packageManager": "[email protected]"
}
-4136
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
plugins: {
'@tailwindcss/postcss': {},
autoprefixer: {},
},
}
View File
-27
View File
@@ -1,27 +0,0 @@
import {
defineConfig,
defineDocs,
} from "fumadocs-mdx/config"
import rehypePrettyCode from "rehype-pretty-code"
export default defineConfig({
mdxOptions: {
rehypePlugins: [
[
rehypePrettyCode,
{
theme: {
dark: "github-dark-dimmed",
light: "github-light",
},
keepBackground: false,
defaultLang: "go",
},
],
],
},
})
export const docs = defineDocs({
dir: "content/docs",
})
-41
View File
@@ -1,41 +0,0 @@
{
"compilerOptions": {
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": [
"./*"
]
},
"target": "ES2017"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}