Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement local ritual verification #232

Closed
wants to merge 0 commits into from
Closed

Conversation

piotr-roslaniec
Copy link
Contributor

@piotr-roslaniec piotr-roslaniec commented Jun 29, 2023

Type of PR:

  • Feature

Required reviews:

  • 2

What this does:

  • Introduces local ritual verification using hard-coded keys

Issues fixed/closed:

  • Fixes #...

Why it's needed:

  • Allows client to verify ritual correctness before performing decryption etc.

Notes for reviewers:

@codecov-commenter
Copy link

codecov-commenter commented Jun 29, 2023

Codecov Report

Merging #232 (c982702) into tdec-epic (d9d957e) will decrease coverage by 1.08%.
The diff coverage is 48.64%.

@@              Coverage Diff              @@
##           tdec-epic     #232      +/-   ##
=============================================
- Coverage      83.24%   82.17%   -1.08%     
=============================================
  Files             37       37              
  Lines            979     1004      +25     
  Branches         123      126       +3     
=============================================
+ Hits             815      825      +10     
- Misses           158      173      +15     
  Partials           6        6              
Impacted Files Coverage Δ
src/agents/subscription-manager.ts 17.39% <0.00%> (ø)
src/dkg.ts 40.74% <14.28%> (-9.26%) ⬇️
src/agents/coordinator.ts 41.37% <66.66%> (+15.06%) ⬆️
src/characters/cbd-recipient.ts 90.76% <75.00%> (-2.46%) ⬇️
src/sdk/strategy/cbd-strategy.ts 100.00% <100.00%> (ø)

@nucypher nucypher deleted a comment from github-actions bot Jun 29, 2023
@nucypher nucypher deleted a comment from github-actions bot Jun 29, 2023
@piotr-roslaniec piotr-roslaniec marked this pull request as ready for review June 29, 2023 13:18
@piotr-roslaniec piotr-roslaniec changed the title Implement local ritual verification Implement local ritual verification with hard-coded keys on lynx Jun 29, 2023
@nucypher nucypher deleted a comment from github-actions bot Jun 29, 2023
@derekpierre derekpierre requested a review from cygnusv June 29, 2023 14:31
src/agents/coordinator.ts Outdated Show resolved Hide resolved
);
}

const isLocallyVerified = await DkgClient.verifyRitual(
Copy link
Member

@derekpierre derekpierre Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether this needs to be done every time retrieve is called. Perhaps this should be optional i.e. provided as a parameter to retrieve(...). It's unclear to me whether the default value should be True or False (cc @cygnusv ).

Copy link
Contributor Author

@piotr-roslaniec piotr-roslaniec Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think true is a sensible default since the security of the user depends on local verification.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe. Technically if the ritual made it to completion, then the validation was crowd-sourced to all of the nodes in the cohort and was fine..., no? This is for the unlikely case that the entire cohort was malicious - since any one non-malicious Ursula would have prevented the DKG ritual from completing.

Copy link
Contributor Author

@piotr-roslaniec piotr-roslaniec Jun 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can only know if the participants contributed the correct transcripts once we perform the verification. I don't think there is any other mechanism in place at the moment. For example, how would a non-malicious Ursula prevent the ritual from completing? I don't see this implemented in the Coordinator contract.

Notice how without verification it's also possible for malicious Ursulas to shut down any ritual without any accountability, etc.

I think in order to address this we need to discuss the scope of configuration sets ("packages") we want to ship and then backtrack how rituals are supposed to work on the client side from there. In principle, for every ritual (or for every kind of ritual) local verification has to be performed at least once, at any point in time, before consuming the ritual. That should apply to every usage scenario, so perhaps this is something we could start with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would moving the ritual verification step to CbdTDecDecrypter.create would be a good temporary solution?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, how would a non-malicious Ursula prevent the ritual from completing? I don't see this implemented in the Coordinator contract.

This is done by the honest Ursula providing a correct aggregated transcript that does match the others (from malicious nodes) - https://github.com/nucypher/nucypher-contracts/blob/main/contracts/contracts/coordination/Coordinator.sol#L228. This is why currently the protocol only needs one honest Ursula out of the n nodes in the cohort. Subsequently, if all aggregated transcripts match, then ritual state is then set to finalized. Knowing that the state is finalized, means that either all nodes were malicious (probabilistically unlikely for larger-sized cohorts though not 0%) or that everything was good/correct.

To be clear, local verification is good as an option 👍 , I don't know/am unsure that we want it to be done every time which is the current set-up; should someone be explicit (default parameter is False and they have to specifically set it to True) about checking it versus being implicit (default to True and they have to specifically set it to False). In the long term, local verification would not be used at all because the protocol would be even more robust in the future (slashing, proofs, on-chain verification etc.), so having the default be False and adopters having to change to True could make sense - it's just something we should think about.... what do others think @cygnusv , @KPrasch ?

Side question: how long does the local verification take?

Would moving the ritual verification step to CbdTDecDecrypter.create would be a good temporary solution?

Interesting. That would seem to be a better spot since the verification would only be done once per encrypter, and is more hidden from the user. That being said, I still have questions about doing local verification in general, but it would definitely be an improvement, and seemingly more hidden from the user. Nice suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done by the honest Ursula providing a correct aggregated transcript

Thanks for explaining that, I just started working on Coordinator changes and didn't have a clear picture there.

Side question: how long does the local verification take?

The complexity ceiling is a single BLS12-381 pairing, so an order of tens of milliseconds.

src/dkg.ts Outdated Show resolved Hide resolved
src/dkg.ts Outdated
Comment on lines 146 to 212
public static getParticipantPublicKey = (address: string) => {
// TODO: Without Validator public key in Coordinator, we cannot verify the
// transcript. We need to add it to the Coordinator (nucypher-contracts #77).
const participantPublicKeys: Record<string, FerveoPublicKey> = {
'0x210eeAC07542F815ebB6FD6689637D8cA2689392': FerveoPublicKey.fromBytes(
fromHexString(
'6000000000000000ace9d7567b26dafc512b2303cfdaa872850c62b100078ddeaabf8408c7308b3a43dfeb88375c21ef63230fb4008ce7e908764463c6765e556f9b03009eb1757d179eaa26bf875332807cc070d62a385ed2e66e09f4f4766451da12779a09036e'
)
),
'0xb15d5A4e2be34f4bE154A1b08a94Ab920FfD8A41': FerveoPublicKey.fromBytes(
fromHexString(
'60000000000000008b373fdb6b43e9dca028bd603c2bf90f0e008ec83ff217a8d7bc006b585570e6ab1ce761bad0e21c1aed1363286145f61134ed0ab53f4ebaa05036396c57f6e587f33d49667c1003cd03b71ad651b09dd4791bc631eaef93f1b313bbee7bd63a'
)
),
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this in a test with mocks etc. instead of having hardcoded values in actual code and subsequently going stale?

Copy link
Contributor Author

@piotr-roslaniec piotr-roslaniec Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until we fix nucypher/nucypher-contracts#77 we can:

  1. Expose this as a parameter
  2. Fetch it from Ursulas
  3. Hardcode it

Either way, this is going to be superseded by changes in the contract and shouldn't remain in the source code for too long. We can also put a pause on this PR and update it after deploying changes from nucypher/nucypher-contracts#77

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My vote would be the pause until nucypher/nucypher-contracts#77 is dealt with. This PR would then be a downstream change. Note that PR 77 would also have downstream effects on nucypher.

I'd like to avoid hard-coding things that we know will change in actual code; tests are one thing, but in actual code it should be avoided if possible.

Copy link
Contributor Author

@piotr-roslaniec piotr-roslaniec Jul 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Let's keep this PR reviewed & open, and reconsider merging after downstream changes are dealt with. I will document them where appropriate.

src/dkg.ts Outdated
shares: number;
threshold: number;
}
): Promise<DkgRitual> {
const ritualId = 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume all of this is only for testing. Is this something that can be moved to tests / mocked in tests instead of including it in actual code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My assumption was that for the time being we're going to operate on a set of premade rituals, and right now we only have one

Copy link
Contributor Author

@piotr-roslaniec piotr-roslaniec Jun 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought I think it's reasonable to expose ritualId as a parameter at least within the SDK. I will add this change and changes related to ritual initialization (which should work on lynx now) in a separate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in #233

@github-actions
Copy link

Bundled size for the package is listed below:

build/module/types/ethers-contracts/factories: 82.03 KB
build/module/types/ethers-contracts: 152.34 KB
build/module/types: 156.25 KB
build/module/src/conditions/predefined: 19.53 KB
build/module/src/conditions/context: 42.97 KB
build/module/src/conditions/base: 54.69 KB
build/module/src/conditions: 156.25 KB
build/module/src/kits: 19.53 KB
build/module/src/agents: 35.16 KB
build/module/src/characters: 93.75 KB
build/module/src/policies: 19.53 KB
build/module/src/sdk/strategy: 31.25 KB
build/module/src/sdk: 46.88 KB
build/module/src: 441.41 KB
build/module/test: 46.88 KB
build/module: 699.22 KB
build/main/types/ethers-contracts/factories: 82.03 KB
build/main/types/ethers-contracts: 152.34 KB
build/main/types: 156.25 KB
build/main/src/conditions/predefined: 19.53 KB
build/main/src/conditions/context: 42.97 KB
build/main/src/conditions/base: 54.69 KB
build/main/src/conditions: 156.25 KB
build/main/src/kits: 19.53 KB
build/main/src/agents: 35.16 KB
build/main/src/characters: 93.75 KB
build/main/src/policies: 19.53 KB
build/main/src/sdk/strategy: 31.25 KB
build/main/src/sdk: 46.88 KB
build/main/src: 445.31 KB
build/main/test: 46.88 KB
build/main: 703.13 KB
build: 1.37 MB

Copy link
Member

@manumonti manumonti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! ✌️

@piotr-roslaniec piotr-roslaniec added the do not merge Open for review but do not merge please label Jul 7, 2023
@piotr-roslaniec piotr-roslaniec changed the title Implement local ritual verification with hard-coded keys on lynx Implement local ritual verification Jul 7, 2023
Base automatically changed from tdec-epic to alpha July 10, 2023 10:39
@piotr-roslaniec piotr-roslaniec deleted the local-verification branch August 3, 2023 14:14
@piotr-roslaniec piotr-roslaniec restored the local-verification branch August 3, 2023 14:14
@piotr-roslaniec
Copy link
Contributor Author

So the original issue was caused by rebasing branches in the wrong order, i.e. local-verification should have been rebased over alpha. Instead, I rebased alpha over local-verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge Open for review but do not merge please
Projects
Status: Completed
Development

Successfully merging this pull request may close these issues.

4 participants