Skip to content
Merged
214 changes: 89 additions & 125 deletions src/apollo/Apollo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
getKeyCurveByNameAndIndex,
ApolloError,
Curve,
KeyTypes,
KeyProperties,
MnemonicWordList,
PrivateKey,
Expand All @@ -29,7 +28,6 @@ import { X25519PublicKey } from "./utils/X25519PublicKey";
import { isEmpty, notEmptyString } from "../utils";
import ApolloPKG from "@hyperledger/identus-apollo";
import { PrismDerivationPath } from "../domain/models/derivation/schemas/PrismDerivation";

const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;
const Mnemonic = ApolloSDK.derivation.Mnemonic.Companion;
const HDKey = ApolloSDK.derivation.HDKey;
Expand All @@ -44,7 +42,6 @@ const BigIntegerWrapper = ApolloSDK.derivation.BigIntegerWrapper;
*
* ```ts
* const privateKey = apollo.createPrivateKey({
* type: KeyTypes.EC,
* curve: Curve.ED25519,
* });
* ```
Expand Down Expand Up @@ -115,7 +112,6 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
static Ed25519PrivateKey = Ed25519PrivateKey;
static X25519PrivateKey = X25519PrivateKey;


/**
* Creates a random set of mnemonic phrases that can be used as a seed for generating a private key.
*
Expand Down Expand Up @@ -197,7 +193,6 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
*
* ```ts
* const privateKey = apollo.createPublicKey({
* type: KeyTypes.EC,
* curve: Curve.SECP256K1,
* raw: Buffer.from(new Arra(64).fill(1)),
* });
Expand All @@ -209,56 +204,38 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
createPublicKey(parameters: {
[name: KeyProperties | string]: any;
}): PublicKey {
const keyType = parameters[KeyProperties.type];
const keyCurve = parameters[KeyProperties.curve];

if (isEmpty(keyType)) {
throw new ApolloError.InvalidKeyType();
}

if (isEmpty(keyCurve)) {
throw new ApolloError.InvalidKeyCurve();
}

const { curve } = getKeyCurveByNameAndIndex(keyCurve);
const keyData = parameters[KeyProperties.rawKey];
const xData = parameters[KeyProperties.curvePointX];
const yData = parameters[KeyProperties.curvePointY];

if (keyType === KeyTypes.EC) {
if (keyData) {
if (curve === Curve.ED25519) {
if (keyData) {
return new Ed25519PublicKey(keyData);
}

throw new ApolloError.MissingKeyParameters(KeyProperties.rawKey);
return new Ed25519PublicKey(keyData);
}

if (curve === Curve.SECP256K1) {
if (keyData) {
return new Secp256k1PublicKey(keyData);
} else {
const xData = parameters[KeyProperties.curvePointX];
const yData = parameters[KeyProperties.curvePointY];

if (xData && yData) {
return Secp256k1PublicKey.secp256k1FromByteCoordinates(xData, yData);
}
}

throw new ApolloError.MissingKeyParameters(KeyProperties.rawKey, KeyProperties.curvePointX, KeyProperties.curvePointY);
return new Secp256k1PublicKey(keyData);
}
}

if (keyType === KeyTypes.Curve25519) {
if (curve === Curve.X25519) {
if (keyData) {
return new X25519PublicKey(keyData);
}
return new X25519PublicKey(keyData);
}
throw new ApolloError.InvalidKeyCurve();
}

throw new ApolloError.MissingKeyParameters(KeyProperties.rawKey);
if (xData && yData) {
if (curve === Curve.SECP256K1) {
return Secp256k1PublicKey.secp256k1FromByteCoordinates(xData, yData);
}
throw new ApolloError.InvalidKeyCurve(curve, [Curve.SECP256K1]);
}

throw new ApolloError.MissingKeyParameters(KeyProperties.rawKey);
throw new ApolloError.MissingKeyParameters(KeyProperties.rawKey, KeyProperties.curvePointX, KeyProperties.curvePointY);
}

/**
Expand All @@ -270,7 +247,6 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
*
* ```ts
* const privateKey = apollo.createPrivateKey({
* type: KeyTypes.EC,
* curve: Curve.SECP256K1,
* seed: Buffer.from(seed.value).toString("hex"),
* });
Expand All @@ -282,7 +258,6 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
*
* ```ts
* const privateKey = apollo.createPrivateKey({
* type: KeyTypes.EC,
* curve: Curve.SECP256K1,
* seed: Buffer.from(seed.value).toString("hex"),
* derivationPath: "m/0'/0'/0'"
Expand All @@ -297,7 +272,6 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
*
* ```ts
* const privateKey = apollo.createPrivateKey({
* type: KeyTypes.EC,
* curve: Curve.ED25519,
* });
* ```
Expand All @@ -310,7 +284,6 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
*
* ```ts
* const privateKey = apollo.createPrivateKey({
* type: KeyTypes.Curve25519,
* curve: Curve.X25519,
* });
* ```
Expand All @@ -321,83 +294,29 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
createPrivateKey(parameters: {
[name: KeyProperties | string]: any;
}): PrivateKey {
const keyType = parameters[KeyProperties.type];
const keyCurve = parameters[KeyProperties.curve];

if (isEmpty(keyType)) {
throw new ApolloError.InvalidKeyType();
}

if (isEmpty(keyCurve)) {
throw new ApolloError.InvalidKeyCurve();
}

const { curve } = getKeyCurveByNameAndIndex(parameters[KeyProperties.curve]);
const keyData = parameters[KeyProperties.rawKey];

if (keyType === KeyTypes.EC) {
if (curve === Curve.ED25519) {
if (keyData) {
return new Ed25519PrivateKey(keyData);
}

const seedHex = parameters[KeyProperties.seed];
if (notEmptyString(seedHex)) {
const derivationIndex = parameters[KeyProperties.index] ?? "0";
const derivationParam = parameters[KeyProperties.derivationPath];
const defaultPath: string = derivationParam ?? PrismDerivationPath.init(derivationIndex).toString();
const seed = Int8Array.from(Buffer.from(seedHex, "hex"));
const hdKey = ApolloSDK.derivation.EdHDKey.Companion.initFromSeed(seed);
const baseKey = new Ed25519PrivateKey(Uint8Array.from(hdKey.privateKey));

baseKey.keySpecification.set(KeyProperties.chainCode, Buffer.from(Uint8Array.from(hdKey.chainCode)).toString("hex"));
baseKey.keySpecification.set(KeyProperties.derivationPath, Buffer.from(defaultPath).toString("hex"));
baseKey.keySpecification.set(KeyProperties.index, derivationIndex);

if (derivationParam) {
const privateKey = baseKey.derive(defaultPath);
return privateKey;
}

return baseKey;
}

const keyPair = Ed25519KeyPair.generateKeyPair();
return keyPair.privateKey;
if (curve === Curve.ED25519) {
if (keyData) {
return new Ed25519PrivateKey(keyData);
}

if (curve === Curve.SECP256K1) {
if (keyData) {
return new Secp256k1PrivateKey(keyData);
}

const seedHex = parameters[KeyProperties.seed];
if (isEmpty(seedHex)) {
throw new ApolloError.MissingKeyParameters(KeyProperties.seed);
}

const seed = Buffer.from(seedHex, "hex");
const seedHex = parameters[KeyProperties.seed];
if (notEmptyString(seedHex)) {
const derivationIndex = parameters[KeyProperties.index] ?? "0";
const derivationParam = parameters[KeyProperties.derivationPath];
const defaultPath: string = derivationParam ?? PrismDerivationPath.init(
derivationIndex
).toString();

const hdKey = HDKey.InitFromSeed(
Int8Array.from(seed),
defaultPath.split("/").slice(1).length,
BigIntegerWrapper.initFromInt(0)
);

if (hdKey.privateKey == null) {
throw new ApolloError.ApolloLibError("Key generated incorrectly: missing privateKey");
}
const defaultPath: string = derivationParam ?? PrismDerivationPath.init(derivationIndex).toString();
const seed = Int8Array.from(Buffer.from(seedHex, "hex"));
const hdKey = ApolloSDK.derivation.EdHDKey.Companion.initFromSeed(seed);
const baseKey = new Ed25519PrivateKey(Uint8Array.from(hdKey.privateKey));

if (hdKey.chainCode == null) {
throw new ApolloError.ApolloLibError("Key generated incorrectly: missing chainCode");
}

const baseKey = new Secp256k1PrivateKey(Uint8Array.from(hdKey.privateKey));
baseKey.keySpecification.set(KeyProperties.chainCode, Buffer.from(Uint8Array.from(hdKey.chainCode)).toString("hex"));
baseKey.keySpecification.set(KeyProperties.derivationPath, Buffer.from(defaultPath).toString("hex"));
baseKey.keySpecification.set(KeyProperties.index, derivationIndex);
Expand All @@ -409,37 +328,82 @@ export default class Apollo implements ApolloInterface, KeyRestoration {

return baseKey;
}

const keyPair = Ed25519KeyPair.generateKeyPair();
return keyPair.privateKey;
}

if (keyType === KeyTypes.Curve25519) {
if (curve === Curve.X25519) {
if (keyData) {
return new X25519PrivateKey(keyData);
}
if (curve === Curve.SECP256K1) {
if (keyData) {
return new Secp256k1PrivateKey(keyData);
}

const seedHex = parameters[KeyProperties.seed];
if (notEmptyString(seedHex)) {
const derivationIndex = parameters[KeyProperties.index] ?? "0";
const derivationParam: string = parameters[KeyProperties.derivationPath] ?? PrismDerivationPath.init(derivationIndex).toString();
const seedHex = parameters[KeyProperties.seed];
if (isEmpty(seedHex)) {
throw new ApolloError.MissingKeyParameters(KeyProperties.seed);
}

const seed = Int8Array.from(Buffer.from(seedHex, "hex"));
const hdKey = ApolloSDK.derivation.EdHDKey.Companion.initFromSeed(seed).derive(derivationParam);
const edKey = Ed25519PrivateKey.from.Buffer(Buffer.from(hdKey.privateKey));
const xKey = edKey.x25519();
const seed = Buffer.from(seedHex, "hex");
const derivationIndex = parameters[KeyProperties.index] ?? "0";
const derivationParam = parameters[KeyProperties.derivationPath];
const defaultPath: string = derivationParam ?? PrismDerivationPath.init(
derivationIndex
).toString();

const hdKey = HDKey.InitFromSeed(
Int8Array.from(seed),
defaultPath.split("/").slice(1).length,
BigIntegerWrapper.initFromInt(0)
);

if (hdKey.privateKey == null) {
throw new ApolloError.ApolloLibError("Key generated incorrectly: missing privateKey");
}

xKey.keySpecification.set(KeyProperties.chainCode, Buffer.from(hdKey.chainCode).toString("hex"));
xKey.keySpecification.set(KeyProperties.derivationPath, Buffer.from(derivationParam).toString("hex"));
xKey.keySpecification.set(KeyProperties.index, derivationIndex);
if (hdKey.chainCode == null) {
throw new ApolloError.ApolloLibError("Key generated incorrectly: missing chainCode");
}

return xKey;
}
const baseKey = new Secp256k1PrivateKey(Uint8Array.from(hdKey.privateKey));
baseKey.keySpecification.set(KeyProperties.chainCode, Buffer.from(Uint8Array.from(hdKey.chainCode)).toString("hex"));
baseKey.keySpecification.set(KeyProperties.derivationPath, Buffer.from(defaultPath).toString("hex"));
baseKey.keySpecification.set(KeyProperties.index, derivationIndex);

if (derivationParam) {
const privateKey = baseKey.derive(defaultPath);
return privateKey;
}

return baseKey;
}

if (curve === Curve.X25519) {
if (keyData) {
return new X25519PrivateKey(keyData);
}

const seedHex = parameters[KeyProperties.seed];
if (notEmptyString(seedHex)) {
const derivationIndex = parameters[KeyProperties.index] ?? "0";
const derivationParam: string = parameters[KeyProperties.derivationPath] ?? PrismDerivationPath.init(derivationIndex).toString();

const keyPair = X25519KeyPair.generateKeyPair();
return keyPair.privateKey;
const seed = Int8Array.from(Buffer.from(seedHex, "hex"));
const hdKey = ApolloSDK.derivation.EdHDKey.Companion.initFromSeed(seed).derive(derivationParam);
const edKey = Ed25519PrivateKey.from.Buffer(Buffer.from(hdKey.privateKey));
const xKey = edKey.x25519();

xKey.keySpecification.set(KeyProperties.chainCode, Buffer.from(hdKey.chainCode).toString("hex"));
xKey.keySpecification.set(KeyProperties.derivationPath, Buffer.from(derivationParam).toString("hex"));
xKey.keySpecification.set(KeyProperties.index, derivationIndex);

return xKey;
}

const keyPair = X25519KeyPair.generateKeyPair();
return keyPair.privateKey;
}

throw new ApolloError.InvalidKeyType(keyType);
throw new ApolloError.InvalidKeyCurve();
}

restorePrivateKey(key: StorableKey): PrivateKey {
Expand Down
6 changes: 1 addition & 5 deletions src/castor/did/prismDID/PrismDIDPublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Curve, getProtosUsage, getUsage, PublicKey, Usage } from "../../../doma
import { ApolloError, CastorError } from "../../../domain/models/Errors";
import * as Protos from "../../protos/node_models";

import { Apollo, KeyProperties, KeyTypes } from "../../../domain";
import { Apollo, KeyProperties } from "../../../domain";

export class PrismDIDPublicKey {

Expand All @@ -28,13 +28,11 @@ export class PrismDIDPublicKey {
switch (proto.key_data) {
case "compressed_ec_key_data":
return apollo.createPublicKey({
[KeyProperties.type]: KeyTypes.EC,
[KeyProperties.curve]: Curve.SECP256K1,
[KeyProperties.rawKey]: proto.compressed_ec_key_data.data
})
case "ec_key_data":
return apollo.createPublicKey({
[KeyProperties.type]: KeyTypes.EC,
[KeyProperties.curve]: Curve.SECP256K1,
[KeyProperties.curvePointX]: proto.ec_key_data.x,
[KeyProperties.curvePointY]: proto.ec_key_data.y,
Expand All @@ -52,14 +50,12 @@ export class PrismDIDPublicKey {
if (proto.has_compressed_ec_key_data) {
if (curve === Curve.ED25519) {
return apollo.createPublicKey({
[KeyProperties.type]: KeyTypes.EC,
[KeyProperties.curve]: Curve.ED25519,
[KeyProperties.rawKey]: proto.compressed_ec_key_data.data
})
}
if (curve === Curve.X25519) {
return apollo.createPublicKey({
[KeyProperties.type]: KeyTypes.Curve25519,
[KeyProperties.curve]: Curve.X25519,
[KeyProperties.rawKey]: proto.compressed_ec_key_data.data
})
Expand Down
5 changes: 0 additions & 5 deletions src/domain/models/KeyProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ export enum KeyProperties {
derivationPath = "derivationPath",
index = "index",

/**
* The 'type' denotes the type of the key.
*/
type = "type",

/**
* The 'curvePointX' represents the x-coordinate of a curve point for an elliptic-curve key.
*/
Expand Down
Loading
Loading