Skip to content

Commit

Permalink
did/generate dids and peers
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruffiano committed Sep 10, 2022
1 parent 523967c commit 9535978
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 34 deletions.
148 changes: 123 additions & 25 deletions libraries/fula-sec/src/did/did.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { decryptJWE, createJWE, JWE,
} from 'did-jwt'
import {prepareCleartext, decodeCleartext } from 'dag-jose-utils'
import * as u8a from 'uint8arrays'

import * as crypto from 'libp2p-crypto';
import { Buffer } from 'buffer';
import * as PeerId from 'peer-id'
import { InvalidDid } from '../did/utils/errors';
/**
* @class AsymEncryption
* @class Decentralized Identity and JWE
* @description Asymetric Encription
* Requires public and private key. The user must import the DID`s private key and
* share the public key among network participants.
Expand All @@ -26,22 +29,115 @@ export type DecryptJWEOptions = {
export class DID {
publicKey: Uint8Array;
private _privateKey: Uint8Array;

constructor(privateKey: Uint8Array, publicKey: Uint8Array) {
this.publicKey = publicKey
this._privateKey = privateKey;
}

/**
* This function for generating DID and PeerID
* @function getDID()
* @property parentKey?: Uin8Array (Optinal) or _privateKey (default)
* @returns {
* PeerId, did
* }
*/

async getDID (parentKey?: Uint8Array): Promise<{
PeerId: PeerId.JSONPeerId;
did: string;
}> {
const key = await this._keyPair(parentKey || this._privateKey);
return this._generateDID(key);
}

/**
* This private helper function for generate key pair
* @function _keyPair()
* @property parentKey: Uin8Array
* @returns Public and PrivateKeys for peerId
*/

private async _keyPair (parentKey: Uint8Array):Promise<crypto.keys.supportedKeys.ed25519.Ed25519PrivateKey> {
return await crypto.keys.generateKeyPairFromSeed('Ed25519', parentKey, 512)
};

/**
* This private helper function for generate DID
* @function _generateDID()
* @property key: crypto.PrivateKey
* @returns { PeerId: identifier.toJSON(), did }
*/

private async _generateDID (key: crypto.PrivateKey): Promise<{
PeerId: PeerId.JSONPeerId;
did: string;
}> {
const identifier = await this._createPeerId(key);
const did = `did:fula:${identifier.toB58String()}`;
return {
PeerId: identifier.toJSON(),
did
}
};

/**
* This private helper function for generate peer-id
* @function _createPeerId()
* @property key: crypto.PrivateKey
* @returns PeerId
*/

private async _createPeerId (key: crypto.PrivateKey): Promise<PeerId> {
let _privateKey = crypto.keys.marshalPrivateKey(key, 'ed25519')
const peerId = await PeerId.createFromPrivKey(_privateKey);
return peerId;
};

/**
* This function for parseDID
* @function parseDID()
* @property did: string
* @returns did
*/

parseDID(did: string) {
const match = did.match(/did:(\w+):(\w+).*/);
if (!match) {
throw new InvalidDid(did);
}
return { method: match[1], identifier: match[2] };
}


/**
* This function for checking if did valid format
* @function isValidDID()
* @property did: string
* @returns boolen
*/

isValidDID(did: string) {
try {
this.parseDID(did);
return true;
} catch (err) {
return false;
}
}

/**
* This private function for encryption
* @function encrypter() {x25519Encrypter}
* @property publicKey array
* @returns encrypter = publicKey
*/

private encrypter(publicKey: Array<Uint8Array>): Encrypter[] {
let encrypter: Encrypter[] = [];
publicKey.forEach((_publicKey:any)=> encrypter.push(x25519Encrypter(u8a.fromString(_publicKey))))
return encrypter
private _encrypter(publicKey: Array<Uint8Array>): Encrypter[] {
let encrypter: Encrypter[] = [];
publicKey.forEach((_publicKey:any)=> encrypter.push(x25519Encrypter(u8a.fromString(_publicKey))))
return encrypter
}

/**
Expand All @@ -50,38 +146,40 @@ export class DID {
* @property _privateKey
* @returns asymDecrypter = privateKey
*/
private decrypter() {
return x25519Decrypter(this._privateKey);
}

/**
private _decrypter() {
return x25519Decrypter(this._privateKey);
}

/**
* Create a JWE encrypted to the given recipients.
*
* @property cleartext The cleartext to be encrypted
* @property recipients An array of DIDs
* @property options Optional parameters
*/
async createJWE(
cleartext: Record<string, any>,
recipients: Encrypter[] | Array<Uint8Array>,
options: CreateJWEOptions = {}
): Promise<JWE> {
if(!recipients.map((key:any)=> { return key.alg }).includes('ECDH-ES+XC20PKW')) {
recipients = this.encrypter(recipients as Array<Uint8Array>);

async createJWE(
cleartext: Record<string, any>,
recipients: Encrypter[] | Array<Uint8Array>,
options: CreateJWEOptions = {}
): Promise<JWE> {
if(!recipients.map((key:any)=> { return key.alg }).includes('ECDH-ES+XC20PKW')) {
recipients = this._encrypter(recipients as Array<Uint8Array>);
}
const preparedCleartext = await prepareCleartext(cleartext);
return await createJWE(preparedCleartext, recipients as Encrypter[], options.protectedHeader, options.aad)
}
const preparedCleartext = await prepareCleartext(cleartext);
return await createJWE(preparedCleartext, recipients as Encrypter[], options.protectedHeader, options.aad)
}

/**
* Try to decrypt the given JWE with the currently authenticated user.
*
* @property jwe The JWE to decrypt
*/

async decryptJWE(jwe: JWE): Promise<Record<string, any>> {
let decrypter = this.decrypter();
const bytes = await decryptJWE(jwe, decrypter)
return decodeCleartext(bytes)
}
async decryptJWE(jwe: JWE): Promise<Record<string, any>> {
let decrypter = this._decrypter();
const bytes = await decryptJWE(jwe, decrypter)
return decodeCleartext(bytes)
}
}
14 changes: 5 additions & 9 deletions libraries/fula-sec/src/did/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,23 @@ import * as crypto from 'libp2p-crypto';
import { Buffer } from 'buffer';
import * as PeerId from 'peer-id'
import { InvalidDid } from './errors.js';
import * as u8a from 'uint8arrays'

export const getDidFromPem = async (pem:any) => {
const key = await pemToBuffer(pem);
return generateDid(key);
};

export const getDidFromParentKey = async (parentKey: Uint8Array, publicKey: Uint8Array) => {
export const getDidFromParentKey = async (parentKey: Uint8Array) => {
const key = await parentKeyToBuffer(parentKey);
return generateDidFromParent(key, publicKey);
return generateDidFromParent(key);
};
export const parentKeyToBuffer = async (parentKey: Uint8Array) => {
return await crypto.keys.generateKeyPairFromSeed('Ed25519', parentKey, 512)
};

export const generateDidFromParent = async (key:crypto.PrivateKey, publicKey: Uint8Array) => {
export const generateDidFromParent = async (key:crypto.PrivateKey) => {
const identifier = await generateIpnsNameFromParent(key);
const encode = {
id: identifier.toB58String(),
publicKey: u8a.toString(publicKey, 'base58btc')
}
const did = `did:fula:${encode.id.concat('/', encode.publicKey)}`;
const did = `did:fula:${identifier.toB58String()}`;
return {
PeerId: identifier.toJSON(),
did
Expand Down

0 comments on commit 9535978

Please sign in to comment.