UNPKG

pooja-docucomb-tink-crypto

Version:

A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

77 lines (69 loc) 2.93 kB
/** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import {SecurityException} from '../exception/security_exception'; import * as Bytes from './bytes'; import * as EllipticCurves from './elliptic_curves'; import * as Hkdf from './hkdf'; /** * HKDF-based ECIES-KEM (key encapsulation mechanism) for ECIES sender. */ export class EciesHkdfKemSender { private readonly publicKey: CryptoKey; constructor(recipientPublicKey: CryptoKey) { if (!recipientPublicKey) { throw new SecurityException('Recipient public key has to be non-null.'); } // CryptoKey should have the properties type and algorithm. if (recipientPublicKey.type !== 'public' || !recipientPublicKey.algorithm) { throw new SecurityException('Expected Crypto key of type: public.'); } this.publicKey = recipientPublicKey; } /** * @param keySizeInBytes The length of the generated pseudorandom * string in bytes. The maximal size is 255 * DigestSize, where DigestSize * is the size of the underlying HMAC. * @param pointFormat The format of the * public ephemeral point. * @param hkdfHash the name of the hash function. Accepted names are * SHA-1, SHA-256 and SHA-512. * @param hkdfInfo Context and application specific * information (can be a zero-length array). * @param opt_hkdfSalt Salt value (a non-secret random * value). If not provided, it is set to a string of hash length zeros. * @return The KEM key and * token. */ async encapsulate( keySizeInBytes: number, pointFormat: EllipticCurves.PointFormatType, hkdfHash: string, hkdfInfo: Uint8Array, opt_hkdfSalt?: Uint8Array): Promise<{key: Uint8Array, token: Uint8Array}> { const {namedCurve}: Partial<EcKeyAlgorithm> = this.publicKey.algorithm; if (!namedCurve) { throw new SecurityException('Curve has to be defined.'); } const ephemeralKeyPair = await EllipticCurves.generateKeyPair('ECDH', namedCurve); const sharedSecret = await EllipticCurves.computeEcdhSharedSecret( ephemeralKeyPair.privateKey!, this.publicKey); const jwk = await EllipticCurves.exportCryptoKey(ephemeralKeyPair.publicKey!); const {crv} = jwk; if (!crv) { throw new SecurityException('Curve has to be defined.'); } const kemToken = EllipticCurves.pointEncode(crv, pointFormat, jwk); const hkdfIkm = Bytes.concat(kemToken, sharedSecret); const kemKey = await Hkdf.compute( keySizeInBytes, hkdfHash, hkdfIkm, hkdfInfo, opt_hkdfSalt); return {'key': kemKey, 'token': kemToken}; } } export async function fromJsonWebKey(jwk: JsonWebKey): Promise<EciesHkdfKemSender> { const publicKey = await EllipticCurves.importPublicKey('ECDH', jwk); return new EciesHkdfKemSender(publicKey); }