@iam-protocol/pulse-sdk 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/sensor/audio.ts","../src/sensor/motion.ts","../src/sensor/touch.ts","../src/extraction/statistics.ts","../src/extraction/lpc.ts","../src/extraction/speaker.ts","../src/extraction/kinematic.ts","../src/hashing/simhash.ts","../src/hashing/poseidon.ts","../src/proof/serializer.ts","../src/proof/prover.ts","../src/submit/wallet.ts","../src/submit/relayer.ts","../src/identity/anchor.ts","../src/pulse.ts","../src/challenge/phrase.ts","../src/challenge/lissajous.ts"],"sourcesContent":["// Main SDK\nexport { PulseSDK, PulseSession } from \"./pulse\";\n\n// Configuration\nexport type { PulseConfig } from \"./config\";\nexport { PROGRAM_IDS, DEFAULT_THRESHOLD, DEFAULT_MIN_DISTANCE, FINGERPRINT_BITS, MIN_CAPTURE_MS, MAX_CAPTURE_MS, DEFAULT_CAPTURE_MS } from \"./config\";\n\n// Hashing\nexport type { TemporalFingerprint, TBH, PackedFingerprint } from \"./hashing/types\";\nexport { simhash, hammingDistance } from \"./hashing/simhash\";\nexport {\n computeCommitment,\n generateSalt,\n generateTBH,\n packBits,\n bigintToBytes32,\n} from \"./hashing/poseidon\";\n\n// Feature extraction\nexport type { StatsSummary, FeatureVector, FusedFeatureVector } from \"./extraction/types\";\nexport { mean, variance, skewness, kurtosis, condense, entropy, autocorrelation, fuseFeatures } from \"./extraction/statistics\";\nexport { extractSpeakerFeatures, SPEAKER_FEATURE_COUNT } from \"./extraction/speaker\";\nexport { extractMotionFeatures, extractTouchFeatures, extractMouseDynamics } from \"./extraction/kinematic\";\n\n// Proof generation\nexport type { SolanaProof, CircuitInput, ProofResult } from \"./proof/types\";\nexport { serializeProof, toBigEndian32 } from \"./proof/serializer\";\nexport { generateProof, generateSolanaProof, prepareCircuitInput } from \"./proof/prover\";\n\n// Submission\nexport type { SubmissionResult, VerificationResult } from \"./submit/types\";\nexport { submitViaWallet } from \"./submit/wallet\";\nexport { submitViaRelayer } from \"./submit/relayer\";\n\n// Identity\nexport type { IdentityState, StoredVerificationData } from \"./identity/types\";\nexport { fetchIdentityState, storeVerificationData, loadVerificationData } from \"./identity/anchor\";\n\n// Sensor types\nexport type { AudioCapture, MotionSample, TouchSample, SensorData, CaptureOptions, CaptureStage, StageState } from \"./sensor/types\";\n\n// Challenge\nexport { generatePhrase, generatePhraseSequence } from \"./challenge/phrase\";\nexport { randomLissajousParams, generateLissajousPoints, generateLissajousSequence } from \"./challenge/lissajous\";\nexport type { LissajousParams, Point2D } from \"./challenge/lissajous\";\n","// BN254 base field prime (for G1 point negation in proof_a)\nexport const BN254_BASE_FIELD = BigInt(\n \"21888242871839275222246405745257275088696311157297823662689037894645226208583\"\n);\n\n// BN254 scalar field prime (for salt generation, field element bounds)\nexport const BN254_SCALAR_FIELD = BigInt(\n \"21888242871839275222246405745257275088548364400416034343698204186575808495617\"\n);\n\nexport const FINGERPRINT_BITS = 256;\nexport const DEFAULT_THRESHOLD = 96;\nexport const DEFAULT_MIN_DISTANCE = 3;\nexport const NUM_PUBLIC_INPUTS = 4;\n\nexport const PROOF_A_SIZE = 64;\nexport const PROOF_B_SIZE = 128;\nexport const PROOF_C_SIZE = 64;\nexport const TOTAL_PROOF_SIZE = 256;\n\nexport const SIMHASH_SEED = \"IAM-PROTOCOL-SIMHASH-V1\";\n\n// Capture duration bounds (ms)\nexport const MIN_CAPTURE_MS = 2000;\nexport const MAX_CAPTURE_MS = 60000;\nexport const DEFAULT_CAPTURE_MS = 7000;\n\nexport const PROGRAM_IDS = {\n iamAnchor: \"GZYwTp2ozeuRA5Gof9vs4ya961aANcJBdUzB7LN6q4b2\",\n iamVerifier: \"4F97jNoxQzT2qRbkWpW3ztC3Nz2TtKj3rnKG8ExgnrfV\",\n iamRegistry: \"6VBs3zr9KrfFPGd6j7aGBPQWwZa5tajVfA7HN6MMV9VW\",\n} as const;\n\nexport interface PulseConfig {\n cluster: \"devnet\" | \"mainnet-beta\" | \"localnet\";\n rpcEndpoint?: string;\n relayerUrl?: string;\n relayerApiKey?: string;\n zkeyUrl?: string;\n wasmUrl?: string;\n threshold?: number;\n}\n","import type { AudioCapture, CaptureOptions } from \"./types\";\nimport { MIN_CAPTURE_MS, MAX_CAPTURE_MS } from \"../config\";\n\nconst TARGET_SAMPLE_RATE = 16000;\n\n/**\n * Capture audio at 16kHz until signaled to stop.\n * Uses ScriptProcessorNode for raw PCM sample access.\n *\n * Stop behavior:\n * - If signal fires before minDurationMs, capture continues until minimum is reached.\n * - If signal never fires, capture auto-stops at maxDurationMs.\n * - If no signal provided, captures for maxDurationMs.\n */\nexport async function captureAudio(\n options: CaptureOptions = {}\n): Promise<AudioCapture> {\n const {\n signal,\n minDurationMs = MIN_CAPTURE_MS,\n maxDurationMs = MAX_CAPTURE_MS,\n onAudioLevel,\n stream: preAcquiredStream,\n } = options;\n\n const stream = preAcquiredStream ?? await navigator.mediaDevices.getUserMedia({\n audio: {\n sampleRate: TARGET_SAMPLE_RATE,\n channelCount: 1,\n echoCancellation: false,\n noiseSuppression: false,\n autoGainControl: false,\n },\n });\n\n const ctx = new AudioContext({ sampleRate: TARGET_SAMPLE_RATE });\n await ctx.resume(); // Required on iOS — AudioContext may be suspended outside user gesture\n const capturedSampleRate = ctx.sampleRate;\n const source = ctx.createMediaStreamSource(stream);\n const chunks: Float32Array[] = [];\n const startTime = performance.now();\n\n return new Promise((resolve) => {\n let stopped = false;\n const bufferSize = 4096;\n const processor = ctx.createScriptProcessor(bufferSize, 1, 1);\n\n processor.onaudioprocess = (e: AudioProcessingEvent) => {\n const data = e.inputBuffer.getChannelData(0);\n chunks.push(new Float32Array(data));\n\n if (onAudioLevel) {\n let sum = 0;\n for (let i = 0; i < data.length; i++) sum += data[i]! * data[i]!;\n onAudioLevel(Math.sqrt(sum / data.length));\n }\n };\n\n source.connect(processor);\n processor.connect(ctx.destination);\n\n function stopCapture() {\n if (stopped) return;\n stopped = true;\n clearTimeout(maxTimer);\n\n processor.disconnect();\n source.disconnect();\n stream.getTracks().forEach((t: MediaStreamTrack) => t.stop());\n ctx.close().catch(() => {});\n\n const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);\n const samples = new Float32Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n samples.set(chunk, offset);\n offset += chunk.length;\n }\n\n resolve({\n samples,\n sampleRate: capturedSampleRate,\n duration: totalLength / capturedSampleRate,\n });\n }\n\n const maxTimer = setTimeout(stopCapture, maxDurationMs);\n\n if (signal) {\n if (signal.aborted) {\n setTimeout(stopCapture, minDurationMs);\n } else {\n signal.addEventListener(\n \"abort\",\n () => {\n const elapsed = performance.now() - startTime;\n const remaining = Math.max(0, minDurationMs - elapsed);\n setTimeout(stopCapture, remaining);\n },\n { once: true }\n );\n }\n }\n });\n}\n","import type { MotionSample, CaptureOptions } from \"./types\";\nimport { MIN_CAPTURE_MS, MAX_CAPTURE_MS } from \"../config\";\n\n/**\n * Request motion sensor permission (required on iOS 13+).\n * No-op on Android/Chrome where permission is implicit.\n */\nexport async function requestMotionPermission(): Promise<boolean> {\n const DME = (globalThis as any).DeviceMotionEvent;\n if (!DME) return false;\n\n if (typeof DME.requestPermission === \"function\") {\n const permission = await DME.requestPermission();\n return permission === \"granted\";\n }\n\n // Android/Chrome: permission is implicit\n return true;\n}\n\n/**\n * Capture accelerometer + gyroscope data until signaled to stop.\n * Samples at the device's native rate (typically ~60-100Hz).\n */\nexport async function captureMotion(\n options: CaptureOptions = {}\n): Promise<MotionSample[]> {\n const {\n signal,\n minDurationMs = MIN_CAPTURE_MS,\n maxDurationMs = MAX_CAPTURE_MS,\n } = options;\n\n const hasPermission = options.permissionGranted ?? await requestMotionPermission();\n if (!hasPermission) return [];\n\n const samples: MotionSample[] = [];\n const startTime = performance.now();\n\n return new Promise((resolve) => {\n let stopped = false;\n\n const handler = (e: DeviceMotionEvent) => {\n samples.push({\n timestamp: performance.now(),\n ax: e.acceleration?.x ?? 0,\n ay: e.acceleration?.y ?? 0,\n az: e.acceleration?.z ?? 0,\n gx: e.rotationRate?.alpha ?? 0,\n gy: e.rotationRate?.beta ?? 0,\n gz: e.rotationRate?.gamma ?? 0,\n });\n };\n\n function stopCapture() {\n if (stopped) return;\n stopped = true;\n clearTimeout(maxTimer);\n window.removeEventListener(\"devicemotion\", handler);\n resolve(samples);\n }\n\n window.addEventListener(\"devicemotion\", handler);\n\n const maxTimer = setTimeout(stopCapture, maxDurationMs);\n\n if (signal) {\n if (signal.aborted) {\n setTimeout(stopCapture, minDurationMs);\n } else {\n signal.addEventListener(\n \"abort\",\n () => {\n const elapsed = performance.now() - startTime;\n const remaining = Math.max(0, minDurationMs - elapsed);\n setTimeout(stopCapture, remaining);\n },\n { once: true }\n );\n }\n }\n });\n}\n","import type { TouchSample, CaptureOptions } from \"./types\";\nimport { MIN_CAPTURE_MS, MAX_CAPTURE_MS } from \"../config\";\n\n/**\n * Capture touch/pointer data (position, pressure, contact area) until signaled to stop.\n * Uses PointerEvent for cross-platform support (touch, pen, mouse).\n */\nexport function captureTouch(\n element: HTMLElement,\n options: CaptureOptions = {}\n): Promise<TouchSample[]> {\n const {\n signal,\n minDurationMs = MIN_CAPTURE_MS,\n maxDurationMs = MAX_CAPTURE_MS,\n } = options;\n\n const samples: TouchSample[] = [];\n const startTime = performance.now();\n\n return new Promise((resolve) => {\n let stopped = false;\n\n const handler = (e: PointerEvent) => {\n samples.push({\n timestamp: performance.now(),\n x: e.clientX,\n y: e.clientY,\n pressure: e.pressure,\n width: e.width,\n height: e.height,\n });\n };\n\n function stopCapture() {\n if (stopped) return;\n stopped = true;\n clearTimeout(maxTimer);\n element.removeEventListener(\"pointermove\", handler);\n element.removeEventListener(\"pointerdown\", handler);\n console.log(`[IAM SDK] Touch capture stopped: ${samples.length} samples collected`);\n resolve(samples);\n }\n\n element.addEventListener(\"pointermove\", handler);\n element.addEventListener(\"pointerdown\", handler);\n console.log(`[IAM SDK] Touch capture started on <${element.tagName}>, listening for pointer events`);\n\n const maxTimer = setTimeout(stopCapture, maxDurationMs);\n\n if (signal) {\n if (signal.aborted) {\n setTimeout(stopCapture, minDurationMs);\n } else {\n signal.addEventListener(\n \"abort\",\n () => {\n const elapsed = performance.now() - startTime;\n const remaining = Math.max(0, minDurationMs - elapsed);\n setTimeout(stopCapture, remaining);\n },\n { once: true }\n );\n }\n }\n });\n}\n","import type { StatsSummary } from \"./types\";\n\nexport function mean(values: number[]): number {\n if (values.length === 0) return 0;\n let sum = 0;\n for (const v of values) sum += v;\n return sum / values.length;\n}\n\nexport function variance(values: number[], mu?: number): number {\n if (values.length < 2) return 0;\n const m = mu ?? mean(values);\n let sum = 0;\n for (const v of values) sum += (v - m) ** 2;\n return sum / (values.length - 1);\n}\n\nexport function skewness(values: number[]): number {\n if (values.length < 3) return 0;\n const n = values.length;\n const m = mean(values);\n const s = Math.sqrt(variance(values, m));\n if (s === 0) return 0;\n let sum = 0;\n for (const v of values) sum += ((v - m) / s) ** 3;\n return (n / ((n - 1) * (n - 2))) * sum;\n}\n\nexport function kurtosis(values: number[]): number {\n if (values.length < 4) return 0;\n const n = values.length;\n const m = mean(values);\n const s2 = variance(values, m);\n if (s2 === 0) return 0;\n let sum = 0;\n for (const v of values) sum += ((v - m) ** 4) / s2 ** 2;\n const k =\n ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sum -\n (3 * (n - 1) ** 2) / ((n - 2) * (n - 3));\n return k;\n}\n\nexport function condense(values: number[]): StatsSummary {\n const m = mean(values);\n return {\n mean: m,\n variance: variance(values, m),\n skewness: skewness(values),\n kurtosis: kurtosis(values),\n };\n}\n\n/**\n * Shannon entropy over histogram bins. Measures information density.\n * Real human data has moderate entropy (varied but structured).\n * Synthetic data is either too uniform (high entropy) or too structured (low entropy).\n */\nexport function entropy(values: number[], bins: number = 16): number {\n if (values.length < 2) return 0;\n let min = values[0]!;\n let max = values[0]!;\n for (let i = 1; i < values.length; i++) {\n if (values[i]! < min) min = values[i]!;\n if (values[i]! > max) max = values[i]!;\n }\n if (min === max) return 0;\n\n const counts = new Array(bins).fill(0);\n const range = max - min;\n for (const v of values) {\n const idx = Math.min(Math.floor(((v - min) / range) * bins), bins - 1);\n counts[idx]++;\n }\n\n let h = 0;\n for (const c of counts) {\n if (c > 0) {\n const p = c / values.length;\n h -= p * Math.log2(p);\n }\n }\n return h;\n}\n\n/**\n * Autocorrelation at a given lag. Detects periodic synthetic patterns.\n * Real human data has low autocorrelation at most lags (chaotic/noisy).\n * Synthetic data often has high autocorrelation (periodic/smooth).\n */\nexport function autocorrelation(values: number[], lag: number = 1): number {\n if (values.length <= lag) return 0;\n const m = mean(values);\n const v = variance(values, m);\n if (v === 0) return 0;\n\n let sum = 0;\n for (let i = 0; i < values.length - lag; i++) {\n sum += (values[i]! - m) * (values[i + lag]! - m);\n }\n return sum / ((values.length - lag) * v);\n}\n\n/**\n * Normalize a feature group to zero mean and unit variance.\n * Ensures each modality (audio, motion, touch) contributes equally\n * to SimHash hyperplane projections regardless of raw magnitude scale.\n */\nfunction normalizeGroup(features: number[]): number[] {\n if (features.length === 0) return features;\n\n let sum = 0;\n for (const v of features) sum += v;\n const mean = sum / features.length;\n\n let sqSum = 0;\n for (const v of features) sqSum += (v - mean) * (v - mean);\n const std = Math.sqrt(sqSum / features.length);\n\n if (std === 0) return features.map(() => 0);\n return features.map((v) => (v - mean) / std);\n}\n\nexport function fuseFeatures(\n audio: number[],\n motion: number[],\n touch: number[]\n): number[] {\n return [...normalizeGroup(audio), ...normalizeGroup(motion), ...normalizeGroup(touch)];\n}\n","/**\n * Linear Predictive Coding (LPC) for formant detection.\n *\n * Implements Levinson-Durbin recursion for LPC coefficient computation\n * and polynomial root-finding for formant frequency estimation.\n */\n\n/**\n * Compute autocorrelation of a signal for lags 0..order.\n */\nfunction autocorrelate(signal: Float32Array, order: number): number[] {\n const r: number[] = [];\n for (let lag = 0; lag <= order; lag++) {\n let sum = 0;\n for (let i = 0; i < signal.length - lag; i++) {\n sum += signal[i]! * signal[i + lag]!;\n }\n r.push(sum);\n }\n return r;\n}\n\n/**\n * Levinson-Durbin recursion to compute LPC coefficients from autocorrelation.\n * Returns the LPC coefficients a[1..order] (a[0] is implicitly 1).\n */\nfunction levinsonDurbin(r: number[], order: number): number[] {\n const a: number[] = new Array(order + 1).fill(0);\n const aTemp: number[] = new Array(order + 1).fill(0);\n a[0] = 1;\n\n let error = r[0]!;\n if (error === 0) return new Array(order).fill(0);\n\n for (let i = 1; i <= order; i++) {\n let lambda = 0;\n for (let j = 1; j < i; j++) {\n lambda += a[j]! * r[i - j]!;\n }\n lambda = -(r[i]! + lambda) / error;\n\n for (let j = 1; j < i; j++) {\n aTemp[j] = a[j]! + lambda * a[i - j]!;\n }\n aTemp[i] = lambda;\n\n for (let j = 1; j <= i; j++) {\n a[j] = aTemp[j]!;\n }\n\n error *= 1 - lambda * lambda;\n if (error <= 0) break;\n }\n\n return a.slice(1);\n}\n\n/**\n * Find roots of a polynomial using the Durand-Kerner method.\n * The polynomial is 1 + a[0]*z^-1 + a[1]*z^-2 + ... + a[n-1]*z^-n\n * which is equivalent to z^n + a[0]*z^(n-1) + ... + a[n-1] = 0.\n *\n * Returns complex roots as [real, imag] pairs.\n */\nfunction findRoots(coefficients: number[], maxIterations: number = 50): [number, number][] {\n const n = coefficients.length;\n if (n === 0) return [];\n\n // Initial guesses: points on a circle of radius 0.9\n const roots: [number, number][] = [];\n for (let i = 0; i < n; i++) {\n const angle = (2 * Math.PI * i) / n + 0.1;\n roots.push([0.9 * Math.cos(angle), 0.9 * Math.sin(angle)]);\n }\n\n for (let iter = 0; iter < maxIterations; iter++) {\n let maxShift = 0;\n\n for (let i = 0; i < n; i++) {\n // Evaluate polynomial at roots[i]: z^n + a[0]*z^(n-1) + ... + a[n-1]\n let pReal = 1;\n let pImag = 0;\n let zPowReal = 1;\n let zPowImag = 0;\n\n // Compute z^n by repeated multiplication\n const [rr, ri] = roots[i]!;\n let curReal = 1;\n let curImag = 0;\n\n // Evaluate as: z^n + sum(a[k] * z^(n-1-k))\n // Start with z^n\n let znReal = 1;\n let znImag = 0;\n for (let k = 0; k < n; k++) {\n const newReal = znReal * rr - znImag * ri;\n const newImag = znReal * ri + znImag * rr;\n znReal = newReal;\n znImag = newImag;\n }\n pReal = znReal;\n pImag = znImag;\n\n // Add coefficient terms: a[k] * z^(n-1-k)\n zPowReal = 1;\n zPowImag = 0;\n for (let k = n - 1; k >= 0; k--) {\n pReal += coefficients[k]! * zPowReal;\n pImag += coefficients[k]! * zPowImag;\n const newReal = zPowReal * rr - zPowImag * ri;\n const newImag = zPowReal * ri + zPowImag * rr;\n zPowReal = newReal;\n zPowImag = newImag;\n }\n\n // Compute product of (roots[i] - roots[j]) for j != i\n let denomReal = 1;\n let denomImag = 0;\n for (let j = 0; j < n; j++) {\n if (j === i) continue;\n const diffReal = rr - roots[j]![0];\n const diffImag = ri - roots[j]![1];\n const newReal = denomReal * diffReal - denomImag * diffImag;\n const newImag = denomReal * diffImag + denomImag * diffReal;\n denomReal = newReal;\n denomImag = newImag;\n }\n\n // Divide p / denom\n const denomMag2 = denomReal * denomReal + denomImag * denomImag;\n if (denomMag2 < 1e-30) continue;\n\n const shiftReal = (pReal * denomReal + pImag * denomImag) / denomMag2;\n const shiftImag = (pImag * denomReal - pReal * denomImag) / denomMag2;\n\n roots[i] = [rr - shiftReal, ri - shiftImag];\n maxShift = Math.max(maxShift, Math.sqrt(shiftReal * shiftReal + shiftImag * shiftImag));\n }\n\n if (maxShift < 1e-10) break;\n }\n\n return roots;\n}\n\n/**\n * Extract formant frequencies (F1, F2, F3) from a single audio frame.\n * Returns [F1, F2, F3] in Hz, or null if extraction fails.\n */\nfunction extractFormants(\n frame: Float32Array,\n sampleRate: number,\n lpcOrder: number = 12\n): [number, number, number] | null {\n const r = autocorrelate(frame, lpcOrder);\n const coeffs = levinsonDurbin(r, lpcOrder);\n\n const roots = findRoots(coeffs);\n\n // Convert roots to frequencies, keep only positive-frequency roots\n const formantCandidates: number[] = [];\n\n for (const [real, imag] of roots) {\n if (imag <= 0) continue; // Keep only positive-frequency roots\n\n const freq = (Math.atan2(imag, real) / (2 * Math.PI)) * sampleRate;\n const bandwidth = (-sampleRate / (2 * Math.PI)) * Math.log(Math.sqrt(real * real + imag * imag));\n\n // Filter: formants are in 200-5000Hz range with reasonable bandwidth\n if (freq > 200 && freq < 5000 && bandwidth < 500) {\n formantCandidates.push(freq);\n }\n }\n\n formantCandidates.sort((a, b) => a - b);\n\n if (formantCandidates.length < 3) return null;\n\n return [formantCandidates[0]!, formantCandidates[1]!, formantCandidates[2]!];\n}\n\n/**\n * Extract formant ratio time series (F1/F2 and F2/F3) from audio.\n * Returns { f1f2: number[], f2f3: number[] } — one ratio per frame where formants were detected.\n */\nexport function extractFormantRatios(\n samples: Float32Array,\n sampleRate: number,\n frameSize: number,\n hopSize: number\n): { f1f2: number[]; f2f3: number[] } {\n const f1f2: number[] = [];\n const f2f3: number[] = [];\n const numFrames = Math.floor((samples.length - frameSize) / hopSize) + 1;\n\n for (let i = 0; i < numFrames; i++) {\n const start = i * hopSize;\n const frame = samples.slice(start, start + frameSize);\n\n // Apply Hamming window\n const windowed = new Float32Array(frameSize);\n for (let j = 0; j < frameSize; j++) {\n windowed[j] = (frame[j] ?? 0) * (0.54 - 0.46 * Math.cos((2 * Math.PI * j) / (frameSize - 1)));\n }\n\n const formants = extractFormants(windowed, sampleRate);\n if (formants) {\n const [f1, f2, f3] = formants;\n if (f2 > 0) f1f2.push(f1 / f2);\n if (f3 > 0) f2f3.push(f2 / f3);\n }\n }\n\n return { f1f2, f2f3 };\n}\n","/**\n * Speaker-dependent audio feature extraction.\n *\n * Extracts features that characterize HOW someone speaks (prosody, vocal physiology)\n * rather than WHAT they say (phonetic content). These features are stable across\n * different utterances from the same speaker.\n *\n * Output: 44 values\n * F0 statistics (5) + F0 delta (4) + jitter (4) + shimmer (4) +\n * HNR statistics (5) + formant ratios (8) + LTAS (8) + voicing ratio (1) +\n * amplitude statistics (5)\n */\nimport type { AudioCapture } from \"../sensor/types\";\nimport { condense, entropy } from \"./statistics\";\nimport { extractFormantRatios } from \"./lpc\";\n\nconst FRAME_SIZE = 512; // ~32ms at 16kHz, power of 2 for FFT\nconst HOP_SIZE = 160; // ~10ms hop\nconst SPEAKER_FEATURE_COUNT = 44;\n\n// Dynamic imports for browser compatibility\nlet pitchDetector: ((buf: Float32Array) => number | null) | null = null;\nlet meydaModule: any = null;\n\nasync function getPitchDetector(): Promise<(buf: Float32Array) => number | null> {\n if (!pitchDetector) {\n const PitchFinder = await import(\"pitchfinder\");\n pitchDetector = PitchFinder.YIN({ sampleRate: 16000 });\n }\n return pitchDetector;\n}\n\nasync function getMeyda(): Promise<any> {\n if (!meydaModule) {\n try {\n meydaModule = await import(\"meyda\");\n } catch {\n return null;\n }\n }\n return meydaModule.default ?? meydaModule;\n}\n\n/**\n * Detect F0 (fundamental frequency) contour and amplitude peaks per frame.\n */\nasync function detectF0Contour(\n samples: Float32Array,\n sampleRate: number\n): Promise<{ f0: number[]; amplitudes: number[]; periods: number[] }> {\n const detect = await getPitchDetector();\n const f0: number[] = [];\n const amplitudes: number[] = [];\n const periods: number[] = [];\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n\n for (let i = 0; i < numFrames; i++) {\n const start = i * HOP_SIZE;\n const frame = samples.slice(start, start + FRAME_SIZE);\n\n // F0 detection\n const pitch = detect(frame);\n if (pitch && pitch > 50 && pitch < 600) {\n f0.push(pitch);\n periods.push(1 / pitch);\n } else {\n f0.push(0); // unvoiced frame\n }\n\n // RMS amplitude per frame\n let sum = 0;\n for (let j = 0; j < frame.length; j++) {\n sum += (frame[j] ?? 0) * (frame[j] ?? 0);\n }\n amplitudes.push(Math.sqrt(sum / frame.length));\n }\n\n return { f0, amplitudes, periods };\n}\n\n/**\n * Compute jitter measures from pitch period contour.\n * Jitter = cycle-to-cycle perturbation of the fundamental period.\n */\nfunction computeJitter(periods: number[]): number[] {\n const voiced = periods.filter((p) => p > 0);\n if (voiced.length < 3) return [0, 0, 0, 0];\n\n const meanPeriod = voiced.reduce((a, b) => a + b, 0) / voiced.length;\n if (meanPeriod === 0) return [0, 0, 0, 0];\n\n // Jitter (local): average absolute difference between consecutive periods\n let localSum = 0;\n for (let i = 1; i < voiced.length; i++) {\n localSum += Math.abs(voiced[i]! - voiced[i - 1]!);\n }\n const jitterLocal = localSum / (voiced.length - 1) / meanPeriod;\n\n // RAP: Relative Average Perturbation (3-point running average)\n let rapSum = 0;\n for (let i = 1; i < voiced.length - 1; i++) {\n const avg3 = (voiced[i - 1]! + voiced[i]! + voiced[i + 1]!) / 3;\n rapSum += Math.abs(voiced[i]! - avg3);\n }\n const jitterRAP = voiced.length > 2 ? rapSum / (voiced.length - 2) / meanPeriod : 0;\n\n // PPQ5: Five-Point Period Perturbation Quotient\n let ppq5Sum = 0;\n let ppq5Count = 0;\n for (let i = 2; i < voiced.length - 2; i++) {\n const avg5 = (voiced[i - 2]! + voiced[i - 1]! + voiced[i]! + voiced[i + 1]! + voiced[i + 2]!) / 5;\n ppq5Sum += Math.abs(voiced[i]! - avg5);\n ppq5Count++;\n }\n const jitterPPQ5 = ppq5Count > 0 ? ppq5Sum / ppq5Count / meanPeriod : 0;\n\n // DDP: Difference of Differences of Periods\n let ddpSum = 0;\n for (let i = 1; i < voiced.length - 1; i++) {\n const d1 = voiced[i]! - voiced[i - 1]!;\n const d2 = voiced[i + 1]! - voiced[i]!;\n ddpSum += Math.abs(d2 - d1);\n }\n const jitterDDP = voiced.length > 2 ? ddpSum / (voiced.length - 2) / meanPeriod : 0;\n\n return [jitterLocal, jitterRAP, jitterPPQ5, jitterDDP];\n}\n\n/**\n * Compute shimmer measures from amplitude peaks.\n * Shimmer = cycle-to-cycle amplitude perturbation.\n */\nfunction computeShimmer(amplitudes: number[], f0: number[]): number[] {\n // Use amplitudes only at voiced frames\n const voicedAmps = amplitudes.filter((_, i) => f0[i]! > 0);\n if (voicedAmps.length < 3) return [0, 0, 0, 0];\n\n const meanAmp = voicedAmps.reduce((a, b) => a + b, 0) / voicedAmps.length;\n if (meanAmp === 0) return [0, 0, 0, 0];\n\n // Shimmer (local)\n let localSum = 0;\n for (let i = 1; i < voicedAmps.length; i++) {\n localSum += Math.abs(voicedAmps[i]! - voicedAmps[i - 1]!);\n }\n const shimmerLocal = localSum / (voicedAmps.length - 1) / meanAmp;\n\n // APQ3: 3-point Amplitude Perturbation Quotient\n let apq3Sum = 0;\n for (let i = 1; i < voicedAmps.length - 1; i++) {\n const avg3 = (voicedAmps[i - 1]! + voicedAmps[i]! + voicedAmps[i + 1]!) / 3;\n apq3Sum += Math.abs(voicedAmps[i]! - avg3);\n }\n const shimmerAPQ3 = voicedAmps.length > 2 ? apq3Sum / (voicedAmps.length - 2) / meanAmp : 0;\n\n // APQ5\n let apq5Sum = 0;\n let apq5Count = 0;\n for (let i = 2; i < voicedAmps.length - 2; i++) {\n const avg5 = (voicedAmps[i - 2]! + voicedAmps[i - 1]! + voicedAmps[i]! + voicedAmps[i + 1]! + voicedAmps[i + 2]!) / 5;\n apq5Sum += Math.abs(voicedAmps[i]! - avg5);\n apq5Count++;\n }\n const shimmerAPQ5 = apq5Count > 0 ? apq5Sum / apq5Count / meanAmp : 0;\n\n // DDA: Difference of Differences of Amplitudes\n let ddaSum = 0;\n for (let i = 1; i < voicedAmps.length - 1; i++) {\n const d1 = voicedAmps[i]! - voicedAmps[i - 1]!;\n const d2 = voicedAmps[i + 1]! - voicedAmps[i]!;\n ddaSum += Math.abs(d2 - d1);\n }\n const shimmerDDA = voicedAmps.length > 2 ? ddaSum / (voicedAmps.length - 2) / meanAmp : 0;\n\n return [shimmerLocal, shimmerAPQ3, shimmerAPQ5, shimmerDDA];\n}\n\n/**\n * Compute Harmonic-to-Noise Ratio per frame using autocorrelation.\n */\nfunction computeHNR(\n samples: Float32Array,\n sampleRate: number,\n f0Contour: number[]\n): number[] {\n const hnr: number[] = [];\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n\n for (let i = 0; i < numFrames && i < f0Contour.length; i++) {\n const f0 = f0Contour[i]!;\n if (f0 <= 0) continue; // Skip unvoiced frames\n\n const start = i * HOP_SIZE;\n const frame = samples.slice(start, start + FRAME_SIZE);\n const period = Math.round(sampleRate / f0);\n\n if (period <= 0 || period >= frame.length) continue;\n\n // Autocorrelation at the fundamental period\n let num = 0;\n let den = 0;\n for (let j = 0; j < frame.length - period; j++) {\n num += (frame[j] ?? 0) * (frame[j + period] ?? 0);\n den += (frame[j] ?? 0) * (frame[j] ?? 0);\n }\n\n if (den > 0) {\n const r = num / den;\n const clampedR = Math.max(0.001, Math.min(0.999, r));\n hnr.push(10 * Math.log10(clampedR / (1 - clampedR)));\n }\n }\n\n return hnr;\n}\n\n/**\n * Compute LTAS (Long-Term Average Spectrum) features using Meyda.\n * Returns 8 values: spectral centroid, rolloff, flatness, spread — each mean + variance.\n */\nasync function computeLTAS(\n samples: Float32Array,\n sampleRate: number\n): Promise<number[]> {\n const Meyda = await getMeyda();\n if (!Meyda) return new Array(8).fill(0);\n\n const centroids: number[] = [];\n const rolloffs: number[] = [];\n const flatnesses: number[] = [];\n const spreads: number[] = [];\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n\n for (let i = 0; i < numFrames; i++) {\n const start = i * HOP_SIZE;\n const frame = samples.slice(start, start + FRAME_SIZE);\n const paddedFrame = new Float32Array(FRAME_SIZE);\n paddedFrame.set(frame);\n\n const features = Meyda.extract(\n [\"spectralCentroid\", \"spectralRolloff\", \"spectralFlatness\", \"spectralSpread\"],\n paddedFrame,\n { sampleRate, bufferSize: FRAME_SIZE }\n );\n\n if (features) {\n if (typeof features.spectralCentroid === \"number\") centroids.push(features.spectralCentroid);\n if (typeof features.spectralRolloff === \"number\") rolloffs.push(features.spectralRolloff);\n if (typeof features.spectralFlatness === \"number\") flatnesses.push(features.spectralFlatness);\n if (typeof features.spectralSpread === \"number\") spreads.push(features.spectralSpread);\n }\n }\n\n const m = (arr: number[]) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;\n const v = (arr: number[]) => {\n if (arr.length < 2) return 0;\n const mu = m(arr);\n return arr.reduce((sum, x) => sum + (x - mu) * (x - mu), 0) / (arr.length - 1);\n };\n\n return [\n m(centroids), v(centroids),\n m(rolloffs), v(rolloffs),\n m(flatnesses), v(flatnesses),\n m(spreads), v(spreads),\n ];\n}\n\n/**\n * Compute derivative (frame-to-frame differences) of a time series.\n */\nfunction derivative(values: number[]): number[] {\n const d: number[] = [];\n for (let i = 1; i < values.length; i++) {\n d.push(values[i]! - values[i - 1]!);\n }\n return d;\n}\n\n/**\n * Extract speaker-dependent audio features.\n *\n * Captures physiological vocal characteristics (F0, jitter, shimmer, HNR, formant\n * ratios) that are stable across different utterances from the same speaker.\n * Content-independent by design — different phrases produce similar feature values.\n *\n * Returns 44 values.\n */\nexport async function extractSpeakerFeatures(audio: AudioCapture): Promise<number[]> {\n const { samples, sampleRate } = audio;\n\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n if (numFrames < 5) {\n console.warn(`[IAM SDK] Too few audio frames (${numFrames}). Speaker features will be zeros.`);\n return new Array(SPEAKER_FEATURE_COUNT).fill(0);\n }\n\n // 1. F0 detection + amplitude contour\n const { f0, amplitudes, periods } = await detectF0Contour(samples, sampleRate);\n\n const voicedF0 = f0.filter((v) => v > 0);\n const voicedRatio = voicedF0.length / f0.length;\n\n // 2. F0 statistics (5 values)\n const f0Stats = condense(voicedF0);\n const f0Entropy = entropy(voicedF0);\n const f0Features = [f0Stats.mean, f0Stats.variance, f0Stats.skewness, f0Stats.kurtosis, f0Entropy];\n\n // 3. F0 delta statistics (4 values)\n const f0Delta = derivative(voicedF0);\n const f0DeltaStats = condense(f0Delta);\n const f0DeltaFeatures = [f0DeltaStats.mean, f0DeltaStats.variance, f0DeltaStats.skewness, f0DeltaStats.kurtosis];\n\n // 4. Jitter (4 values)\n const jitterFeatures = computeJitter(periods);\n\n // 5. Shimmer (4 values)\n const shimmerFeatures = computeShimmer(amplitudes, f0);\n\n // 6. HNR statistics (5 values)\n const hnrValues = computeHNR(samples, sampleRate, f0);\n const hnrStats = condense(hnrValues);\n const hnrEntropy = entropy(hnrValues);\n const hnrFeatures = [hnrStats.mean, hnrStats.variance, hnrStats.skewness, hnrStats.kurtosis, hnrEntropy];\n\n // 7. Formant ratios (8 values)\n const { f1f2, f2f3 } = extractFormantRatios(samples, sampleRate, FRAME_SIZE, HOP_SIZE);\n const f1f2Stats = condense(f1f2);\n const f2f3Stats = condense(f2f3);\n const formantFeatures = [\n f1f2Stats.mean, f1f2Stats.variance, f1f2Stats.skewness, f1f2Stats.kurtosis,\n f2f3Stats.mean, f2f3Stats.variance, f2f3Stats.skewness, f2f3Stats.kurtosis,\n ];\n\n // 8. LTAS (8 values)\n const ltasFeatures = await computeLTAS(samples, sampleRate);\n\n // 9. Voicing ratio (1 value)\n const voicingFeatures = [voicedRatio];\n\n // 10. Amplitude statistics (5 values)\n const ampStats = condense(amplitudes);\n const ampEntropy = entropy(amplitudes);\n const ampFeatures = [ampStats.mean, ampStats.variance, ampStats.skewness, ampStats.kurtosis, ampEntropy];\n\n const features = [\n ...f0Features, // 5\n ...f0DeltaFeatures, // 4\n ...jitterFeatures, // 4\n ...shimmerFeatures, // 4\n ...hnrFeatures, // 5\n ...formantFeatures, // 8\n ...ltasFeatures, // 8\n ...voicingFeatures, // 1\n ...ampFeatures, // 5\n ]; // = 44\n\n return features;\n}\n\nexport { SPEAKER_FEATURE_COUNT };\n","import type { MotionSample, TouchSample } from \"../sensor/types\";\nimport { condense, variance, entropy } from \"./statistics\";\n\n/**\n * Extract kinematic features from motion (IMU) data.\n * Computes jerk (3rd derivative) and jounce (4th derivative) of acceleration,\n * then condenses each axis into statistics.\n *\n * Returns: ~54 values (6 axes × 2 derivatives × 4 stats + 6 jitter variance values)\n */\nexport function extractMotionFeatures(samples: MotionSample[]): number[] {\n if (samples.length < 5) return new Array(54).fill(0);\n\n // Extract acceleration and rotation time series\n const axes = {\n ax: samples.map((s) => s.ax),\n ay: samples.map((s) => s.ay),\n az: samples.map((s) => s.az),\n gx: samples.map((s) => s.gx),\n gy: samples.map((s) => s.gy),\n gz: samples.map((s) => s.gz),\n };\n\n const features: number[] = [];\n\n for (const values of Object.values(axes)) {\n // Jerk = 3rd derivative of position = 1st derivative of acceleration\n const jerk = derivative(values);\n // Jounce = 4th derivative of position = 2nd derivative of acceleration\n const jounce = derivative(jerk);\n\n const jerkStats = condense(jerk);\n const jounceStats = condense(jounce);\n\n features.push(\n jerkStats.mean,\n jerkStats.variance,\n jerkStats.skewness,\n jerkStats.kurtosis,\n jounceStats.mean,\n jounceStats.variance,\n jounceStats.skewness,\n jounceStats.kurtosis\n );\n }\n\n // Jitter variance per axis: variance of windowed jerk variance.\n // Real human tremor fluctuates over time (high jitter variance).\n // Synthetic/replay data has constant jitter (low jitter variance).\n for (const values of Object.values(axes)) {\n const jerk = derivative(values);\n const windowSize = Math.max(5, Math.floor(jerk.length / 4));\n const windowVariances: number[] = [];\n for (let i = 0; i <= jerk.length - windowSize; i += windowSize) {\n windowVariances.push(variance(jerk.slice(i, i + windowSize)));\n }\n features.push(windowVariances.length >= 2 ? variance(windowVariances) : 0);\n }\n\n return features;\n}\n\n/**\n * Extract kinematic features from touch data.\n * Computes velocity and acceleration of touch coordinates,\n * plus pressure and area statistics.\n *\n * Returns: ~36 values (32 base + 4 jitter variance for x, y, pressure, area)\n */\nexport function extractTouchFeatures(samples: TouchSample[]): number[] {\n if (samples.length < 5) return new Array(36).fill(0);\n\n const x = samples.map((s) => s.x);\n const y = samples.map((s) => s.y);\n const pressure = samples.map((s) => s.pressure);\n const area = samples.map((s) => s.width * s.height);\n\n const features: number[] = [];\n\n // X velocity and acceleration\n const vx = derivative(x);\n const accX = derivative(vx);\n features.push(...Object.values(condense(vx)));\n features.push(...Object.values(condense(accX)));\n\n // Y velocity and acceleration\n const vy = derivative(y);\n const accY = derivative(vy);\n features.push(...Object.values(condense(vy)));\n features.push(...Object.values(condense(accY)));\n\n // Pressure statistics\n features.push(...Object.values(condense(pressure)));\n\n // Contact area statistics\n features.push(...Object.values(condense(area)));\n\n // Jerk of touch path\n const jerkX = derivative(accX);\n const jerkY = derivative(accY);\n features.push(...Object.values(condense(jerkX)));\n features.push(...Object.values(condense(jerkY)));\n\n // Jitter variance for touch signals: detects synthetic smoothness\n for (const values of [vx, vy, pressure, area]) {\n const windowSize = Math.max(5, Math.floor(values.length / 4));\n const windowVariances: number[] = [];\n for (let i = 0; i <= values.length - windowSize; i += windowSize) {\n windowVariances.push(variance(values.slice(i, i + windowSize)));\n }\n features.push(windowVariances.length >= 2 ? variance(windowVariances) : 0);\n }\n\n return features;\n}\n\n/** Compute discrete derivative (differences between consecutive values) */\nfunction derivative(values: number[]): number[] {\n const d: number[] = [];\n for (let i = 1; i < values.length; i++) {\n d.push((values[i] ?? 0) - (values[i - 1] ?? 0));\n }\n return d;\n}\n\n/**\n * Extract mouse dynamics features as a desktop replacement for motion sensor data.\n * Captures behavioral patterns from mouse/pointer movement that are user-specific:\n * path curvature, speed patterns, micro-corrections, pause behavior.\n *\n * Returns: 54 values (matches motion feature dimension for consistent SimHash input)\n */\nexport function extractMouseDynamics(samples: TouchSample[]): number[] {\n if (samples.length < 10) return new Array(54).fill(0);\n\n const x = samples.map((s) => s.x);\n const y = samples.map((s) => s.y);\n const pressure = samples.map((s) => s.pressure);\n const area = samples.map((s) => s.width * s.height);\n\n // Velocity\n const vx = derivative(x);\n const vy = derivative(y);\n const speed = vx.map((dx, i) => Math.sqrt(dx * dx + (vy[i] ?? 0) * (vy[i] ?? 0)));\n\n // Acceleration\n const accX = derivative(vx);\n const accY = derivative(vy);\n const acc = accX.map((ax, i) => Math.sqrt(ax * ax + (accY[i] ?? 0) * (accY[i] ?? 0)));\n\n // Jerk (derivative of acceleration)\n const jerkX = derivative(accX);\n const jerkY = derivative(accY);\n const jerk = jerkX.map((jx, i) => Math.sqrt(jx * jx + (jerkY[i] ?? 0) * (jerkY[i] ?? 0)));\n\n // Path curvature: angle change between consecutive movement vectors\n const curvatures: number[] = [];\n for (let i = 1; i < vx.length; i++) {\n const angle1 = Math.atan2(vy[i - 1] ?? 0, vx[i - 1] ?? 0);\n const angle2 = Math.atan2(vy[i] ?? 0, vx[i] ?? 0);\n let diff = angle2 - angle1;\n while (diff > Math.PI) diff -= 2 * Math.PI;\n while (diff < -Math.PI) diff += 2 * Math.PI;\n curvatures.push(Math.abs(diff));\n }\n\n // Movement directions for directional entropy\n const directions = vx.map((dx, i) => Math.atan2(vy[i] ?? 0, dx));\n\n // Micro-corrections: direction reversals\n let reversals = 0;\n for (let i = 2; i < directions.length; i++) {\n const d1 = directions[i - 1]! - directions[i - 2]!;\n const d2 = directions[i]! - directions[i - 1]!;\n if (d1 * d2 < 0) reversals++;\n }\n const reversalRate = directions.length > 2 ? reversals / (directions.length - 2) : 0;\n const reversalMagnitude = curvatures.length > 0\n ? curvatures.reduce((a, b) => a + b, 0) / curvatures.length\n : 0;\n\n // Pause detection: frames where speed is near zero\n const speedThreshold = 0.5;\n const pauseFrames = speed.filter((s) => s < speedThreshold).length;\n const pauseRatio = speed.length > 0 ? pauseFrames / speed.length : 0;\n\n // Path efficiency: straight-line distance / total path length\n const totalPathLength = speed.reduce((a, b) => a + b, 0);\n const straightLine = Math.sqrt(\n (x[x.length - 1]! - x[0]!) ** 2 + (y[y.length - 1]! - y[0]!) ** 2\n );\n const pathEfficiency = totalPathLength > 0 ? straightLine / totalPathLength : 0;\n\n // Movement durations between pauses\n const movementDurations: number[] = [];\n let currentDuration = 0;\n for (const s of speed) {\n if (s >= speedThreshold) {\n currentDuration++;\n } else if (currentDuration > 0) {\n movementDurations.push(currentDuration);\n currentDuration = 0;\n }\n }\n if (currentDuration > 0) movementDurations.push(currentDuration);\n\n // Segment lengths between direction changes\n const segmentLengths: number[] = [];\n let segLen = 0;\n for (let i = 1; i < directions.length; i++) {\n segLen += speed[i] ?? 0;\n const angleDiff = Math.abs(directions[i]! - directions[i - 1]!);\n if (angleDiff > Math.PI / 4) {\n segmentLengths.push(segLen);\n segLen = 0;\n }\n }\n if (segLen > 0) segmentLengths.push(segLen);\n\n // Windowed jitter variance of speed\n const windowSize = Math.max(5, Math.floor(speed.length / 4));\n const windowVariances: number[] = [];\n for (let i = 0; i + windowSize <= speed.length; i += windowSize) {\n const window = speed.slice(i, i + windowSize);\n windowVariances.push(variance(window));\n }\n const speedJitter = windowVariances.length > 1 ? variance(windowVariances) : 0;\n\n // Path length normalized by capture duration\n const duration = samples.length > 1\n ? (samples[samples.length - 1]!.timestamp - samples[0]!.timestamp) / 1000\n : 1;\n const normalizedPathLength = totalPathLength / Math.max(duration, 0.001);\n\n // Angle autocorrelation at lags 1, 2, 3\n const angleAutoCorr: number[] = [];\n for (let lag = 1; lag <= 3; lag++) {\n if (directions.length <= lag) {\n angleAutoCorr.push(0);\n continue;\n }\n const n = directions.length - lag;\n const meanDir = directions.reduce((a, b) => a + b, 0) / directions.length;\n let num = 0;\n let den = 0;\n for (let i = 0; i < n; i++) {\n num += (directions[i]! - meanDir) * (directions[i + lag]! - meanDir);\n den += (directions[i]! - meanDir) ** 2;\n }\n angleAutoCorr.push(den > 0 ? num / den : 0);\n }\n\n // Assemble 54 features\n const curvatureStats = condense(curvatures); // 4\n const dirEntropy = entropy(directions, 16); // 1\n const speedStats = condense(speed); // 4\n const accStats = condense(acc); // 4\n // micro-corrections: reversalRate + reversalMagnitude // 2\n // pauseRatio // 1\n // pathEfficiency // 1\n // speedJitter // 1\n const jerkStats = condense(jerk); // 4\n const vxStats = condense(vx); // 4\n const vyStats = condense(vy); // 4\n const accXStats = condense(accX); // 4\n const accYStats = condense(accY); // 4\n const pressureStats = condense(pressure); // 4\n const moveDurStats = condense(movementDurations); // 4\n const segLenStats = condense(segmentLengths); // 4\n // angleAutoCorr[0..2] // 3\n // normalizedPathLength // 1\n // Total: 4+1+4+4+2+1+1+1+4+4+4+4+4+4+4+4+3+1 = 54\n\n return [\n curvatureStats.mean, curvatureStats.variance, curvatureStats.skewness, curvatureStats.kurtosis,\n dirEntropy,\n speedStats.mean, speedStats.variance, speedStats.skewness, speedStats.kurtosis,\n accStats.mean, accStats.variance, accStats.skewness, accStats.kurtosis,\n reversalRate, reversalMagnitude,\n pauseRatio,\n pathEfficiency,\n speedJitter,\n jerkStats.mean, jerkStats.variance, jerkStats.skewness, jerkStats.kurtosis,\n vxStats.mean, vxStats.variance, vxStats.skewness, vxStats.kurtosis,\n vyStats.mean, vyStats.variance, vyStats.skewness, vyStats.kurtosis,\n accXStats.mean, accXStats.variance, accXStats.skewness, accXStats.kurtosis,\n accYStats.mean, accYStats.variance, accYStats.skewness, accYStats.kurtosis,\n pressureStats.mean, pressureStats.variance, pressureStats.skewness, pressureStats.kurtosis,\n moveDurStats.mean, moveDurStats.variance, moveDurStats.skewness, moveDurStats.kurtosis,\n segLenStats.mean, segLenStats.variance, segLenStats.skewness, segLenStats.kurtosis,\n angleAutoCorr[0] ?? 0, angleAutoCorr[1] ?? 0, angleAutoCorr[2] ?? 0,\n normalizedPathLength,\n ];\n}\n","import { FINGERPRINT_BITS, SIMHASH_SEED } from \"../config\";\nimport type { TemporalFingerprint } from \"./types\";\n\n// Mulberry32 PRNG: deterministic, fast, good distribution\nfunction mulberry32(seed: number): () => number {\n let state = seed | 0;\n return () => {\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n// Derive a numeric seed from the protocol seed string\nfunction deriveSeed(seedStr: string): number {\n let hash = 0;\n for (let i = 0; i < seedStr.length; i++) {\n const ch = seedStr.charCodeAt(i);\n hash = ((hash << 5) - hash + ch) | 0;\n }\n return hash;\n}\n\nlet cachedHyperplanes: number[][] | null = null;\nlet cachedDimension = 0;\n\nfunction getHyperplanes(dimension: number): number[][] {\n if (cachedHyperplanes && cachedDimension === dimension) {\n return cachedHyperplanes;\n }\n\n const rng = mulberry32(deriveSeed(SIMHASH_SEED));\n const planes: number[][] = [];\n\n for (let i = 0; i < FINGERPRINT_BITS; i++) {\n const plane: number[] = [];\n for (let j = 0; j < dimension; j++) {\n // Random value in [-1, 1]\n plane.push(rng() * 2 - 1);\n }\n planes.push(plane);\n }\n\n cachedHyperplanes = planes;\n cachedDimension = dimension;\n return planes;\n}\n\n/**\n * Compute a 256-bit SimHash fingerprint from a feature vector.\n * Uses deterministic random hyperplanes seeded from the protocol constant.\n * Similar feature vectors produce fingerprints with low Hamming distance.\n */\nconst EXPECTED_FEATURE_DIMENSION = 134; // 44 speaker + 54 motion/mouse + 36 touch\n\nexport function simhash(features: number[]): TemporalFingerprint {\n if (features.length === 0) {\n return new Array(FINGERPRINT_BITS).fill(0);\n }\n\n if (features.length !== EXPECTED_FEATURE_DIMENSION) {\n console.warn(\n `[IAM SDK] Feature vector has ${features.length} dimensions, expected ${EXPECTED_FEATURE_DIMENSION}. ` +\n `Fingerprint quality may be degraded.`\n );\n }\n\n const planes = getHyperplanes(features.length);\n const fingerprint: TemporalFingerprint = [];\n\n for (let i = 0; i < FINGERPRINT_BITS; i++) {\n const plane = planes[i];\n let dot = 0;\n for (let j = 0; j < features.length; j++) {\n dot += (features[j] ?? 0) * (plane?.[j] ?? 0);\n }\n fingerprint.push(dot >= 0 ? 1 : 0);\n }\n\n return fingerprint;\n}\n\n/**\n * Compute Hamming distance between two fingerprints.\n */\nexport function hammingDistance(\n a: TemporalFingerprint,\n b: TemporalFingerprint\n): number {\n let distance = 0;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) distance++;\n }\n return distance;\n}\n","import { BN254_SCALAR_FIELD, FINGERPRINT_BITS } from \"../config\";\nimport type { PackedFingerprint, TBH, TemporalFingerprint } from \"./types\";\n\n// Lazy-initialized Poseidon instance\nlet poseidonInstance: any = null;\n\nasync function getPoseidon(): Promise<any> {\n if (!poseidonInstance) {\n const circomlibjs = await import(\"circomlibjs\");\n poseidonInstance = await (circomlibjs as any).buildPoseidon();\n }\n return poseidonInstance;\n}\n\n/**\n * Pack 256-bit fingerprint into two 128-bit field elements.\n * Little-endian bit ordering within each chunk (matches circuit's Bits2Num).\n */\nexport function packBits(fingerprint: TemporalFingerprint): PackedFingerprint {\n let lo = BigInt(0);\n for (let i = 0; i < 128; i++) {\n if (fingerprint[i] === 1) {\n lo += BigInt(1) << BigInt(i);\n }\n }\n\n let hi = BigInt(0);\n for (let i = 0; i < 128; i++) {\n if (fingerprint[128 + i] === 1) {\n hi += BigInt(1) << BigInt(i);\n }\n }\n\n return { lo, hi };\n}\n\n/**\n * Compute Poseidon commitment: Poseidon(pack_lo, pack_hi, salt).\n * Matches the circuit's CommitmentCheck template exactly.\n */\nexport async function computeCommitment(\n fingerprint: TemporalFingerprint,\n salt: bigint\n): Promise<bigint> {\n const poseidon = await getPoseidon();\n const { lo, hi } = packBits(fingerprint);\n const hash = poseidon([lo, hi, salt]);\n return poseidon.F.toObject(hash) as bigint;\n}\n\n/**\n * Generate a random salt within the BN254 scalar field.\n */\nexport function generateSalt(): bigint {\n const bytes = new Uint8Array(31);\n crypto.getRandomValues(bytes);\n let val = BigInt(0);\n for (let i = 0; i < bytes.length; i++) {\n val = (val << BigInt(8)) + BigInt(bytes[i] ?? 0);\n }\n return val % BN254_SCALAR_FIELD;\n}\n\n/**\n * Convert a BigInt to a 32-byte big-endian Uint8Array.\n */\nexport function bigintToBytes32(n: bigint): Uint8Array {\n const bytes = new Uint8Array(32);\n let val = n;\n for (let i = 31; i >= 0; i--) {\n bytes[i] = Number(val & BigInt(0xff));\n val >>= BigInt(8);\n }\n return bytes;\n}\n\n/**\n * Generate a complete TBH from a fingerprint.\n */\nexport async function generateTBH(\n fingerprint: TemporalFingerprint,\n salt?: bigint\n): Promise<TBH> {\n const s = salt ?? generateSalt();\n const commitment = await computeCommitment(fingerprint, s);\n return {\n fingerprint,\n salt: s,\n commitment,\n commitmentBytes: bigintToBytes32(commitment),\n };\n}\n","import {\n BN254_BASE_FIELD,\n PROOF_A_SIZE,\n PROOF_B_SIZE,\n PROOF_C_SIZE,\n TOTAL_PROOF_SIZE,\n NUM_PUBLIC_INPUTS,\n} from \"../config\";\nimport type { RawProof, SolanaProof } from \"./types\";\n\n/**\n * Convert a decimal string to a 32-byte big-endian Uint8Array.\n */\nexport function toBigEndian32(decStr: string): Uint8Array {\n let n = BigInt(decStr);\n const bytes = new Uint8Array(32);\n for (let i = 31; i >= 0; i--) {\n bytes[i] = Number(n & BigInt(0xff));\n n >>= BigInt(8);\n }\n return bytes;\n}\n\n/**\n * Negate a G1 y-coordinate for groth16-solana proof_a format.\n */\nfunction negateG1Y(yDecStr: string): Uint8Array {\n const y = BigInt(yDecStr);\n const yNeg = (BN254_BASE_FIELD - y) % BN254_BASE_FIELD;\n return toBigEndian32(yNeg.toString());\n}\n\n/**\n * Serialize an snarkjs proof into the 256-byte format groth16-solana expects.\n *\n * proof_a: 64 bytes (x + negated y)\n * proof_b: 128 bytes (G2 with reversed coordinate ordering: c1 before c0)\n * proof_c: 64 bytes (x + y)\n */\nexport function serializeProof(\n proof: RawProof,\n publicSignals: string[]\n): SolanaProof {\n if (publicSignals.length !== NUM_PUBLIC_INPUTS) {\n throw new Error(\n `Expected ${NUM_PUBLIC_INPUTS} public signals, got ${publicSignals.length}`\n );\n }\n\n // proof_a: x (32 bytes) + negated y (32 bytes)\n const a0 = toBigEndian32(proof.pi_a[0]!);\n const a1 = negateG1Y(proof.pi_a[1]!);\n const proofA = new Uint8Array(PROOF_A_SIZE);\n proofA.set(a0, 0);\n proofA.set(a1, 32);\n\n // proof_b: G2 reversed coordinate ordering\n const b00 = toBigEndian32(proof.pi_b[0]![1]!); // c1 first\n const b01 = toBigEndian32(proof.pi_b[0]![0]!); // c0 second\n const b10 = toBigEndian32(proof.pi_b[1]![1]!);\n const b11 = toBigEndian32(proof.pi_b[1]![0]!);\n const proofB = new Uint8Array(PROOF_B_SIZE);\n proofB.set(b00, 0);\n proofB.set(b01, 32);\n proofB.set(b10, 64);\n proofB.set(b11, 96);\n\n // proof_c: x + y (no negation)\n const c0 = toBigEndian32(proof.pi_c[0]!);\n const c1 = toBigEndian32(proof.pi_c[1]!);\n const proofC = new Uint8Array(PROOF_C_SIZE);\n proofC.set(c0, 0);\n proofC.set(c1, 32);\n\n // Combine into single 256-byte blob\n const proofBytes = new Uint8Array(TOTAL_PROOF_SIZE);\n proofBytes.set(proofA, 0);\n proofBytes.set(proofB, PROOF_A_SIZE);\n proofBytes.set(proofC, PROOF_A_SIZE + PROOF_B_SIZE);\n\n // Public inputs as 32-byte big-endian arrays\n const publicInputs = publicSignals.map((s) => toBigEndian32(s));\n\n return { proofBytes, publicInputs };\n}\n","import type { TBH } from \"../hashing/types\";\nimport type { CircuitInput, ProofResult, SolanaProof } from \"./types\";\nimport { serializeProof } from \"./serializer\";\nimport { DEFAULT_THRESHOLD, DEFAULT_MIN_DISTANCE } from \"../config\";\n\n// Use dynamic import for snarkjs (it's a CJS module)\nlet snarkjsModule: any = null;\n\nasync function getSnarkjs(): Promise<any> {\n if (!snarkjsModule) {\n snarkjsModule = await import(\"snarkjs\");\n }\n return snarkjsModule;\n}\n\n/**\n * Prepare circuit input from current and previous TBH data.\n */\nexport function prepareCircuitInput(\n current: TBH,\n previous: TBH,\n threshold: number = DEFAULT_THRESHOLD,\n minDistance: number = DEFAULT_MIN_DISTANCE\n): CircuitInput {\n return {\n ft_new: current.fingerprint,\n ft_prev: previous.fingerprint,\n salt_new: current.salt.toString(),\n salt_prev: previous.salt.toString(),\n commitment_new: current.commitment.toString(),\n commitment_prev: previous.commitment.toString(),\n threshold: threshold.toString(),\n min_distance: minDistance.toString(),\n };\n}\n\n/**\n * Generate a Groth16 proof for the Hamming distance circuit.\n *\n * @param input - Circuit input (fingerprints, salts, commitments, threshold)\n * @param wasmPath - Path or URL to iam_hamming.wasm\n * @param zkeyPath - Path or URL to iam_hamming_final.zkey\n */\nexport async function generateProof(\n input: CircuitInput,\n wasmPath: string,\n zkeyPath: string\n): Promise<ProofResult> {\n const snarkjs = await getSnarkjs();\n const { proof, publicSignals } = await snarkjs.groth16.fullProve(\n input,\n wasmPath,\n zkeyPath\n );\n return { proof, publicSignals };\n}\n\n/**\n * Generate a proof and serialize it for Solana submission.\n */\nexport async function generateSolanaProof(\n current: TBH,\n previous: TBH,\n wasmPath: string,\n zkeyPath: string,\n threshold?: number\n): Promise<SolanaProof> {\n const input = prepareCircuitInput(current, previous, threshold);\n const { proof, publicSignals } = await generateProof(\n input,\n wasmPath,\n zkeyPath\n );\n return serializeProof(proof, publicSignals);\n}\n\n/**\n * Verify a proof locally using snarkjs (for debugging/testing).\n * Caller is responsible for loading the verification key.\n */\nexport async function verifyProofLocally(\n proof: any,\n publicSignals: string[],\n vkey: Record<string, unknown>\n): Promise<boolean> {\n const snarkjs = await getSnarkjs();\n return snarkjs.groth16.verify(vkey, publicSignals, proof);\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n// Anchor program interactions use runtime IDL fetching, requiring dynamic typing.\nimport type { SolanaProof } from \"../proof/types\";\nimport type { SubmissionResult } from \"./types\";\nimport { PROGRAM_IDS } from \"../config\";\n\n/**\n * Submit a proof on-chain via a connected wallet (wallet-connected mode).\n * Uses Anchor SDK to construct and send the transaction.\n *\n * Flow: create_challenge → verify_proof → update_anchor (or mint_anchor for first time)\n */\nexport async function submitViaWallet(\n proof: SolanaProof,\n commitment: Uint8Array,\n options: {\n wallet: any;\n connection: any;\n isFirstVerification: boolean;\n }\n): Promise<SubmissionResult> {\n try {\n const anchor = await import(\"@coral-xyz/anchor\");\n const { PublicKey, SystemProgram } = await import(\"@solana/web3.js\");\n\n const provider = new anchor.AnchorProvider(\n options.connection,\n options.wallet,\n { commitment: \"confirmed\" }\n );\n\n const verifierProgramId = new PublicKey(PROGRAM_IDS.iamVerifier);\n const anchorProgramId = new PublicKey(PROGRAM_IDS.iamAnchor);\n\n // Generate nonce for challenge\n const nonce = Array.from(crypto.getRandomValues(new Uint8Array(32)));\n\n // Derive PDAs\n const [challengePda] = PublicKey.findProgramAddressSync(\n [\n new TextEncoder().encode(\"challenge\"),\n provider.wallet.publicKey.toBuffer(),\n new Uint8Array(nonce),\n ],\n verifierProgramId\n );\n\n const [verificationPda] = PublicKey.findProgramAddressSync(\n [\n new TextEncoder().encode(\"verification\"),\n provider.wallet.publicKey.toBuffer(),\n new Uint8Array(nonce),\n ],\n verifierProgramId\n );\n\n // Build and send create_challenge + verify_proof transactions\n // These use the raw Anchor program interface\n const verifierIdl = await anchor.Program.fetchIdl(\n verifierProgramId,\n provider\n );\n if (!verifierIdl) {\n return { success: false, error: \"Failed to fetch verifier IDL\" };\n }\n\n const verifierProgram: any = new anchor.Program(\n verifierIdl,\n provider\n );\n\n // 1. Create challenge\n await verifierProgram.methods\n .createChallenge(nonce)\n .accounts({\n challenger: provider.wallet.publicKey,\n challenge: challengePda,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n\n // 2. Verify proof\n const txSig = await verifierProgram.methods\n .verifyProof(\n Array.from(proof.proofBytes),\n proof.publicInputs.map((pi) => Array.from(pi)),\n nonce\n )\n .accounts({\n verifier: provider.wallet.publicKey,\n challenge: challengePda,\n verificationResult: verificationPda,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n\n // 3. Mint or update anchor\n const anchorIdl = await anchor.Program.fetchIdl(anchorProgramId, provider);\n if (!anchorIdl) {\n return { success: false, error: \"Failed to fetch IAM Anchor program IDL\" };\n }\n\n {\n const anchorProgram: any = new anchor.Program(anchorIdl, provider);\n\n if (options.isFirstVerification) {\n const [identityPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"identity\"), provider.wallet.publicKey.toBuffer()],\n anchorProgramId\n );\n const [mintPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"mint\"), provider.wallet.publicKey.toBuffer()],\n anchorProgramId\n );\n const [mintAuthority] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"mint_authority\")],\n anchorProgramId\n );\n\n // Token-2022 program ID\n const TOKEN_2022_PROGRAM_ID = new PublicKey(\n \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\"\n );\n\n const { getAssociatedTokenAddressSync } = await import(\n \"@solana/spl-token\"\n );\n const ata = getAssociatedTokenAddressSync(\n mintPda,\n provider.wallet.publicKey,\n false,\n TOKEN_2022_PROGRAM_ID\n );\n\n await anchorProgram.methods\n .mintAnchor(Array.from(commitment))\n .accounts({\n user: provider.wallet.publicKey,\n identityState: identityPda,\n mint: mintPda,\n mintAuthority,\n tokenAccount: ata,\n associatedTokenProgram: new PublicKey(\n \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n ),\n tokenProgram: TOKEN_2022_PROGRAM_ID,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n } else {\n const [identityPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"identity\"), provider.wallet.publicKey.toBuffer()],\n anchorProgramId\n );\n\n // Derive iam-registry ProtocolConfig PDA for trust score computation\n const registryProgramId = new PublicKey(PROGRAM_IDS.iamRegistry);\n const [protocolConfigPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"protocol_config\")],\n registryProgramId\n );\n\n await anchorProgram.methods\n .updateAnchor(Array.from(commitment))\n .accounts({\n authority: provider.wallet.publicKey,\n identityState: identityPda,\n protocolConfig: protocolConfigPda,\n })\n .rpc();\n }\n }\n\n return { success: true, txSignature: txSig };\n } catch (err: any) {\n return { success: false, error: err.message ?? String(err) };\n }\n}\n","import type { SolanaProof } from \"../proof/types\";\nimport type { SubmissionResult } from \"./types\";\n\nconst RELAYER_TIMEOUT_MS = 30_000;\n\n/**\n * Submit a proof via the IAM relayer API (walletless mode).\n * The relayer submits the on-chain transaction using the integrator's funded account.\n * The user needs no wallet, no SOL, no crypto knowledge.\n */\nexport async function submitViaRelayer(\n proof: SolanaProof,\n commitment: Uint8Array,\n options: {\n relayerUrl: string;\n apiKey?: string;\n isFirstVerification: boolean;\n }\n): Promise<SubmissionResult> {\n try {\n const body = {\n proof_bytes: Array.from(proof.proofBytes),\n public_inputs: proof.publicInputs.map((pi) => Array.from(pi)),\n commitment: Array.from(commitment),\n is_first_verification: options.isFirstVerification,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (options.apiKey) {\n headers[\"X-API-Key\"] = options.apiKey;\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), RELAYER_TIMEOUT_MS);\n\n const response = await fetch(options.relayerUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n clearTimeout(timer);\n\n if (!response.ok) {\n const errorText = await response.text();\n return { success: false, error: `Relayer error: ${response.status} ${errorText}` };\n }\n\n const result = (await response.json()) as {\n success?: boolean;\n tx_signature?: string;\n verified?: boolean;\n registered?: boolean;\n };\n\n if (result.success !== true) {\n return { success: false, error: \"Relayer returned unsuccessful response\" };\n }\n\n return {\n success: true,\n txSignature: result.tx_signature,\n };\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n return { success: false, error: \"Relayer request timed out\" };\n }\n return { success: false, error: err.message ?? String(err) };\n }\n}\n","import { PROGRAM_IDS } from \"../config\";\nimport type { IdentityState, StoredVerificationData } from \"./types\";\n\nconst STORAGE_KEY = \"iam-protocol-verification-data\";\n\n/**\n * Fetch identity state from the on-chain IdentityState PDA.\n */\nexport async function fetchIdentityState(\n walletPubkey: string,\n connection: any\n): Promise<IdentityState | null> {\n try {\n const { PublicKey } = await import(\"@solana/web3.js\");\n const anchor = await import(\"@coral-xyz/anchor\");\n\n const programId = new PublicKey(PROGRAM_IDS.iamAnchor);\n const [identityPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"identity\"), new PublicKey(walletPubkey).toBuffer()],\n programId\n );\n\n const accountInfo = await connection.getAccountInfo(identityPda);\n if (!accountInfo) return null;\n\n // Decode using Anchor's BorshAccountsCoder\n const idl = await anchor.Program.fetchIdl(programId, {\n connection,\n } as any);\n if (!idl) return null;\n\n const coder = new anchor.BorshAccountsCoder(idl);\n const decoded = coder.decode(\"identityState\", accountInfo.data);\n\n return {\n owner: decoded.owner.toBase58(),\n creationTimestamp: decoded.creationTimestamp.toNumber(),\n lastVerificationTimestamp: decoded.lastVerificationTimestamp.toNumber(),\n verificationCount: decoded.verificationCount,\n trustScore: decoded.trustScore,\n currentCommitment: new Uint8Array(decoded.currentCommitment),\n mint: decoded.mint.toBase58(),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Store verification data locally for re-verification.\n * Uses localStorage (browser) or in-memory fallback (Node.js).\n */\nexport function storeVerificationData(data: StoredVerificationData): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n } catch {\n // localStorage not available (Node.js or private browsing)\n inMemoryStore = data;\n }\n}\n\n/**\n * Load previously stored verification data.\n */\nexport function loadVerificationData(): StoredVerificationData | null {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return inMemoryStore;\n return JSON.parse(raw);\n } catch {\n return inMemoryStore;\n }\n}\n\nlet inMemoryStore: StoredVerificationData | null = null;\n","import type { PulseConfig } from \"./config\";\nimport { DEFAULT_THRESHOLD, DEFAULT_CAPTURE_MS } from \"./config\";\nimport type { SensorData, AudioCapture, MotionSample, TouchSample, StageState } from \"./sensor/types\";\nimport type { TBH } from \"./hashing/types\";\nimport type { SolanaProof } from \"./proof/types\";\nimport type { VerificationResult } from \"./submit/types\";\nimport type { StoredVerificationData } from \"./identity/types\";\n\nimport { captureAudio } from \"./sensor/audio\";\nimport { captureMotion, requestMotionPermission } from \"./sensor/motion\";\nimport { captureTouch } from \"./sensor/touch\";\nimport { extractSpeakerFeatures, SPEAKER_FEATURE_COUNT } from \"./extraction/speaker\";\nimport {\n extractMotionFeatures,\n extractTouchFeatures,\n extractMouseDynamics,\n} from \"./extraction/kinematic\";\nimport { fuseFeatures } from \"./extraction/statistics\";\nimport { simhash, hammingDistance } from \"./hashing/simhash\";\nimport { generateTBH, bigintToBytes32 } from \"./hashing/poseidon\";\nimport { prepareCircuitInput, generateProof } from \"./proof/prover\";\nimport { serializeProof } from \"./proof/serializer\";\nimport { submitViaWallet } from \"./submit/wallet\";\nimport { submitViaRelayer } from \"./submit/relayer\";\nimport {\n storeVerificationData,\n loadVerificationData,\n} from \"./identity/anchor\";\n\ntype ResolvedConfig = Required<Pick<PulseConfig, \"cluster\" | \"threshold\">> &\n PulseConfig;\n\n/**\n * Extract features from sensor data and fuse into a single vector.\n */\nasync function extractFeatures(data: SensorData): Promise<number[]> {\n if (!data.audio) {\n throw new Error(\"Audio data required for feature extraction\");\n }\n const audioFeatures = await extractSpeakerFeatures(data.audio);\n\n const hasMotion = data.motion.length >= MIN_MOTION_SAMPLES;\n const hasTouch = data.touch.length >= MIN_TOUCH_SAMPLES;\n\n // On mobile (both IMU and touch available), use touch/pointer dynamics for\n // kinematic features. Stationary IMU reads constant gravity — the derivatives\n // are near-zero and produce identical features across sessions. Finger tracing\n // has natural inter-session variance because no two paths are identical.\n const motionFeatures =\n hasMotion && hasTouch\n ? extractMouseDynamics(data.touch)\n : hasMotion\n ? extractMotionFeatures(data.motion)\n : extractMouseDynamics(data.touch);\n\n const touchFeatures = extractTouchFeatures(data.touch);\n return fuseFeatures(audioFeatures, motionFeatures, touchFeatures);\n}\n\n/**\n * Shared pipeline: features → simhash → TBH → proof → submit.\n * Used by both PulseSDK.verify() and PulseSession.complete().\n */\n// Minimum sample counts for meaningful feature extraction\nconst MIN_AUDIO_SAMPLES = 16000; // ~1 second at 16kHz\nconst MIN_MOTION_SAMPLES = 10;\nconst MIN_TOUCH_SAMPLES = 10;\n\nasync function processSensorData(\n sensorData: SensorData,\n config: ResolvedConfig,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Solana types are optional peer deps\n wallet?: any,\n connection?: any\n): Promise<VerificationResult> {\n // Data quality gate: reject if insufficient behavioral data captured\n const audioSamples = sensorData.audio?.samples.length ?? 0;\n const motionSamples = sensorData.motion.length;\n const touchSamples = sensorData.touch.length;\n\n // Need at least audio OR (motion + touch) to produce a meaningful fingerprint\n const hasAudio = audioSamples >= MIN_AUDIO_SAMPLES;\n const hasMotion = motionSamples >= MIN_MOTION_SAMPLES;\n const hasTouch = touchSamples >= MIN_TOUCH_SAMPLES;\n\n if (!hasAudio && !hasMotion && !hasTouch) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: true,\n error: \"Insufficient behavioral data. Please speak the phrase and trace the curve during capture.\",\n };\n }\n\n if (!hasAudio) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: true,\n error: \"No voice data detected. Please speak the phrase clearly during capture.\",\n };\n }\n\n // Re-verification requires audio + at least one other modality.\n // Audio-only fingerprints lack inter-session variance from motion/touch,\n // producing identical SimHash results that fail the min_distance constraint.\n const hasPreviousData = loadVerificationData() !== null;\n if (hasPreviousData && !hasMotion && !hasTouch) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: false,\n error: \"Insufficient sensor data for re-verification. Please trace the curve and allow motion access.\",\n };\n }\n\n // Extract features\n const features = await extractFeatures(sensorData);\n\n // Diagnostic: log feature vector composition\n const nonZero = features.filter((v) => v !== 0).length;\n console.log(\n `[IAM SDK] Feature vector: ${features.length} dimensions, ${nonZero} non-zero. ` +\n `Audio[0..43]: ${features.slice(0, 44).filter((v) => v !== 0).length} non-zero. ` +\n `Motion/Mouse[44..97]: ${features.slice(44, 98).filter((v) => v !== 0).length} non-zero. ` +\n `Touch[98..133]: ${features.slice(98, 134).filter((v) => v !== 0).length} non-zero.`\n );\n\n // Generate fingerprint via SimHash\n const fingerprint = simhash(features);\n\n // Generate TBH (Poseidon commitment)\n const tbh = await generateTBH(fingerprint);\n\n // Check for previous verification data\n const previousData = loadVerificationData();\n const isFirstVerification = !previousData;\n\n let solanaProof: SolanaProof | null = null;\n\n if (!isFirstVerification && previousData) {\n const previousTBH: TBH = {\n fingerprint: previousData.fingerprint,\n salt: BigInt(previousData.salt),\n commitment: BigInt(previousData.commitment),\n commitmentBytes: bigintToBytes32(BigInt(previousData.commitment)),\n };\n\n const distance = hammingDistance(fingerprint, previousData.fingerprint);\n console.log(\n `[IAM SDK] Re-verification: Hamming distance = ${distance} / 256 bits (threshold = ${config.threshold})`\n );\n\n const circuitInput = prepareCircuitInput(\n tbh,\n previousTBH,\n config.threshold\n );\n\n const wasmPath = config.wasmUrl;\n const zkeyPath = config.zkeyUrl;\n\n if (!wasmPath || !zkeyPath) {\n return {\n success: false,\n commitment: tbh.commitmentBytes,\n isFirstVerification: false,\n error: \"wasmUrl and zkeyUrl must be configured for re-verification proof generation\",\n };\n }\n\n try {\n const { proof, publicSignals } = await generateProof(\n circuitInput,\n wasmPath,\n zkeyPath\n );\n solanaProof = serializeProof(proof, publicSignals);\n } catch (proofErr: any) {\n // Include diagnostics in error for mobile debugging (no devtools)\n const audioNZ = features.slice(0, 44).filter((v) => v !== 0).length;\n const motionNZ = features.slice(44, 98).filter((v) => v !== 0).length;\n const touchNZ = features.slice(98, 134).filter((v) => v !== 0).length;\n return {\n success: false,\n commitment: tbh.commitmentBytes,\n isFirstVerification: false,\n error: `Proof failed (distance=${distance}, audio=${audioNZ}/44, motion=${motionNZ}/54, touch=${touchNZ}/36): ${proofErr?.message ?? proofErr}`,\n };\n }\n }\n\n // Submit\n let submission;\n\n if (wallet && connection) {\n if (isFirstVerification) {\n submission = await submitViaWallet(\n solanaProof ?? { proofBytes: new Uint8Array(0), publicInputs: [] },\n tbh.commitmentBytes,\n { wallet, connection, isFirstVerification: true }\n );\n } else {\n submission = await submitViaWallet(solanaProof!, tbh.commitmentBytes, {\n wallet,\n connection,\n isFirstVerification: false,\n });\n }\n } else if (config.relayerUrl) {\n submission = await submitViaRelayer(\n solanaProof ?? { proofBytes: new Uint8Array(0), publicInputs: [] },\n tbh.commitmentBytes,\n { relayerUrl: config.relayerUrl, apiKey: config.relayerApiKey, isFirstVerification }\n );\n } else {\n return {\n success: false,\n commitment: tbh.commitmentBytes,\n isFirstVerification,\n error: \"No wallet or relayer configured\",\n };\n }\n\n // Store verification data locally for next re-verification\n if (submission.success) {\n storeVerificationData({\n fingerprint: tbh.fingerprint,\n salt: tbh.salt.toString(),\n commitment: tbh.commitment.toString(),\n timestamp: Date.now(),\n });\n }\n\n return {\n success: submission.success,\n commitment: tbh.commitmentBytes,\n txSignature: submission.txSignature,\n isFirstVerification,\n error: submission.error,\n };\n}\n\n/**\n * PulseSession — event-driven staged capture session.\n *\n * Gives the caller control over when each sensor stage starts and stops.\n * After all stages complete, call complete() to run the processing pipeline.\n *\n * Usage:\n * const session = pulse.createSession(touchElement);\n * await session.startAudio();\n * // ... user speaks ...\n * await session.stopAudio();\n * await session.startMotion();\n * // ... user holds device ...\n * await session.stopMotion();\n * await session.startTouch();\n * // ... user traces curve ...\n * await session.stopTouch();\n * const result = await session.complete(wallet, connection);\n */\nexport class PulseSession {\n private config: ResolvedConfig;\n private touchElement: HTMLElement | undefined;\n\n private audioStageState: StageState = \"idle\";\n private motionStageState: StageState = \"idle\";\n private touchStageState: StageState = \"idle\";\n\n private audioController: AbortController | null = null;\n private motionController: AbortController | null = null;\n private touchController: AbortController | null = null;\n\n private audioPromise: Promise<AudioCapture | null> | null = null;\n private motionPromise: Promise<MotionSample[]> | null = null;\n private touchPromise: Promise<TouchSample[]> | null = null;\n\n private audioData: AudioCapture | null = null;\n private motionData: MotionSample[] = [];\n private touchData: TouchSample[] = [];\n\n constructor(config: ResolvedConfig, touchElement?: HTMLElement) {\n this.config = config;\n this.touchElement = touchElement;\n }\n\n // --- Audio ---\n\n async startAudio(onAudioLevel?: (rms: number) => void): Promise<void> {\n if (this.audioStageState !== \"idle\")\n throw new Error(\"Audio capture already started\");\n\n // Acquire microphone permission within the user gesture context.\n // Awaited so the caller knows audio is ready before proceeding.\n // State transitions happen AFTER permission succeeds to avoid zombie state.\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n sampleRate: 16000,\n channelCount: 1,\n echoCancellation: false,\n noiseSuppression: false,\n autoGainControl: false,\n },\n });\n\n this.audioStageState = \"capturing\";\n this.audioController = new AbortController();\n this.audioPromise = captureAudio({\n signal: this.audioController.signal,\n onAudioLevel,\n stream,\n }).catch(() => {\n stream.getTracks().forEach((t) => t.stop());\n return null;\n });\n }\n\n async stopAudio(): Promise<AudioCapture | null> {\n if (this.audioStageState !== \"capturing\")\n throw new Error(\"Audio capture not active\");\n this.audioController!.abort();\n this.audioData = await this.audioPromise!;\n this.audioStageState = \"captured\";\n return this.audioData;\n }\n\n // Audio is mandatory — no skipAudio() method.\n // If startAudio() fails, the verification cannot proceed.\n\n // --- Motion ---\n\n async startMotion(): Promise<void> {\n if (this.motionStageState !== \"idle\")\n throw new Error(\"Motion capture already started\");\n\n // Request motion permission within the user gesture context (iOS 13+).\n // Awaited so the capture timer doesn't start before the user approves.\n const hasPermission = await requestMotionPermission();\n if (!hasPermission) {\n this.motionStageState = \"skipped\";\n return;\n }\n\n this.motionStageState = \"capturing\";\n this.motionController = new AbortController();\n this.motionPromise = captureMotion({\n signal: this.motionController.signal,\n permissionGranted: true,\n }).catch(() => []);\n }\n\n async stopMotion(): Promise<MotionSample[]> {\n if (this.motionStageState !== \"capturing\")\n throw new Error(\"Motion capture not active\");\n this.motionController!.abort();\n this.motionData = await this.motionPromise!;\n this.motionStageState = \"captured\";\n return this.motionData;\n }\n\n skipMotion(): void {\n if (this.motionStageState !== \"idle\")\n throw new Error(\"Motion capture already started\");\n this.motionStageState = \"skipped\";\n }\n\n isMotionCapturing(): boolean {\n return this.motionStageState === \"capturing\";\n }\n\n // --- Touch ---\n\n async startTouch(): Promise<void> {\n if (this.touchStageState !== \"idle\")\n throw new Error(\"Touch capture already started\");\n if (!this.touchElement)\n throw new Error(\"No touch element provided to session\");\n this.touchStageState = \"capturing\";\n this.touchController = new AbortController();\n this.touchPromise = captureTouch(this.touchElement, {\n signal: this.touchController.signal,\n }).catch(() => []);\n }\n\n async stopTouch(): Promise<TouchSample[]> {\n if (this.touchStageState !== \"capturing\")\n throw new Error(\"Touch capture not active\");\n this.touchController!.abort();\n this.touchData = await this.touchPromise!;\n this.touchStageState = \"captured\";\n return this.touchData;\n }\n\n skipTouch(): void {\n if (this.touchStageState !== \"idle\")\n throw new Error(\"Touch capture already started\");\n this.touchStageState = \"skipped\";\n }\n\n // --- Complete ---\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Solana types are optional peer deps\n async complete(wallet?: any, connection?: any): Promise<VerificationResult> {\n const active: string[] = [];\n if (this.audioStageState === \"capturing\") active.push(\"audio\");\n if (this.motionStageState === \"capturing\") active.push(\"motion\");\n if (this.touchStageState === \"capturing\") active.push(\"touch\");\n if (active.length > 0) {\n throw new Error(\n `Cannot complete: stages still capturing: ${active.join(\", \")}`\n );\n }\n\n const sensorData: SensorData = {\n audio: this.audioData,\n motion: this.motionData,\n touch: this.touchData,\n modalities: {\n audio: this.audioData !== null,\n motion: this.motionData.length > 0,\n touch: this.touchData.length > 0,\n },\n };\n\n return processSensorData(sensorData, this.config, wallet, connection);\n }\n}\n\n/**\n * PulseSDK — main entry point for IAM Protocol verification.\n *\n * Two usage modes:\n * 1. Simple (backward-compatible): pulse.verify(touchElement) — captures all sensors\n * for DEFAULT_CAPTURE_MS in parallel, then processes.\n * 2. Staged (event-driven): pulse.createSession(touchElement) — caller controls\n * when each sensor stage starts and stops.\n */\nexport class PulseSDK {\n private config: ResolvedConfig;\n\n constructor(config: PulseConfig) {\n this.config = {\n threshold: DEFAULT_THRESHOLD,\n ...config,\n };\n }\n\n /**\n * Create a staged capture session for event-driven control.\n */\n createSession(touchElement?: HTMLElement): PulseSession {\n return new PulseSession(this.config, touchElement);\n }\n\n /**\n * Run a full verification with automatic timed capture (backward-compatible).\n * Captures all sensors in parallel for DEFAULT_CAPTURE_MS, then processes.\n */\n async verify(\n touchElement?: HTMLElement,\n wallet?: any,\n connection?: any\n ): Promise<VerificationResult> {\n try {\n const session = this.createSession(touchElement);\n const stopPromises: Promise<void>[] = [];\n\n // Motion first — requires user gesture on iOS (gesture expires after getUserMedia)\n try {\n await session.startMotion();\n } catch {\n /* unexpected error — motion already skipped or idle */\n }\n if (session.isMotionCapturing()) {\n stopPromises.push(\n new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))\n .then(() => session.stopMotion())\n .then(() => {})\n );\n }\n\n // Audio second — getUserMedia works without a gesture on secure origins\n try {\n await session.startAudio();\n stopPromises.push(\n new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))\n .then(() => session.stopAudio())\n .then(() => {})\n );\n } catch (err: any) {\n throw new Error(`Audio capture failed: ${err?.message ?? \"microphone unavailable\"}`);\n }\n\n // Touch\n if (touchElement) {\n try {\n await session.startTouch();\n stopPromises.push(\n new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))\n .then(() => session.stopTouch())\n .then(() => {})\n );\n } catch {\n session.skipTouch();\n }\n } else {\n session.skipTouch();\n }\n\n await Promise.all(stopPromises);\n return session.complete(wallet, connection);\n } catch (err: any) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: true,\n error: err.message ?? String(err),\n };\n }\n }\n}\n","// Phonetically-balanced nonsense syllables for the voice challenge.\n// Designed to elicit diverse vocal patterns while preventing dictionary-based deepfake attacks.\nconst SYLLABLES = [\n \"ba\", \"da\", \"fa\", \"ga\", \"ha\", \"ja\", \"ka\", \"la\", \"ma\", \"na\",\n \"pa\", \"ra\", \"sa\", \"ta\", \"wa\", \"za\", \"be\", \"de\", \"fe\", \"ge\",\n \"ke\", \"le\", \"me\", \"ne\", \"pe\", \"re\", \"se\", \"te\", \"we\", \"ze\",\n \"bi\", \"di\", \"fi\", \"gi\", \"ki\", \"li\", \"mi\", \"ni\", \"pi\", \"ri\",\n \"si\", \"ti\", \"wi\", \"zi\", \"bo\", \"do\", \"fo\", \"go\", \"ko\", \"lo\",\n \"mo\", \"no\", \"po\", \"ro\", \"so\", \"to\", \"wo\", \"zo\", \"bu\", \"du\",\n \"fu\", \"gu\", \"ku\", \"lu\", \"mu\", \"nu\", \"pu\", \"ru\", \"su\", \"tu\",\n];\n\n/** Cryptographically random integer in [0, max) */\nfunction secureRandom(max: number): number {\n const arr = new Uint32Array(1);\n crypto.getRandomValues(arr);\n return arr[0]! % max;\n}\n\n/**\n * Generate a random phonetically-balanced phrase for the voice challenge.\n * Each phrase is 5-6 syllable pairs, forming nonsensical but speakable words.\n * Uses crypto.getRandomValues for unpredictable challenge generation.\n */\nexport function generatePhrase(wordCount: number = 5): string {\n const words: string[] = [];\n for (let w = 0; w < wordCount; w++) {\n const syllableCount = 2 + secureRandom(2);\n let word = \"\";\n for (let s = 0; s < syllableCount; s++) {\n word += SYLLABLES[secureRandom(SYLLABLES.length)];\n }\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Generate a sequence of phrases for dynamic mid-session switching.\n * Each phrase uses a different syllable subset to prevent pre-computation.\n */\nexport function generatePhraseSequence(\n count: number = 3,\n wordCount: number = 4\n): string[] {\n const subsetSize = Math.floor(SYLLABLES.length / count);\n const phrases: string[] = [];\n\n for (let p = 0; p < count; p++) {\n const start = (p * subsetSize) % SYLLABLES.length;\n const subset = [\n ...SYLLABLES.slice(start, start + subsetSize),\n ...SYLLABLES.slice(0, Math.max(0, (start + subsetSize) - SYLLABLES.length)),\n ];\n\n const words: string[] = [];\n for (let w = 0; w < wordCount; w++) {\n const syllableCount = 2 + secureRandom(2);\n let word = \"\";\n for (let s = 0; s < syllableCount; s++) {\n word += subset[secureRandom(subset.length)];\n }\n words.push(word);\n }\n phrases.push(words.join(\" \"));\n }\n\n return phrases;\n}\n","/**\n * Generate Lissajous curve points for the touch tracing challenge.\n * The user traces this shape on screen while speaking the phrase.\n *\n * x(t) = A * sin(a*t + delta)\n * y(t) = B * sin(b*t)\n */\nexport interface LissajousParams {\n a: number;\n b: number;\n delta: number;\n points: number;\n}\n\nexport interface Point2D {\n x: number;\n y: number;\n}\n\n/**\n * Generate random Lissajous parameters for a challenge.\n */\nexport function randomLissajousParams(): LissajousParams {\n const ratios = [\n [1, 2],\n [2, 3],\n [3, 4],\n [3, 5],\n [4, 5],\n ];\n const arr = new Uint32Array(2);\n crypto.getRandomValues(arr);\n const pair = ratios[arr[0]! % ratios.length]!;\n return {\n a: pair[0]!,\n b: pair[1]!,\n delta: Math.PI * (0.25 + (arr[1]! / 0xFFFFFFFF) * 0.5),\n points: 200,\n };\n}\n\n/**\n * Generate Lissajous curve points normalized to [0, 1] range.\n */\nexport function generateLissajousPoints(params: LissajousParams): Point2D[] {\n const { a, b, delta, points } = params;\n const result: Point2D[] = [];\n\n for (let i = 0; i < points; i++) {\n const t = (i / points) * 2 * Math.PI;\n result.push({\n x: (Math.sin(a * t + delta) + 1) / 2,\n y: (Math.sin(b * t) + 1) / 2,\n });\n }\n\n return result;\n}\n\n/**\n * Generate a sequence of Lissajous curves for dynamic mid-session switching.\n * Each curve uses different parameters, preventing pre-computation.\n */\nexport function generateLissajousSequence(\n count: number = 2\n): { params: LissajousParams; points: Point2D[] }[] {\n const allRatios: [number, number][] = [\n [1, 2], [2, 3], [3, 4], [3, 5], [4, 5],\n [1, 3], [2, 5], [5, 6], [3, 7], [4, 7],\n ];\n\n // Fisher-Yates shuffle with crypto randomness\n const shuffled = [...allRatios];\n for (let i = shuffled.length - 1; i > 0; i--) {\n const arr = new Uint32Array(1);\n crypto.getRandomValues(arr);\n const j = arr[0]! % (i + 1);\n [shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!];\n }\n\n const sequence: { params: LissajousParams; points: Point2D[] }[] = [];\n\n for (let i = 0; i < count; i++) {\n const pair = shuffled[i % shuffled.length]!;\n const deltaArr = new Uint32Array(1);\n crypto.getRandomValues(deltaArr);\n const params: LissajousParams = {\n a: pair[0],\n b: pair[1],\n delta: Math.PI * (0.1 + (deltaArr[0]! / 0xFFFFFFFF) * 0.8),\n points: 200,\n };\n sequence.push({ params, points: generateLissajousPoints(params) });\n }\n\n return sequence;\n}\n"],"mappings":"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","names":["mean","derivative","window"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/sensor/audio.ts","../src/sensor/motion.ts","../src/sensor/touch.ts","../src/extraction/statistics.ts","../src/extraction/lpc.ts","../src/extraction/speaker.ts","../src/extraction/kinematic.ts","../src/hashing/simhash.ts","../src/hashing/poseidon.ts","../src/proof/serializer.ts","../src/proof/prover.ts","../src/submit/wallet.ts","../src/submit/relayer.ts","../src/identity/anchor.ts","../src/pulse.ts","../src/challenge/phrase.ts","../src/challenge/lissajous.ts"],"sourcesContent":["// Main SDK\nexport { PulseSDK, PulseSession } from \"./pulse\";\n\n// Configuration\nexport type { PulseConfig } from \"./config\";\nexport { PROGRAM_IDS, DEFAULT_THRESHOLD, DEFAULT_MIN_DISTANCE, FINGERPRINT_BITS, MIN_CAPTURE_MS, MAX_CAPTURE_MS, DEFAULT_CAPTURE_MS } from \"./config\";\n\n// Hashing\nexport type { TemporalFingerprint, TBH, PackedFingerprint } from \"./hashing/types\";\nexport { simhash, hammingDistance } from \"./hashing/simhash\";\nexport {\n computeCommitment,\n generateSalt,\n generateTBH,\n packBits,\n bigintToBytes32,\n} from \"./hashing/poseidon\";\n\n// Feature extraction\nexport type { StatsSummary, FeatureVector, FusedFeatureVector } from \"./extraction/types\";\nexport { mean, variance, skewness, kurtosis, condense, entropy, autocorrelation, fuseFeatures } from \"./extraction/statistics\";\nexport { extractSpeakerFeatures, SPEAKER_FEATURE_COUNT } from \"./extraction/speaker\";\nexport { extractMotionFeatures, extractTouchFeatures, extractMouseDynamics } from \"./extraction/kinematic\";\n\n// Proof generation\nexport type { SolanaProof, CircuitInput, ProofResult } from \"./proof/types\";\nexport { serializeProof, toBigEndian32 } from \"./proof/serializer\";\nexport { generateProof, generateSolanaProof, prepareCircuitInput } from \"./proof/prover\";\n\n// Submission\nexport type { SubmissionResult, VerificationResult } from \"./submit/types\";\nexport { submitViaWallet } from \"./submit/wallet\";\nexport { submitViaRelayer } from \"./submit/relayer\";\n\n// Identity\nexport type { IdentityState, StoredVerificationData } from \"./identity/types\";\nexport { fetchIdentityState, storeVerificationData, loadVerificationData } from \"./identity/anchor\";\n\n// Sensor types\nexport type { AudioCapture, MotionSample, TouchSample, SensorData, CaptureOptions, CaptureStage, StageState } from \"./sensor/types\";\n\n// Challenge\nexport { generatePhrase, generatePhraseSequence } from \"./challenge/phrase\";\nexport { randomLissajousParams, generateLissajousPoints, generateLissajousSequence } from \"./challenge/lissajous\";\nexport type { LissajousParams, Point2D } from \"./challenge/lissajous\";\n","// BN254 base field prime (for G1 point negation in proof_a)\nexport const BN254_BASE_FIELD = BigInt(\n \"21888242871839275222246405745257275088696311157297823662689037894645226208583\"\n);\n\n// BN254 scalar field prime (for salt generation, field element bounds)\nexport const BN254_SCALAR_FIELD = BigInt(\n \"21888242871839275222246405745257275088548364400416034343698204186575808495617\"\n);\n\nexport const FINGERPRINT_BITS = 256;\nexport const DEFAULT_THRESHOLD = 96;\nexport const DEFAULT_MIN_DISTANCE = 3;\nexport const NUM_PUBLIC_INPUTS = 4;\n\nexport const PROOF_A_SIZE = 64;\nexport const PROOF_B_SIZE = 128;\nexport const PROOF_C_SIZE = 64;\nexport const TOTAL_PROOF_SIZE = 256;\n\nexport const SIMHASH_SEED = \"IAM-PROTOCOL-SIMHASH-V1\";\n\n// Capture duration bounds (ms)\nexport const MIN_CAPTURE_MS = 2000;\nexport const MAX_CAPTURE_MS = 60000;\nexport const DEFAULT_CAPTURE_MS = 7000;\n\nexport const PROGRAM_IDS = {\n iamAnchor: \"GZYwTp2ozeuRA5Gof9vs4ya961aANcJBdUzB7LN6q4b2\",\n iamVerifier: \"4F97jNoxQzT2qRbkWpW3ztC3Nz2TtKj3rnKG8ExgnrfV\",\n iamRegistry: \"6VBs3zr9KrfFPGd6j7aGBPQWwZa5tajVfA7HN6MMV9VW\",\n} as const;\n\nexport interface PulseConfig {\n cluster: \"devnet\" | \"mainnet-beta\" | \"localnet\";\n rpcEndpoint?: string;\n relayerUrl?: string;\n relayerApiKey?: string;\n zkeyUrl?: string;\n wasmUrl?: string;\n threshold?: number;\n}\n","import type { AudioCapture, CaptureOptions } from \"./types\";\nimport { MIN_CAPTURE_MS, MAX_CAPTURE_MS } from \"../config\";\n\nconst TARGET_SAMPLE_RATE = 16000;\n\n/**\n * Capture audio at 16kHz until signaled to stop.\n * Uses ScriptProcessorNode for raw PCM sample access.\n *\n * Stop behavior:\n * - If signal fires before minDurationMs, capture continues until minimum is reached.\n * - If signal never fires, capture auto-stops at maxDurationMs.\n * - If no signal provided, captures for maxDurationMs.\n */\nexport async function captureAudio(\n options: CaptureOptions = {}\n): Promise<AudioCapture> {\n const {\n signal,\n minDurationMs = MIN_CAPTURE_MS,\n maxDurationMs = MAX_CAPTURE_MS,\n onAudioLevel,\n stream: preAcquiredStream,\n } = options;\n\n const stream = preAcquiredStream ?? await navigator.mediaDevices.getUserMedia({\n audio: {\n sampleRate: TARGET_SAMPLE_RATE,\n channelCount: 1,\n echoCancellation: false,\n noiseSuppression: false,\n autoGainControl: false,\n },\n });\n\n const ctx = new AudioContext({ sampleRate: TARGET_SAMPLE_RATE });\n await ctx.resume(); // Required on iOS — AudioContext may be suspended outside user gesture\n const capturedSampleRate = ctx.sampleRate;\n const source = ctx.createMediaStreamSource(stream);\n const chunks: Float32Array[] = [];\n const startTime = performance.now();\n\n return new Promise((resolve) => {\n let stopped = false;\n const bufferSize = 4096;\n const processor = ctx.createScriptProcessor(bufferSize, 1, 1);\n\n processor.onaudioprocess = (e: AudioProcessingEvent) => {\n const data = e.inputBuffer.getChannelData(0);\n chunks.push(new Float32Array(data));\n\n if (onAudioLevel) {\n let sum = 0;\n for (let i = 0; i < data.length; i++) sum += data[i]! * data[i]!;\n onAudioLevel(Math.sqrt(sum / data.length));\n }\n };\n\n source.connect(processor);\n processor.connect(ctx.destination);\n\n function stopCapture() {\n if (stopped) return;\n stopped = true;\n clearTimeout(maxTimer);\n\n processor.disconnect();\n source.disconnect();\n stream.getTracks().forEach((t: MediaStreamTrack) => t.stop());\n ctx.close().catch(() => {});\n\n const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);\n const samples = new Float32Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n samples.set(chunk, offset);\n offset += chunk.length;\n }\n\n resolve({\n samples,\n sampleRate: capturedSampleRate,\n duration: totalLength / capturedSampleRate,\n });\n }\n\n const maxTimer = setTimeout(stopCapture, maxDurationMs);\n\n if (signal) {\n if (signal.aborted) {\n setTimeout(stopCapture, minDurationMs);\n } else {\n signal.addEventListener(\n \"abort\",\n () => {\n const elapsed = performance.now() - startTime;\n const remaining = Math.max(0, minDurationMs - elapsed);\n setTimeout(stopCapture, remaining);\n },\n { once: true }\n );\n }\n }\n });\n}\n","import type { MotionSample, CaptureOptions } from \"./types\";\nimport { MIN_CAPTURE_MS, MAX_CAPTURE_MS } from \"../config\";\n\n/**\n * Request motion sensor permission (required on iOS 13+).\n * No-op on Android/Chrome where permission is implicit.\n */\nexport async function requestMotionPermission(): Promise<boolean> {\n const DME = (globalThis as any).DeviceMotionEvent;\n if (!DME) return false;\n\n if (typeof DME.requestPermission === \"function\") {\n const permission = await DME.requestPermission();\n return permission === \"granted\";\n }\n\n // Android/Chrome: permission is implicit\n return true;\n}\n\n/**\n * Capture accelerometer + gyroscope data until signaled to stop.\n * Samples at the device's native rate (typically ~60-100Hz).\n */\nexport async function captureMotion(\n options: CaptureOptions = {}\n): Promise<MotionSample[]> {\n const {\n signal,\n minDurationMs = MIN_CAPTURE_MS,\n maxDurationMs = MAX_CAPTURE_MS,\n } = options;\n\n const hasPermission = options.permissionGranted ?? await requestMotionPermission();\n if (!hasPermission) return [];\n\n const samples: MotionSample[] = [];\n const startTime = performance.now();\n\n return new Promise((resolve) => {\n let stopped = false;\n\n const handler = (e: DeviceMotionEvent) => {\n samples.push({\n timestamp: performance.now(),\n ax: e.acceleration?.x ?? 0,\n ay: e.acceleration?.y ?? 0,\n az: e.acceleration?.z ?? 0,\n gx: e.rotationRate?.alpha ?? 0,\n gy: e.rotationRate?.beta ?? 0,\n gz: e.rotationRate?.gamma ?? 0,\n });\n };\n\n function stopCapture() {\n if (stopped) return;\n stopped = true;\n clearTimeout(maxTimer);\n window.removeEventListener(\"devicemotion\", handler);\n resolve(samples);\n }\n\n window.addEventListener(\"devicemotion\", handler);\n\n const maxTimer = setTimeout(stopCapture, maxDurationMs);\n\n if (signal) {\n if (signal.aborted) {\n setTimeout(stopCapture, minDurationMs);\n } else {\n signal.addEventListener(\n \"abort\",\n () => {\n const elapsed = performance.now() - startTime;\n const remaining = Math.max(0, minDurationMs - elapsed);\n setTimeout(stopCapture, remaining);\n },\n { once: true }\n );\n }\n }\n });\n}\n","import type { TouchSample, CaptureOptions } from \"./types\";\nimport { MIN_CAPTURE_MS, MAX_CAPTURE_MS } from \"../config\";\n\n/**\n * Capture touch/pointer data (position, pressure, contact area) until signaled to stop.\n * Uses PointerEvent for cross-platform support (touch, pen, mouse).\n */\nexport function captureTouch(\n element: HTMLElement,\n options: CaptureOptions = {}\n): Promise<TouchSample[]> {\n const {\n signal,\n minDurationMs = MIN_CAPTURE_MS,\n maxDurationMs = MAX_CAPTURE_MS,\n } = options;\n\n const samples: TouchSample[] = [];\n const startTime = performance.now();\n\n return new Promise((resolve) => {\n let stopped = false;\n\n const handler = (e: PointerEvent) => {\n samples.push({\n timestamp: performance.now(),\n x: e.clientX,\n y: e.clientY,\n pressure: e.pressure,\n width: e.width,\n height: e.height,\n });\n };\n\n function stopCapture() {\n if (stopped) return;\n stopped = true;\n clearTimeout(maxTimer);\n element.removeEventListener(\"pointermove\", handler);\n element.removeEventListener(\"pointerdown\", handler);\n console.log(`[IAM SDK] Touch capture stopped: ${samples.length} samples collected`);\n resolve(samples);\n }\n\n element.addEventListener(\"pointermove\", handler);\n element.addEventListener(\"pointerdown\", handler);\n console.log(`[IAM SDK] Touch capture started on <${element.tagName}>, listening for pointer events`);\n\n const maxTimer = setTimeout(stopCapture, maxDurationMs);\n\n if (signal) {\n if (signal.aborted) {\n setTimeout(stopCapture, minDurationMs);\n } else {\n signal.addEventListener(\n \"abort\",\n () => {\n const elapsed = performance.now() - startTime;\n const remaining = Math.max(0, minDurationMs - elapsed);\n setTimeout(stopCapture, remaining);\n },\n { once: true }\n );\n }\n }\n });\n}\n","import type { StatsSummary } from \"./types\";\n\nexport function mean(values: number[]): number {\n if (values.length === 0) return 0;\n let sum = 0;\n for (const v of values) sum += v;\n return sum / values.length;\n}\n\nexport function variance(values: number[], mu?: number): number {\n if (values.length < 2) return 0;\n const m = mu ?? mean(values);\n let sum = 0;\n for (const v of values) sum += (v - m) ** 2;\n return sum / (values.length - 1);\n}\n\nexport function skewness(values: number[]): number {\n if (values.length < 3) return 0;\n const n = values.length;\n const m = mean(values);\n const s = Math.sqrt(variance(values, m));\n if (s === 0) return 0;\n let sum = 0;\n for (const v of values) sum += ((v - m) / s) ** 3;\n return (n / ((n - 1) * (n - 2))) * sum;\n}\n\nexport function kurtosis(values: number[]): number {\n if (values.length < 4) return 0;\n const n = values.length;\n const m = mean(values);\n const s2 = variance(values, m);\n if (s2 === 0) return 0;\n let sum = 0;\n for (const v of values) sum += ((v - m) ** 4) / s2 ** 2;\n const k =\n ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sum -\n (3 * (n - 1) ** 2) / ((n - 2) * (n - 3));\n return k;\n}\n\nexport function condense(values: number[]): StatsSummary {\n const m = mean(values);\n return {\n mean: m,\n variance: variance(values, m),\n skewness: skewness(values),\n kurtosis: kurtosis(values),\n };\n}\n\n/**\n * Shannon entropy over histogram bins. Measures information density.\n * Real human data has moderate entropy (varied but structured).\n * Synthetic data is either too uniform (high entropy) or too structured (low entropy).\n */\nexport function entropy(values: number[], bins: number = 16): number {\n if (values.length < 2) return 0;\n let min = values[0]!;\n let max = values[0]!;\n for (let i = 1; i < values.length; i++) {\n if (values[i]! < min) min = values[i]!;\n if (values[i]! > max) max = values[i]!;\n }\n if (min === max) return 0;\n\n const counts = new Array(bins).fill(0);\n const range = max - min;\n for (const v of values) {\n const idx = Math.min(Math.floor(((v - min) / range) * bins), bins - 1);\n counts[idx]++;\n }\n\n let h = 0;\n for (const c of counts) {\n if (c > 0) {\n const p = c / values.length;\n h -= p * Math.log2(p);\n }\n }\n return h;\n}\n\n/**\n * Autocorrelation at a given lag. Detects periodic synthetic patterns.\n * Real human data has low autocorrelation at most lags (chaotic/noisy).\n * Synthetic data often has high autocorrelation (periodic/smooth).\n */\nexport function autocorrelation(values: number[], lag: number = 1): number {\n if (values.length <= lag) return 0;\n const m = mean(values);\n const v = variance(values, m);\n if (v === 0) return 0;\n\n let sum = 0;\n for (let i = 0; i < values.length - lag; i++) {\n sum += (values[i]! - m) * (values[i + lag]! - m);\n }\n return sum / ((values.length - lag) * v);\n}\n\n/**\n * Normalize a feature group to zero mean and unit variance.\n * Ensures each modality (audio, motion, touch) contributes equally\n * to SimHash hyperplane projections regardless of raw magnitude scale.\n */\nfunction normalizeGroup(features: number[]): number[] {\n if (features.length === 0) return features;\n\n // Sanitize NaN/Infinity to 0 before computing stats.\n // Meyda spectral features can produce NaN on near-silent frames (0/0),\n // and a single NaN would poison the entire modality group.\n const clean = features.map((v) => (Number.isFinite(v) ? v : 0));\n\n let sum = 0;\n for (const v of clean) sum += v;\n const mean = sum / clean.length;\n\n let sqSum = 0;\n for (const v of clean) sqSum += (v - mean) * (v - mean);\n const std = Math.sqrt(sqSum / clean.length);\n\n if (std === 0) return clean.map(() => 0);\n return clean.map((v) => (v - mean) / std);\n}\n\nexport function fuseFeatures(\n audio: number[],\n motion: number[],\n touch: number[]\n): number[] {\n return [...normalizeGroup(audio), ...normalizeGroup(motion), ...normalizeGroup(touch)];\n}\n","/**\n * Linear Predictive Coding (LPC) for formant detection.\n *\n * Implements Levinson-Durbin recursion for LPC coefficient computation\n * and polynomial root-finding for formant frequency estimation.\n */\n\n/**\n * Compute autocorrelation of a signal for lags 0..order.\n */\nfunction autocorrelate(signal: Float32Array, order: number): number[] {\n const r: number[] = [];\n for (let lag = 0; lag <= order; lag++) {\n let sum = 0;\n for (let i = 0; i < signal.length - lag; i++) {\n sum += signal[i]! * signal[i + lag]!;\n }\n r.push(sum);\n }\n return r;\n}\n\n/**\n * Levinson-Durbin recursion to compute LPC coefficients from autocorrelation.\n * Returns the LPC coefficients a[1..order] (a[0] is implicitly 1).\n */\nfunction levinsonDurbin(r: number[], order: number): number[] {\n const a: number[] = new Array(order + 1).fill(0);\n const aTemp: number[] = new Array(order + 1).fill(0);\n a[0] = 1;\n\n let error = r[0]!;\n if (error === 0) return new Array(order).fill(0);\n\n for (let i = 1; i <= order; i++) {\n let lambda = 0;\n for (let j = 1; j < i; j++) {\n lambda += a[j]! * r[i - j]!;\n }\n lambda = -(r[i]! + lambda) / error;\n\n for (let j = 1; j < i; j++) {\n aTemp[j] = a[j]! + lambda * a[i - j]!;\n }\n aTemp[i] = lambda;\n\n for (let j = 1; j <= i; j++) {\n a[j] = aTemp[j]!;\n }\n\n error *= 1 - lambda * lambda;\n if (error <= 0) break;\n }\n\n return a.slice(1);\n}\n\n/**\n * Find roots of a polynomial using the Durand-Kerner method.\n * The polynomial is 1 + a[0]*z^-1 + a[1]*z^-2 + ... + a[n-1]*z^-n\n * which is equivalent to z^n + a[0]*z^(n-1) + ... + a[n-1] = 0.\n *\n * Returns complex roots as [real, imag] pairs.\n */\nfunction findRoots(coefficients: number[], maxIterations: number = 50): [number, number][] {\n const n = coefficients.length;\n if (n === 0) return [];\n\n // Initial guesses: points on a circle of radius 0.9\n const roots: [number, number][] = [];\n for (let i = 0; i < n; i++) {\n const angle = (2 * Math.PI * i) / n + 0.1;\n roots.push([0.9 * Math.cos(angle), 0.9 * Math.sin(angle)]);\n }\n\n for (let iter = 0; iter < maxIterations; iter++) {\n let maxShift = 0;\n\n for (let i = 0; i < n; i++) {\n // Evaluate polynomial at roots[i]: z^n + a[0]*z^(n-1) + ... + a[n-1]\n let pReal = 1;\n let pImag = 0;\n let zPowReal = 1;\n let zPowImag = 0;\n\n // Compute z^n by repeated multiplication\n const [rr, ri] = roots[i]!;\n let curReal = 1;\n let curImag = 0;\n\n // Evaluate as: z^n + sum(a[k] * z^(n-1-k))\n // Start with z^n\n let znReal = 1;\n let znImag = 0;\n for (let k = 0; k < n; k++) {\n const newReal = znReal * rr - znImag * ri;\n const newImag = znReal * ri + znImag * rr;\n znReal = newReal;\n znImag = newImag;\n }\n pReal = znReal;\n pImag = znImag;\n\n // Add coefficient terms: a[k] * z^(n-1-k)\n zPowReal = 1;\n zPowImag = 0;\n for (let k = n - 1; k >= 0; k--) {\n pReal += coefficients[k]! * zPowReal;\n pImag += coefficients[k]! * zPowImag;\n const newReal = zPowReal * rr - zPowImag * ri;\n const newImag = zPowReal * ri + zPowImag * rr;\n zPowReal = newReal;\n zPowImag = newImag;\n }\n\n // Compute product of (roots[i] - roots[j]) for j != i\n let denomReal = 1;\n let denomImag = 0;\n for (let j = 0; j < n; j++) {\n if (j === i) continue;\n const diffReal = rr - roots[j]![0];\n const diffImag = ri - roots[j]![1];\n const newReal = denomReal * diffReal - denomImag * diffImag;\n const newImag = denomReal * diffImag + denomImag * diffReal;\n denomReal = newReal;\n denomImag = newImag;\n }\n\n // Divide p / denom\n const denomMag2 = denomReal * denomReal + denomImag * denomImag;\n if (denomMag2 < 1e-30) continue;\n\n const shiftReal = (pReal * denomReal + pImag * denomImag) / denomMag2;\n const shiftImag = (pImag * denomReal - pReal * denomImag) / denomMag2;\n\n roots[i] = [rr - shiftReal, ri - shiftImag];\n maxShift = Math.max(maxShift, Math.sqrt(shiftReal * shiftReal + shiftImag * shiftImag));\n }\n\n if (maxShift < 1e-10) break;\n }\n\n return roots;\n}\n\n/**\n * Extract formant frequencies (F1, F2, F3) from a single audio frame.\n * Returns [F1, F2, F3] in Hz, or null if extraction fails.\n */\nfunction extractFormants(\n frame: Float32Array,\n sampleRate: number,\n lpcOrder: number = 12\n): [number, number, number] | null {\n const r = autocorrelate(frame, lpcOrder);\n const coeffs = levinsonDurbin(r, lpcOrder);\n\n const roots = findRoots(coeffs);\n\n // Convert roots to frequencies, keep only positive-frequency roots\n const formantCandidates: number[] = [];\n\n for (const [real, imag] of roots) {\n if (imag <= 0) continue; // Keep only positive-frequency roots\n\n const freq = (Math.atan2(imag, real) / (2 * Math.PI)) * sampleRate;\n const bandwidth = (-sampleRate / (2 * Math.PI)) * Math.log(Math.sqrt(real * real + imag * imag));\n\n // Filter: formants are in 200-5000Hz range with reasonable bandwidth\n if (freq > 200 && freq < 5000 && bandwidth < 500) {\n formantCandidates.push(freq);\n }\n }\n\n formantCandidates.sort((a, b) => a - b);\n\n if (formantCandidates.length < 3) return null;\n\n return [formantCandidates[0]!, formantCandidates[1]!, formantCandidates[2]!];\n}\n\n/**\n * Extract formant ratio time series (F1/F2 and F2/F3) from audio.\n * Returns { f1f2: number[], f2f3: number[] } — one ratio per frame where formants were detected.\n */\nexport function extractFormantRatios(\n samples: Float32Array,\n sampleRate: number,\n frameSize: number,\n hopSize: number\n): { f1f2: number[]; f2f3: number[] } {\n const f1f2: number[] = [];\n const f2f3: number[] = [];\n const numFrames = Math.floor((samples.length - frameSize) / hopSize) + 1;\n\n for (let i = 0; i < numFrames; i++) {\n const start = i * hopSize;\n const frame = samples.slice(start, start + frameSize);\n\n // Apply Hamming window\n const windowed = new Float32Array(frameSize);\n for (let j = 0; j < frameSize; j++) {\n windowed[j] = (frame[j] ?? 0) * (0.54 - 0.46 * Math.cos((2 * Math.PI * j) / (frameSize - 1)));\n }\n\n const formants = extractFormants(windowed, sampleRate);\n if (formants) {\n const [f1, f2, f3] = formants;\n if (f2 > 0) f1f2.push(f1 / f2);\n if (f3 > 0) f2f3.push(f2 / f3);\n }\n }\n\n return { f1f2, f2f3 };\n}\n","/**\n * Speaker-dependent audio feature extraction.\n *\n * Extracts features that characterize HOW someone speaks (prosody, vocal physiology)\n * rather than WHAT they say (phonetic content). These features are stable across\n * different utterances from the same speaker.\n *\n * Output: 44 values\n * F0 statistics (5) + F0 delta (4) + jitter (4) + shimmer (4) +\n * HNR statistics (5) + formant ratios (8) + LTAS (8) + voicing ratio (1) +\n * amplitude statistics (5)\n */\nimport type { AudioCapture } from \"../sensor/types\";\nimport { condense, entropy } from \"./statistics\";\nimport { extractFormantRatios } from \"./lpc\";\n\nconst FRAME_SIZE = 512; // ~32ms at 16kHz, power of 2 for FFT\nconst HOP_SIZE = 160; // ~10ms hop\nconst SPEAKER_FEATURE_COUNT = 44;\n\n// Dynamic imports for browser compatibility\nlet pitchDetector: ((buf: Float32Array) => number | null) | null = null;\nlet pitchDetectorRate = 0;\nlet meydaModule: any = null;\n\nasync function getPitchDetector(sampleRate: number): Promise<(buf: Float32Array) => number | null> {\n if (!pitchDetector || pitchDetectorRate !== sampleRate) {\n const PitchFinder = await import(\"pitchfinder\");\n pitchDetector = PitchFinder.YIN({ sampleRate });\n pitchDetectorRate = sampleRate;\n }\n return pitchDetector;\n}\n\nasync function getMeyda(): Promise<any> {\n if (!meydaModule) {\n try {\n meydaModule = await import(\"meyda\");\n } catch {\n return null;\n }\n }\n return meydaModule.default ?? meydaModule;\n}\n\n/**\n * Detect F0 (fundamental frequency) contour and amplitude peaks per frame.\n */\nasync function detectF0Contour(\n samples: Float32Array,\n sampleRate: number\n): Promise<{ f0: number[]; amplitudes: number[]; periods: number[] }> {\n const detect = await getPitchDetector(sampleRate);\n const f0: number[] = [];\n const amplitudes: number[] = [];\n const periods: number[] = [];\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n\n for (let i = 0; i < numFrames; i++) {\n const start = i * HOP_SIZE;\n const frame = samples.slice(start, start + FRAME_SIZE);\n\n // F0 detection\n const pitch = detect(frame);\n if (pitch && pitch > 50 && pitch < 600) {\n f0.push(pitch);\n periods.push(1 / pitch);\n } else {\n f0.push(0); // unvoiced frame\n }\n\n // RMS amplitude per frame\n let sum = 0;\n for (let j = 0; j < frame.length; j++) {\n sum += (frame[j] ?? 0) * (frame[j] ?? 0);\n }\n amplitudes.push(Math.sqrt(sum / frame.length));\n }\n\n return { f0, amplitudes, periods };\n}\n\n/**\n * Compute jitter measures from pitch period contour.\n * Jitter = cycle-to-cycle perturbation of the fundamental period.\n */\nfunction computeJitter(periods: number[]): number[] {\n const voiced = periods.filter((p) => p > 0);\n if (voiced.length < 3) return [0, 0, 0, 0];\n\n const meanPeriod = voiced.reduce((a, b) => a + b, 0) / voiced.length;\n if (meanPeriod === 0) return [0, 0, 0, 0];\n\n // Jitter (local): average absolute difference between consecutive periods\n let localSum = 0;\n for (let i = 1; i < voiced.length; i++) {\n localSum += Math.abs(voiced[i]! - voiced[i - 1]!);\n }\n const jitterLocal = localSum / (voiced.length - 1) / meanPeriod;\n\n // RAP: Relative Average Perturbation (3-point running average)\n let rapSum = 0;\n for (let i = 1; i < voiced.length - 1; i++) {\n const avg3 = (voiced[i - 1]! + voiced[i]! + voiced[i + 1]!) / 3;\n rapSum += Math.abs(voiced[i]! - avg3);\n }\n const jitterRAP = voiced.length > 2 ? rapSum / (voiced.length - 2) / meanPeriod : 0;\n\n // PPQ5: Five-Point Period Perturbation Quotient\n let ppq5Sum = 0;\n let ppq5Count = 0;\n for (let i = 2; i < voiced.length - 2; i++) {\n const avg5 = (voiced[i - 2]! + voiced[i - 1]! + voiced[i]! + voiced[i + 1]! + voiced[i + 2]!) / 5;\n ppq5Sum += Math.abs(voiced[i]! - avg5);\n ppq5Count++;\n }\n const jitterPPQ5 = ppq5Count > 0 ? ppq5Sum / ppq5Count / meanPeriod : 0;\n\n // DDP: Difference of Differences of Periods\n let ddpSum = 0;\n for (let i = 1; i < voiced.length - 1; i++) {\n const d1 = voiced[i]! - voiced[i - 1]!;\n const d2 = voiced[i + 1]! - voiced[i]!;\n ddpSum += Math.abs(d2 - d1);\n }\n const jitterDDP = voiced.length > 2 ? ddpSum / (voiced.length - 2) / meanPeriod : 0;\n\n return [jitterLocal, jitterRAP, jitterPPQ5, jitterDDP];\n}\n\n/**\n * Compute shimmer measures from amplitude peaks.\n * Shimmer = cycle-to-cycle amplitude perturbation.\n */\nfunction computeShimmer(amplitudes: number[], f0: number[]): number[] {\n // Use amplitudes only at voiced frames\n const voicedAmps = amplitudes.filter((_, i) => f0[i]! > 0);\n if (voicedAmps.length < 3) return [0, 0, 0, 0];\n\n const meanAmp = voicedAmps.reduce((a, b) => a + b, 0) / voicedAmps.length;\n if (meanAmp === 0) return [0, 0, 0, 0];\n\n // Shimmer (local)\n let localSum = 0;\n for (let i = 1; i < voicedAmps.length; i++) {\n localSum += Math.abs(voicedAmps[i]! - voicedAmps[i - 1]!);\n }\n const shimmerLocal = localSum / (voicedAmps.length - 1) / meanAmp;\n\n // APQ3: 3-point Amplitude Perturbation Quotient\n let apq3Sum = 0;\n for (let i = 1; i < voicedAmps.length - 1; i++) {\n const avg3 = (voicedAmps[i - 1]! + voicedAmps[i]! + voicedAmps[i + 1]!) / 3;\n apq3Sum += Math.abs(voicedAmps[i]! - avg3);\n }\n const shimmerAPQ3 = voicedAmps.length > 2 ? apq3Sum / (voicedAmps.length - 2) / meanAmp : 0;\n\n // APQ5\n let apq5Sum = 0;\n let apq5Count = 0;\n for (let i = 2; i < voicedAmps.length - 2; i++) {\n const avg5 = (voicedAmps[i - 2]! + voicedAmps[i - 1]! + voicedAmps[i]! + voicedAmps[i + 1]! + voicedAmps[i + 2]!) / 5;\n apq5Sum += Math.abs(voicedAmps[i]! - avg5);\n apq5Count++;\n }\n const shimmerAPQ5 = apq5Count > 0 ? apq5Sum / apq5Count / meanAmp : 0;\n\n // DDA: Difference of Differences of Amplitudes\n let ddaSum = 0;\n for (let i = 1; i < voicedAmps.length - 1; i++) {\n const d1 = voicedAmps[i]! - voicedAmps[i - 1]!;\n const d2 = voicedAmps[i + 1]! - voicedAmps[i]!;\n ddaSum += Math.abs(d2 - d1);\n }\n const shimmerDDA = voicedAmps.length > 2 ? ddaSum / (voicedAmps.length - 2) / meanAmp : 0;\n\n return [shimmerLocal, shimmerAPQ3, shimmerAPQ5, shimmerDDA];\n}\n\n/**\n * Compute Harmonic-to-Noise Ratio per frame using autocorrelation.\n */\nfunction computeHNR(\n samples: Float32Array,\n sampleRate: number,\n f0Contour: number[]\n): number[] {\n const hnr: number[] = [];\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n\n for (let i = 0; i < numFrames && i < f0Contour.length; i++) {\n const f0 = f0Contour[i]!;\n if (f0 <= 0) continue; // Skip unvoiced frames\n\n const start = i * HOP_SIZE;\n const frame = samples.slice(start, start + FRAME_SIZE);\n const period = Math.round(sampleRate / f0);\n\n if (period <= 0 || period >= frame.length) continue;\n\n // Autocorrelation at the fundamental period\n let num = 0;\n let den = 0;\n for (let j = 0; j < frame.length - period; j++) {\n num += (frame[j] ?? 0) * (frame[j + period] ?? 0);\n den += (frame[j] ?? 0) * (frame[j] ?? 0);\n }\n\n if (den > 0) {\n const r = num / den;\n const clampedR = Math.max(0.001, Math.min(0.999, r));\n hnr.push(10 * Math.log10(clampedR / (1 - clampedR)));\n }\n }\n\n return hnr;\n}\n\n/**\n * Compute LTAS (Long-Term Average Spectrum) features using Meyda.\n * Returns 8 values: spectral centroid, rolloff, flatness, spread — each mean + variance.\n */\nasync function computeLTAS(\n samples: Float32Array,\n sampleRate: number\n): Promise<number[]> {\n const Meyda = await getMeyda();\n if (!Meyda) return new Array(8).fill(0);\n\n const centroids: number[] = [];\n const rolloffs: number[] = [];\n const flatnesses: number[] = [];\n const spreads: number[] = [];\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n\n for (let i = 0; i < numFrames; i++) {\n const start = i * HOP_SIZE;\n const frame = samples.slice(start, start + FRAME_SIZE);\n const paddedFrame = new Float32Array(FRAME_SIZE);\n paddedFrame.set(frame);\n\n const features = Meyda.extract(\n [\"spectralCentroid\", \"spectralRolloff\", \"spectralFlatness\", \"spectralSpread\"],\n paddedFrame,\n { sampleRate, bufferSize: FRAME_SIZE }\n );\n\n if (features) {\n if (Number.isFinite(features.spectralCentroid)) centroids.push(features.spectralCentroid);\n if (Number.isFinite(features.spectralRolloff)) rolloffs.push(features.spectralRolloff);\n if (Number.isFinite(features.spectralFlatness)) flatnesses.push(features.spectralFlatness);\n if (Number.isFinite(features.spectralSpread)) spreads.push(features.spectralSpread);\n }\n }\n\n const m = (arr: number[]) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;\n const v = (arr: number[]) => {\n if (arr.length < 2) return 0;\n const mu = m(arr);\n return arr.reduce((sum, x) => sum + (x - mu) * (x - mu), 0) / (arr.length - 1);\n };\n\n return [\n m(centroids), v(centroids),\n m(rolloffs), v(rolloffs),\n m(flatnesses), v(flatnesses),\n m(spreads), v(spreads),\n ];\n}\n\n/**\n * Compute derivative (frame-to-frame differences) of a time series.\n */\nfunction derivative(values: number[]): number[] {\n const d: number[] = [];\n for (let i = 1; i < values.length; i++) {\n d.push(values[i]! - values[i - 1]!);\n }\n return d;\n}\n\n/**\n * Extract speaker-dependent audio features.\n *\n * Captures physiological vocal characteristics (F0, jitter, shimmer, HNR, formant\n * ratios) that are stable across different utterances from the same speaker.\n * Content-independent by design — different phrases produce similar feature values.\n *\n * Returns 44 values.\n */\nexport async function extractSpeakerFeatures(audio: AudioCapture): Promise<number[]> {\n const { samples, sampleRate } = audio;\n\n const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;\n if (numFrames < 5) {\n console.warn(`[IAM SDK] Too few audio frames (${numFrames}). Speaker features will be zeros.`);\n return new Array(SPEAKER_FEATURE_COUNT).fill(0);\n }\n\n // 1. F0 detection + amplitude contour\n const { f0, amplitudes, periods } = await detectF0Contour(samples, sampleRate);\n\n const voicedF0 = f0.filter((v) => v > 0);\n const voicedRatio = voicedF0.length / f0.length;\n\n // 2. F0 statistics (5 values)\n const f0Stats = condense(voicedF0);\n const f0Entropy = entropy(voicedF0);\n const f0Features = [f0Stats.mean, f0Stats.variance, f0Stats.skewness, f0Stats.kurtosis, f0Entropy];\n\n // 3. F0 delta statistics (4 values)\n const f0Delta = derivative(voicedF0);\n const f0DeltaStats = condense(f0Delta);\n const f0DeltaFeatures = [f0DeltaStats.mean, f0DeltaStats.variance, f0DeltaStats.skewness, f0DeltaStats.kurtosis];\n\n // 4. Jitter (4 values)\n const jitterFeatures = computeJitter(periods);\n\n // 5. Shimmer (4 values)\n const shimmerFeatures = computeShimmer(amplitudes, f0);\n\n // 6. HNR statistics (5 values)\n const hnrValues = computeHNR(samples, sampleRate, f0);\n const hnrStats = condense(hnrValues);\n const hnrEntropy = entropy(hnrValues);\n const hnrFeatures = [hnrStats.mean, hnrStats.variance, hnrStats.skewness, hnrStats.kurtosis, hnrEntropy];\n\n // 7. Formant ratios (8 values)\n const { f1f2, f2f3 } = extractFormantRatios(samples, sampleRate, FRAME_SIZE, HOP_SIZE);\n const f1f2Stats = condense(f1f2);\n const f2f3Stats = condense(f2f3);\n const formantFeatures = [\n f1f2Stats.mean, f1f2Stats.variance, f1f2Stats.skewness, f1f2Stats.kurtosis,\n f2f3Stats.mean, f2f3Stats.variance, f2f3Stats.skewness, f2f3Stats.kurtosis,\n ];\n\n // 8. LTAS (8 values)\n const ltasFeatures = await computeLTAS(samples, sampleRate);\n\n // 9. Voicing ratio (1 value)\n const voicingFeatures = [voicedRatio];\n\n // 10. Amplitude statistics (5 values)\n const ampStats = condense(amplitudes);\n const ampEntropy = entropy(amplitudes);\n const ampFeatures = [ampStats.mean, ampStats.variance, ampStats.skewness, ampStats.kurtosis, ampEntropy];\n\n const features = [\n ...f0Features, // 5\n ...f0DeltaFeatures, // 4\n ...jitterFeatures, // 4\n ...shimmerFeatures, // 4\n ...hnrFeatures, // 5\n ...formantFeatures, // 8\n ...ltasFeatures, // 8\n ...voicingFeatures, // 1\n ...ampFeatures, // 5\n ]; // = 44\n\n return features;\n}\n\nexport { SPEAKER_FEATURE_COUNT };\n","import type { MotionSample, TouchSample } from \"../sensor/types\";\nimport { condense, variance, entropy } from \"./statistics\";\n\n/**\n * Extract kinematic features from motion (IMU) data.\n * Computes jerk (3rd derivative) and jounce (4th derivative) of acceleration,\n * then condenses each axis into statistics.\n *\n * Returns: ~54 values (6 axes × 2 derivatives × 4 stats + 6 jitter variance values)\n */\nexport function extractMotionFeatures(samples: MotionSample[]): number[] {\n if (samples.length < 5) return new Array(54).fill(0);\n\n // Extract acceleration and rotation time series\n const axes = {\n ax: samples.map((s) => s.ax),\n ay: samples.map((s) => s.ay),\n az: samples.map((s) => s.az),\n gx: samples.map((s) => s.gx),\n gy: samples.map((s) => s.gy),\n gz: samples.map((s) => s.gz),\n };\n\n const features: number[] = [];\n\n for (const values of Object.values(axes)) {\n // Jerk = 3rd derivative of position = 1st derivative of acceleration\n const jerk = derivative(values);\n // Jounce = 4th derivative of position = 2nd derivative of acceleration\n const jounce = derivative(jerk);\n\n const jerkStats = condense(jerk);\n const jounceStats = condense(jounce);\n\n features.push(\n jerkStats.mean,\n jerkStats.variance,\n jerkStats.skewness,\n jerkStats.kurtosis,\n jounceStats.mean,\n jounceStats.variance,\n jounceStats.skewness,\n jounceStats.kurtosis\n );\n }\n\n // Jitter variance per axis: variance of windowed jerk variance.\n // Real human tremor fluctuates over time (high jitter variance).\n // Synthetic/replay data has constant jitter (low jitter variance).\n for (const values of Object.values(axes)) {\n const jerk = derivative(values);\n const windowSize = Math.max(5, Math.floor(jerk.length / 4));\n const windowVariances: number[] = [];\n for (let i = 0; i <= jerk.length - windowSize; i += windowSize) {\n windowVariances.push(variance(jerk.slice(i, i + windowSize)));\n }\n features.push(windowVariances.length >= 2 ? variance(windowVariances) : 0);\n }\n\n return features;\n}\n\n/**\n * Extract kinematic features from touch data.\n * Computes velocity and acceleration of touch coordinates,\n * plus pressure and area statistics.\n *\n * Returns: ~36 values (32 base + 4 jitter variance for x, y, pressure, area)\n */\nexport function extractTouchFeatures(samples: TouchSample[]): number[] {\n if (samples.length < 5) return new Array(36).fill(0);\n\n const x = samples.map((s) => s.x);\n const y = samples.map((s) => s.y);\n const pressure = samples.map((s) => s.pressure);\n const area = samples.map((s) => s.width * s.height);\n\n const features: number[] = [];\n\n // X velocity and acceleration\n const vx = derivative(x);\n const accX = derivative(vx);\n features.push(...Object.values(condense(vx)));\n features.push(...Object.values(condense(accX)));\n\n // Y velocity and acceleration\n const vy = derivative(y);\n const accY = derivative(vy);\n features.push(...Object.values(condense(vy)));\n features.push(...Object.values(condense(accY)));\n\n // Pressure statistics\n features.push(...Object.values(condense(pressure)));\n\n // Contact area statistics\n features.push(...Object.values(condense(area)));\n\n // Jerk of touch path\n const jerkX = derivative(accX);\n const jerkY = derivative(accY);\n features.push(...Object.values(condense(jerkX)));\n features.push(...Object.values(condense(jerkY)));\n\n // Jitter variance for touch signals: detects synthetic smoothness\n for (const values of [vx, vy, pressure, area]) {\n const windowSize = Math.max(5, Math.floor(values.length / 4));\n const windowVariances: number[] = [];\n for (let i = 0; i <= values.length - windowSize; i += windowSize) {\n windowVariances.push(variance(values.slice(i, i + windowSize)));\n }\n features.push(windowVariances.length >= 2 ? variance(windowVariances) : 0);\n }\n\n return features;\n}\n\n/** Compute discrete derivative (differences between consecutive values) */\nfunction derivative(values: number[]): number[] {\n const d: number[] = [];\n for (let i = 1; i < values.length; i++) {\n d.push((values[i] ?? 0) - (values[i - 1] ?? 0));\n }\n return d;\n}\n\n/**\n * Extract mouse dynamics features as a desktop replacement for motion sensor data.\n * Captures behavioral patterns from mouse/pointer movement that are user-specific:\n * path curvature, speed patterns, micro-corrections, pause behavior.\n *\n * Returns: 54 values (matches motion feature dimension for consistent SimHash input)\n */\nexport function extractMouseDynamics(samples: TouchSample[]): number[] {\n if (samples.length < 10) return new Array(54).fill(0);\n\n const x = samples.map((s) => s.x);\n const y = samples.map((s) => s.y);\n const pressure = samples.map((s) => s.pressure);\n const area = samples.map((s) => s.width * s.height);\n\n // Velocity\n const vx = derivative(x);\n const vy = derivative(y);\n const speed = vx.map((dx, i) => Math.sqrt(dx * dx + (vy[i] ?? 0) * (vy[i] ?? 0)));\n\n // Acceleration\n const accX = derivative(vx);\n const accY = derivative(vy);\n const acc = accX.map((ax, i) => Math.sqrt(ax * ax + (accY[i] ?? 0) * (accY[i] ?? 0)));\n\n // Jerk (derivative of acceleration)\n const jerkX = derivative(accX);\n const jerkY = derivative(accY);\n const jerk = jerkX.map((jx, i) => Math.sqrt(jx * jx + (jerkY[i] ?? 0) * (jerkY[i] ?? 0)));\n\n // Path curvature: angle change between consecutive movement vectors\n const curvatures: number[] = [];\n for (let i = 1; i < vx.length; i++) {\n const angle1 = Math.atan2(vy[i - 1] ?? 0, vx[i - 1] ?? 0);\n const angle2 = Math.atan2(vy[i] ?? 0, vx[i] ?? 0);\n let diff = angle2 - angle1;\n while (diff > Math.PI) diff -= 2 * Math.PI;\n while (diff < -Math.PI) diff += 2 * Math.PI;\n curvatures.push(Math.abs(diff));\n }\n\n // Movement directions for directional entropy\n const directions = vx.map((dx, i) => Math.atan2(vy[i] ?? 0, dx));\n\n // Micro-corrections: direction reversals\n let reversals = 0;\n for (let i = 2; i < directions.length; i++) {\n const d1 = directions[i - 1]! - directions[i - 2]!;\n const d2 = directions[i]! - directions[i - 1]!;\n if (d1 * d2 < 0) reversals++;\n }\n const reversalRate = directions.length > 2 ? reversals / (directions.length - 2) : 0;\n const reversalMagnitude = curvatures.length > 0\n ? curvatures.reduce((a, b) => a + b, 0) / curvatures.length\n : 0;\n\n // Pause detection: frames where speed is near zero\n const speedThreshold = 0.5;\n const pauseFrames = speed.filter((s) => s < speedThreshold).length;\n const pauseRatio = speed.length > 0 ? pauseFrames / speed.length : 0;\n\n // Path efficiency: straight-line distance / total path length\n const totalPathLength = speed.reduce((a, b) => a + b, 0);\n const straightLine = Math.sqrt(\n (x[x.length - 1]! - x[0]!) ** 2 + (y[y.length - 1]! - y[0]!) ** 2\n );\n const pathEfficiency = totalPathLength > 0 ? straightLine / totalPathLength : 0;\n\n // Movement durations between pauses\n const movementDurations: number[] = [];\n let currentDuration = 0;\n for (const s of speed) {\n if (s >= speedThreshold) {\n currentDuration++;\n } else if (currentDuration > 0) {\n movementDurations.push(currentDuration);\n currentDuration = 0;\n }\n }\n if (currentDuration > 0) movementDurations.push(currentDuration);\n\n // Segment lengths between direction changes\n const segmentLengths: number[] = [];\n let segLen = 0;\n for (let i = 1; i < directions.length; i++) {\n segLen += speed[i] ?? 0;\n const angleDiff = Math.abs(directions[i]! - directions[i - 1]!);\n if (angleDiff > Math.PI / 4) {\n segmentLengths.push(segLen);\n segLen = 0;\n }\n }\n if (segLen > 0) segmentLengths.push(segLen);\n\n // Windowed jitter variance of speed\n const windowSize = Math.max(5, Math.floor(speed.length / 4));\n const windowVariances: number[] = [];\n for (let i = 0; i + windowSize <= speed.length; i += windowSize) {\n const window = speed.slice(i, i + windowSize);\n windowVariances.push(variance(window));\n }\n const speedJitter = windowVariances.length > 1 ? variance(windowVariances) : 0;\n\n // Path length normalized by capture duration\n const duration = samples.length > 1\n ? (samples[samples.length - 1]!.timestamp - samples[0]!.timestamp) / 1000\n : 1;\n const normalizedPathLength = totalPathLength / Math.max(duration, 0.001);\n\n // Angle autocorrelation at lags 1, 2, 3\n const angleAutoCorr: number[] = [];\n for (let lag = 1; lag <= 3; lag++) {\n if (directions.length <= lag) {\n angleAutoCorr.push(0);\n continue;\n }\n const n = directions.length - lag;\n const meanDir = directions.reduce((a, b) => a + b, 0) / directions.length;\n let num = 0;\n let den = 0;\n for (let i = 0; i < n; i++) {\n num += (directions[i]! - meanDir) * (directions[i + lag]! - meanDir);\n den += (directions[i]! - meanDir) ** 2;\n }\n angleAutoCorr.push(den > 0 ? num / den : 0);\n }\n\n // Assemble 54 features\n const curvatureStats = condense(curvatures); // 4\n const dirEntropy = entropy(directions, 16); // 1\n const speedStats = condense(speed); // 4\n const accStats = condense(acc); // 4\n // micro-corrections: reversalRate + reversalMagnitude // 2\n // pauseRatio // 1\n // pathEfficiency // 1\n // speedJitter // 1\n const jerkStats = condense(jerk); // 4\n const vxStats = condense(vx); // 4\n const vyStats = condense(vy); // 4\n const accXStats = condense(accX); // 4\n const accYStats = condense(accY); // 4\n const pressureStats = condense(pressure); // 4\n const moveDurStats = condense(movementDurations); // 4\n const segLenStats = condense(segmentLengths); // 4\n // angleAutoCorr[0..2] // 3\n // normalizedPathLength // 1\n // Total: 4+1+4+4+2+1+1+1+4+4+4+4+4+4+4+4+3+1 = 54\n\n return [\n curvatureStats.mean, curvatureStats.variance, curvatureStats.skewness, curvatureStats.kurtosis,\n dirEntropy,\n speedStats.mean, speedStats.variance, speedStats.skewness, speedStats.kurtosis,\n accStats.mean, accStats.variance, accStats.skewness, accStats.kurtosis,\n reversalRate, reversalMagnitude,\n pauseRatio,\n pathEfficiency,\n speedJitter,\n jerkStats.mean, jerkStats.variance, jerkStats.skewness, jerkStats.kurtosis,\n vxStats.mean, vxStats.variance, vxStats.skewness, vxStats.kurtosis,\n vyStats.mean, vyStats.variance, vyStats.skewness, vyStats.kurtosis,\n accXStats.mean, accXStats.variance, accXStats.skewness, accXStats.kurtosis,\n accYStats.mean, accYStats.variance, accYStats.skewness, accYStats.kurtosis,\n pressureStats.mean, pressureStats.variance, pressureStats.skewness, pressureStats.kurtosis,\n moveDurStats.mean, moveDurStats.variance, moveDurStats.skewness, moveDurStats.kurtosis,\n segLenStats.mean, segLenStats.variance, segLenStats.skewness, segLenStats.kurtosis,\n angleAutoCorr[0] ?? 0, angleAutoCorr[1] ?? 0, angleAutoCorr[2] ?? 0,\n normalizedPathLength,\n ];\n}\n","import { FINGERPRINT_BITS, SIMHASH_SEED } from \"../config\";\nimport type { TemporalFingerprint } from \"./types\";\n\n// Mulberry32 PRNG: deterministic, fast, good distribution\nfunction mulberry32(seed: number): () => number {\n let state = seed | 0;\n return () => {\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n// Derive a numeric seed from the protocol seed string\nfunction deriveSeed(seedStr: string): number {\n let hash = 0;\n for (let i = 0; i < seedStr.length; i++) {\n const ch = seedStr.charCodeAt(i);\n hash = ((hash << 5) - hash + ch) | 0;\n }\n return hash;\n}\n\nlet cachedHyperplanes: number[][] | null = null;\nlet cachedDimension = 0;\n\nfunction getHyperplanes(dimension: number): number[][] {\n if (cachedHyperplanes && cachedDimension === dimension) {\n return cachedHyperplanes;\n }\n\n const rng = mulberry32(deriveSeed(SIMHASH_SEED));\n const planes: number[][] = [];\n\n for (let i = 0; i < FINGERPRINT_BITS; i++) {\n const plane: number[] = [];\n for (let j = 0; j < dimension; j++) {\n // Random value in [-1, 1]\n plane.push(rng() * 2 - 1);\n }\n planes.push(plane);\n }\n\n cachedHyperplanes = planes;\n cachedDimension = dimension;\n return planes;\n}\n\n/**\n * Compute a 256-bit SimHash fingerprint from a feature vector.\n * Uses deterministic random hyperplanes seeded from the protocol constant.\n * Similar feature vectors produce fingerprints with low Hamming distance.\n */\nconst EXPECTED_FEATURE_DIMENSION = 134; // 44 speaker + 54 motion/mouse + 36 touch\n\nexport function simhash(features: number[]): TemporalFingerprint {\n if (features.length === 0) {\n return new Array(FINGERPRINT_BITS).fill(0);\n }\n\n if (features.length !== EXPECTED_FEATURE_DIMENSION) {\n console.warn(\n `[IAM SDK] Feature vector has ${features.length} dimensions, expected ${EXPECTED_FEATURE_DIMENSION}. ` +\n `Fingerprint quality may be degraded.`\n );\n }\n\n const planes = getHyperplanes(features.length);\n const fingerprint: TemporalFingerprint = [];\n\n for (let i = 0; i < FINGERPRINT_BITS; i++) {\n const plane = planes[i];\n let dot = 0;\n for (let j = 0; j < features.length; j++) {\n dot += (features[j] ?? 0) * (plane?.[j] ?? 0);\n }\n fingerprint.push(dot >= 0 ? 1 : 0);\n }\n\n return fingerprint;\n}\n\n/**\n * Compute Hamming distance between two fingerprints.\n */\nexport function hammingDistance(\n a: TemporalFingerprint,\n b: TemporalFingerprint\n): number {\n let distance = 0;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) distance++;\n }\n return distance;\n}\n","import { BN254_SCALAR_FIELD, FINGERPRINT_BITS } from \"../config\";\nimport type { PackedFingerprint, TBH, TemporalFingerprint } from \"./types\";\n\n// Lazy-initialized Poseidon instance\nlet poseidonInstance: any = null;\n\nasync function getPoseidon(): Promise<any> {\n if (!poseidonInstance) {\n const circomlibjs = await import(\"circomlibjs\");\n poseidonInstance = await (circomlibjs as any).buildPoseidon();\n }\n return poseidonInstance;\n}\n\n/**\n * Pack 256-bit fingerprint into two 128-bit field elements.\n * Little-endian bit ordering within each chunk (matches circuit's Bits2Num).\n */\nexport function packBits(fingerprint: TemporalFingerprint): PackedFingerprint {\n let lo = BigInt(0);\n for (let i = 0; i < 128; i++) {\n if (fingerprint[i] === 1) {\n lo += BigInt(1) << BigInt(i);\n }\n }\n\n let hi = BigInt(0);\n for (let i = 0; i < 128; i++) {\n if (fingerprint[128 + i] === 1) {\n hi += BigInt(1) << BigInt(i);\n }\n }\n\n return { lo, hi };\n}\n\n/**\n * Compute Poseidon commitment: Poseidon(pack_lo, pack_hi, salt).\n * Matches the circuit's CommitmentCheck template exactly.\n */\nexport async function computeCommitment(\n fingerprint: TemporalFingerprint,\n salt: bigint\n): Promise<bigint> {\n const poseidon = await getPoseidon();\n const { lo, hi } = packBits(fingerprint);\n const hash = poseidon([lo, hi, salt]);\n return poseidon.F.toObject(hash) as bigint;\n}\n\n/**\n * Generate a random salt within the BN254 scalar field.\n */\nexport function generateSalt(): bigint {\n const bytes = new Uint8Array(31);\n crypto.getRandomValues(bytes);\n let val = BigInt(0);\n for (let i = 0; i < bytes.length; i++) {\n val = (val << BigInt(8)) + BigInt(bytes[i] ?? 0);\n }\n return val % BN254_SCALAR_FIELD;\n}\n\n/**\n * Convert a BigInt to a 32-byte big-endian Uint8Array.\n */\nexport function bigintToBytes32(n: bigint): Uint8Array {\n const bytes = new Uint8Array(32);\n let val = n;\n for (let i = 31; i >= 0; i--) {\n bytes[i] = Number(val & BigInt(0xff));\n val >>= BigInt(8);\n }\n return bytes;\n}\n\n/**\n * Generate a complete TBH from a fingerprint.\n */\nexport async function generateTBH(\n fingerprint: TemporalFingerprint,\n salt?: bigint\n): Promise<TBH> {\n const s = salt ?? generateSalt();\n const commitment = await computeCommitment(fingerprint, s);\n return {\n fingerprint,\n salt: s,\n commitment,\n commitmentBytes: bigintToBytes32(commitment),\n };\n}\n","import {\n BN254_BASE_FIELD,\n PROOF_A_SIZE,\n PROOF_B_SIZE,\n PROOF_C_SIZE,\n TOTAL_PROOF_SIZE,\n NUM_PUBLIC_INPUTS,\n} from \"../config\";\nimport type { RawProof, SolanaProof } from \"./types\";\n\n/**\n * Convert a decimal string to a 32-byte big-endian Uint8Array.\n */\nexport function toBigEndian32(decStr: string): Uint8Array {\n let n = BigInt(decStr);\n const bytes = new Uint8Array(32);\n for (let i = 31; i >= 0; i--) {\n bytes[i] = Number(n & BigInt(0xff));\n n >>= BigInt(8);\n }\n return bytes;\n}\n\n/**\n * Negate a G1 y-coordinate for groth16-solana proof_a format.\n */\nfunction negateG1Y(yDecStr: string): Uint8Array {\n const y = BigInt(yDecStr);\n const yNeg = (BN254_BASE_FIELD - y) % BN254_BASE_FIELD;\n return toBigEndian32(yNeg.toString());\n}\n\n/**\n * Serialize an snarkjs proof into the 256-byte format groth16-solana expects.\n *\n * proof_a: 64 bytes (x + negated y)\n * proof_b: 128 bytes (G2 with reversed coordinate ordering: c1 before c0)\n * proof_c: 64 bytes (x + y)\n */\nexport function serializeProof(\n proof: RawProof,\n publicSignals: string[]\n): SolanaProof {\n if (publicSignals.length !== NUM_PUBLIC_INPUTS) {\n throw new Error(\n `Expected ${NUM_PUBLIC_INPUTS} public signals, got ${publicSignals.length}`\n );\n }\n\n // proof_a: x (32 bytes) + negated y (32 bytes)\n const a0 = toBigEndian32(proof.pi_a[0]!);\n const a1 = negateG1Y(proof.pi_a[1]!);\n const proofA = new Uint8Array(PROOF_A_SIZE);\n proofA.set(a0, 0);\n proofA.set(a1, 32);\n\n // proof_b: G2 reversed coordinate ordering\n const b00 = toBigEndian32(proof.pi_b[0]![1]!); // c1 first\n const b01 = toBigEndian32(proof.pi_b[0]![0]!); // c0 second\n const b10 = toBigEndian32(proof.pi_b[1]![1]!);\n const b11 = toBigEndian32(proof.pi_b[1]![0]!);\n const proofB = new Uint8Array(PROOF_B_SIZE);\n proofB.set(b00, 0);\n proofB.set(b01, 32);\n proofB.set(b10, 64);\n proofB.set(b11, 96);\n\n // proof_c: x + y (no negation)\n const c0 = toBigEndian32(proof.pi_c[0]!);\n const c1 = toBigEndian32(proof.pi_c[1]!);\n const proofC = new Uint8Array(PROOF_C_SIZE);\n proofC.set(c0, 0);\n proofC.set(c1, 32);\n\n // Combine into single 256-byte blob\n const proofBytes = new Uint8Array(TOTAL_PROOF_SIZE);\n proofBytes.set(proofA, 0);\n proofBytes.set(proofB, PROOF_A_SIZE);\n proofBytes.set(proofC, PROOF_A_SIZE + PROOF_B_SIZE);\n\n // Public inputs as 32-byte big-endian arrays\n const publicInputs = publicSignals.map((s) => toBigEndian32(s));\n\n return { proofBytes, publicInputs };\n}\n","import type { TBH } from \"../hashing/types\";\nimport type { CircuitInput, ProofResult, SolanaProof } from \"./types\";\nimport { serializeProof } from \"./serializer\";\nimport { DEFAULT_THRESHOLD, DEFAULT_MIN_DISTANCE } from \"../config\";\n\n// Use dynamic import for snarkjs (it's a CJS module)\nlet snarkjsModule: any = null;\n\nasync function getSnarkjs(): Promise<any> {\n if (!snarkjsModule) {\n snarkjsModule = await import(\"snarkjs\");\n }\n return snarkjsModule;\n}\n\n/**\n * Prepare circuit input from current and previous TBH data.\n */\nexport function prepareCircuitInput(\n current: TBH,\n previous: TBH,\n threshold: number = DEFAULT_THRESHOLD,\n minDistance: number = DEFAULT_MIN_DISTANCE\n): CircuitInput {\n return {\n ft_new: current.fingerprint,\n ft_prev: previous.fingerprint,\n salt_new: current.salt.toString(),\n salt_prev: previous.salt.toString(),\n commitment_new: current.commitment.toString(),\n commitment_prev: previous.commitment.toString(),\n threshold: threshold.toString(),\n min_distance: minDistance.toString(),\n };\n}\n\n/**\n * Generate a Groth16 proof for the Hamming distance circuit.\n *\n * @param input - Circuit input (fingerprints, salts, commitments, threshold)\n * @param wasmPath - Path or URL to iam_hamming.wasm\n * @param zkeyPath - Path or URL to iam_hamming_final.zkey\n */\nexport async function generateProof(\n input: CircuitInput,\n wasmPath: string,\n zkeyPath: string\n): Promise<ProofResult> {\n const snarkjs = await getSnarkjs();\n const { proof, publicSignals } = await snarkjs.groth16.fullProve(\n input,\n wasmPath,\n zkeyPath\n );\n return { proof, publicSignals };\n}\n\n/**\n * Generate a proof and serialize it for Solana submission.\n */\nexport async function generateSolanaProof(\n current: TBH,\n previous: TBH,\n wasmPath: string,\n zkeyPath: string,\n threshold?: number\n): Promise<SolanaProof> {\n const input = prepareCircuitInput(current, previous, threshold);\n const { proof, publicSignals } = await generateProof(\n input,\n wasmPath,\n zkeyPath\n );\n return serializeProof(proof, publicSignals);\n}\n\n/**\n * Verify a proof locally using snarkjs (for debugging/testing).\n * Caller is responsible for loading the verification key.\n */\nexport async function verifyProofLocally(\n proof: any,\n publicSignals: string[],\n vkey: Record<string, unknown>\n): Promise<boolean> {\n const snarkjs = await getSnarkjs();\n return snarkjs.groth16.verify(vkey, publicSignals, proof);\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n// Anchor program interactions use runtime IDL fetching, requiring dynamic typing.\nimport type { SolanaProof } from \"../proof/types\";\nimport type { SubmissionResult } from \"./types\";\nimport { PROGRAM_IDS } from \"../config\";\n\n/**\n * Submit a proof on-chain via a connected wallet (wallet-connected mode).\n * Uses Anchor SDK to construct and send the transaction.\n *\n * Flow: create_challenge → verify_proof → update_anchor (or mint_anchor for first time)\n */\nexport async function submitViaWallet(\n proof: SolanaProof,\n commitment: Uint8Array,\n options: {\n wallet: any;\n connection: any;\n isFirstVerification: boolean;\n }\n): Promise<SubmissionResult> {\n try {\n const anchor = await import(\"@coral-xyz/anchor\");\n const { PublicKey, SystemProgram } = await import(\"@solana/web3.js\");\n\n const provider = new anchor.AnchorProvider(\n options.connection,\n options.wallet,\n { commitment: \"confirmed\" }\n );\n\n const verifierProgramId = new PublicKey(PROGRAM_IDS.iamVerifier);\n const anchorProgramId = new PublicKey(PROGRAM_IDS.iamAnchor);\n\n // Generate nonce for challenge\n const nonce = Array.from(crypto.getRandomValues(new Uint8Array(32)));\n\n // Derive PDAs\n const [challengePda] = PublicKey.findProgramAddressSync(\n [\n new TextEncoder().encode(\"challenge\"),\n provider.wallet.publicKey.toBuffer(),\n new Uint8Array(nonce),\n ],\n verifierProgramId\n );\n\n const [verificationPda] = PublicKey.findProgramAddressSync(\n [\n new TextEncoder().encode(\"verification\"),\n provider.wallet.publicKey.toBuffer(),\n new Uint8Array(nonce),\n ],\n verifierProgramId\n );\n\n // Build and send create_challenge + verify_proof transactions\n // These use the raw Anchor program interface\n const verifierIdl = await anchor.Program.fetchIdl(\n verifierProgramId,\n provider\n );\n if (!verifierIdl) {\n return { success: false, error: \"Failed to fetch verifier IDL\" };\n }\n\n const verifierProgram: any = new anchor.Program(\n verifierIdl,\n provider\n );\n\n // 1. Create challenge\n await verifierProgram.methods\n .createChallenge(nonce)\n .accounts({\n challenger: provider.wallet.publicKey,\n challenge: challengePda,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n\n // 2. Verify proof\n const txSig = await verifierProgram.methods\n .verifyProof(\n Array.from(proof.proofBytes),\n proof.publicInputs.map((pi) => Array.from(pi)),\n nonce\n )\n .accounts({\n verifier: provider.wallet.publicKey,\n challenge: challengePda,\n verificationResult: verificationPda,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n\n // 3. Mint or update anchor\n const anchorIdl = await anchor.Program.fetchIdl(anchorProgramId, provider);\n if (!anchorIdl) {\n return { success: false, error: \"Failed to fetch IAM Anchor program IDL\" };\n }\n\n {\n const anchorProgram: any = new anchor.Program(anchorIdl, provider);\n\n if (options.isFirstVerification) {\n const [identityPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"identity\"), provider.wallet.publicKey.toBuffer()],\n anchorProgramId\n );\n const [mintPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"mint\"), provider.wallet.publicKey.toBuffer()],\n anchorProgramId\n );\n const [mintAuthority] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"mint_authority\")],\n anchorProgramId\n );\n\n // Token-2022 program ID\n const TOKEN_2022_PROGRAM_ID = new PublicKey(\n \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\"\n );\n\n const { getAssociatedTokenAddressSync } = await import(\n \"@solana/spl-token\"\n );\n const ata = getAssociatedTokenAddressSync(\n mintPda,\n provider.wallet.publicKey,\n false,\n TOKEN_2022_PROGRAM_ID\n );\n\n await anchorProgram.methods\n .mintAnchor(Array.from(commitment))\n .accounts({\n user: provider.wallet.publicKey,\n identityState: identityPda,\n mint: mintPda,\n mintAuthority,\n tokenAccount: ata,\n associatedTokenProgram: new PublicKey(\n \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"\n ),\n tokenProgram: TOKEN_2022_PROGRAM_ID,\n systemProgram: SystemProgram.programId,\n })\n .rpc();\n } else {\n const [identityPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"identity\"), provider.wallet.publicKey.toBuffer()],\n anchorProgramId\n );\n\n // Derive iam-registry ProtocolConfig PDA for trust score computation\n const registryProgramId = new PublicKey(PROGRAM_IDS.iamRegistry);\n const [protocolConfigPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"protocol_config\")],\n registryProgramId\n );\n\n await anchorProgram.methods\n .updateAnchor(Array.from(commitment))\n .accounts({\n authority: provider.wallet.publicKey,\n identityState: identityPda,\n protocolConfig: protocolConfigPda,\n })\n .rpc();\n }\n }\n\n return { success: true, txSignature: txSig };\n } catch (err: any) {\n return { success: false, error: err.message ?? String(err) };\n }\n}\n","import type { SolanaProof } from \"../proof/types\";\nimport type { SubmissionResult } from \"./types\";\n\nconst RELAYER_TIMEOUT_MS = 30_000;\n\n/**\n * Submit a proof via the IAM relayer API (walletless mode).\n * The relayer submits the on-chain transaction using the integrator's funded account.\n * The user needs no wallet, no SOL, no crypto knowledge.\n */\nexport async function submitViaRelayer(\n proof: SolanaProof,\n commitment: Uint8Array,\n options: {\n relayerUrl: string;\n apiKey?: string;\n isFirstVerification: boolean;\n }\n): Promise<SubmissionResult> {\n try {\n const body = {\n proof_bytes: Array.from(proof.proofBytes),\n public_inputs: proof.publicInputs.map((pi) => Array.from(pi)),\n commitment: Array.from(commitment),\n is_first_verification: options.isFirstVerification,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (options.apiKey) {\n headers[\"X-API-Key\"] = options.apiKey;\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), RELAYER_TIMEOUT_MS);\n\n const response = await fetch(options.relayerUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n clearTimeout(timer);\n\n if (!response.ok) {\n const errorText = await response.text();\n return { success: false, error: `Relayer error: ${response.status} ${errorText}` };\n }\n\n const result = (await response.json()) as {\n success?: boolean;\n tx_signature?: string;\n verified?: boolean;\n registered?: boolean;\n };\n\n if (result.success !== true) {\n return { success: false, error: \"Relayer returned unsuccessful response\" };\n }\n\n return {\n success: true,\n txSignature: result.tx_signature,\n };\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n return { success: false, error: \"Relayer request timed out\" };\n }\n return { success: false, error: err.message ?? String(err) };\n }\n}\n","import { PROGRAM_IDS } from \"../config\";\nimport type { IdentityState, StoredVerificationData } from \"./types\";\n\nconst STORAGE_KEY = \"iam-protocol-verification-data\";\n\n/**\n * Fetch identity state from the on-chain IdentityState PDA.\n */\nexport async function fetchIdentityState(\n walletPubkey: string,\n connection: any\n): Promise<IdentityState | null> {\n try {\n const { PublicKey } = await import(\"@solana/web3.js\");\n const anchor = await import(\"@coral-xyz/anchor\");\n\n const programId = new PublicKey(PROGRAM_IDS.iamAnchor);\n const [identityPda] = PublicKey.findProgramAddressSync(\n [new TextEncoder().encode(\"identity\"), new PublicKey(walletPubkey).toBuffer()],\n programId\n );\n\n const accountInfo = await connection.getAccountInfo(identityPda);\n if (!accountInfo) return null;\n\n // Decode using Anchor's BorshAccountsCoder\n const idl = await anchor.Program.fetchIdl(programId, {\n connection,\n } as any);\n if (!idl) return null;\n\n const coder = new anchor.BorshAccountsCoder(idl);\n const decoded = coder.decode(\"identityState\", accountInfo.data);\n\n return {\n owner: decoded.owner.toBase58(),\n creationTimestamp: decoded.creationTimestamp.toNumber(),\n lastVerificationTimestamp: decoded.lastVerificationTimestamp.toNumber(),\n verificationCount: decoded.verificationCount,\n trustScore: decoded.trustScore,\n currentCommitment: new Uint8Array(decoded.currentCommitment),\n mint: decoded.mint.toBase58(),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Store verification data locally for re-verification.\n * Uses localStorage (browser) or in-memory fallback (Node.js).\n */\nexport function storeVerificationData(data: StoredVerificationData): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n } catch {\n // localStorage not available (Node.js or private browsing)\n inMemoryStore = data;\n }\n}\n\n/**\n * Load previously stored verification data.\n */\nexport function loadVerificationData(): StoredVerificationData | null {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return inMemoryStore;\n return JSON.parse(raw);\n } catch {\n return inMemoryStore;\n }\n}\n\nlet inMemoryStore: StoredVerificationData | null = null;\n","import type { PulseConfig } from \"./config\";\nimport { DEFAULT_THRESHOLD, DEFAULT_CAPTURE_MS } from \"./config\";\nimport type { SensorData, AudioCapture, MotionSample, TouchSample, StageState } from \"./sensor/types\";\nimport type { TBH } from \"./hashing/types\";\nimport type { SolanaProof } from \"./proof/types\";\nimport type { VerificationResult } from \"./submit/types\";\nimport type { StoredVerificationData } from \"./identity/types\";\n\nimport { captureAudio } from \"./sensor/audio\";\nimport { captureMotion, requestMotionPermission } from \"./sensor/motion\";\nimport { captureTouch } from \"./sensor/touch\";\nimport { extractSpeakerFeatures, SPEAKER_FEATURE_COUNT } from \"./extraction/speaker\";\nimport {\n extractMotionFeatures,\n extractTouchFeatures,\n extractMouseDynamics,\n} from \"./extraction/kinematic\";\nimport { fuseFeatures } from \"./extraction/statistics\";\nimport { simhash, hammingDistance } from \"./hashing/simhash\";\nimport { generateTBH, bigintToBytes32 } from \"./hashing/poseidon\";\nimport { prepareCircuitInput, generateProof } from \"./proof/prover\";\nimport { serializeProof } from \"./proof/serializer\";\nimport { submitViaWallet } from \"./submit/wallet\";\nimport { submitViaRelayer } from \"./submit/relayer\";\nimport {\n storeVerificationData,\n loadVerificationData,\n} from \"./identity/anchor\";\n\ntype ResolvedConfig = Required<Pick<PulseConfig, \"cluster\" | \"threshold\">> &\n PulseConfig;\n\n/**\n * Extract features from sensor data and fuse into a single vector.\n */\nasync function extractFeatures(data: SensorData): Promise<number[]> {\n if (!data.audio) {\n throw new Error(\"Audio data required for feature extraction\");\n }\n const audioFeatures = await extractSpeakerFeatures(data.audio);\n\n const hasMotion = data.motion.length >= MIN_MOTION_SAMPLES;\n const hasTouch = data.touch.length >= MIN_TOUCH_SAMPLES;\n\n // On mobile (both IMU and touch available), use touch/pointer dynamics for\n // kinematic features. Stationary IMU reads constant gravity — the derivatives\n // are near-zero and produce identical features across sessions. Finger tracing\n // has natural inter-session variance because no two paths are identical.\n const motionFeatures =\n hasMotion && hasTouch\n ? extractMouseDynamics(data.touch)\n : hasMotion\n ? extractMotionFeatures(data.motion)\n : extractMouseDynamics(data.touch);\n\n const touchFeatures = extractTouchFeatures(data.touch);\n return fuseFeatures(audioFeatures, motionFeatures, touchFeatures);\n}\n\n/**\n * Shared pipeline: features → simhash → TBH → proof → submit.\n * Used by both PulseSDK.verify() and PulseSession.complete().\n */\n// Minimum sample counts for meaningful feature extraction\nconst MIN_AUDIO_SAMPLES = 16000; // ~1 second at 16kHz\nconst MIN_MOTION_SAMPLES = 10;\nconst MIN_TOUCH_SAMPLES = 10;\n\nasync function processSensorData(\n sensorData: SensorData,\n config: ResolvedConfig,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Solana types are optional peer deps\n wallet?: any,\n connection?: any\n): Promise<VerificationResult> {\n // Data quality gate: reject if insufficient behavioral data captured\n const audioSamples = sensorData.audio?.samples.length ?? 0;\n const motionSamples = sensorData.motion.length;\n const touchSamples = sensorData.touch.length;\n\n // Need at least audio OR (motion + touch) to produce a meaningful fingerprint\n const hasAudio = audioSamples >= MIN_AUDIO_SAMPLES;\n const hasMotion = motionSamples >= MIN_MOTION_SAMPLES;\n const hasTouch = touchSamples >= MIN_TOUCH_SAMPLES;\n\n if (!hasAudio && !hasMotion && !hasTouch) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: true,\n error: \"Insufficient behavioral data. Please speak the phrase and trace the curve during capture.\",\n };\n }\n\n if (!hasAudio) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: true,\n error: \"No voice data detected. Please speak the phrase clearly during capture.\",\n };\n }\n\n // Re-verification requires audio + at least one other modality.\n // Audio-only fingerprints lack inter-session variance from motion/touch,\n // producing identical SimHash results that fail the min_distance constraint.\n const hasPreviousData = loadVerificationData() !== null;\n if (hasPreviousData && !hasMotion && !hasTouch) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: false,\n error: \"Insufficient sensor data for re-verification. Please trace the curve and allow motion access.\",\n };\n }\n\n // Extract features\n const features = await extractFeatures(sensorData);\n\n // Diagnostic: log feature vector composition\n const nonZero = features.filter((v) => v !== 0).length;\n console.log(\n `[IAM SDK] Feature vector: ${features.length} dimensions, ${nonZero} non-zero. ` +\n `Audio[0..43]: ${features.slice(0, 44).filter((v) => v !== 0).length} non-zero. ` +\n `Motion/Mouse[44..97]: ${features.slice(44, 98).filter((v) => v !== 0).length} non-zero. ` +\n `Touch[98..133]: ${features.slice(98, 134).filter((v) => v !== 0).length} non-zero.`\n );\n\n // Generate fingerprint via SimHash\n const fingerprint = simhash(features);\n\n // Generate TBH (Poseidon commitment)\n const tbh = await generateTBH(fingerprint);\n\n // Check for previous verification data\n const previousData = loadVerificationData();\n const isFirstVerification = !previousData;\n\n let solanaProof: SolanaProof | null = null;\n\n if (!isFirstVerification && previousData) {\n const previousTBH: TBH = {\n fingerprint: previousData.fingerprint,\n salt: BigInt(previousData.salt),\n commitment: BigInt(previousData.commitment),\n commitmentBytes: bigintToBytes32(BigInt(previousData.commitment)),\n };\n\n const distance = hammingDistance(fingerprint, previousData.fingerprint);\n console.log(\n `[IAM SDK] Re-verification: Hamming distance = ${distance} / 256 bits (threshold = ${config.threshold})`\n );\n\n const circuitInput = prepareCircuitInput(\n tbh,\n previousTBH,\n config.threshold\n );\n\n const wasmPath = config.wasmUrl;\n const zkeyPath = config.zkeyUrl;\n\n if (!wasmPath || !zkeyPath) {\n return {\n success: false,\n commitment: tbh.commitmentBytes,\n isFirstVerification: false,\n error: \"wasmUrl and zkeyUrl must be configured for re-verification proof generation\",\n };\n }\n\n try {\n const { proof, publicSignals } = await generateProof(\n circuitInput,\n wasmPath,\n zkeyPath\n );\n solanaProof = serializeProof(proof, publicSignals);\n } catch (proofErr: any) {\n // Include diagnostics in error for mobile debugging (no devtools)\n const audioNZ = features.slice(0, 44).filter((v) => v !== 0).length;\n const motionNZ = features.slice(44, 98).filter((v) => v !== 0).length;\n const touchNZ = features.slice(98, 134).filter((v) => v !== 0).length;\n const rawAudio = sensorData.audio?.samples.length ?? 0;\n const rawMotion = sensorData.motion.length;\n const rawTouch = sensorData.touch.length;\n // First 3 feature values as a fingerprint to detect identical data\n const sig = features.slice(0, 3).map((v) => v.toFixed(4)).join(\",\");\n return {\n success: false,\n commitment: tbh.commitmentBytes,\n isFirstVerification: false,\n error: `Proof failed (dist=${distance}, feat=${audioNZ}/${motionNZ}/${touchNZ}, raw=${rawAudio}/${rawMotion}/${rawTouch}, sig=${sig}): ${proofErr?.message ?? proofErr}`,\n };\n }\n }\n\n // Submit\n let submission;\n\n if (wallet && connection) {\n if (isFirstVerification) {\n submission = await submitViaWallet(\n solanaProof ?? { proofBytes: new Uint8Array(0), publicInputs: [] },\n tbh.commitmentBytes,\n { wallet, connection, isFirstVerification: true }\n );\n } else {\n submission = await submitViaWallet(solanaProof!, tbh.commitmentBytes, {\n wallet,\n connection,\n isFirstVerification: false,\n });\n }\n } else if (config.relayerUrl) {\n submission = await submitViaRelayer(\n solanaProof ?? { proofBytes: new Uint8Array(0), publicInputs: [] },\n tbh.commitmentBytes,\n { relayerUrl: config.relayerUrl, apiKey: config.relayerApiKey, isFirstVerification }\n );\n } else {\n return {\n success: false,\n commitment: tbh.commitmentBytes,\n isFirstVerification,\n error: \"No wallet or relayer configured\",\n };\n }\n\n // Store verification data locally for next re-verification\n if (submission.success) {\n storeVerificationData({\n fingerprint: tbh.fingerprint,\n salt: tbh.salt.toString(),\n commitment: tbh.commitment.toString(),\n timestamp: Date.now(),\n });\n }\n\n return {\n success: submission.success,\n commitment: tbh.commitmentBytes,\n txSignature: submission.txSignature,\n isFirstVerification,\n error: submission.error,\n };\n}\n\n/**\n * PulseSession — event-driven staged capture session.\n *\n * Gives the caller control over when each sensor stage starts and stops.\n * After all stages complete, call complete() to run the processing pipeline.\n *\n * Usage:\n * const session = pulse.createSession(touchElement);\n * await session.startAudio();\n * // ... user speaks ...\n * await session.stopAudio();\n * await session.startMotion();\n * // ... user holds device ...\n * await session.stopMotion();\n * await session.startTouch();\n * // ... user traces curve ...\n * await session.stopTouch();\n * const result = await session.complete(wallet, connection);\n */\nexport class PulseSession {\n private config: ResolvedConfig;\n private touchElement: HTMLElement | undefined;\n\n private audioStageState: StageState = \"idle\";\n private motionStageState: StageState = \"idle\";\n private touchStageState: StageState = \"idle\";\n\n private audioController: AbortController | null = null;\n private motionController: AbortController | null = null;\n private touchController: AbortController | null = null;\n\n private audioPromise: Promise<AudioCapture | null> | null = null;\n private motionPromise: Promise<MotionSample[]> | null = null;\n private touchPromise: Promise<TouchSample[]> | null = null;\n\n private audioData: AudioCapture | null = null;\n private motionData: MotionSample[] = [];\n private touchData: TouchSample[] = [];\n\n constructor(config: ResolvedConfig, touchElement?: HTMLElement) {\n this.config = config;\n this.touchElement = touchElement;\n }\n\n // --- Audio ---\n\n async startAudio(onAudioLevel?: (rms: number) => void): Promise<void> {\n if (this.audioStageState !== \"idle\")\n throw new Error(\"Audio capture already started\");\n\n // Acquire microphone permission within the user gesture context.\n // Awaited so the caller knows audio is ready before proceeding.\n // State transitions happen AFTER permission succeeds to avoid zombie state.\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n sampleRate: 16000,\n channelCount: 1,\n echoCancellation: false,\n noiseSuppression: false,\n autoGainControl: false,\n },\n });\n\n this.audioStageState = \"capturing\";\n this.audioController = new AbortController();\n this.audioPromise = captureAudio({\n signal: this.audioController.signal,\n onAudioLevel,\n stream,\n }).catch(() => {\n stream.getTracks().forEach((t) => t.stop());\n return null;\n });\n }\n\n async stopAudio(): Promise<AudioCapture | null> {\n if (this.audioStageState !== \"capturing\")\n throw new Error(\"Audio capture not active\");\n this.audioController!.abort();\n this.audioData = await this.audioPromise!;\n this.audioStageState = \"captured\";\n return this.audioData;\n }\n\n // Audio is mandatory — no skipAudio() method.\n // If startAudio() fails, the verification cannot proceed.\n\n // --- Motion ---\n\n async startMotion(): Promise<void> {\n if (this.motionStageState !== \"idle\")\n throw new Error(\"Motion capture already started\");\n\n // Request motion permission within the user gesture context (iOS 13+).\n // Awaited so the capture timer doesn't start before the user approves.\n const hasPermission = await requestMotionPermission();\n if (!hasPermission) {\n this.motionStageState = \"skipped\";\n return;\n }\n\n this.motionStageState = \"capturing\";\n this.motionController = new AbortController();\n this.motionPromise = captureMotion({\n signal: this.motionController.signal,\n permissionGranted: true,\n }).catch(() => []);\n }\n\n async stopMotion(): Promise<MotionSample[]> {\n if (this.motionStageState !== \"capturing\")\n throw new Error(\"Motion capture not active\");\n this.motionController!.abort();\n this.motionData = await this.motionPromise!;\n this.motionStageState = \"captured\";\n return this.motionData;\n }\n\n skipMotion(): void {\n if (this.motionStageState !== \"idle\")\n throw new Error(\"Motion capture already started\");\n this.motionStageState = \"skipped\";\n }\n\n isMotionCapturing(): boolean {\n return this.motionStageState === \"capturing\";\n }\n\n // --- Touch ---\n\n async startTouch(): Promise<void> {\n if (this.touchStageState !== \"idle\")\n throw new Error(\"Touch capture already started\");\n if (!this.touchElement)\n throw new Error(\"No touch element provided to session\");\n this.touchStageState = \"capturing\";\n this.touchController = new AbortController();\n this.touchPromise = captureTouch(this.touchElement, {\n signal: this.touchController.signal,\n }).catch(() => []);\n }\n\n async stopTouch(): Promise<TouchSample[]> {\n if (this.touchStageState !== \"capturing\")\n throw new Error(\"Touch capture not active\");\n this.touchController!.abort();\n this.touchData = await this.touchPromise!;\n this.touchStageState = \"captured\";\n return this.touchData;\n }\n\n skipTouch(): void {\n if (this.touchStageState !== \"idle\")\n throw new Error(\"Touch capture already started\");\n this.touchStageState = \"skipped\";\n }\n\n // --- Complete ---\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Solana types are optional peer deps\n async complete(wallet?: any, connection?: any): Promise<VerificationResult> {\n const active: string[] = [];\n if (this.audioStageState === \"capturing\") active.push(\"audio\");\n if (this.motionStageState === \"capturing\") active.push(\"motion\");\n if (this.touchStageState === \"capturing\") active.push(\"touch\");\n if (active.length > 0) {\n throw new Error(\n `Cannot complete: stages still capturing: ${active.join(\", \")}`\n );\n }\n\n const sensorData: SensorData = {\n audio: this.audioData,\n motion: this.motionData,\n touch: this.touchData,\n modalities: {\n audio: this.audioData !== null,\n motion: this.motionData.length > 0,\n touch: this.touchData.length > 0,\n },\n };\n\n return processSensorData(sensorData, this.config, wallet, connection);\n }\n}\n\n/**\n * PulseSDK — main entry point for IAM Protocol verification.\n *\n * Two usage modes:\n * 1. Simple (backward-compatible): pulse.verify(touchElement) — captures all sensors\n * for DEFAULT_CAPTURE_MS in parallel, then processes.\n * 2. Staged (event-driven): pulse.createSession(touchElement) — caller controls\n * when each sensor stage starts and stops.\n */\nexport class PulseSDK {\n private config: ResolvedConfig;\n\n constructor(config: PulseConfig) {\n this.config = {\n threshold: DEFAULT_THRESHOLD,\n ...config,\n };\n }\n\n /**\n * Create a staged capture session for event-driven control.\n */\n createSession(touchElement?: HTMLElement): PulseSession {\n return new PulseSession(this.config, touchElement);\n }\n\n /**\n * Run a full verification with automatic timed capture (backward-compatible).\n * Captures all sensors in parallel for DEFAULT_CAPTURE_MS, then processes.\n */\n async verify(\n touchElement?: HTMLElement,\n wallet?: any,\n connection?: any\n ): Promise<VerificationResult> {\n try {\n const session = this.createSession(touchElement);\n const stopPromises: Promise<void>[] = [];\n\n // Motion first — requires user gesture on iOS (gesture expires after getUserMedia)\n try {\n await session.startMotion();\n } catch {\n /* unexpected error — motion already skipped or idle */\n }\n if (session.isMotionCapturing()) {\n stopPromises.push(\n new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))\n .then(() => session.stopMotion())\n .then(() => {})\n );\n }\n\n // Audio second — getUserMedia works without a gesture on secure origins\n try {\n await session.startAudio();\n stopPromises.push(\n new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))\n .then(() => session.stopAudio())\n .then(() => {})\n );\n } catch (err: any) {\n throw new Error(`Audio capture failed: ${err?.message ?? \"microphone unavailable\"}`);\n }\n\n // Touch\n if (touchElement) {\n try {\n await session.startTouch();\n stopPromises.push(\n new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))\n .then(() => session.stopTouch())\n .then(() => {})\n );\n } catch {\n session.skipTouch();\n }\n } else {\n session.skipTouch();\n }\n\n await Promise.all(stopPromises);\n return session.complete(wallet, connection);\n } catch (err: any) {\n return {\n success: false,\n commitment: new Uint8Array(32),\n isFirstVerification: true,\n error: err.message ?? String(err),\n };\n }\n }\n}\n","// Phonetically-balanced nonsense syllables for the voice challenge.\n// Designed to elicit diverse vocal patterns while preventing dictionary-based deepfake attacks.\nconst SYLLABLES = [\n \"ba\", \"da\", \"fa\", \"ga\", \"ha\", \"ja\", \"ka\", \"la\", \"ma\", \"na\",\n \"pa\", \"ra\", \"sa\", \"ta\", \"wa\", \"za\", \"be\", \"de\", \"fe\", \"ge\",\n \"ke\", \"le\", \"me\", \"ne\", \"pe\", \"re\", \"se\", \"te\", \"we\", \"ze\",\n \"bi\", \"di\", \"fi\", \"gi\", \"ki\", \"li\", \"mi\", \"ni\", \"pi\", \"ri\",\n \"si\", \"ti\", \"wi\", \"zi\", \"bo\", \"do\", \"fo\", \"go\", \"ko\", \"lo\",\n \"mo\", \"no\", \"po\", \"ro\", \"so\", \"to\", \"wo\", \"zo\", \"bu\", \"du\",\n \"fu\", \"gu\", \"ku\", \"lu\", \"mu\", \"nu\", \"pu\", \"ru\", \"su\", \"tu\",\n];\n\n/** Cryptographically random integer in [0, max) */\nfunction secureRandom(max: number): number {\n const arr = new Uint32Array(1);\n crypto.getRandomValues(arr);\n return arr[0]! % max;\n}\n\n/**\n * Generate a random phonetically-balanced phrase for the voice challenge.\n * Each phrase is 5-6 syllable pairs, forming nonsensical but speakable words.\n * Uses crypto.getRandomValues for unpredictable challenge generation.\n */\nexport function generatePhrase(wordCount: number = 5): string {\n const words: string[] = [];\n for (let w = 0; w < wordCount; w++) {\n const syllableCount = 2 + secureRandom(2);\n let word = \"\";\n for (let s = 0; s < syllableCount; s++) {\n word += SYLLABLES[secureRandom(SYLLABLES.length)];\n }\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Generate a sequence of phrases for dynamic mid-session switching.\n * Each phrase uses a different syllable subset to prevent pre-computation.\n */\nexport function generatePhraseSequence(\n count: number = 3,\n wordCount: number = 4\n): string[] {\n const subsetSize = Math.floor(SYLLABLES.length / count);\n const phrases: string[] = [];\n\n for (let p = 0; p < count; p++) {\n const start = (p * subsetSize) % SYLLABLES.length;\n const subset = [\n ...SYLLABLES.slice(start, start + subsetSize),\n ...SYLLABLES.slice(0, Math.max(0, (start + subsetSize) - SYLLABLES.length)),\n ];\n\n const words: string[] = [];\n for (let w = 0; w < wordCount; w++) {\n const syllableCount = 2 + secureRandom(2);\n let word = \"\";\n for (let s = 0; s < syllableCount; s++) {\n word += subset[secureRandom(subset.length)];\n }\n words.push(word);\n }\n phrases.push(words.join(\" \"));\n }\n\n return phrases;\n}\n","/**\n * Generate Lissajous curve points for the touch tracing challenge.\n * The user traces this shape on screen while speaking the phrase.\n *\n * x(t) = A * sin(a*t + delta)\n * y(t) = B * sin(b*t)\n */\nexport interface LissajousParams {\n a: number;\n b: number;\n delta: number;\n points: number;\n}\n\nexport interface Point2D {\n x: number;\n y: number;\n}\n\n/**\n * Generate random Lissajous parameters for a challenge.\n */\nexport function randomLissajousParams(): LissajousParams {\n const ratios = [\n [1, 2],\n [2, 3],\n [3, 4],\n [3, 5],\n [4, 5],\n ];\n const arr = new Uint32Array(2);\n crypto.getRandomValues(arr);\n const pair = ratios[arr[0]! % ratios.length]!;\n return {\n a: pair[0]!,\n b: pair[1]!,\n delta: Math.PI * (0.25 + (arr[1]! / 0xFFFFFFFF) * 0.5),\n points: 200,\n };\n}\n\n/**\n * Generate Lissajous curve points normalized to [0, 1] range.\n */\nexport function generateLissajousPoints(params: LissajousParams): Point2D[] {\n const { a, b, delta, points } = params;\n const result: Point2D[] = [];\n\n for (let i = 0; i < points; i++) {\n const t = (i / points) * 2 * Math.PI;\n result.push({\n x: (Math.sin(a * t + delta) + 1) / 2,\n y: (Math.sin(b * t) + 1) / 2,\n });\n }\n\n return result;\n}\n\n/**\n * Generate a sequence of Lissajous curves for dynamic mid-session switching.\n * Each curve uses different parameters, preventing pre-computation.\n */\nexport function generateLissajousSequence(\n count: number = 2\n): { params: LissajousParams; points: Point2D[] }[] {\n const allRatios: [number, number][] = [\n [1, 2], [2, 3], [3, 4], [3, 5], [4, 5],\n [1, 3], [2, 5], [5, 6], [3, 7], [4, 7],\n ];\n\n // Fisher-Yates shuffle with crypto randomness\n const shuffled = [...allRatios];\n for (let i = shuffled.length - 1; i > 0; i--) {\n const arr = new Uint32Array(1);\n crypto.getRandomValues(arr);\n const j = arr[0]! % (i + 1);\n [shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!];\n }\n\n const sequence: { params: LissajousParams; points: Point2D[] }[] = [];\n\n for (let i = 0; i < count; i++) {\n const pair = shuffled[i % shuffled.length]!;\n const deltaArr = new Uint32Array(1);\n crypto.getRandomValues(deltaArr);\n const params: LissajousParams = {\n a: pair[0],\n b: pair[1],\n delta: Math.PI * (0.1 + (deltaArr[0]! / 0xFFFFFFFF) * 0.8),\n points: 200,\n };\n sequence.push({ params, points: generateLissajousPoints(params) });\n }\n\n return sequence;\n}\n"],"mappings":"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","names":["mean","derivative","window"]}