Skip to content

Commit

Permalink
Adding two layer proposal encryption handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
brickpop committed Apr 3, 2024
1 parent 5cfcf50 commit 72d4d22
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 1 deletion.
2 changes: 1 addition & 1 deletion utils/encryption/asymmetric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function decryptString(ciphertext: Uint8Array, keyPair: KeyPair) {

export function decryptBytes(
ciphertext: Uint8Array,
keyPair: KeyPair
keyPair: KeyPair | Omit<KeyPair, "keyType">
): Uint8Array {
return sodium.crypto_box_seal_open(
ciphertext,
Expand Down
93 changes: 93 additions & 0 deletions utils/encryption/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import libsodium from "libsodium-wrappers";
import {
generateSymmetricKey,
encrypt as symmetricEncrypt,
decryptString as symmetricDecryptString,
decryptBytes as symmetricDecryptBytes,
} from "./symmetric";
import {
encrypt as asymmetricEncrypt,
decryptBytes as asymmetricDecryptBytes,
KeyPair,
} from "./asymmetric";

export type SymmetricKey = Uint8Array;
type JsonLiteral = string | number | boolean;
type JsonValue = JsonLiteral | Array<JsonValue> | { [k: string]: JsonValue };

export function encryptProposal(
metadata: JsonValue,
actionBytes: Uint8Array
): {
data: { [k: string]: string };
symmetricKey: SymmetricKey;
} {
const symmetricKey = generateSymmetricKey();

const strMetadata = JSON.stringify(metadata);
const encryptedMetadata = symmetricEncrypt(strMetadata, symmetricKey);
const encryptedActions = symmetricEncrypt(actionBytes, symmetricKey);

return {
data: {
metadata: libsodium.to_base64(encryptedMetadata),
actions: libsodium.to_base64(encryptedActions),
},
symmetricKey,
};
}

/**
* Returns a list of encrypted symKey payloads. Each position can be decrypted by the respective public key on the given list.
* @param symKey The symmetric key to encrypt
* @param recipientPubKeys The list of public keys to encrypt for
* @returns
*/
export function encryptSymmetricKey(
symKey: Uint8Array,
recipientPubKeys: Uint8Array[]
) {
return recipientPubKeys.map((pubKey) => {
return asymmetricEncrypt(symKey, pubKey);
});
}

/**
*
* @param encryptedItems The list of encrypted symmetric keys, one of which can be decrypted by the keyPair
* @param keyPair An object with the private and public keys
* @returns
*/
export function decryptSymmetricKey(
encryptedItems: Uint8Array[],
keyPair: KeyPair | Omit<KeyPair, "keyType">
) {
for (const item of encryptedItems) {
try {
// Attempt to decrypt, continue on fail
const decryptedSymKey = asymmetricDecryptBytes(item, keyPair);
return decryptedSymKey;
} catch (err) {}
}
throw new Error("The given keypair cannot decrypt any of the ciphertext's");
}

export function decryptProposal(
data: { [k: string]: string },
symmetricKey: SymmetricKey
): {
metadata: JsonValue;
actions: Uint8Array;
} {
if (!data["metadata"] || !data["actions"]) throw new Error("Invalid data");

const metadata = symmetricDecryptString(
libsodium.from_base64(data["metadata"]),
symmetricKey
);
const actions = symmetricDecryptBytes(
libsodium.from_base64(data["actions"]),
symmetricKey
);
return { metadata: JSON.parse(metadata), actions };
}

0 comments on commit 72d4d22

Please sign in to comment.