(feat): finish chat crypto migration
(wip): prep for full ECDH repo migration
This commit is contained in:
parent
ecca5241bc
commit
2cd326d0b1
10 changed files with 195 additions and 339 deletions
|
|
@ -49,12 +49,6 @@ describe("createCryptoActions", () => {
|
|||
secret: string,
|
||||
ciphertext: string,
|
||||
): Promise<string> => `${secret}|${ciphertext}`,
|
||||
getSharedSecret: async (
|
||||
ownPrivateKey: string,
|
||||
ownPublicKey: string,
|
||||
otherPublicKey: string,
|
||||
): Promise<string> =>
|
||||
`${ownPrivateKey}.${ownPublicKey}.${otherPublicKey}`,
|
||||
};
|
||||
|
||||
const actions = createCryptoActions(() => api);
|
||||
|
|
@ -67,6 +61,5 @@ describe("createCryptoActions", () => {
|
|||
).toBe("s|c");
|
||||
expect(await actions.encryptText("s", "p")).toBe("s:p");
|
||||
expect(await actions.decryptText("s", "c")).toBe("s|c");
|
||||
expect(await actions.getSharedSecret("a", "b", "c")).toBe("a.b.c");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { createContext, useContext } from "react";
|
||||
import { base64ToBytes, bytesToBase64, crypto } from "mtp";
|
||||
import { base64ToBytes, crypto } from "mtp";
|
||||
|
||||
type CryptoContextType = {
|
||||
decrypt: (
|
||||
|
|
@ -12,11 +12,6 @@ type CryptoContextType = {
|
|||
input: Uint8Array<ArrayBuffer>,
|
||||
) => Promise<Uint8Array<ArrayBuffer>>;
|
||||
encryptText: (secret: string, plaintext: string) => Promise<string>;
|
||||
getSharedSecret: (
|
||||
ownPrivateKey: string,
|
||||
ownPublicKey: string,
|
||||
otherPublicKey: string,
|
||||
) => Promise<string>;
|
||||
};
|
||||
|
||||
export const context = createContext<CryptoContextType | undefined>(undefined);
|
||||
|
|
@ -39,8 +34,6 @@ export function createCryptoActions(
|
|||
encrypt: (secret, input) => requireApi().encrypt(secret, input),
|
||||
encryptText: (secret, plaintext) =>
|
||||
requireApi().encryptText(secret, plaintext),
|
||||
getSharedSecret: (ownPrivateKey, ownPublicKey, otherPublicKey) =>
|
||||
requireApi().getSharedSecret(ownPrivateKey, ownPublicKey, otherPublicKey),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -58,45 +51,6 @@ function secretKeyFromString(secret: string): Uint8Array {
|
|||
);
|
||||
}
|
||||
|
||||
function compareBytes(a: Uint8Array, b: Uint8Array): number {
|
||||
const len = Math.min(a.byteLength, b.byteLength);
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const diff = a[i] - b[i];
|
||||
if (diff !== 0) return diff;
|
||||
}
|
||||
|
||||
return a.byteLength - b.byteLength;
|
||||
}
|
||||
|
||||
async function getSharedSecret(
|
||||
ownPrivateKey: string,
|
||||
ownPublicKey: string,
|
||||
otherPublicKey: string,
|
||||
): Promise<string> {
|
||||
crypto.keyringToKeys(ownPrivateKey);
|
||||
|
||||
const ownKeys = crypto.publicKeyBundleToKeys(ownPublicKey);
|
||||
const otherKeys = crypto.publicKeyBundleToKeys(otherPublicKey);
|
||||
const publicKeys = [ownKeys.kemPublicKey, otherKeys.kemPublicKey].sort(
|
||||
compareBytes,
|
||||
);
|
||||
const input = new Uint8Array(
|
||||
publicKeys[0].byteLength + publicKeys[1].byteLength,
|
||||
);
|
||||
|
||||
input.set(publicKeys[0]);
|
||||
input.set(publicKeys[1], publicKeys[0].byteLength);
|
||||
|
||||
return bytesToBase64(
|
||||
crypto.deriveEncryptionKey(
|
||||
input,
|
||||
new Uint8Array(0),
|
||||
new TextEncoder().encode("tensamin:legacy-shared-secret"),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export default function Provider(props: { children: React.ReactNode }) {
|
||||
const actions = createCryptoActions(() => ({
|
||||
decrypt: async (secret, input) =>
|
||||
|
|
@ -107,7 +61,6 @@ export default function Provider(props: { children: React.ReactNode }) {
|
|||
ownedBytes(await crypto.encrypt(secretKeyFromString(secret), input)),
|
||||
encryptText: (secret, plaintext) =>
|
||||
crypto.encryptText(secretKeyFromString(secret), plaintext),
|
||||
getSharedSecret,
|
||||
}));
|
||||
|
||||
return <context.Provider value={actions}>{props.children}</context.Provider>;
|
||||
|
|
|
|||
Loading…
Reference in a new issue