From 5983ed0355dd19429bdfde994aa4b4f2bd4b96a1 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Mon, 4 Sep 2023 09:45:04 +0200 Subject: [PATCH] update after rebase --- src/characters/cbd-recipient.ts | 7 +++-- src/conditions/condition-expr.ts | 11 +------ src/conditions/context/context.ts | 2 +- src/taco.ts | 34 ++++++++++----------- test/unit/cbd-strategy.test.ts | 18 ++++++----- test/unit/conditions/condition-expr.test.ts | 9 ------ test/unit/taco.test.ts | 19 +++++++----- test/utils.ts | 14 ++++----- 8 files changed, 50 insertions(+), 64 deletions(-) diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts index 2dd5f56c7..cdffc8f4d 100644 --- a/src/characters/cbd-recipient.ts +++ b/src/characters/cbd-recipient.ts @@ -14,7 +14,6 @@ import { ethers } from 'ethers'; import { DkgCoordinatorAgent, DkgParticipant } from '../agents/coordinator'; import { ConditionExpression } from '../conditions'; -import { DkgClient, DkgRitual } from '../dkg'; import { PorterClient } from '../porter'; import { fromJSON, objectEquals, toJSON } from '../utils'; @@ -43,12 +42,14 @@ export class ThresholdDecrypter { public async retrieveAndDecrypt( web3Provider: ethers.providers.Provider, conditionExpr: ConditionExpression, - thresholdMessageKit: ThresholdMessageKit + thresholdMessageKit: ThresholdMessageKit, + signer?: ethers.Signer ): Promise { const decryptionShares = await this.retrieve( web3Provider, conditionExpr, - thresholdMessageKit + thresholdMessageKit, + signer ); const sharedSecret = combineDecryptionSharesSimple(decryptionShares); return thresholdMessageKit.decryptWithSharedSecret(sharedSecret); diff --git a/src/conditions/condition-expr.ts b/src/conditions/condition-expr.ts index 64b895c5b..d5e0d0e45 100644 --- a/src/conditions/condition-expr.ts +++ b/src/conditions/condition-expr.ts @@ -2,8 +2,7 @@ import { Conditions as WASMConditions } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; import { SemVer } from 'semver'; -import { fromBytes } from '../../test/utils'; -import { objectEquals, toBytes, toJSON } from '../utils'; +import { objectEquals, toJSON } from '../utils'; import { Condition, @@ -102,14 +101,6 @@ export class ConditionExpression { return this.condition.requiresSigner(); } - public asAad(): Uint8Array { - return toBytes(this.toJson()); - } - - public static fromAad(aad: Uint8Array): ConditionExpression { - return ConditionExpression.fromJSON(fromBytes(aad)); - } - public equals(other: ConditionExpression): boolean { return [ this.version === other.version, diff --git a/src/conditions/context/context.ts b/src/conditions/context/context.ts index 0f1f7fc04..0ef16be08 100644 --- a/src/conditions/context/context.ts +++ b/src/conditions/context/context.ts @@ -51,7 +51,7 @@ export class ConditionContext { if (this.requiresSigner() && !this.signer) { throw new Error( - `Cannot use ${USER_ADDRESS_PARAM} as custom parameter without a signer` + `Cannot use ${USER_ADDRESS_PARAM} as a parameter without a signer` ); } diff --git a/src/taco.ts b/src/taco.ts index 434a587e7..012370279 100644 --- a/src/taco.ts +++ b/src/taco.ts @@ -1,19 +1,16 @@ -import { - Ciphertext, - DkgPublicKey, - ferveoEncrypt, -} from '@nucypher/nucypher-core'; +import { DkgPublicKey, ThresholdMessageKit } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; import { ThresholdDecrypter } from './characters/cbd-recipient'; +import { Enrico } from './characters/enrico'; import { Condition, ConditionExpression } from './conditions'; import { DkgClient } from './dkg'; import { getPorterUri } from './porter'; import { toBytes } from './utils'; export interface TacoMessageKit { - ciphertext: Ciphertext; - aad: Uint8Array; + thresholdMessageKit: ThresholdMessageKit; + conditionExpr: ConditionExpression; // TODO: How do we get rid of these two fields? We need them for decrypting // We ritualId in order to fetch the DKG participants and create DecryptionRequests for them ritualId: number; @@ -45,19 +42,24 @@ export const encryptLight = async ( threshold: number, ritualId: number ): Promise => { - const aad = new ConditionExpression(condition).asAad(); - const ciphertext = ferveoEncrypt(toBytes(message), aad, dkgPublicKey); + const encrypter = new Enrico(dkgPublicKey); + const conditionExpr = new ConditionExpression(condition); + const thresholdMessageKit = await encrypter.encryptMessageCbd( + toBytes(message), + conditionExpr + ); return { - ciphertext, - aad, + thresholdMessageKit, threshold, ritualId, + conditionExpr, }; }; export const decrypt = async ( web3Provider: ethers.providers.Web3Provider, messageKit: TacoMessageKit, + signer?: ethers.Signer, porterUri = getPorterUri('tapir') ): Promise => { const decrypter = ThresholdDecrypter.create( @@ -65,15 +67,11 @@ export const decrypt = async ( messageKit.ritualId, messageKit.threshold ); - const condExpr = ConditionExpression.fromAad(messageKit.aad); - // TODO: We need web3Provider to fetch participants from Coordinator to make decryption requests. - // Removing this dependency is tied to release of ThresholdMessageKit - // Blocked by changes to nucypher-core and nucypher: - // https://github.com/nucypher/nucypher/pull/3194 return decrypter.retrieveAndDecrypt( web3Provider, - condExpr, - messageKit.ciphertext + messageKit.conditionExpr, + messageKit.thresholdMessageKit, + signer ); }; diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts index 54953de67..8e1aabc21 100644 --- a/test/unit/cbd-strategy.test.ts +++ b/test/unit/cbd-strategy.test.ts @@ -10,6 +10,7 @@ import { fakeDkgParticipants, fakeDkgRitual, fakeProvider, + fakeSigner, fakeTDecFlow, fakeUrsulas, makeCohort, @@ -28,8 +29,9 @@ const { } = conditions; // Shared test variables -const aliceSecretKey = SecretKey.fromBEBytes(aliceSecretKeyBytes); -const aliceProvider = fakeProvider(aliceSecretKey.toBEBytes()); +const secretKey = SecretKey.fromBEBytes(aliceSecretKeyBytes); +const provider = fakeProvider(secretKey.toBEBytes()); +const signer = fakeSigner(secretKey.toBEBytes()); const ownsNFT = new ERC721Ownership({ contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', parameters: [3591], @@ -39,7 +41,6 @@ const conditionExpr = new ConditionExpression(ownsNFT); const ursulas = fakeUrsulas(); const variant = FerveoVariant.precomputed; const ritualId = 0; -const web3Provider = fakeProvider(aliceSecretKey.toBEBytes()); const makeCbdStrategy = async () => { const cohort = await makeCohort(ursulas); @@ -55,7 +56,7 @@ async function makeDeployedCbdStrategy() { const getUrsulasSpy = mockGetUrsulas(ursulas); const getExistingRitualSpy = mockGetExistingRitual(mockedDkgRitual); - const deployedStrategy = await strategy.deploy(web3Provider, ritualId); + const deployedStrategy = await strategy.deploy(provider, ritualId); expect(getUrsulasSpy).toHaveBeenCalled(); expect(getExistingRitualSpy).toHaveBeenCalled(); @@ -107,14 +108,14 @@ describe('CbdDeployedStrategy', () => { .encryptMessageCbd(message); // Setup mocks for `retrieveAndDecrypt` - const { decryptionShares } = await fakeTDecFlow({ + const { decryptionShares } = fakeTDecFlow({ ...mockedDkg, message: toBytes(message), conditionExpr, dkgPublicKey: mockedDkg.dkg.publicKey(), thresholdMessageKit, }); - const { participantSecrets, participants } = await fakeDkgParticipants( + const { participantSecrets, participants } = fakeDkgParticipants( mockedDkg.ritualId ); const requesterSessionKey = SessionStaticSecret.random(); @@ -130,9 +131,10 @@ describe('CbdDeployedStrategy', () => { const decryptedMessage = await deployedStrategy.decrypter.retrieveAndDecrypt( - aliceProvider, + provider, conditionExpr, - thresholdMessageKit + thresholdMessageKit, + signer ); expect(getUrsulasSpy).toHaveBeenCalled(); expect(getParticipantsSpy).toHaveBeenCalled(); diff --git a/test/unit/conditions/condition-expr.test.ts b/test/unit/conditions/condition-expr.test.ts index 4d961026f..238020313 100644 --- a/test/unit/conditions/condition-expr.test.ts +++ b/test/unit/conditions/condition-expr.test.ts @@ -186,15 +186,6 @@ describe('condition set', () => { expect(conditionExprFromJson.equals(conditionExprFromJson)).toBeTruthy(); }); - it('serializes to and from aad', () => { - const conditionExpr = new ConditionExpression(rpcCondition); - const conditionExprAad = conditionExpr.asAad(); - const conditionExprFromAad = - ConditionExpression.fromAad(conditionExprAad); - expect(conditionExprFromAad).toBeDefined(); - expect(conditionExprFromAad.equals(conditionExpr)).toBeTruthy(); - }); - it('incompatible version', () => { const currentVersion = new SemVer(ConditionExpression.VERSION); const invalidVersion = currentVersion.inc('major'); diff --git a/test/unit/taco.test.ts b/test/unit/taco.test.ts index 619620202..bfe6ffc1f 100644 --- a/test/unit/taco.test.ts +++ b/test/unit/taco.test.ts @@ -12,8 +12,9 @@ import { fakeDkgParticipants, fakeDkgRitual, fakePorterUri, + fakeProvider, + fakeSigner, fakeTDecFlow, - fakeWeb3Provider, mockCbdDecrypt, mockGetExistingRitual, mockGetParticipants, @@ -40,11 +41,12 @@ describe('taco', () => { it('encrypts and decrypts', async () => { const mockedDkg = fakeDkgFlow(variant, 0, 4, 4); const mockedDkgRitual = fakeDkgRitual(mockedDkg); - const web3Provider = fakeWeb3Provider(aliceSecretKey.toBEBytes()); + const provider = fakeProvider(aliceSecretKey.toBEBytes()); + const signer = fakeSigner(aliceSecretKey.toBEBytes()); const getExistingRitualSpy = mockGetExistingRitual(mockedDkgRitual); const tacoMk = await taco.encrypt( - web3Provider, + provider, message, ownsNFT, mockedDkg.ritualId @@ -55,12 +57,12 @@ describe('taco', () => { const { decryptionShares } = fakeTDecFlow({ ...mockedDkg, message: toBytes(message), - aad: tacoMk.aad, - ciphertext: tacoMk.ciphertext, + conditionExpr: tacoMk.conditionExpr, + dkgPublicKey: mockedDkg.dkg.publicKey(), + thresholdMessageKit: tacoMk.thresholdMessageKit, }); const { participantSecrets, participants } = fakeDkgParticipants( - mockedDkg.ritualId, - variant + mockedDkg.ritualId ); const requesterSessionKey = SessionStaticSecret.random(); const decryptSpy = mockCbdDecrypt( @@ -73,8 +75,9 @@ describe('taco', () => { const sessionKeySpy = mockRandomSessionStaticSecret(requesterSessionKey); const decryptedMessage = await taco.decrypt( - web3Provider, + provider, tacoMk, + signer, fakePorterUri ); expect(getParticipantsSpy).toHaveBeenCalled(); diff --git a/test/utils.ts b/test/utils.ts index 0e4eb342c..adb1cb2a9 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -315,7 +315,7 @@ interface FakeDkgRitualFlow { thresholdMessageKit: ThresholdMessageKit; } -export const fakeTDecFlow = async ({ +export const fakeTDecFlow = ({ validators, validatorKeypairs, ritualId, @@ -375,7 +375,7 @@ const fakeConditionExpr = () => { return new ConditionExpression(erc721Balance); }; -export const fakeDkgTDecFlowE2E = async ( +export const fakeDkgTDecFlowE2E = ( ritualId = 0, variant: FerveoVariant = FerveoVariant.precomputed, conditionExpr: ConditionExpression = fakeConditionExpr(), @@ -390,7 +390,7 @@ export const fakeDkgTDecFlowE2E = async ( conditionExpr ); - const { decryptionShares, authenticatedData } = await fakeTDecFlow({ + const { decryptionShares, authenticatedData } = fakeTDecFlow({ ...ritual, message, conditionExpr, @@ -442,13 +442,13 @@ export const fakeCoordinatorRitual = async ( }; }; -export const fakeDkgParticipants = async ( +export const fakeDkgParticipants = ( ritualId: number -): Promise<{ +): { participants: DkgParticipant[]; participantSecrets: Record; -}> => { - const ritual = await fakeDkgTDecFlowE2E(ritualId); +} => { + const ritual = fakeDkgTDecFlowE2E(ritualId); const label = toBytes(`${ritualId}`); const participantSecrets: Record =