Skip to content

Commit

Permalink
feat: Backup and Restore (#215)
Browse files Browse the repository at this point in the history
Signed-off-by: Curtis Harding <[email protected]>
  • Loading branch information
curtis-h authored and elribonazo committed Jul 19, 2024
1 parent 1922128 commit bf15325
Show file tree
Hide file tree
Showing 54 changed files with 1,601 additions and 206 deletions.
21 changes: 19 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
"request": "launch",
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
"args": [
"${fileBasenameNoExtension}",
"--colors",
"--workerThreads",
"--detectOpenHandles",
Expand All @@ -44,6 +43,24 @@
"${workspaceRoot}/../../node_modules/**/*",
"<node_internals>/**/*"
]
},
{
"name": "TEST:file",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
"args": [
"--colors",
"--workerThreads",
"--detectOpenHandles",
"--maxWorkers",
"1",
"${fileBasenameNoExtension}",
],
"skipFiles": [
"${workspaceRoot}/../../node_modules/**/*",
"<node_internals>/**/*"
]
}
]
}
}
27 changes: 27 additions & 0 deletions docs/examples/Backup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Edge SDK Backup & Restore

## Requirements
1. SDK A - a used instance with data in the store.
2. SDK B - an unused instance, with an empty store.


## Flow
1. SDK A creates a Backup `jwe`
2. SDK B restores from the `jwe`


## Code Reference
* Create the `jwe` using the Agent function provided.

Example
```TS
const jwe = await Agent_a.backup.createJWE();
```

* Transfer the `jwe` to another SDK.
* Restore from the `jwe` using the Agent function provided.

Example
```TS
await Agent_b.backup.restore(jwe);
```
25 changes: 16 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,10 @@
"outputName": "junit.xml"
},
"dependencies": {
"@atala/apollo": "~1.2.16",
"@atala/apollo": "^1.3.4",
"@scure/bip32": "^1.3.0",
"@scure/bip39": "^1.1.1",
"@sinclair/typebox": "^0.32.31",
"@stablelib/base64": "^1.0.1",
"@stablelib/sha256": "^1.0.1",
"@stablelib/uuid": "^1.0.2",
Expand Down Expand Up @@ -210,4 +211,4 @@
"overrides": {
"crypto-js": "^4.2.0"
}
}
}
32 changes: 29 additions & 3 deletions src/apollo/Apollo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ import { Secp256k1PublicKey } from "./utils/Secp256k1PublicKey";
import { Ed25519PublicKey } from "./utils/Ed25519PublicKey";
import { X25519PublicKey } from "./utils/X25519PublicKey";

import ApolloPKG from "@atala/apollo";
import { DerivationPath } from "./utils/derivation/DerivationPath";

const ApolloSDK = ApolloPKG.io.iohk.atala.prism.apollo;
import { notEmptyString } from "../utils";
import ApolloPKG from "@atala/apollo";
const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;
const Mnemonic = ApolloSDK.derivation.Mnemonic.Companion;
const HDKey = ApolloSDK.derivation.HDKey;
const BigIntegerWrapper = ApolloSDK.derivation.BigIntegerWrapper;

/**
* Apollo defines the set of cryptographic operations.
*
Expand Down Expand Up @@ -274,6 +275,18 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
if (keyData) {
return new Ed25519PrivateKey(keyData);
}

const seedHex = parameters[KeyProperties.seed];
if (notEmptyString(seedHex)) {
const derivationParam = parameters[KeyProperties.derivationPath] ?? "m/0'/0'/0'";
const derivationPath = DerivationPath.from(derivationParam);
const seed = Int8Array.from(Buffer.from(seedHex, "hex"));
const hdKey = ApolloSDK.derivation.EdHDKey.Companion.initFromSeed(seed).derive(derivationPath.toString());
const edKey = Ed25519PrivateKey.from.Buffer(Buffer.from(hdKey.privateKey));

return edKey;
}

const keyPair = Ed25519KeyPair.generateKeyPair();
return keyPair.privateKey;
}
Expand Down Expand Up @@ -322,6 +335,19 @@ export default class Apollo implements ApolloInterface, KeyRestoration {
if (keyData) {
return new X25519PrivateKey(keyData);
}

const seedHex = parameters[KeyProperties.seed];
if (notEmptyString(seedHex)) {
const derivationParam = parameters[KeyProperties.derivationPath] ?? "m/0'/0'/0'";
const derivationPath = DerivationPath.from(derivationParam);
const seed = Int8Array.from(Buffer.from(seedHex, "hex"));
const hdKey = ApolloSDK.derivation.EdHDKey.Companion.initFromSeed(seed).derive(derivationPath.toString());
const edKey = Ed25519PrivateKey.from.Buffer(Buffer.from(hdKey.privateKey));
const xKey = edKey.x25519();

return xKey;
}

const keyPair = X25519KeyPair.generateKeyPair();
return keyPair.privateKey;
}
Expand Down
6 changes: 3 additions & 3 deletions src/apollo/utils/Ed25519KeyPair.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import ApolloBaseAsymmetricEncryption from "@atala/apollo";
import { KeyPair } from "../../domain";
import { Ed25519PrivateKey } from "./Ed25519PrivateKey";
import { Ed25519PublicKey } from "./Ed25519PublicKey";
import ApolloPKG from "@atala/apollo";
const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;

/**
* @ignore
Expand All @@ -15,8 +16,7 @@ export class Ed25519KeyPair extends KeyPair {
}

static generateKeyPair() {
const keyPair =
ApolloBaseAsymmetricEncryption.io.iohk.atala.prism.apollo.utils.KMMEdKeyPair.Companion.generateKeyPair();
const keyPair = ApolloSDK.utils.KMMEdKeyPair.Companion.generateKeyPair();

return new Ed25519KeyPair(
new Ed25519PrivateKey(keyPair.privateKey.raw),
Expand Down
16 changes: 10 additions & 6 deletions src/apollo/utils/Ed25519PrivateKey.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ApolloPkg from "@atala/apollo";
import { Ed25519PublicKey } from "./Ed25519PublicKey";
import { X25519PrivateKey } from "./X25519PrivateKey";
import {
Curve,
ExportableKey,
Expand All @@ -11,6 +11,8 @@ import {
SignableKey
} from "../../domain";

import ApolloPKG from "@atala/apollo";
const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;

/**
* @ignore
Expand Down Expand Up @@ -48,15 +50,17 @@ export class Ed25519PrivateKey extends PrivateKey implements ExportableKey, Sign
return Buffer.from(signature);
}

x25519() {
const key = this.getInstance().x25519PrivateKey();
return X25519PrivateKey.from.Buffer(key.raw);
}

private getInstance(
value?: Int8Array | Uint8Array
): ApolloPkg.io.iohk.atala.prism.apollo.utils.KMMEdPrivateKey {
) {
// eslint-disable-next-line no-extra-boolean-cast
const bytes = !!value ? Buffer.from(value) : this.raw;
const instance =
new ApolloPkg.io.iohk.atala.prism.apollo.utils.KMMEdPrivateKey(
Int8Array.from(bytes)
);
const instance = new ApolloSDK.utils.KMMEdPrivateKey(Int8Array.from(bytes));

return instance;
}
Expand Down
11 changes: 5 additions & 6 deletions src/apollo/utils/Ed25519PublicKey.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ApolloPkg from "@atala/apollo";
import {
Curve,
ExportableKey,
Expand All @@ -10,6 +9,9 @@ import {
VerifiableKey
} from "../../domain";

import ApolloPKG from "@atala/apollo";
const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;

/**
* @ignore
*/
Expand Down Expand Up @@ -46,13 +48,10 @@ export class Ed25519PublicKey extends PublicKey implements ExportableKey, Storab

private getInstance(
value?: Int8Array | Uint8Array
): ApolloPkg.io.iohk.atala.prism.apollo.utils.KMMEdPublicKey {
) {
// eslint-disable-next-line no-extra-boolean-cast
const bytes = !!value ? Buffer.from(value) : this.raw;
const instance =
new ApolloPkg.io.iohk.atala.prism.apollo.utils.KMMEdPublicKey(
Int8Array.from(bytes)
);
const instance = new ApolloSDK.utils.KMMEdPublicKey(Int8Array.from(bytes));

return instance;
}
Expand Down
16 changes: 3 additions & 13 deletions src/apollo/utils/Secp256k1KeyPair.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { KeyPair, MnemonicWordList } from "../../domain";

import { Secp256k1PrivateKey } from "./Secp256k1PrivateKey";
import { Secp256k1PublicKey } from "./Secp256k1PublicKey";

import * as ApolloPKG from "@atala/apollo";
import ApolloPKG from "@atala/apollo";
const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;

/**
* @ignore
Expand All @@ -17,16 +16,7 @@ export class Secp256k1KeyPair extends KeyPair {
}

static generateKeyPair() {
const {
io: {
iohk: {
atala: {
prism: { apollo },
},
},
},
} = ApolloPKG;
const Mnemonic = apollo.derivation.Mnemonic.Companion;
const Mnemonic = ApolloSDK.derivation.Mnemonic.Companion;
const mnemonics = Mnemonic.createRandomMnemonics() as MnemonicWordList;
const seed = Mnemonic.createSeed(mnemonics, `mnemonic`);
const priv = new Secp256k1PrivateKey(Uint8Array.from(seed.slice(0, 32)));
Expand Down
10 changes: 5 additions & 5 deletions src/apollo/utils/Secp256k1PrivateKey.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ApolloPkg from "@atala/apollo";
import BN from "bn.js";

import * as ECConfig from "../../config/ECConfig";
Expand All @@ -14,9 +13,10 @@ import {
StorableKey,
} from "../../domain/models/keyManagement";

const Apollo = ApolloPkg.io.iohk.atala.prism.apollo;
const HDKey = Apollo.derivation.HDKey;
const BigIntegerWrapper = Apollo.derivation.BigIntegerWrapper;
import ApolloPKG from "@atala/apollo";
const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;
const HDKey = ApolloSDK.derivation.HDKey;
const BigIntegerWrapper = ApolloSDK.derivation.BigIntegerWrapper;

/**
* @ignore
Expand All @@ -36,7 +36,7 @@ export class Secp256k1PrivateKey
static from = ImportableKey.factory(Secp256k1PrivateKey, { pemLabel: "EC PRIVATE KEY" });

private get native() {
return Apollo.utils.KMMECSecp256k1PrivateKey.Companion.secp256k1FromByteArray(
return ApolloSDK.utils.KMMECSecp256k1PrivateKey.Companion.secp256k1FromByteArray(
Int8Array.from(this.raw)
);
}
Expand Down
10 changes: 6 additions & 4 deletions src/apollo/utils/Secp256k1PublicKey.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ApolloPkg from "@atala/apollo";
import BN from "bn.js";
import BigInteger from "bn.js";

Expand All @@ -13,6 +12,9 @@ import {
VerifiableKey
} from "../../domain/models/keyManagement";

import ApolloPKG from "@atala/apollo";
const ApolloSDK = ApolloPKG.org.hyperledger.identus.apollo;

/**
* @ignore
*/
Expand All @@ -35,7 +37,7 @@ export class Secp256k1PublicKey extends PublicKey implements StorableKey, Export
}

private get native() {
return ApolloPkg.io.iohk.atala.prism.apollo.utils.KMMECSecp256k1PublicKey.Companion.secp256k1FromBytes(
return ApolloSDK.utils.KMMECSecp256k1PublicKey.Companion.secp256k1FromBytes(
Int8Array.from(this.raw)
);
}
Expand Down Expand Up @@ -143,7 +145,7 @@ export class Secp256k1PublicKey extends PublicKey implements StorableKey, Export
static secp256k1FromBytes(encoded: Uint8Array): Secp256k1PublicKey {
return new Secp256k1PublicKey(
Uint8Array.from(
ApolloPkg.io.iohk.atala.prism.apollo.utils.KMMECSecp256k1PublicKey.Companion.secp256k1FromBytes(
ApolloSDK.utils.KMMECSecp256k1PublicKey.Companion.secp256k1FromBytes(
Int8Array.from(encoded)
).raw
)
Expand Down Expand Up @@ -178,7 +180,7 @@ export class Secp256k1PublicKey extends PublicKey implements StorableKey, Export
const xCoord = Buffer.from(x.toArray());
const yCoord = Buffer.from(y.toArray());
const publicKey =
ApolloPkg.io.iohk.atala.prism.apollo.utils.KMMECSecp256k1PublicKey.Companion.secp256k1FromByteCoordinates(
ApolloSDK.utils.KMMECSecp256k1PublicKey.Companion.secp256k1FromByteCoordinates(
Int8Array.from(xCoord),
Int8Array.from(yCoord)
);
Expand Down
Loading

0 comments on commit bf15325

Please sign in to comment.