encryptWalletToBundle function
Encrypts a mnemonic wallet bundle using HPKE and verifies the enclave signature.
This function securely encrypts a mnemonic phrase using HPKE (Hybrid Public Key Encryption) based on a target public key extracted from the provided import bundle. The function also verifies the integrity of the enclave signature to ensure the authenticity of the bundle before encryption.
Parameters:
mnemonic: The mnemonic phrase to encrypt.importBundle: A JSON string representing the import bundle, which includes enclave-generated metadata and target public key.userId: The user ID associated with the import bundle.organizationId: The organization ID associated with the import bundle.dangerouslyOverrideSignerPublicKey: Optionally override the default signer public key for testing purposes.
Returns:
- A String representing the encrypted wallet bundle in JSON format.
Throws:
- Exception: If the enclave signature verification fails, or if the bundle validation fails (e.g., mismatched organization or user ID).
Implementation
Future<String> encryptWalletToBundle({
required String mnemonic,
required String importBundle,
required String userId,
required String organizationId,
String? dangerouslyOverrideSignerPublicKey,
}) async {
final Map<String, dynamic> parsedImportBundle = jsonDecode(importBundle);
final Uint8List plainTextBuf = Uint8List.fromList(utf8.encode(mnemonic));
final bool verified = await verifyEnclaveSignature(
enclaveQuorumPublic: parsedImportBundle['enclaveQuorumPublic'],
publicSignature: parsedImportBundle['dataSignature'],
signedData: parsedImportBundle['data'],
dangerouslyOverrideSignerPublicKey: dangerouslyOverrideSignerPublicKey,
);
if (!verified) {
throw Exception('Failed to verify enclave signature: $importBundle');
}
final Uint8List dataBytes =
uint8ArrayFromHexString(parsedImportBundle['data']);
final String signedDataJson = utf8.decode(dataBytes);
final Map<String, dynamic> signedData = jsonDecode(signedDataJson);
if (signedData['organizationId'] == null ||
signedData['organizationId'] != organizationId) {
throw Exception(
'Organization ID does not match expected value. '
'Expected: $organizationId. Found: ${signedData["organizationId"]}.',
);
}
if (signedData['userId'] == null || signedData['userId'] != userId) {
throw Exception(
'User ID does not match expected value. '
'Expected: $userId. Found: ${signedData["userId"]}.',
);
}
if (signedData['targetPublic'] == null) {
throw Exception('Missing "targetPublic" in bundle signed data.');
}
// Load target public key generated from enclave
final Uint8List targetKeyBuf =
uint8ArrayFromHexString(signedData['targetPublic']);
final Uint8List privateKeyBundle = hpkeEncrypt(
plainTextBuf: plainTextBuf,
targetKeyBuf: targetKeyBuf,
hpkeInfo: zeroxkeyHpkeInfo,
);
return formatHpkeBuf(privateKeyBundle);
}