purity-identity
Version:
Key generation for the Purity users, tool to encrypt/decrypt messages with their identities and helpers for compressing decompressing public keys
143 lines (122 loc) • 3.47 kB
text/typescript
import EthCrypto, { Encrypted } from "eth-crypto";
import { hexToBytes } from "web3-utils"
export type IdentityType = {
privateKey: string,
publicKey: string,
address: string
}
export type SerializedPublicKey = {
pubKeyPrefix: boolean,
pubKey: Array<number>
}
/**
* Used for Premium Content's encryption/decryption and contract store for pubkeys
**/
export class IdenityService {
private identity: IdentityType;
constructor(identity: IdentityType | null = null) {
if(identity) {
this.identity = identity
} else {
this.identity = createIdentity()
}
}
public async encryptData(data: string): Promise<Encrypted> {
return encryptData(
this.identity.publicKey,
data
);
}
public async decryptEncryptedData(encryptedData: Encrypted): Promise<string> {
return decryptData(this.identity.privateKey, encryptedData);
}
public getCompressedPublicKey(): string {
return compressPublicKey(this.identity.publicKey);
}
public getDecompressedPublicKey(): string {
return this.identity.publicKey;
}
public getSerializedPublicKey(): SerializedPublicKey {
return serializePublicKey(
this.identity.publicKey
)
}
}
// PUBLIC FUNCTIONS
export function createIdentity(): IdentityType {
return EthCrypto.createIdentity();
}
export function encryptData(pubKey: string, data: string): Promise<Encrypted> {
return EthCrypto.encryptWithPublicKey(
pubKey,
data // message
);
}
export function decryptData(privKey: string, encryptedData: Encrypted): Promise<string> {
return EthCrypto.decryptWithPrivateKey(privKey, encryptedData);
}
export function compressPublicKey(pubKey: string): string {
return EthCrypto.publicKey.compress(pubKey);
}
/**
* For contract store, the public key has to be serialized and compressed
* as much as possible
**/
export function serializePublicKey(
pubKey: string
): SerializedPublicKey {
const compressedPubKey = compressPublicKey(pubKey)
const userPubKeyPart1: boolean = serializeCompressedPublicKeyPrefix(
compressedPubKey
);
const userPubKeyPart2: Array<number> = serializeCompressedPublicKey(
compressedPubKey
)
return {
pubKeyPrefix: userPubKeyPart1,
pubKey: userPubKeyPart2
}
}
/**
* Get decompressed public key string from contract store
**/
export function unserializePublicKey(
pubKeyPrefix: boolean,
pubKey: string
): string {
return EthCrypto.publicKey.decompress(
decompressPublicKeyPrefix(pubKeyPrefix) + pubKey.substr(2, pubKey.length)
)
}
/**
* Gives back the compressed public key's first two characters in a boolean,
* because it only can be "02" or "03"
* returns true if "03"
**/
function serializeCompressedPublicKeyPrefix(compressedPubKey: string): boolean {
const firstTwoChars: string = compressedPubKey.substr(0, 2)
if(firstTwoChars === "03") {
return true
}
if(firstTwoChars === "02") {
return false
}
// else
throw new Error(`The first two characters of the ${compressedPubKey}`
+ ` compressed public key are not 02 or 03`)
}
/**
* Serializes the public key's bigger part (without prefix)
**/
function serializeCompressedPublicKey(
compressedPubKey: string
): Array<number> {
let userPubKeyPart2: string = compressedPubKey.substr(
2,
compressedPubKey.length
);
return hexToBytes("0x" + userPubKeyPart2);
}
function decompressPublicKeyPrefix(prefix: boolean): string {
return prefix ? "03" : "02";
}