mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
89 lines
2.8 KiB
TypeScript
89 lines
2.8 KiB
TypeScript
import { Community } from '@entity/Community'
|
|
|
|
// https://www.npmjs.com/package/bip32-ed25519
|
|
import { LogError } from '@/server/LogError'
|
|
|
|
import { toPublic, derivePrivate, sign, verify, generateFromSeed } from 'bip32-ed25519'
|
|
|
|
import { Mnemonic } from './Mnemonic'
|
|
import { SignaturePair } from './proto/3_3/SignaturePair'
|
|
|
|
/**
|
|
* Class Managing Key Pair and also generate, sign and verify signature with it
|
|
*/
|
|
export class KeyPair {
|
|
private _publicKey: Buffer
|
|
private _chainCode: Buffer
|
|
private _privateKey: Buffer
|
|
|
|
/**
|
|
* @param input: Mnemonic = Mnemonic or Passphrase which work as seed for generating algorithms
|
|
* @param input: Buffer = extended private key, returned from bip32-ed25519 generateFromSeed or from derivePrivate
|
|
* @param input: Community = community entity with keys loaded from db
|
|
*
|
|
*/
|
|
public constructor(input: Mnemonic | Buffer | Community) {
|
|
if (input instanceof Mnemonic) {
|
|
this.loadFromExtendedPrivateKey(generateFromSeed(input.seed))
|
|
} else if (input instanceof Buffer) {
|
|
this.loadFromExtendedPrivateKey(input)
|
|
} else if (input instanceof Community) {
|
|
if (!input.rootPrivkey || !input.rootChaincode || !input.rootPubkey) {
|
|
throw new LogError('missing private key or chaincode or public key in commmunity entity')
|
|
}
|
|
this._privateKey = input.rootPrivkey
|
|
this._publicKey = input.rootPubkey
|
|
this._chainCode = input.rootChaincode
|
|
}
|
|
}
|
|
|
|
/**
|
|
* copy keys to community entity
|
|
* @param community
|
|
*/
|
|
public fillInCommunityKeys(community: Community) {
|
|
community.rootPubkey = this._publicKey
|
|
community.rootPrivkey = this._privateKey
|
|
community.rootChaincode = this._chainCode
|
|
}
|
|
|
|
private loadFromExtendedPrivateKey(extendedPrivateKey: Buffer) {
|
|
if (extendedPrivateKey.length !== 96) {
|
|
throw new LogError('invalid extended private key')
|
|
}
|
|
this._privateKey = extendedPrivateKey.subarray(0, 64)
|
|
this._chainCode = extendedPrivateKey.subarray(64, 96)
|
|
this._publicKey = toPublic(extendedPrivateKey).subarray(0, 32)
|
|
}
|
|
|
|
public getExtendPrivateKey(): Buffer {
|
|
return Buffer.concat([this._privateKey, this._chainCode])
|
|
}
|
|
|
|
public getExtendPublicKey(): Buffer {
|
|
return Buffer.concat([this._publicKey, this._chainCode])
|
|
}
|
|
|
|
public get publicKey(): Buffer {
|
|
return this._publicKey
|
|
}
|
|
|
|
public derive(path: number[]): KeyPair {
|
|
const extendedPrivateKey = this.getExtendPrivateKey()
|
|
return new KeyPair(
|
|
path.reduce(
|
|
(extendPrivateKey: Buffer, node: number) => derivePrivate(extendPrivateKey, node),
|
|
extendedPrivateKey,
|
|
),
|
|
)
|
|
}
|
|
|
|
public sign(message: Buffer): Buffer {
|
|
return sign(message, this.getExtendPrivateKey())
|
|
}
|
|
|
|
public static verify(message: Buffer, { signature, pubKey }: SignaturePair): boolean {
|
|
return verify(message, signature, pubKey)
|
|
}
|
|
}
|