Skip to content

Commit

Permalink
Refactor CBD API (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec authored and derekpierre committed Aug 9, 2023
2 parents b861631 + bd35523 commit a3d6295
Show file tree
Hide file tree
Showing 19 changed files with 252 additions and 293 deletions.
43 changes: 20 additions & 23 deletions src/characters/alice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,22 @@ import {
} from '@nucypher/nucypher-core';
import { ethers } from 'ethers';

import { Configuration } from '../config';
import { Keyring } from '../keyring';
import {
BlockchainPolicy,
BlockchainPolicyParameters,
EnactedPolicy,
PreEnactedPolicy,
} from '../policies/policy';
import { PorterClient } from '../porter';
import { ChecksumAddress } from '../types';

import { RemoteBob } from './bob';
import { Porter } from './porter';

export class Alice {
private readonly porter: Porter;
private readonly keyring: Keyring;

private constructor(
config: Configuration,
secretKey: SecretKey,
public readonly web3Provider: ethers.providers.Web3Provider
) {
this.porter = new Porter(config.porterUri);
private constructor(secretKey: SecretKey) {
this.keyring = new Keyring(secretKey);
}

Expand All @@ -40,43 +33,45 @@ export class Alice {
return this.keyring.signer;
}

public static fromSecretKey(
config: Configuration,
secretKey: SecretKey,
web3Provider: ethers.providers.Web3Provider
): Alice {
return new Alice(config, secretKey, web3Provider);
public static fromSecretKey(secretKey: SecretKey): Alice {
return new Alice(secretKey);
}

public getPolicyEncryptingKeyFromLabel(label: string): PublicKey {
return this.keyring.getPublicKeyFromLabel(label);
}

public async grant(
web3Provider: ethers.providers.Web3Provider,
porterUri: string,
policyParameters: BlockchainPolicyParameters,
includeUrsulas?: readonly ChecksumAddress[],
excludeUrsulas?: readonly ChecksumAddress[]
): Promise<EnactedPolicy> {
const ursulas = await this.porter.getUrsulas(
const porter = new PorterClient(porterUri);
const ursulas = await porter.getUrsulas(
policyParameters.shares,
excludeUrsulas,
includeUrsulas
);
const policy = await this.createPolicy(policyParameters);
return await policy.enact(ursulas);
const policy = await this.createPolicy(web3Provider, policyParameters);
return await policy.enact(web3Provider, ursulas);
}

public async generatePreEnactedPolicy(
web3Provider: ethers.providers.Web3Provider,
porterUri: string,
policyParameters: BlockchainPolicyParameters,
includeUrsulas?: readonly ChecksumAddress[],
excludeUrsulas?: readonly ChecksumAddress[]
): Promise<PreEnactedPolicy> {
const ursulas = await this.porter.getUrsulas(
const porter = new PorterClient(porterUri);
const ursulas = await porter.getUrsulas(
policyParameters.shares,
excludeUrsulas,
includeUrsulas
);
const policy = await this.createPolicy(policyParameters);
const policy = await this.createPolicy(web3Provider, policyParameters);
return await policy.generatePreEnactedPolicy(ursulas);
}

Expand All @@ -99,10 +94,11 @@ export class Alice {
}

private async createPolicy(
web3Provider: ethers.providers.Web3Provider,
rawParameters: BlockchainPolicyParameters
): Promise<BlockchainPolicy> {
const { bob, label, threshold, shares, startDate, endDate } =
await this.validatePolicyParameters(rawParameters);
await this.validatePolicyParameters(web3Provider, rawParameters);
const { delegatingKey, verifiedKFrags } = this.generateKFrags(
bob,
label,
Expand All @@ -123,6 +119,7 @@ export class Alice {
}

private async validatePolicyParameters(
web3Provider: ethers.providers.Web3Provider,
rawParams: BlockchainPolicyParameters
): Promise<BlockchainPolicyParameters> {
const startDate = rawParams.startDate ?? new Date();
Expand All @@ -144,8 +141,8 @@ export class Alice {
);
}

const blockNumber = await this.web3Provider.getBlockNumber();
const block = await this.web3Provider.getBlock(blockNumber);
const blockNumber = await web3Provider.getBlockNumber();
const block = await web3Provider.getBlock(blockNumber);
const blockTime = new Date(block.timestamp * 1000);
if (endDate < blockTime) {
throw new Error(
Expand Down
21 changes: 9 additions & 12 deletions src/characters/bob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ import {
Signer,
} from '@nucypher/nucypher-core';

import { Configuration } from '../config';
import { Keyring } from '../keyring';
import { PolicyMessageKit } from '../kits/message';
import { RetrievalResult } from '../kits/retrieval';
import { PorterClient } from '../porter';
import { zip } from '../utils';

import { Porter } from './porter';

export class RemoteBob {
private constructor(
public readonly decryptingKey: PublicKey,
Expand All @@ -37,11 +35,9 @@ export class RemoteBob {
}

export class Bob {
private readonly porter: Porter;
private readonly keyring: Keyring;

constructor(config: Configuration, secretKey: SecretKey) {
this.porter = new Porter(config.porterUri);
constructor(secretKey: SecretKey) {
this.keyring = new Keyring(secretKey);
}

Expand All @@ -57,24 +53,23 @@ export class Bob {
return this.keyring.signer;
}

public static fromSecretKey(
config: Configuration,
secretKey: SecretKey
): Bob {
return new Bob(config, secretKey);
public static fromSecretKey(secretKey: SecretKey): Bob {
return new Bob(secretKey);
}

public decrypt(messageKit: MessageKit | PolicyMessageKit): Uint8Array {
return this.keyring.decrypt(messageKit);
}

public async retrieveAndDecrypt(
porterUri: string,
policyEncryptingKey: PublicKey,
publisherVerifyingKey: PublicKey,
messageKits: readonly MessageKit[],
encryptedTreasureMap: EncryptedTreasureMap
): Promise<readonly Uint8Array[]> {
const policyMessageKits = await this.retrieve(
porterUri,
policyEncryptingKey,
publisherVerifyingKey,
messageKits,
Expand Down Expand Up @@ -103,6 +98,7 @@ export class Bob {
}

public async retrieve(
porterUri: string,
policyEncryptingKey: PublicKey,
publisherVerifyingKey: PublicKey,
messageKits: readonly MessageKit[],
Expand All @@ -122,7 +118,8 @@ export class Bob {
);

const retrievalKits = policyMessageKits.map((pk) => pk.asRetrievalKit());
const retrieveCFragsResponses = await this.porter.retrieveCFrags(
const porter = new PorterClient(porterUri);
const retrieveCFragsResponses = await porter.retrieveCFrags(
treasureMap,
retrievalKits,
publisherVerifyingKey,
Expand Down
27 changes: 15 additions & 12 deletions src/characters/cbd-recipient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,27 @@ import {
getCombineDecryptionSharesFunction,
getVariantClass,
} from '../dkg';
import { PorterClient } from '../porter';
import { fromJSON, toJSON } from '../utils';

import { Porter } from './porter';

export type CbdTDecDecrypterJSON = {
export type ThresholdDecrypterJSON = {
porterUri: string;
ritualId: number;
threshold: number;
};

export class CbdTDecDecrypter {
export class ThresholdDecrypter {
// private readonly verifyingKey: Keyring;

private constructor(
private readonly porter: Porter,
private readonly porter: PorterClient,
private readonly ritualId: number,
private readonly threshold: number
) {}

public static create(porterUri: string, dkgRitual: DkgRitual) {
return new CbdTDecDecrypter(
new Porter(porterUri),
return new ThresholdDecrypter(
new PorterClient(porterUri),
dkgRitual.id,
dkgRitual.dkgParams.threshold
);
Expand Down Expand Up @@ -193,7 +192,7 @@ export class CbdTDecDecrypter {
return SessionStaticSecret.random();
}

public toObj(): CbdTDecDecrypterJSON {
public toObj(): ThresholdDecrypterJSON {
return {
porterUri: this.porter.porterUrl.toString(),
ritualId: this.ritualId,
Expand All @@ -209,15 +208,19 @@ export class CbdTDecDecrypter {
porterUri,
ritualId,
threshold,
}: CbdTDecDecrypterJSON) {
return new CbdTDecDecrypter(new Porter(porterUri), ritualId, threshold);
}: ThresholdDecrypterJSON) {
return new ThresholdDecrypter(
new PorterClient(porterUri),
ritualId,
threshold
);
}

public static fromJSON(json: string) {
return CbdTDecDecrypter.fromObj(fromJSON(json));
return ThresholdDecrypter.fromObj(fromJSON(json));
}

public equals(other: CbdTDecDecrypter): boolean {
public equals(other: ThresholdDecrypter): boolean {
return (
this.porter.porterUrl.toString() === other.porter.porterUrl.toString()
);
Expand Down
45 changes: 20 additions & 25 deletions src/characters/pre-recipient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@ import { ConditionContext, ConditionExpression } from '../conditions';
import { Keyring } from '../keyring';
import { PolicyMessageKit } from '../kits/message';
import { RetrievalResult } from '../kits/retrieval';
import { base64ToU8Receiver, bytesEquals, toJSON, zip } from '../utils';
import { PorterClient } from '../porter';
import { base64ToU8Receiver, toJSON, zip } from '../utils';

import { Porter } from './porter';

export type PreTDecDecrypterJSON = {
export type PreDecrypterJSON = {
porterUri: string;
policyEncryptingKeyBytes: Uint8Array;
encryptedTreasureMapBytes: Uint8Array;
publisherVerifyingKeyBytes: Uint8Array;
bobSecretKeyBytes: Uint8Array;
};

export class PreTDecDecrypter {
export class PreDecrypter {
// private readonly verifyingKey: Keyring;

constructor(
private readonly porter: Porter,
private readonly porter: PorterClient,
private readonly keyring: Keyring,
private readonly policyEncryptingKey: PublicKey,
private readonly publisherVerifyingKey: PublicKey,
Expand All @@ -41,9 +40,9 @@ export class PreTDecDecrypter {
policyEncryptingKey: PublicKey,
publisherVerifyingKey: PublicKey,
encryptedTreasureMap: EncryptedTreasureMap
): PreTDecDecrypter {
return new PreTDecDecrypter(
new Porter(porterUri),
): PreDecrypter {
return new PreDecrypter(
new PorterClient(porterUri),
new Keyring(secretKey),
policyEncryptingKey,
publisherVerifyingKey,
Expand Down Expand Up @@ -149,7 +148,7 @@ export class PreTDecDecrypter {
});
}

public toObj(): PreTDecDecrypterJSON {
public toObj(): PreDecrypterJSON {
return {
porterUri: this.porter.porterUrl.toString(),
policyEncryptingKeyBytes: this.policyEncryptingKey.toCompressedBytes(),
Expand All @@ -170,9 +169,9 @@ export class PreTDecDecrypter {
encryptedTreasureMapBytes,
publisherVerifyingKeyBytes,
bobSecretKeyBytes,
}: PreTDecDecrypterJSON) {
return new PreTDecDecrypter(
new Porter(porterUri),
}: PreDecrypterJSON) {
return new PreDecrypter(
new PorterClient(porterUri),
new Keyring(SecretKey.fromBEBytes(bobSecretKeyBytes)),
PublicKey.fromCompressedBytes(policyEncryptingKeyBytes),
PublicKey.fromCompressedBytes(publisherVerifyingKeyBytes),
Expand All @@ -182,19 +181,15 @@ export class PreTDecDecrypter {

public static fromJSON(json: string) {
const config = JSON.parse(json, base64ToU8Receiver);
return PreTDecDecrypter.fromObj(config);
return PreDecrypter.fromObj(config);
}

public equals(other: PreTDecDecrypter): boolean {
return (
this.porter.porterUrl.toString() === other.porter.porterUrl.toString() &&
this.policyEncryptingKey.equals(other.policyEncryptingKey) &&
// TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed
bytesEquals(
this.encryptedTreasureMap.toBytes(),
other.encryptedTreasureMap.toBytes()
) &&
this.publisherVerifyingKey.equals(other.publisherVerifyingKey)
);
public equals(other: PreDecrypter): boolean {
return [
this.porter.porterUrl.toString() === other.porter.porterUrl.toString(),
this.policyEncryptingKey.equals(other.policyEncryptingKey),
this.encryptedTreasureMap.equals(other.encryptedTreasureMap),
this.publisherVerifyingKey.equals(other.publisherVerifyingKey),
].every(Boolean);
}
}
8 changes: 4 additions & 4 deletions src/conditions/condition-expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ export class ConditionExpression {
}

public equals(other: ConditionExpression): boolean {
return (
this.version === other.version &&
objectEquals(this.condition.toObj(), other.condition.toObj())
);
return [
this.version === other.version,
objectEquals(this.condition.toObj(), other.condition.toObj()),
].every(Boolean);
}
}
Loading

0 comments on commit a3d6295

Please sign in to comment.