anon-identity
Version:
Decentralized identity framework with DIDs, Verifiable Credentials, and privacy-preserving selective disclosure
165 lines • 6.02 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActivityEncryption = void 0;
const crypto = __importStar(require("crypto"));
class ActivityEncryption {
constructor() {
this.algorithm = 'aes-256-gcm';
}
/**
* Generate a new encryption key
*/
static generateKey() {
return crypto.randomBytes(32);
}
/**
* Encrypt an activity object
*/
async encryptActivity(activity, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(this.algorithm, key, iv);
const activityString = JSON.stringify(activity);
const encrypted = Buffer.concat([
cipher.update(activityString, 'utf8'),
cipher.final()
]);
const tag = cipher.getAuthTag();
return {
data: encrypted.toString('base64'),
iv: iv.toString('base64'),
tag: tag.toString('base64'),
algorithm: this.algorithm
};
}
/**
* Decrypt an activity object
*/
async decryptActivity(encrypted, key) {
const decipher = crypto.createDecipheriv(encrypted.algorithm || this.algorithm, key, Buffer.from(encrypted.iv, 'base64'));
decipher.setAuthTag(Buffer.from(encrypted.tag, 'base64'));
const decrypted = Buffer.concat([
decipher.update(Buffer.from(encrypted.data, 'base64')),
decipher.final()
]);
return JSON.parse(decrypted.toString('utf8'));
}
/**
* Encrypt a batch of activities
*/
async encryptBatch(batch, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(this.algorithm, key, iv);
const batchString = JSON.stringify(batch);
const encrypted = Buffer.concat([
cipher.update(batchString, 'utf8'),
cipher.final()
]);
const tag = cipher.getAuthTag();
return {
data: encrypted.toString('base64'),
iv: iv.toString('base64'),
tag: tag.toString('base64'),
algorithm: this.algorithm
};
}
/**
* Decrypt a batch of activities
*/
async decryptBatch(encrypted, key) {
const decipher = crypto.createDecipheriv(encrypted.algorithm || this.algorithm, key, Buffer.from(encrypted.iv, 'base64'));
decipher.setAuthTag(Buffer.from(encrypted.tag, 'base64'));
const decrypted = Buffer.concat([
decipher.update(Buffer.from(encrypted.data, 'base64')),
decipher.final()
]);
return JSON.parse(decrypted.toString('utf8'));
}
/**
* Create a deterministic key from user DID and passphrase
*/
static async deriveKey(userDID, passphrase) {
const salt = crypto.createHash('sha256').update(userDID).digest();
return new Promise((resolve, reject) => {
crypto.pbkdf2(passphrase, salt, 100000, 32, 'sha256', (err, derivedKey) => {
if (err)
reject(err);
else
resolve(new Uint8Array(derivedKey));
});
});
}
/**
* Create a hash of an activity for integrity verification
*/
static createActivityHash(activity) {
const hash = crypto.createHash('sha256');
hash.update(JSON.stringify({
id: activity.id,
agentDID: activity.agentDID,
parentDID: activity.parentDID,
timestamp: activity.timestamp,
type: activity.type,
serviceDID: activity.serviceDID,
status: activity.status,
scopes: activity.scopes
}));
return hash.digest('hex');
}
/**
* Create a merkle root for a batch of activities
*/
static createBatchMerkleRoot(activities) {
if (activities.length === 0)
return '';
// Create leaf hashes
let hashes = activities.map(activity => this.createActivityHash(activity));
// Build merkle tree
while (hashes.length > 1) {
const newHashes = [];
for (let i = 0; i < hashes.length; i += 2) {
const left = hashes[i];
const right = hashes[i + 1] || left; // Duplicate last hash if odd number
const combined = crypto.createHash('sha256');
combined.update(left + right);
newHashes.push(combined.digest('hex'));
}
hashes = newHashes;
}
return hashes[0];
}
}
exports.ActivityEncryption = ActivityEncryption;
//# sourceMappingURL=activity-encryption.js.map