Skip to content

Commit 4b33f60

Browse files
Merge pull request #39 from internxt/switch_to_noble_curve
[_] Switch from crypto api to noble curve
2 parents eb2418c + b4b61b6 commit 4b33f60

11 files changed

Lines changed: 29 additions & 238 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ expect(resultAlice).toStrictEqual(resultBob);
8585
// Symmetric encryption
8686
const data = utils.UTF8ToUint8('Sensitive information to encrypt'); // convert to Uint8Array
8787
const additionalData = 'Additional non-secret data';
88-
const key = await symmetric.genSymmetricCryptoKey(); // CryptoKey
88+
const key = await symmetric.genSymmetricKey();
8989
const ciphertext: Uint8Array = await symmetric.encryptSymmetrically(key, data, additionalData);
9090
const plainText = await symmetric.decryptSymmetrically(encryptionKey, ciphertext, additionalData);
9191
expect(data).toStrictEqual(plainText);

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
},
3838
"dependencies": {
3939
"@noble/ciphers": "^2.1.1",
40+
"@noble/curves": "^2.0.1",
4041
"@noble/hashes": "^2.0.1",
4142
"@noble/post-quantum": "^0.5.2",
4243
"@scure/bip39": "^2.0.1",
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
import { ECC_ALGORITHM, AES_KEY_BIT_LENGTH } from '../constants';
1+
import { x25519 } from '@noble/curves/webcrypto.js';
22

33
/**
44
* Derives secret key from the other user's public key and own private key
55
*
6-
* @param otherUserPublicKey - The public key of the other user
7-
* @param ownPrivateKey - The private key
6+
* @param aliceSecX - The secret key of the user deriving the shared secret key
7+
* @param bobPubX - The public key of the other user
88
* @returns The derived secret key bits
99
*/
10-
export async function deriveSecretKey(otherUserPublicKey: CryptoKey, ownPrivateKey: CryptoKey): Promise<Uint8Array> {
10+
export async function deriveSecretKey(aliceSecX: Uint8Array, bobPubX: Uint8Array): Promise<Uint8Array> {
1111
try {
12-
const result = await crypto.subtle.deriveBits(
13-
{
14-
name: ECC_ALGORITHM,
15-
public: otherUserPublicKey,
16-
},
17-
ownPrivateKey,
18-
AES_KEY_BIT_LENGTH,
19-
);
20-
return new Uint8Array(result);
12+
return await x25519.getSharedSecret(aliceSecX, bobPubX);
2113
} catch (error) {
2214
throw new Error('Failed to derive elliptic curve secret key', { cause: error });
2315
}
2416
}
17+
18+
/**
19+
* Generates elliptic curve key pair
20+
*
21+
* @returns The generated key pair
22+
*/
23+
export async function generateEccKeys(): Promise<{ secretKey: Uint8Array; publicKey: Uint8Array }> {
24+
return x25519.keygen();
25+
}

src/asymmetric-crypto/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
export * from './ellipticCurve';
2-
export * from './keys';

src/asymmetric-crypto/keys.ts

Lines changed: 0 additions & 90 deletions
This file was deleted.

src/constants.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ export const KEY_WRAPPING_ALGORITHM = 'AES-KW';
77
export const KEY_FORMAT = 'raw';
88
export const CONTEXT_WRAPPING = 'CRYPTO library 2025-08-22 18:10:00 key derived from ecc and kyber secrets';
99

10-
export const ECC_ALGORITHM = 'X25519';
11-
1210
export const CONTEXT_ENC_KEYSTORE = 'CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore';
1311
export const CONTEXT_RECOVERY = 'CRYPTO library 2025-07-30 16:20:00 key for account recovery';
1412
export const CONTEXT_INDEX = 'CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices';

src/index.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
export {
2-
deriveSecretKey,
3-
generateEccKeys,
4-
exportPublicKey,
5-
importPublicKey,
6-
exportPrivateKey,
7-
importPrivateKey,
8-
} from './asymmetric-crypto';
1+
export { deriveSecretKey, generateEccKeys } from './asymmetric-crypto';
92
export {
103
deriveSymmetricKeyFromTwoKeys,
114
deriveSymmetricKeyFromTwoKeysAndContext,

src/types.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,6 @@ export type UserWithPublicKey = User & {
1414
publicHybridKey: Uint8Array;
1515
};
1616

17-
export type PublicKeys = {
18-
eccPublicKey: CryptoKey;
19-
kyberPublicKey: Uint8Array;
20-
};
21-
22-
export type PublicKeysBase64 = {
23-
eccPublicKeyBase64: string;
24-
kyberPublicKeyBase64: string;
25-
};
26-
2717
export type HybridKeyPair = {
2818
publicKey: Uint8Array;
2919
secretKey: Uint8Array;

tests/asymmetric-crypto/ecc.test.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@ import { describe, expect, it } from 'vitest';
22
import { generateEccKeys, deriveSecretKey } from '../../src/asymmetric-crypto';
33

44
describe('Test ecc functions', () => {
5+
it('should generate elliptic curves key pair', async () => {
6+
const keyPair = await generateEccKeys();
7+
expect(keyPair.publicKey).toBeInstanceOf(Uint8Array);
8+
expect(keyPair.secretKey).toBeInstanceOf(Uint8Array);
9+
});
10+
511
it('should derive the same keys for Bob and Alice', async () => {
612
const keysAlice = await generateEccKeys();
713
const keysBob = await generateEccKeys();
814

9-
const resultAlice = await deriveSecretKey(keysBob.publicKey, keysAlice.privateKey);
10-
const resultBob = await deriveSecretKey(keysAlice.publicKey, keysBob.privateKey);
15+
const resultAlice = await deriveSecretKey(keysBob.secretKey, keysAlice.publicKey);
16+
const resultBob = await deriveSecretKey(keysAlice.secretKey, keysBob.publicKey);
1117

1218
expect(resultAlice).toStrictEqual(resultBob);
1319
});
@@ -17,16 +23,16 @@ describe('Test ecc functions', () => {
1723
const keysBob = await generateEccKeys();
1824
const keysEve = await generateEccKeys();
1925

20-
const resultAliceEve = await deriveSecretKey(keysEve.publicKey, keysAlice.privateKey);
21-
const resultAliceBob = await deriveSecretKey(keysBob.publicKey, keysAlice.privateKey);
26+
const resultAliceEve = await deriveSecretKey(keysEve.secretKey, keysAlice.publicKey);
27+
const resultAliceBob = await deriveSecretKey(keysBob.secretKey, keysAlice.publicKey);
2228

2329
expect(resultAliceBob).not.toStrictEqual(resultAliceEve);
2430
});
2531

2632
it('should throw an error if cannot derive', async () => {
2733
const keysAlice = await generateEccKeys();
2834

29-
await expect(deriveSecretKey(keysAlice.privateKey, keysAlice.privateKey)).rejects.toThrowError(
35+
await expect(deriveSecretKey(keysAlice.secretKey, new Uint8Array())).rejects.toThrowError(
3036
/Failed to derive elliptic curve secret key/,
3137
);
3238
});

tests/asymmetric-crypto/keys.test.ts

Lines changed: 0 additions & 107 deletions
This file was deleted.

0 commit comments

Comments
 (0)