@clduab11/gemini-flow
Version:
Revolutionary AI agent swarm coordination platform with Google Services integration, multimedia processing, and production-ready monitoring. Features 8 Google AI services, quantum computing capabilities, and enterprise-grade security.
1,265 lines (1,094 loc) • 35.4 kB
text/typescript
/**
* A2A Secure Key Exchange System
*
* Implements advanced cryptographic protocols for secure key exchange:
* - Elliptic Curve Diffie-Hellman (ECDH) with P-384
* - Post-quantum cryptography preparation (Kyber, Dilithium)
* - Distributed key generation and management
* - Automated key rotation with forward secrecy
* - Key derivation functions (HKDF, PBKDF2)
* - Hardware Security Module (HSM) integration ready
* - Certificate-based authentication with PKI
*/
import crypto from "crypto";
import { EventEmitter } from "events";
import { Logger } from "../utils/logger.js";
import { CacheManager } from "./cache-manager.js";
export interface KeyPairInfo {
keyId: string;
algorithm: "ECDH" | "RSA" | "Kyber" | "Dilithium";
curve?: "secp256r1" | "secp384r1" | "secp521r1";
keySize?: number;
publicKey: string;
privateKey?: string; // Only stored securely
createdAt: Date;
expiresAt: Date;
status: "active" | "rotating" | "revoked" | "expired";
usageCount: number;
maxUsage: number;
}
export interface KeyExchangeRequest {
requestId: string;
fromAgentId: string;
toAgentId: string;
publicKey: string;
algorithm: string;
curve?: string;
nonce: string;
timestamp: number;
signature: string;
capabilities: string[];
}
export interface KeyExchangeResponse {
requestId: string;
responseId: string;
fromAgentId: string;
toAgentId: string;
publicKey: string;
algorithm: string;
curve?: string;
nonce: string;
timestamp: number;
signature: string;
agreed: boolean;
sharedSecretHash?: string; // For verification
}
export interface SharedSecret {
secretId: string;
agentPair: [string, string];
sharedSecret: Buffer;
derivedKeys: {
encryptionKey: Buffer;
macKey: Buffer;
signingKey: Buffer;
};
createdAt: Date;
expiresAt: Date;
rotationScheduled: Date;
usageCount: number;
maxUsage: number;
}
export interface KeyRotationPolicy {
automaticRotation: boolean;
rotationInterval: number; // milliseconds
maxKeyUsage: number;
keyLifetime: number; // milliseconds
preRotationWarning: number; // milliseconds before expiry
emergencyRotation: boolean;
quantumSafeTransition: boolean;
}
export interface DistributedKeyShare {
shareId: string;
threshold: number;
totalShares: number;
shareIndex: number;
encryptedShare: string;
publicCommitment: string;
verificationProof: string;
createdAt: Date;
}
export interface HSMConfig {
enabled: boolean;
provider: "PKCS11" | "CloudHSM" | "Azure" | "Google";
endpoint?: string;
credentials?: any;
keyGeneration: boolean;
keyStorage: boolean;
signing: boolean;
}
export class A2AKeyExchange extends EventEmitter {
private logger: Logger;
private cache: CacheManager;
// Key management
private keyPairs: Map<string, KeyPairInfo> = new Map();
private sharedSecrets: Map<string, SharedSecret> = new Map();
private distributedShares: Map<string, DistributedKeyShare[]> = new Map();
// Exchange tracking
private pendingExchanges: Map<string, KeyExchangeRequest> = new Map();
private completedExchanges: Map<string, KeyExchangeResponse> = new Map();
// Security and policy
private rotationPolicy: KeyRotationPolicy;
private hsmConfig: HSMConfig;
// Cryptographic state
private masterKeyPair: crypto.KeyPairKeyObjectResult | null = null;
private certificateChain: string[] = [];
private trustedCAs: Set<string> = new Set();
// Performance tracking
private metrics = {
keyGenerations: 0,
keyExchanges: 0,
keyRotations: 0,
failedExchanges: 0,
hsmOperations: 0,
};
constructor(
options: {
rotationPolicy?: Partial<KeyRotationPolicy>;
hsmConfig?: Partial<HSMConfig>;
trustedCAs?: string[];
} = {},
) {
super();
this.logger = new Logger("A2AKeyExchange");
this.cache = new CacheManager();
this.initializeRotationPolicy(options.rotationPolicy);
this.initializeHSMConfig(options.hsmConfig);
this.initializeTrustedCAs(options.trustedCAs);
this.initializeMasterKeys();
this.startKeyRotationScheduler();
this.startPerformanceMonitoring();
this.logger.info("A2A Key Exchange system initialized", {
rotationEnabled: this.rotationPolicy.automaticRotation,
hsmEnabled: this.hsmConfig.enabled,
quantumSafe: this.rotationPolicy.quantumSafeTransition,
});
}
/**
* Initialize key rotation policy
*/
private initializeRotationPolicy(
policy: Partial<KeyRotationPolicy> = {},
): void {
this.rotationPolicy = {
automaticRotation: true,
rotationInterval: 7 * 24 * 60 * 60 * 1000, // 7 days
maxKeyUsage: 10000,
keyLifetime: 30 * 24 * 60 * 60 * 1000, // 30 days
preRotationWarning: 24 * 60 * 60 * 1000, // 24 hours
emergencyRotation: true,
quantumSafeTransition: false,
...policy,
};
}
/**
* Initialize HSM configuration
*/
private initializeHSMConfig(config: Partial<HSMConfig> = {}): void {
this.hsmConfig = {
enabled: false,
provider: "PKCS11",
keyGeneration: false,
keyStorage: false,
signing: false,
...config,
};
}
/**
* Initialize trusted Certificate Authorities
*/
private initializeTrustedCAs(cas: string[] = []): void {
for (const ca of cas) {
this.trustedCAs.add(ca);
}
// Add default system CAs if none provided
if (cas.length === 0) {
this.loadSystemCAs();
}
}
/**
* Initialize master key pairs
*/
private async initializeMasterKeys(): Promise<void> {
try {
if (this.hsmConfig.enabled && this.hsmConfig.keyGeneration) {
this.masterKeyPair = await this.generateHSMKeyPair();
} else {
this.masterKeyPair = await this.generateSoftwareKeyPair();
}
// Create master key info
const masterKeyInfo: KeyPairInfo = {
keyId: "master",
algorithm: "ECDH",
curve: "secp384r1",
publicKey: this.masterKeyPair.publicKey.export({
type: "spki",
format: "pem",
}) as string,
createdAt: new Date(),
expiresAt: new Date(Date.now() + this.rotationPolicy.keyLifetime),
status: "active",
usageCount: 0,
maxUsage: this.rotationPolicy.maxKeyUsage,
};
this.keyPairs.set("master", masterKeyInfo);
this.logger.info("Master keys initialized", {
algorithm: masterKeyInfo.algorithm,
curve: masterKeyInfo.curve,
hsm: this.hsmConfig.enabled,
});
} catch (error) {
this.logger.error("Failed to initialize master keys", { error });
throw error;
}
}
/**
* Generate agent-specific key pair
*/
async generateAgentKeyPair(
agentId: string,
algorithm: "ECDH" | "RSA" | "Kyber" = "ECDH",
curve: "secp256r1" | "secp384r1" | "secp521r1" = "secp384r1",
): Promise<KeyPairInfo> {
try {
let keyPair: crypto.KeyPairKeyObjectResult;
if (this.hsmConfig.enabled && this.hsmConfig.keyGeneration) {
keyPair = await this.generateHSMKeyPair(algorithm, curve);
this.metrics.hsmOperations++;
} else {
keyPair = await this.generateSoftwareKeyPair(algorithm, curve);
}
const keyInfo: KeyPairInfo = {
keyId: `${agentId}-${Date.now()}`,
algorithm,
curve: algorithm === "ECDH" ? curve : undefined,
keySize: algorithm === "RSA" ? 4096 : undefined,
publicKey: keyPair.publicKey.export({
type: "spki",
format: "pem",
}) as string,
privateKey: this.hsmConfig.enabled
? undefined
: (keyPair.privateKey.export({
type: "pkcs8",
format: "pem",
}) as string),
createdAt: new Date(),
expiresAt: new Date(Date.now() + this.rotationPolicy.keyLifetime),
status: "active",
usageCount: 0,
maxUsage: this.rotationPolicy.maxKeyUsage,
};
this.keyPairs.set(keyInfo.keyId, keyInfo);
await this.cache.set(
`keyexchange:keypair:${keyInfo.keyId}`,
keyInfo,
this.rotationPolicy.keyLifetime,
);
this.metrics.keyGenerations++;
this.logger.info("Agent key pair generated", {
agentId,
keyId: keyInfo.keyId,
algorithm,
curve,
});
this.emit("key_pair_generated", { agentId, keyInfo });
return keyInfo;
} catch (error) {
this.logger.error("Failed to generate agent key pair", {
agentId,
error,
});
throw error;
}
}
/**
* Initiate key exchange between two agents
*/
async initiateKeyExchange(
fromAgentId: string,
toAgentId: string,
capabilities: string[] = [],
): Promise<KeyExchangeRequest> {
try {
// Get or generate key pair for initiating agent
let fromKeyPair = await this.getAgentKeyPair(fromAgentId);
if (!fromKeyPair || fromKeyPair.status !== "active") {
fromKeyPair = await this.generateAgentKeyPair(fromAgentId);
}
// Create exchange request
const request: KeyExchangeRequest = {
requestId: crypto.randomUUID(),
fromAgentId,
toAgentId,
publicKey: fromKeyPair.publicKey,
algorithm: fromKeyPair.algorithm,
curve: fromKeyPair.curve,
nonce: crypto.randomBytes(32).toString("hex"),
timestamp: Date.now(),
signature: "",
capabilities,
};
// Sign the request
request.signature = await this.signKeyExchangeRequest(request);
// Store pending exchange
this.pendingExchanges.set(request.requestId, request);
// Set expiration for pending exchange
setTimeout(() => {
if (this.pendingExchanges.has(request.requestId)) {
this.pendingExchanges.delete(request.requestId);
this.logger.warn("Key exchange request expired", {
requestId: request.requestId,
fromAgent: fromAgentId,
toAgent: toAgentId,
});
}
}, 300000); // 5 minutes expiration
this.logger.info("Key exchange initiated", {
requestId: request.requestId,
fromAgent: fromAgentId,
toAgent: toAgentId,
});
this.emit("key_exchange_initiated", request);
return request;
} catch (error) {
this.logger.error("Failed to initiate key exchange", {
fromAgent: fromAgentId,
toAgent: toAgentId,
error,
});
throw error;
}
}
/**
* Respond to key exchange request
*/
async respondToKeyExchange(
request: KeyExchangeRequest,
accept: boolean = true,
): Promise<KeyExchangeResponse> {
try {
// Verify request signature
const isValidRequest = await this.verifyKeyExchangeRequest(request);
if (!isValidRequest) {
throw new Error("Invalid key exchange request signature");
}
// Check if request is still pending
if (!this.pendingExchanges.has(request.requestId)) {
throw new Error("Key exchange request not found or expired");
}
let response: KeyExchangeResponse;
if (accept) {
// Get or generate key pair for responding agent
let toKeyPair = await this.getAgentKeyPair(request.toAgentId);
if (!toKeyPair || toKeyPair.status !== "active") {
toKeyPair = await this.generateAgentKeyPair(request.toAgentId);
}
// Perform ECDH key exchange
const sharedSecret = await this.performECDH(
request.publicKey,
toKeyPair.privateKey || (await this.getPrivateKey(toKeyPair.keyId)),
);
// Derive session keys
const derivedKeys = await this.deriveSessionKeys(
sharedSecret,
request.nonce,
crypto.randomBytes(32).toString("hex"),
);
// Store shared secret
const secretInfo: SharedSecret = {
secretId: crypto.randomUUID(),
agentPair: [request.fromAgentId, request.toAgentId].sort() as [
string,
string,
],
sharedSecret,
derivedKeys,
createdAt: new Date(),
expiresAt: new Date(Date.now() + this.rotationPolicy.keyLifetime),
rotationScheduled: new Date(
Date.now() + this.rotationPolicy.rotationInterval,
),
usageCount: 0,
maxUsage: this.rotationPolicy.maxKeyUsage,
};
this.sharedSecrets.set(secretInfo.secretId, secretInfo);
await this.cache.set(
`keyexchange:secret:${secretInfo.agentPair.join(":")}`,
secretInfo,
this.rotationPolicy.keyLifetime,
);
// Create response
response = {
requestId: request.requestId,
responseId: crypto.randomUUID(),
fromAgentId: request.toAgentId,
toAgentId: request.fromAgentId,
publicKey: toKeyPair.publicKey,
algorithm: toKeyPair.algorithm,
curve: toKeyPair.curve,
nonce: crypto.randomBytes(32).toString("hex"),
timestamp: Date.now(),
signature: "",
agreed: true,
sharedSecretHash: crypto
.createHash("sha256")
.update(sharedSecret)
.digest("hex"),
};
this.metrics.keyExchanges++;
this.logger.info("Key exchange accepted", {
requestId: request.requestId,
secretId: secretInfo.secretId,
agentPair: secretInfo.agentPair,
});
} else {
// Rejection response
response = {
requestId: request.requestId,
responseId: crypto.randomUUID(),
fromAgentId: request.toAgentId,
toAgentId: request.fromAgentId,
publicKey: "",
algorithm: request.algorithm,
nonce: crypto.randomBytes(32).toString("hex"),
timestamp: Date.now(),
signature: "",
agreed: false,
};
this.logger.info("Key exchange rejected", {
requestId: request.requestId,
fromAgent: request.fromAgentId,
toAgent: request.toAgentId,
});
}
// Sign response
response.signature = await this.signKeyExchangeResponse(response);
// Store completed exchange
this.completedExchanges.set(response.responseId, response);
this.pendingExchanges.delete(request.requestId);
this.emit("key_exchange_completed", { request, response });
return response;
} catch (error) {
this.metrics.failedExchanges++;
this.logger.error("Failed to respond to key exchange", {
requestId: request.requestId,
error,
});
throw error;
}
}
/**
* Get shared secret for agent pair
*/
async getSharedSecret(
agentId1: string,
agentId2: string,
): Promise<SharedSecret | null> {
const agentPair = [agentId1, agentId2].sort() as [string, string];
// Check memory first
for (const secret of this.sharedSecrets.values()) {
if (
secret.agentPair[0] === agentPair[0] &&
secret.agentPair[1] === agentPair[1]
) {
// Check if secret is still valid
if (
secret.expiresAt > new Date() &&
secret.usageCount < secret.maxUsage
) {
return secret;
}
}
}
// Check cache
const cachedSecret = await this.cache.get(
`keyexchange:secret:${agentPair.join(":")}`,
);
if (cachedSecret && cachedSecret.expiresAt > new Date()) {
this.sharedSecrets.set(cachedSecret.secretId, cachedSecret);
return cachedSecret;
}
return null;
}
/**
* Rotate keys for an agent
*/
async rotateAgentKeys(
agentId: string,
emergencyRotation: boolean = false,
): Promise<KeyPairInfo> {
try {
const currentKey = await this.getAgentKeyPair(agentId);
if (currentKey) {
// Mark current key as rotating
currentKey.status = "rotating";
await this.cache.set(
`keyexchange:keypair:${currentKey.keyId}`,
currentKey,
3600000,
);
}
// Generate new key pair
const newKeyPair = await this.generateAgentKeyPair(agentId);
// Update shared secrets that use the old key
await this.updateSharedSecretsForAgent(agentId, currentKey, newKeyPair);
if (currentKey) {
// Revoke old key after grace period
setTimeout(
() => {
currentKey.status = "revoked";
this.keyPairs.delete(currentKey.keyId);
},
emergencyRotation ? 0 : 300000,
); // 5 minutes grace period for normal rotation
}
this.metrics.keyRotations++;
this.logger.info("Agent keys rotated", {
agentId,
oldKeyId: currentKey?.keyId,
newKeyId: newKeyPair.keyId,
emergency: emergencyRotation,
});
this.emit("keys_rotated", {
agentId,
oldKey: currentKey,
newKey: newKeyPair,
emergency: emergencyRotation,
});
return newKeyPair;
} catch (error) {
this.logger.error("Failed to rotate agent keys", { agentId, error });
throw error;
}
}
/**
* Generate distributed key shares using Shamir's Secret Sharing
*/
async generateDistributedKeyShares(
secretData: Buffer,
threshold: number,
totalShares: number,
): Promise<DistributedKeyShare[]> {
try {
if (threshold > totalShares || threshold < 2) {
throw new Error("Invalid threshold parameters");
}
const shares: DistributedKeyShare[] = [];
const polynomial = this.generateShamirPolynomial(secretData, threshold);
for (let i = 1; i <= totalShares; i++) {
const shareValue = this.evaluatePolynomial(polynomial, i);
const encryptedShare = await this.encryptShare(shareValue);
const publicCommitment = await this.generateCommitment(shareValue);
const verificationProof = await this.generateVerificationProof(
shareValue,
publicCommitment,
);
const share: DistributedKeyShare = {
shareId: crypto.randomUUID(),
threshold,
totalShares,
shareIndex: i,
encryptedShare,
publicCommitment,
verificationProof,
createdAt: new Date(),
};
shares.push(share);
}
// Store shares securely
const sharesKey = crypto
.createHash("sha256")
.update(secretData)
.digest("hex");
this.distributedShares.set(sharesKey, shares);
this.logger.info("Distributed key shares generated", {
threshold,
totalShares,
sharesKey: sharesKey.substring(0, 8),
});
return shares;
} catch (error) {
this.logger.error("Failed to generate distributed key shares", { error });
throw error;
}
}
/**
* Reconstruct secret from distributed shares
*/
async reconstructSecretFromShares(
shares: DistributedKeyShare[],
): Promise<Buffer> {
try {
if (shares.length < shares[0].threshold) {
throw new Error("Insufficient shares for reconstruction");
}
// Verify shares
for (const share of shares) {
const isValid = await this.verifyShare(share);
if (!isValid) {
throw new Error(`Invalid share: ${share.shareId}`);
}
}
// Decrypt shares
const decryptedShares = await Promise.all(
shares.map((share) => this.decryptShare(share.encryptedShare)),
);
// Reconstruct using Lagrange interpolation
const secret = this.lagrangeInterpolation(
decryptedShares.slice(0, shares[0].threshold),
shares.slice(0, shares[0].threshold).map((s) => s.shareIndex),
);
this.logger.info("Secret reconstructed from shares", {
sharesUsed: shares.length,
threshold: shares[0].threshold,
});
return secret;
} catch (error) {
this.logger.error("Failed to reconstruct secret from shares", { error });
throw error;
}
}
/**
* Cryptographic helper methods
*/
private async generateSoftwareKeyPair(
algorithm: "ECDH" | "RSA" | "Kyber" = "ECDH",
curve: "secp256r1" | "secp384r1" | "secp521r1" = "secp384r1",
): Promise<crypto.KeyPairKeyObjectResult> {
if (algorithm === "ECDH") {
return crypto.generateKeyPairSync("ec", {
namedCurve: curve,
publicKeyEncoding: { type: "spki", format: "pem" },
privateKeyEncoding: { type: "pkcs8", format: "pem" },
});
} else if (algorithm === "RSA") {
return crypto.generateKeyPairSync("rsa", {
modulusLength: 4096,
publicKeyEncoding: { type: "spki", format: "pem" },
privateKeyEncoding: { type: "pkcs8", format: "pem" },
});
} else {
// Post-quantum algorithms would be implemented here
throw new Error(`Algorithm ${algorithm} not yet implemented`);
}
}
private async generateHSMKeyPair(
algorithm: "ECDH" | "RSA" | "Kyber" = "ECDH",
curve: "secp256r1" | "secp384r1" | "secp521r1" = "secp384r1",
): Promise<crypto.KeyPairKeyObjectResult> {
// HSM integration would be implemented here
// For now, fallback to software generation
this.logger.warn(
"HSM key generation not implemented, using software fallback",
);
return this.generateSoftwareKeyPair(algorithm, curve);
}
private async performECDH(
publicKeyPem: string,
privateKeyPem: string,
): Promise<Buffer> {
const publicKey = crypto.createPublicKey(publicKeyPem);
const privateKey = crypto.createPrivateKey(privateKeyPem);
return crypto.diffieHellman({
privateKey,
publicKey,
});
}
private async deriveSessionKeys(
sharedSecret: Buffer,
nonce1: string,
nonce2: string,
): Promise<{
encryptionKey: Buffer;
macKey: Buffer;
signingKey: Buffer;
}> {
const salt = Buffer.concat([
Buffer.from(nonce1, "hex"),
Buffer.from(nonce2, "hex"),
]);
const info = Buffer.from("A2A-Session-Keys-v1");
// Use HKDF for key derivation
const prk = crypto.createHmac("sha256", salt).update(sharedSecret).digest();
const encryptionKey = crypto
.createHmac("sha256", prk)
.update(
Buffer.concat([info, Buffer.from("encryption"), Buffer.from([1])]),
)
.digest();
const macKey = crypto
.createHmac("sha256", prk)
.update(Buffer.concat([info, Buffer.from("mac"), Buffer.from([2])]))
.digest();
const signingKey = crypto
.createHmac("sha256", prk)
.update(Buffer.concat([info, Buffer.from("signing"), Buffer.from([3])]))
.digest();
return { encryptionKey, macKey, signingKey };
}
private async signKeyExchangeRequest(
request: KeyExchangeRequest,
): Promise<string> {
const data = JSON.stringify({
requestId: request.requestId,
fromAgentId: request.fromAgentId,
toAgentId: request.toAgentId,
publicKey: request.publicKey,
nonce: request.nonce,
timestamp: request.timestamp,
});
if (!this.masterKeyPair) {
throw new Error("Master key pair not initialized");
}
const signature = crypto.sign("sha256", Buffer.from(data), {
key: this.masterKeyPair.privateKey,
format: "pem",
});
return signature.toString("base64");
}
private async signKeyExchangeResponse(
response: KeyExchangeResponse,
): Promise<string> {
const data = JSON.stringify({
requestId: response.requestId,
responseId: response.responseId,
fromAgentId: response.fromAgentId,
toAgentId: response.toAgentId,
publicKey: response.publicKey,
nonce: response.nonce,
timestamp: response.timestamp,
agreed: response.agreed,
});
if (!this.masterKeyPair) {
throw new Error("Master key pair not initialized");
}
const signature = crypto.sign("sha256", Buffer.from(data), {
key: this.masterKeyPair.privateKey,
format: "pem",
});
return signature.toString("base64");
}
private async verifyKeyExchangeRequest(
request: KeyExchangeRequest,
): Promise<boolean> {
const data = JSON.stringify({
requestId: request.requestId,
fromAgentId: request.fromAgentId,
toAgentId: request.toAgentId,
publicKey: request.publicKey,
nonce: request.nonce,
timestamp: request.timestamp,
});
if (!this.masterKeyPair) {
return false;
}
try {
return crypto.verify(
"sha256",
Buffer.from(data),
this.masterKeyPair.publicKey,
Buffer.from(request.signature, "base64"),
);
} catch (error) {
return false;
}
}
private async getAgentKeyPair(agentId: string): Promise<KeyPairInfo | null> {
// Find most recent active key pair for agent
for (const [keyId, keyInfo] of this.keyPairs) {
if (keyId.startsWith(agentId) && keyInfo.status === "active") {
return keyInfo;
}
}
// Check cache
// const cachePattern = `keyexchange:keypair:${agentId}-*`;
// In a real implementation, you'd search the cache with pattern matching
return null;
}
private async getPrivateKey(keyId: string): Promise<string> {
if (this.hsmConfig.enabled) {
// Retrieve from HSM
return this.getHSMPrivateKey(keyId);
}
const keyInfo = this.keyPairs.get(keyId);
if (!keyInfo?.privateKey) {
throw new Error("Private key not found");
}
return keyInfo.privateKey;
}
private async getHSMPrivateKey(_keyId: string): Promise<string> {
// HSM private key retrieval would be implemented here
throw new Error("HSM private key retrieval not implemented");
}
private async updateSharedSecretsForAgent(
agentId: string,
_oldKey: KeyPairInfo | null,
_newKey: KeyPairInfo,
): Promise<void> {
// Find and update shared secrets that involve this agent
for (const [secretId, secret] of this.sharedSecrets) {
if (secret.agentPair.includes(agentId)) {
// Mark for rotation
secret.rotationScheduled = new Date();
this.sharedSecrets.set(secretId, secret);
}
}
}
/**
* Shamir's Secret Sharing implementation
*/
private generateShamirPolynomial(
secret: Buffer,
threshold: number,
): Buffer[] {
const polynomial: Buffer[] = [secret]; // a0 = secret
// Generate random coefficients a1, a2, ..., a(threshold-1)
for (let i = 1; i < threshold; i++) {
polynomial.push(crypto.randomBytes(32));
}
return polynomial;
}
private evaluatePolynomial(polynomial: Buffer[], x: number): Buffer {
const result = Buffer.alloc(32);
for (let i = 0; i < polynomial.length; i++) {
const coefficient = polynomial[i];
const power = Math.pow(x, i);
// Simplified polynomial evaluation (in production, use proper finite field arithmetic)
const term = Buffer.alloc(32);
for (let j = 0; j < 32; j++) {
term[j] = (coefficient[j] * power) % 256;
}
for (let j = 0; j < 32; j++) {
result[j] ^= term[j];
}
}
return result;
}
private lagrangeInterpolation(shares: Buffer[], indices: number[]): Buffer {
const result = Buffer.alloc(32);
for (let i = 0; i < shares.length; i++) {
let numerator = 1;
let denominator = 1;
for (let j = 0; j < shares.length; j++) {
if (i !== j) {
numerator *= 0 - indices[j];
denominator *= indices[i] - indices[j];
}
}
const coefficient = numerator / denominator;
// Apply coefficient to share (simplified)
for (let k = 0; k < 32; k++) {
result[k] ^= Math.floor(shares[i][k] * coefficient) % 256;
}
}
return result;
}
private async encryptShare(share: Buffer): Promise<string> {
// Encrypt share with master key
if (!this.masterKeyPair) {
throw new Error("Master key not available for share encryption");
}
const cipher = crypto.createCipher(
"aes-256-gcm",
Buffer.from("share-encryption-key"),
);
const encrypted = Buffer.concat([cipher.update(share), cipher.final()]);
return encrypted.toString("base64");
}
private async decryptShare(encryptedShare: string): Promise<Buffer> {
// Decrypt share with master key
if (!this.masterKeyPair) {
throw new Error("Master key not available for share decryption");
}
const decipher = crypto.createDecipher(
"aes-256-gcm",
Buffer.from("share-encryption-key"),
);
const decrypted = Buffer.concat([
decipher.update(Buffer.from(encryptedShare, "base64")),
decipher.final(),
]);
return decrypted;
}
private async generateCommitment(share: Buffer): Promise<string> {
// Generate cryptographic commitment for share verification
const commitment = crypto
.createHash("sha256")
.update(share)
.update(Buffer.from("commitment-salt"))
.digest();
return commitment.toString("hex");
}
private async generateVerificationProof(
share: Buffer,
commitment: string,
): Promise<string> {
// Generate zero-knowledge proof for share verification
const proof = crypto
.createHmac("sha256", share)
.update(commitment)
.digest();
return proof.toString("hex");
}
private async verifyShare(share: DistributedKeyShare): Promise<boolean> {
try {
const decryptedShare = await this.decryptShare(share.encryptedShare);
const expectedCommitment = await this.generateCommitment(decryptedShare);
const expectedProof = await this.generateVerificationProof(
decryptedShare,
expectedCommitment,
);
return (
share.publicCommitment === expectedCommitment &&
share.verificationProof === expectedProof
);
} catch (error) {
return false;
}
}
/**
* System management methods
*/
private loadSystemCAs(): void {
// Load system certificate authorities
// In production, this would load from the system trust store
this.logger.debug("Loading system CAs");
}
private startKeyRotationScheduler(): void {
if (!this.rotationPolicy.automaticRotation) {
return;
}
const checkInterval = Math.min(
this.rotationPolicy.rotationInterval / 10,
3600000,
); // Check every hour max
setInterval(() => {
this.checkAndRotateKeys();
}, checkInterval);
this.logger.info("Key rotation scheduler started", {
checkInterval: checkInterval / 1000,
rotationInterval: this.rotationPolicy.rotationInterval / 1000,
});
}
private async checkAndRotateKeys(): Promise<void> {
const now = new Date();
for (const [keyId, keyInfo] of this.keyPairs) {
if (keyInfo.status !== "active") continue;
// Check if key needs rotation
const needsRotation =
keyInfo.expiresAt <= now ||
keyInfo.usageCount >= keyInfo.maxUsage ||
(this.rotationPolicy.preRotationWarning > 0 &&
keyInfo.expiresAt.getTime() - now.getTime() <=
this.rotationPolicy.preRotationWarning);
if (needsRotation && keyId !== "master") {
const agentId = keyId.split("-")[0];
try {
await this.rotateAgentKeys(agentId);
} catch (error) {
this.logger.error("Scheduled key rotation failed", {
keyId,
agentId,
error,
});
}
}
}
// Check shared secrets
for (const [secretId, secret] of this.sharedSecrets) {
if (
secret.rotationScheduled <= now ||
secret.expiresAt <= now ||
secret.usageCount >= secret.maxUsage
) {
try {
await this.rotateSharedSecret(secretId);
} catch (error) {
this.logger.error("Shared secret rotation failed", {
secretId,
error,
});
}
}
}
}
private async rotateSharedSecret(secretId: string): Promise<void> {
const secret = this.sharedSecrets.get(secretId);
if (!secret) return;
// Initiate new key exchange between the agent pair
const [agentId1, agentId2] = secret.agentPair;
try {
await this.initiateKeyExchange(agentId1, agentId2);
// Mark old secret for deletion
setTimeout(() => {
this.sharedSecrets.delete(secretId);
}, 300000); // 5 minutes grace period
this.logger.info("Shared secret rotation initiated", {
secretId,
agentPair: secret.agentPair,
});
} catch (error) {
this.logger.error("Failed to rotate shared secret", { secretId, error });
}
}
private startPerformanceMonitoring(): void {
setInterval(() => {
this.updatePerformanceMetrics();
}, 60000); // Update every minute
}
private updatePerformanceMetrics(): void {
const currentMetrics = {
...this.metrics,
activeKeyPairs: Array.from(this.keyPairs.values()).filter(
(k) => k.status === "active",
).length,
activeSharedSecrets: this.sharedSecrets.size,
pendingExchanges: this.pendingExchanges.size,
distributedShares: this.distributedShares.size,
timestamp: Date.now(),
};
this.emit("performance_metrics", currentMetrics);
}
/**
* Public API methods
*/
getKeyPairs(): KeyPairInfo[] {
return Array.from(this.keyPairs.values());
}
getSharedSecrets(): Omit<SharedSecret, "sharedSecret" | "derivedKeys">[] {
return Array.from(this.sharedSecrets.values()).map((secret) => ({
secretId: secret.secretId,
agentPair: secret.agentPair,
createdAt: secret.createdAt,
expiresAt: secret.expiresAt,
rotationScheduled: secret.rotationScheduled,
usageCount: secret.usageCount,
maxUsage: secret.maxUsage,
}));
}
getMetrics() {
return { ...this.metrics };
}
getRotationPolicy(): KeyRotationPolicy {
return { ...this.rotationPolicy };
}
async updateRotationPolicy(
updates: Partial<KeyRotationPolicy>,
): Promise<void> {
this.rotationPolicy = { ...this.rotationPolicy, ...updates };
this.logger.info("Key rotation policy updated", updates);
this.emit("rotation_policy_updated", this.rotationPolicy);
}
async emergencyKeyRotation(agentId?: string): Promise<void> {
if (!this.rotationPolicy.emergencyRotation) {
throw new Error("Emergency rotation is disabled");
}
if (agentId) {
await this.rotateAgentKeys(agentId, true);
} else {
// Rotate all agent keys
const activeAgents = new Set<string>();
for (const keyId of this.keyPairs.keys()) {
if (keyId !== "master") {
const agentId = keyId.split("-")[0];
activeAgents.add(agentId);
}
}
for (const agentId of activeAgents) {
try {
await this.rotateAgentKeys(agentId, true);
} catch (error) {
this.logger.error("Emergency rotation failed for agent", {
agentId,
error,
});
}
}
}
this.logger.warn("Emergency key rotation completed", { agentId });
this.emit("emergency_rotation_completed", {
agentId,
timestamp: Date.now(),
});
}
}