jsonld-signatures-merkleproof2019
Version:
A jsonld signature implementation to support MerkleProof2019 verification in Verifiable Credential context
140 lines (139 loc) • 6.29 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import keyto from '@trust/keyto';
import base64url from 'base64url';
import crypto from 'crypto';
import bs58 from 'bs58';
import secp256k1 from 'secp256k1';
import { Buffer as BufferPolyfill } from 'buffer';
import canonicalize from 'canonicalize';
// @ts-expect-error not a TS package
import * as multikey from '@digitalbazaar/ecdsa-multikey';
const buffer = typeof Buffer === 'undefined' ? BufferPolyfill : Buffer;
const compressedHexEncodedPublicKeyLength = 66;
/**
* Example
* ```js
* {
* kty: 'EC',
* crv: 'secp256k1',
* d: 'rhYFsBPF9q3-uZThy7B3c4LDF_8wnozFUAEm5LLC4Zw',
* x: 'dWCvM4fTdeM0KmloF57zxtBPXTOythHPMm1HCLrdd3A',
* y: '36uMVGM7hnw-N6GnjFcihWE3SkrhMLzzLCdPMXPEXlA',
* kid: 'JUvpllMEYUZ2joO59UNui_XYDqxVqiFLLAJ8klWuPBw'
* }
* ```
* See [rfc7638](https://tools.ietf.org/html/rfc7638) for more details on Jwk.
*/
export const getKid = (jwk) => {
const copy = Object.assign({}, jwk);
delete copy.d;
delete copy.kid;
delete copy.alg;
const digest = crypto
.createHash('sha256')
.update(canonicalize(copy))
.digest();
return base64url.encode(buffer.from(digest));
};
/** convert compressed hex encoded private key to jwk */
export const privateKeyJwkFromPrivateKeyHex = (privateKeyHex) => {
const jwk = Object.assign(Object.assign({}, keyto.from(privateKeyHex, 'blk').toJwk('private')), { crv: 'secp256k1' });
const kid = getKid(jwk);
return Object.assign(Object.assign({}, jwk), { kid });
};
/** convert compressed hex encoded public key to jwk */
export const publicKeyJwkFromPublicKeyHex = (publicKeyHex) => {
let key = publicKeyHex;
if (publicKeyHex.length === compressedHexEncodedPublicKeyLength) {
const keyBin = secp256k1.publicKeyConvert(buffer.from(publicKeyHex, 'hex'), false);
key = buffer.from(keyBin).toString('hex');
}
const jwk = Object.assign(Object.assign({}, keyto.from(key, 'blk').toJwk('public')), { crv: 'secp256k1' });
const kid = getKid(jwk);
return Object.assign(Object.assign({}, jwk), { kid });
};
/** convert pem encoded private key to jwk */
export const privateKeyJwkFromPrivateKeyPem = (privateKeyPem) => {
const jwk = Object.assign(Object.assign({}, keyto.from(privateKeyPem, 'pem').toJwk('private')), { crv: 'secp256k1' });
// console.log(jwk);
const kid = getKid(jwk);
return Object.assign(Object.assign({}, jwk), { kid });
};
/** convert pem encoded public key to jwk */
export const publicKeyJwkFromPublicKeyPem = (publicKeyPem) => {
const jwk = Object.assign(Object.assign({}, keyto.from(publicKeyPem, 'pem').toJwk('public')), { crv: 'secp256k1' });
const kid = getKid(jwk);
return Object.assign(Object.assign({}, jwk), { kid });
};
/** convert jwk to hex encoded private key */
export const privateKeyHexFromJwk = (jwk) => keyto
.from(Object.assign(Object.assign({}, jwk), { crv: 'K-256' }), 'jwk')
.toString('blk', 'private');
/** convert jwk to hex encoded public key */
export const publicKeyHexFromJwk = (jwk) => {
const uncompressedPublicKey = keyto
.from(Object.assign(Object.assign({}, jwk), { crv: 'K-256' }), 'jwk')
.toString('blk', 'public');
const compressed = secp256k1.publicKeyConvert(buffer.from(uncompressedPublicKey, 'hex'), true);
return buffer.from(compressed).toString('hex');
};
/** convert jwk to binary encoded private key */
export const privateKeyUInt8ArrayFromJwk = (jwk) => {
const privateKeyHex = privateKeyHexFromJwk(jwk);
let asBuffer = buffer.from(privateKeyHex, 'hex');
let padding = 32 - asBuffer.length;
while (padding > 0) {
asBuffer = buffer.concat([buffer.from('00', 'hex'), asBuffer]);
padding--;
}
return asBuffer;
};
/** convert jwk to binary encoded public key */
export const publicKeyUInt8ArrayFromJwk = (jwk) => {
const publicKeyHex = publicKeyHexFromJwk(jwk);
let asBuffer = buffer.from(publicKeyHex, 'hex');
let padding = 32 - asBuffer.length;
while (padding > 0) {
asBuffer = buffer.concat([buffer.from('00', 'hex'), asBuffer]);
padding--;
}
return asBuffer;
};
export const publicKeyUInt8ArrayFromMultibase = (publicKeyMultibase) => __awaiter(void 0, void 0, void 0, function* () {
const pubKeyJwk = yield multikey.toJwk({ keyPair: publicKeyMultibase });
return publicKeyUInt8ArrayFromJwk(pubKeyJwk);
});
/** convert publicKeyHex to base58 */
export const publicKeyBase58FromPublicKeyHex = (publicKeyHex) => {
return bs58.encode(buffer.from(publicKeyHex, 'hex'));
};
/** convert publicKeyHex to base58 */
export const privateKeyBase58FromPrivateKeyHex = (privateKeyHex) => {
return bs58.encode(buffer.from(privateKeyHex, 'hex'));
};
export const privateKeyUInt8ArrayFromPrivateKeyBase58 = (privateKeyBase58) => {
return bs58.decode(privateKeyBase58);
};
export const publicKeyUInt8ArrayFromPublicKeyBase58 = (publicKeyBase58) => {
return bs58.decode(publicKeyBase58);
};
export const publicKeyHexFromPrivateKeyHex = (privateKeyHex) => {
const publicKey = secp256k1.publicKeyCreate(new Uint8Array(buffer.from(privateKeyHex, 'hex')));
return buffer.from(publicKey).toString('hex');
};
export const publicKeyJwkFromPublicKeyBase58 = (publicKeybase58) => {
const decodedPublicKeyAsHex = bs58.decode(publicKeybase58).toString();
return publicKeyJwkFromPublicKeyHex(decodedPublicKeyAsHex);
};
export const privateKeyJwkFromPrivateKeyBase58 = (privateKeyBase58) => {
const decodedPrivateKeyAsHex = bs58.decode(privateKeyBase58).toString();
return privateKeyJwkFromPrivateKeyHex(decodedPrivateKeyAsHex);
};