Skip to content

Commit d13590b

Browse files
committed
feat: add dreiveProvider
1 parent f35dbe3 commit d13590b

File tree

4 files changed

+180
-3
lines changed

4 files changed

+180
-3
lines changed

packages/plugin-tee-verifiable-log/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from "./types/logTypes.ts";
1111

1212
export { PageQuery, VerifiableAgent, VerifiableLog, VerifiableLogQuery };
13+
export { DeriveProvider } from "./providers/dreriveProvider.ts"
1314

1415
export class VerifiableLogService extends Service {
1516
getInstance(): VerifiableLogService {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { DeriveKeyProvider } from "@elizaos/plugin-tee";
2+
import * as crypto from "crypto";
3+
4+
export class DeriveProvider {
5+
private provider: DeriveKeyProvider;
6+
7+
constructor(teeModel: string) {
8+
this.provider = new DeriveKeyProvider(teeModel);
9+
}
10+
11+
async deriveKeyPair(params: {
12+
agentId: string;
13+
bizModel: string;
14+
}): Promise<Buffer> {
15+
const keyPath = `/${params.agentId}/tee/keypair/${params.bizModel}`;
16+
const seed = await this.provider.rawDeriveKey(keyPath, params.agentId);
17+
// 从 PEM 格式解析私钥
18+
const privateKey = crypto.createPrivateKey({
19+
key: seed.key,
20+
format: "pem",
21+
});
22+
// 导出私钥为 DER 格式
23+
const privateKeyDer = privateKey.export({
24+
format: "der",
25+
type: "pkcs8",
26+
});
27+
// 使用 SHA-256 对私钥进行哈希,派生出对称加密密钥
28+
return crypto.createHash("sha256").update(privateKeyDer).digest();
29+
}
30+
31+
async encryptAgentData(
32+
params: {
33+
agentId: string;
34+
bizModel: string;
35+
},
36+
plainText: string
37+
): Promise<{
38+
success: boolean;
39+
errorMsg: string;
40+
ivHex: string;
41+
encryptedData: string;
42+
}> {
43+
try {
44+
const rawKey = await this.deriveKeyPair(params);
45+
const { ivHex, encrypted } = this.encrypt(plainText, rawKey);
46+
47+
return {
48+
success: true,
49+
errorMsg: "",
50+
ivHex: ivHex,
51+
encryptedData: encrypted,
52+
};
53+
} catch (error) {
54+
return {
55+
success: true,
56+
errorMsg: "encryptAgentData failed:" + error,
57+
ivHex: "",
58+
encryptedData: "",
59+
};
60+
}
61+
}
62+
63+
async decryptAgentData(
64+
params: {
65+
agentId: string;
66+
bizModel: string;
67+
},
68+
ivHex: string,
69+
encryptedData: string
70+
): Promise<{
71+
success: boolean;
72+
errorMsg: string;
73+
plainText: string;
74+
}> {
75+
try {
76+
const rawKey = await this.deriveKeyPair(params);
77+
const plainText = this.decrypt(encryptedData, ivHex, rawKey);
78+
return {
79+
success: true,
80+
errorMsg: "",
81+
plainText: plainText,
82+
};
83+
} catch (error) {
84+
return {
85+
success: false,
86+
errorMsg: "decryptAgentData failed: " + error,
87+
plainText: "",
88+
};
89+
}
90+
}
91+
92+
// 加密函数
93+
private encrypt(
94+
text: string,
95+
key: Buffer
96+
): { ivHex: string; encrypted: string } {
97+
// 生成随机初始化向量(IV)
98+
const iv = crypto.randomBytes(16);
99+
100+
// 创建 cipher 对象
101+
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
102+
103+
// 加密
104+
let encrypted = cipher.update(text, "utf8", "hex");
105+
encrypted += cipher.final("hex");
106+
107+
// 返回 IV 和加密后的数据(IV 需要在解密时使用)
108+
return { ivHex: iv.toString("hex"), encrypted: encrypted };
109+
}
110+
111+
// 解密函数
112+
private decrypt(encryptedData: string, ivHex: string, key: Buffer): string {
113+
const decipher = crypto.createDecipheriv(
114+
"aes-256-cbc",
115+
key,
116+
Buffer.from(ivHex, "hex")
117+
);
118+
let decrypted = decipher.update(encryptedData, "hex", "utf8");
119+
decrypted += decipher.final("utf8");
120+
return decrypted;
121+
}
122+
}

packages/plugin-tee-verifiable-log/src/providers/verifiableLogProvider.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { elizaLogger } from "@elizaos/core";
12
import {
23
IVerifiableLogProvider,
34
VerifiableAgent,
@@ -47,8 +48,7 @@ export class VerifiableLogProvider implements IVerifiableLogProvider {
4748

4849
// evmKeypair can now be used for Ethereum operations
4950
} catch (error) {
50-
console.error("EVM key derivation failed:", error);
51-
51+
elizaLogger.error("EVM key derivation failed:", error)
5252
return false;
5353
}
5454
return this.dao.addLog(<VerifiableLog>{
@@ -108,7 +108,7 @@ export class VerifiableLogProvider implements IVerifiableLogProvider {
108108
const quote: RemoteAttestationQuote = await this.remoteAttestationProvider.generateAttestation(reportData);
109109
return JSON.stringify(quote);
110110
} catch (error) {
111-
console.error("Failed to generate attestation quote:", error);
111+
elizaLogger.error("Failed to generate attestation quote:", error);
112112
throw error;
113113
}
114114
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { v4 as uuidv4 } from "uuid";
3+
4+
import { DeriveProvider } from "../providers/dreriveProvider.ts";
5+
6+
describe("DeriveProvider", () => {
7+
let deriveProvider: DeriveProvider;
8+
const teeEndpoint = "LOCAL";
9+
beforeEach(() => {
10+
deriveProvider = new DeriveProvider(teeEndpoint);
11+
});
12+
describe("DeriveProvider Management", () => {
13+
it("should deriveKeyPair when available", async () => {
14+
const agentId = uuidv4();
15+
const { keys } = await deriveProvider.deriveKeyPair({
16+
agentId: agentId,
17+
bizModel: "test",
18+
});
19+
expect(keys).not.toBeNull();
20+
});
21+
it("should deriveKeyPair when available", async () => {
22+
const agentId = uuidv4();
23+
const plantText = "Helo World";
24+
const { success, errorMsg, ivHex, encryptedData } =
25+
await deriveProvider.encryptAgentData(
26+
{
27+
agentId: agentId,
28+
bizModel: "test",
29+
},
30+
plantText
31+
);
32+
console.log("encryptAgentData:", {
33+
success,
34+
errorMsg,
35+
ivHex,
36+
encryptedData,
37+
});
38+
expect(success).toBe(true);
39+
expect(errorMsg).toBe("");
40+
41+
const result =
42+
await deriveProvider.decryptAgentData(
43+
{
44+
agentId: agentId,
45+
bizModel: "test",
46+
},
47+
ivHex,
48+
encryptedData
49+
);
50+
console.log("=====",result)
51+
expect(result.plainText).toBe(plantText);
52+
});
53+
});
54+
});

0 commit comments

Comments
 (0)