Replace typescript compiler with native tsgo compiler

This commit is contained in:
Jamie
2026-03-18 11:26:18 -07:00
committed by GitHub
parent 5e6af4708b
commit c90ca2b4e0
207 changed files with 1819 additions and 1270 deletions

View File

@@ -36,8 +36,8 @@ export const PaddedLengths = {
};
export type EncryptedAttachment = {
ciphertext: Uint8Array;
digest: Uint8Array;
ciphertext: Uint8Array<ArrayBuffer>;
digest: Uint8Array<ArrayBuffer>;
plaintextHash: string;
};
@@ -45,7 +45,9 @@ export function generateRegistrationId(): number {
return randomInt(1, 16383);
}
export function deriveStickerPackKey(packKey: Uint8Array): Uint8Array {
export function deriveStickerPackKey(
packKey: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
const salt = getZeroes(32);
const info = Bytes.fromString('Sticker Pack');
@@ -55,10 +57,10 @@ export function deriveStickerPackKey(packKey: Uint8Array): Uint8Array {
}
export function deriveSecrets(
input: Uint8Array,
salt: Uint8Array,
info: Uint8Array
): [Uint8Array, Uint8Array, Uint8Array] {
input: Uint8Array<ArrayBuffer>,
salt: Uint8Array<ArrayBuffer>,
info: Uint8Array<ArrayBuffer>
): [Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>] {
const output = hkdf(3 * 32, input, info, salt);
return [
output.subarray(0, 32),
@@ -67,7 +69,9 @@ export function deriveSecrets(
];
}
export function deriveMasterKeyFromGroupV1(groupV1Id: Uint8Array): Uint8Array {
export function deriveMasterKeyFromGroupV1(
groupV1Id: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
const salt = getZeroes(32);
const info = Bytes.fromString('GV2 Migration');
@@ -96,7 +100,7 @@ export function hashProfileKey(
return webSafe.slice(-3);
}
export function computeHash(data: Uint8Array): string {
export function computeHash(data: Uint8Array<ArrayBuffer>): string {
return Bytes.toBase64(hash(HashType.size512, data));
}
@@ -104,8 +108,8 @@ export function computeHash(data: Uint8Array): string {
export type EncryptedDeviceName = {
ephemeralPublic: PublicKey;
syntheticIv: Uint8Array;
ciphertext: Uint8Array;
syntheticIv: Uint8Array<ArrayBuffer>;
ciphertext: Uint8Array<ArrayBuffer>;
};
export function encryptDeviceName(
@@ -163,7 +167,7 @@ export function encryptDeviceCreatedAt(
deviceId: number,
registrationId: number,
identityPublic: PublicKey
): Uint8Array {
): Uint8Array<ArrayBuffer> {
const createdAtBuffer = new ArrayBuffer(8);
const dataView = new DataView(createdAtBuffer);
dataView.setBigUint64(0, BigInt(createdAt), false);
@@ -180,7 +184,7 @@ export function encryptDeviceCreatedAt(
// createdAtCiphertext is an Int64, encrypted using the identity key
// PrivateKey with 5 bytes of associated data (deviceId || registrationId).
export function decryptDeviceCreatedAt(
createdAtCiphertext: Uint8Array,
createdAtCiphertext: Uint8Array<ArrayBuffer>,
deviceId: number,
registrationId: number,
identityPrivate: PrivateKey
@@ -200,7 +204,7 @@ export function decryptDeviceCreatedAt(
function getAssociatedDataForDeviceCreatedAt(
deviceId: number,
registrationId: number
): Uint8Array {
): Uint8Array<ArrayBuffer> {
if (deviceId > 255) {
throw new Error('deviceId above 255, must be 1 byte');
}
@@ -212,18 +216,22 @@ function getAssociatedDataForDeviceCreatedAt(
return new Uint8Array(associatedDataBuffer);
}
export function deriveMasterKey(accountEntropyPool: string): Uint8Array {
export function deriveMasterKey(
accountEntropyPool: string
): Uint8Array<ArrayBuffer> {
return AccountEntropyPool.deriveSvrKey(accountEntropyPool);
}
export function deriveStorageServiceKey(masterKey: Uint8Array): Uint8Array {
export function deriveStorageServiceKey(
masterKey: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return hmacSha256(masterKey, Bytes.fromString('Storage Service Encryption'));
}
export function deriveStorageManifestKey(
storageServiceKey: Uint8Array,
storageServiceKey: Uint8Array<ArrayBuffer>,
version = 0n
): Uint8Array {
): Uint8Array<ArrayBuffer> {
return hmacSha256(storageServiceKey, Bytes.fromString(`Manifest_${version}`));
}
@@ -232,16 +240,16 @@ const STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX =
const STORAGE_SERVICE_ITEM_KEY_LEN = 32;
export type DeriveStorageItemKeyOptionsType = Readonly<{
storageServiceKey: Uint8Array;
recordIkm: Uint8Array | undefined;
key: Uint8Array;
storageServiceKey: Uint8Array<ArrayBuffer>;
recordIkm: Uint8Array<ArrayBuffer> | undefined;
key: Uint8Array<ArrayBuffer>;
}>;
export function deriveStorageItemKey({
storageServiceKey,
recordIkm,
key,
}: DeriveStorageItemKeyOptionsType): Uint8Array {
}: DeriveStorageItemKeyOptionsType): Uint8Array<ArrayBuffer> {
if (recordIkm == null) {
const itemID = Bytes.toBase64(key);
return hmacSha256(storageServiceKey, Bytes.fromString(`Item_${itemID}`));
@@ -258,15 +266,17 @@ export function deriveStorageItemKey({
);
}
export function getAccessKeyVerifier(accessKey: Uint8Array): Uint8Array {
export function getAccessKeyVerifier(
accessKey: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
const plaintext = getZeroes(32);
return hmacSha256(accessKey, plaintext);
}
export function verifyAccessKey(
accessKey: Uint8Array,
theirVerifier: Uint8Array
accessKey: Uint8Array<ArrayBuffer>,
theirVerifier: Uint8Array<ArrayBuffer>
): boolean {
const ourVerifier = getAccessKeyVerifier(accessKey);
@@ -282,9 +292,9 @@ const NONCE_LENGTH = 16;
const SYMMETRIC_MAC_LENGTH = 16;
export function encryptSymmetric(
key: Uint8Array,
plaintext: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
plaintext: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
const iv = getZeroes(IV_LENGTH);
const nonce = getRandomBytes(NONCE_LENGTH);
@@ -301,9 +311,9 @@ export function encryptSymmetric(
}
export function decryptSymmetric(
key: Uint8Array,
data: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
data: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
const iv = getZeroes(IV_LENGTH);
const nonce = getFirstBytes(data, NONCE_LENGTH);
@@ -336,7 +346,10 @@ export function decryptSymmetric(
// Encryption
export function hmacSha256(key: Uint8Array, plaintext: Uint8Array): Uint8Array {
export function hmacSha256(
key: Uint8Array<ArrayBuffer>,
plaintext: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return sign(key, plaintext);
}
@@ -344,9 +357,9 @@ export function hmacSha256(key: Uint8Array, plaintext: Uint8Array): Uint8Array {
// to be longer than the passed-in length. This allows easy comparisons against
// arbitrary MAC lengths.
export function verifyHmacSha256(
plaintext: Uint8Array,
key: Uint8Array,
theirMac: Uint8Array,
plaintext: Uint8Array<ArrayBuffer>,
key: Uint8Array<ArrayBuffer>,
theirMac: Uint8Array<ArrayBuffer>,
length: number
): void {
const ourMac = hmacSha256(key, plaintext);
@@ -366,10 +379,10 @@ export function verifyHmacSha256(
}
export function encryptAes256CbcPkcsPadding(
key: Uint8Array,
plaintext: Uint8Array,
iv: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
plaintext: Uint8Array<ArrayBuffer>,
iv: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return encrypt(CipherType.AES256CBC, {
key,
plaintext,
@@ -378,10 +391,10 @@ export function encryptAes256CbcPkcsPadding(
}
export function decryptAes256CbcPkcsPadding(
key: Uint8Array,
ciphertext: Uint8Array,
iv: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
ciphertext: Uint8Array<ArrayBuffer>,
iv: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return decrypt(CipherType.AES256CBC, {
key,
ciphertext,
@@ -390,10 +403,10 @@ export function decryptAes256CbcPkcsPadding(
}
export function encryptAesCtr(
key: Uint8Array,
plaintext: Uint8Array,
counter: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
plaintext: Uint8Array<ArrayBuffer>,
counter: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return encrypt(CipherType.AES256CTR, {
key,
plaintext,
@@ -402,10 +415,10 @@ export function encryptAesCtr(
}
export function decryptAesCtr(
key: Uint8Array,
ciphertext: Uint8Array,
counter: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
ciphertext: Uint8Array<ArrayBuffer>,
counter: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return decrypt(CipherType.AES256CTR, {
key,
ciphertext,
@@ -414,11 +427,11 @@ export function decryptAesCtr(
}
export function encryptAesGcm(
key: Uint8Array,
iv: Uint8Array,
plaintext: Uint8Array,
aad?: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
iv: Uint8Array<ArrayBuffer>,
plaintext: Uint8Array<ArrayBuffer>,
aad?: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return encrypt(CipherType.AES256GCM, {
key,
plaintext,
@@ -428,10 +441,10 @@ export function encryptAesGcm(
}
export function decryptAesGcm(
key: Uint8Array,
iv: Uint8Array,
ciphertext: Uint8Array
): Uint8Array {
key: Uint8Array<ArrayBuffer>,
iv: Uint8Array<ArrayBuffer>,
ciphertext: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return decrypt(CipherType.AES256GCM, {
key,
ciphertext,
@@ -441,13 +454,13 @@ export function decryptAesGcm(
// Hashing
export function sha256(data: Uint8Array): Uint8Array {
export function sha256(data: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer> {
return hash(HashType.size256, data);
}
// Utility
export function getZeroes(n: number): Uint8Array {
export function getZeroes(n: number): Uint8Array<ArrayBuffer> {
return new Uint8Array(n);
}
@@ -464,11 +477,16 @@ export function intsToByteHighAndLow(
return ((highValue << 4) | lowValue) & 0xff;
}
export function getFirstBytes(data: Uint8Array, n: number): Uint8Array {
export function getFirstBytes(
data: Uint8Array<ArrayBuffer>,
n: number
): Uint8Array<ArrayBuffer> {
return data.subarray(0, n);
}
export function trimForDisplay(padded: Uint8Array): Uint8Array {
export function trimForDisplay(
padded: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
let paddingEnd = 0;
for (paddingEnd; paddingEnd < padded.length; paddingEnd += 1) {
if (padded[paddingEnd] === 0x00) {
@@ -478,7 +496,10 @@ export function trimForDisplay(padded: Uint8Array): Uint8Array {
return padded.subarray(0, paddingEnd);
}
function verifyDigest(data: Uint8Array, theirDigest: Uint8Array): void {
function verifyDigest(
data: Uint8Array<ArrayBuffer>,
theirDigest: Uint8Array<ArrayBuffer>
): void {
const ourDigest = sha256(data);
let result = 0;
for (let i = 0; i < theirDigest.byteLength; i += 1) {
@@ -491,10 +512,10 @@ function verifyDigest(data: Uint8Array, theirDigest: Uint8Array): void {
}
export function decryptAttachmentV1(
encryptedBin: Uint8Array,
keys: Uint8Array,
theirDigest?: Uint8Array
): Uint8Array {
encryptedBin: Uint8Array<ArrayBuffer>,
keys: Uint8Array<ArrayBuffer>,
theirDigest?: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
if (keys.byteLength !== 64) {
throw new Error('Got invalid length attachment keys');
}
@@ -530,9 +551,9 @@ export function encryptAttachment({
keys,
dangerousTestOnlyIv,
}: {
plaintext: Readonly<Uint8Array>;
keys: Readonly<Uint8Array>;
dangerousTestOnlyIv?: Readonly<Uint8Array>;
plaintext: Readonly<Uint8Array<ArrayBuffer>>;
keys: Readonly<Uint8Array<ArrayBuffer>>;
dangerousTestOnlyIv?: Readonly<Uint8Array<ArrayBuffer>>;
}): Omit<EncryptedAttachment, 'plaintextHash'> {
const logId = 'encryptAttachment';
if (!(plaintext instanceof Uint8Array)) {
@@ -573,9 +594,9 @@ export function padAndEncryptAttachment({
keys,
dangerousTestOnlyIv,
}: {
plaintext: Readonly<Uint8Array>;
keys: Readonly<Uint8Array>;
dangerousTestOnlyIv?: Readonly<Uint8Array>;
plaintext: Readonly<Uint8Array<ArrayBuffer>>;
keys: Readonly<Uint8Array<ArrayBuffer>>;
dangerousTestOnlyIv?: Readonly<Uint8Array<ArrayBuffer>>;
}): EncryptedAttachment {
const size = plaintext.byteLength;
const paddedSize = logPadSize(size);
@@ -594,7 +615,10 @@ export function padAndEncryptAttachment({
};
}
export function encryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array {
export function encryptProfile(
data: Uint8Array<ArrayBuffer>,
key: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
const iv = getRandomBytes(PROFILE_IV_LENGTH);
if (key.byteLength !== PROFILE_KEY_LENGTH) {
throw new Error('Got invalid length profile key');
@@ -606,7 +630,10 @@ export function encryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array {
return Bytes.concatenate([iv, ciphertext]);
}
export function decryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array {
export function decryptProfile(
data: Uint8Array<ArrayBuffer>,
key: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
if (data.byteLength < 12 + 16 + 1) {
throw new Error(`Got too short input: ${data.byteLength}`);
}
@@ -630,10 +657,10 @@ export function decryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array {
}
export function encryptProfileItemWithPadding(
item: Uint8Array,
profileKey: Uint8Array,
item: Uint8Array<ArrayBuffer>,
profileKey: Uint8Array<ArrayBuffer>,
paddedLengths: (typeof PaddedLengths)[keyof typeof PaddedLengths]
): Uint8Array {
): Uint8Array<ArrayBuffer> {
const paddedLength = paddedLengths.find(
(length: number) => item.byteLength <= length
);
@@ -647,8 +674,8 @@ export function encryptProfileItemWithPadding(
export function decryptProfileName(
encryptedProfileName: string,
key: Uint8Array
): { given: Uint8Array; family: Uint8Array | null } {
key: Uint8Array<ArrayBuffer>
): { given: Uint8Array<ArrayBuffer>; family: Uint8Array<ArrayBuffer> | null } {
const data = Bytes.fromBase64(encryptedProfileName);
const padded = decryptProfile(data, key);
@@ -681,23 +708,29 @@ export function decryptProfileName(
const crypto = globalThis.window?.SignalContext.crypto || new Crypto();
export function sign(key: Uint8Array, data: Uint8Array): Uint8Array {
export function sign(
key: Uint8Array<ArrayBuffer>,
data: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return crypto.sign(key, data);
}
export function hash(type: HashType, data: Uint8Array): Uint8Array {
export function hash(
type: HashType,
data: Uint8Array<ArrayBuffer>
): Uint8Array<ArrayBuffer> {
return crypto.hash(type, data);
}
export function encrypt(
...args: Parameters<typeof crypto.encrypt>
): Uint8Array {
): Uint8Array<ArrayBuffer> {
return crypto.encrypt(...args);
}
export function decrypt(
...args: Parameters<typeof crypto.decrypt>
): Uint8Array {
): Uint8Array<ArrayBuffer> {
return crypto.decrypt(...args);
}
@@ -708,13 +741,13 @@ export function randomInt(min: number, max: number): number {
return crypto.randomInt(min, max + 1);
}
export function getRandomBytes(size: number): Uint8Array {
export function getRandomBytes(size: number): Uint8Array<ArrayBuffer> {
return crypto.getRandomBytes(size);
}
export function constantTimeEqual(
left: Uint8Array,
right: Uint8Array
left: Uint8Array<ArrayBuffer>,
right: Uint8Array<ArrayBuffer>
): boolean {
return crypto.constantTimeEqual(left, right);
}
@@ -730,7 +763,7 @@ export function getIdentifierHash({
pni: PniString | undefined;
groupId: string | undefined;
}): number | null {
let identifier: Uint8Array;
let identifier: Uint8Array<ArrayBuffer>;
if (aci != null) {
identifier = Aci.parseFromServiceIdString(aci).getServiceIdBinary();
} else if (e164 != null) {