a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore(crypto): upgrade noble/secp256k1 dependency

Mary 141bc681 f9009d5e

+25 -21
+5
.changeset/easy-windows-grab.md
··· 1 + --- 2 + '@atcute/crypto': patch 3 + --- 4 + 5 + upgrade noble/secp256k1 dependency
+8 -8
packages/utilities/crypto/lib/keypairs/secp256k1-web.test.ts
··· 16 16 keypair.exportPublicKey('raw'), 17 17 ]); 18 18 19 - expect(secp256k1.utils.isValidPrivateKey(privateKeyBytes)).toBe(true); 19 + expect(secp256k1.utils.isValidSecretKey(privateKeyBytes)).toBe(true); 20 20 expect(publicKeyBytes).toEqual(secp256k1.getPublicKey(privateKeyBytes)); 21 21 }); 22 22 23 23 it('produces valid signatures', async () => { 24 - const privateKeyBytes = secp256k1.utils.randomPrivateKey(); 24 + const privateKeyBytes = secp256k1.utils.randomSecretKey(); 25 25 const publicKeyBytes = secp256k1.getPublicKey(privateKeyBytes); 26 26 27 27 const keypair = await Secp256k1PrivateKey.importRaw(privateKeyBytes); ··· 38 38 }); 39 39 40 40 it('verifies valid signatures', async () => { 41 - const privateKeyBytes = secp256k1.utils.randomPrivateKey(); 41 + const privateKeyBytes = secp256k1.utils.randomSecretKey(); 42 42 const publicKeyBytes = secp256k1.getPublicKey(privateKeyBytes); 43 43 44 44 const keypair = await Secp256k1PublicKey.importRaw(publicKeyBytes); ··· 53 53 54 54 describe('.importRaw()', () => { 55 55 it('imports public keys', async () => { 56 - const privateKeyBytes = secp256k1.utils.randomPrivateKey(); 56 + const privateKeyBytes = secp256k1.utils.randomSecretKey(); 57 57 const publicKeyBytes = secp256k1.getPublicKey(privateKeyBytes); 58 58 59 59 await expect(Secp256k1PublicKey.importRaw(publicKeyBytes)).resolves.toBeInstanceOf(Secp256k1PublicKey); 60 60 }); 61 61 62 62 it('imports private keys without specifying public key', async () => { 63 - const privateKeyBytes = secp256k1.utils.randomPrivateKey(); 63 + const privateKeyBytes = secp256k1.utils.randomSecretKey(); 64 64 65 65 await expect(Secp256k1PrivateKey.importRaw(privateKeyBytes)).resolves.toBeInstanceOf(Secp256k1PrivateKey); 66 66 }); 67 67 68 68 it('imports keypairs', async () => { 69 - const privateKeyBytes = secp256k1.utils.randomPrivateKey(); 69 + const privateKeyBytes = secp256k1.utils.randomSecretKey(); 70 70 const publicKeyBytes = secp256k1.getPublicKey(privateKeyBytes); 71 71 72 72 await expect(Secp256k1PrivateKey.importRaw(privateKeyBytes, publicKeyBytes)).resolves.toBeInstanceOf( ··· 75 75 }); 76 76 77 77 it('throws on mismatching public/private keys', async () => { 78 - const privateKeyBytes = secp256k1.utils.randomPrivateKey(); 79 - const publicKeyBytes = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey()); 78 + const privateKeyBytes = secp256k1.utils.randomSecretKey(); 79 + const publicKeyBytes = secp256k1.getPublicKey(secp256k1.utils.randomSecretKey()); 80 80 81 81 await expect(Secp256k1PrivateKey.importRaw(privateKeyBytes, publicKeyBytes)).rejects.toThrowError( 82 82 TypeError,
+6 -7
packages/utilities/crypto/lib/keypairs/secp256k1-web.ts
··· 1 1 import { toBase16, toBase64Url } from '@atcute/multibase'; 2 2 import { toSha256 } from '@atcute/uint8array'; 3 - import { getPublicKey, ProjectivePoint, signAsync, utils, verify } from '@noble/secp256k1'; 3 + import { getPublicKey, Point, signAsync, utils, verify } from '@noble/secp256k1'; 4 4 5 5 import type { DidKeyString, PrivateKey, PrivateKeyExportable, PublicKey, VerifyOptions } from '../types.js'; 6 6 import { assertUnreachable, checkKeypairRelationship, toMultikey } from '../utils.js'; ··· 17 17 18 18 // Decompress point so we can encode both x and y. 19 19 // Could just make it a bool, but it's not recommended [4] and poorly supported. 20 - const point = ProjectivePoint.fromHex(publicKey).toRawBytes(false); 20 + const point = Point.fromBytes(publicKey).toBytes(false); 21 21 22 22 const key = { 23 23 kty: 'EC', // [2]; [3] § 3.1. ··· 64 64 const allowMalleable = options?.allowMalleableSig ?? false; 65 65 const hashed = await toSha256(data); 66 66 67 - return verify(sig, hashed, this._publicKey, { lowS: !allowMalleable }); 67 + return verify(sig, hashed, this._publicKey, { lowS: !allowMalleable, prehash: false }); 68 68 } 69 69 70 70 exportPublicKey(format: 'did'): Promise<DidKeyString>; ··· 125 125 126 126 async sign(data: Uint8Array): Promise<Uint8Array<ArrayBuffer>> { 127 127 const hashed = await toSha256(data); 128 - const sig = await signAsync(hashed, this._privateKey, { lowS: true }); 128 + const sig = await signAsync(hashed, this._privateKey, { lowS: true, prehash: false }); 129 129 130 - // return raw 64 byte sig not DER-encoded 131 - return sig.toCompactRawBytes() as Uint8Array<ArrayBuffer>; 130 + return sig as Uint8Array<ArrayBuffer>; 132 131 } 133 132 } 134 133 135 134 export class Secp256k1PrivateKeyExportable extends Secp256k1PrivateKey implements PrivateKeyExportable { 136 135 static async createKeypair(): Promise<Secp256k1PrivateKeyExportable> { 137 - const privateKeyBytes = utils.randomPrivateKey(); 136 + const privateKeyBytes = utils.randomSecretKey(); 138 137 const publicKeyBytes = getPublicKey(privateKeyBytes); 139 138 140 139 return new Secp256k1PrivateKeyExportable(privateKeyBytes, publicKeyBytes);
+1 -1
packages/utilities/crypto/package.json
··· 50 50 "dependencies": { 51 51 "@atcute/multibase": "workspace:^", 52 52 "@atcute/uint8array": "workspace:^", 53 - "@noble/secp256k1": "^2.3.0" 53 + "@noble/secp256k1": "^3.0.0" 54 54 } 55 55 }
+5 -5
pnpm-lock.yaml
··· 772 772 specifier: workspace:^ 773 773 version: link:../uint8array 774 774 '@noble/secp256k1': 775 - specifier: ^2.3.0 776 - version: 2.3.0 775 + specifier: ^3.0.0 776 + version: 3.0.0 777 777 devDependencies: 778 778 '@noble/curves': 779 779 specifier: ^1.9.7 ··· 1686 1686 '@noble/secp256k1@1.7.2': 1687 1687 resolution: {integrity: sha512-/qzwYl5eFLH8OWIecQWM31qld2g1NfjgylK+TNhqtaUKP37Nm+Y+z30Fjhw0Ct8p9yCQEm2N3W/AckdIb3SMcQ==} 1688 1688 1689 - '@noble/secp256k1@2.3.0': 1690 - resolution: {integrity: sha512-0TQed2gcBbIrh7Ccyw+y/uZQvbJwm7Ao4scBUxqpBCcsOlZG0O4KGfjtNAy/li4W8n1xt3dxrwJ0beZ2h2G6Kw==} 1689 + '@noble/secp256k1@3.0.0': 1690 + resolution: {integrity: sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==} 1691 1691 1692 1692 '@nodelib/fs.scandir@2.1.5': 1693 1693 resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} ··· 5246 5246 5247 5247 '@noble/secp256k1@1.7.2': {} 5248 5248 5249 - '@noble/secp256k1@2.3.0': {} 5249 + '@noble/secp256k1@3.0.0': {} 5250 5250 5251 5251 '@nodelib/fs.scandir@2.1.5': 5252 5252 dependencies: