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

Diverge link methods #346

Merged
merged 5 commits into from
Feb 13, 2024
Merged

Diverge link methods #346

merged 5 commits into from
Feb 13, 2024

Conversation

samtay
Copy link
Contributor

@samtay samtay commented Feb 12, 2024

I had merged the notions of referencing an existing message in SDLP and in ZKP. This doesn't make sense and also imposes unnecessarily limitations. This PR separates the two notions.

api

Essentially the API looks like this (with each one also having a corresponding symmetric version):

impl Builder {
    /// Encrypt a plaintext, adding the encryption statement to the proof.
    pub fn encrypt<P>(&mut self, message: &P, public_key: &'k PublicKey) -> Result<Ciphertext>
        where
            P: TryIntoPlaintext + TypeName;

    /// Encrypt a plaintext, adding the encryption statement to the proof and returning the
    /// message to optionally be [encrypted again](`Self::encrypt_again`), that is, _shared_
    /// with another proof statement.
    pub fn encrypt_and_share<P>(&mut self, message: &P, public_key: &'k PublicKey) -> Result<(Ciphertext, Message)>
        where
            P: TryIntoPlaintext + TypeName;

    /// Encrypt a plaintext intended for linking.
    ///
    /// The returned `LinkedMessage` can be used:
    /// 1. to add an encryption statement of ciphertext equality to the proof (see [`Self::encrypt_again`]).
    /// 2. as a linked input to a ZKP program (see [`Self::linked_input`]).
    pub fn encrypt_and_link<P>(&mut self, message: &P, public_key: &'k PublicKey) -> Result<(Ciphertext, LinkedMessage)>
        where
            P: LinkWithZkp + TryIntoPlaintext + TypeName;

    /// Encrypt an existing message, adding the new encryption statement to the proof.
    ///
    /// This method purposefully reveals that two ciphertexts encrypt the same underlying value. If
    /// this is not what you want, use [`Self::encrypt`].
    pub fn encrypt_again<E>(&mut self, message: &E, public_key: &'k PublicKey) -> Result<Ciphertext>
        where
            E: ExistingMessage;
}

other ideas

I played with some other ideas, like using a singular Message<T = ()> and type LinkedMessage = Message<Link> rather than the sealed ExistingMessage trait. We do use that pattern elsewhere so it wouldn't be inconsistent to do so, but in the end I thought above was simpler. I also considered always returning a Message from these methods, where Message can be converted into a ciphertext, but again thought it was not as clear as the above.

Let me know what you think regarding ExistingMessage vs Message<T>, I could go either way.

Copy link
Contributor

@ryanorendorff ryanorendorff left a comment

Choose a reason for hiding this comment

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

This is mostly bike shedding around which proof system is being referenced. Potentially we could call encrypt_and_share as encrypt_and_reuse_message and encrypt_and_link could be encrypt_and_send_to_zkp_program. I don't know if there is an awesome way to differentiate the two ZKP methods without making it confusing to the user that there are two, but maybe that is because we know too much 😆 .

sunscreen_runtime/src/builder.rs Outdated Show resolved Hide resolved
@samtay
Copy link
Contributor Author

samtay commented Feb 13, 2024

Updated the naming to the following:

impl Builder {
    /// Encrypt a plaintext, adding the encryption statement to the logproof.
    pub fn encrypt<P>(&mut self, message: &P, public_key: &'k PublicKey) -> Result<Ciphertext>
        where
            P: TryIntoPlaintext + TypeName;

    /// Encrypt a plaintext, adding the encryption statement to the logproof and returning the
    /// message to optionally be [encrypted again](`Self::encrypt_again`), that is, _shared_
    /// with another proof statement.
    pub fn encrypt_returning_msg<P>(&mut self, message: &P, public_key: &'k PublicKey) -> Result<(Ciphertext, Message)>
        where
            P: TryIntoPlaintext + TypeName;

    /// Encrypt a plaintext intended for linking.
    ///
    /// The returned `LinkedMessage` can be used:
    /// 1. to add an encryption statement of ciphertext equality to the logproof (see [`Self::encrypt_again`]).
    /// 2. as a linked input to a ZKP program (see [`Self::linked_input`]).
    pub fn encrypt_returning_link<P>(&mut self, message: &P, public_key: &'k PublicKey) -> Result<(Ciphertext, LinkedMessage)>
        where
            P: LinkWithZkp + TryIntoPlaintext + TypeName;

    /// Encrypt an existing message, adding the new encryption statement to the logproof.
    ///
    /// This method purposefully reveals that two ciphertexts encrypt the same underlying value. If
    /// this is not what you want, use [`Self::encrypt`].
    pub fn encrypt_msg<E>(&mut self, message: &E, public_key: &'k PublicKey) -> Result<Ciphertext>
        where
            E: ExistingMessage;
}

@samtay samtay enabled auto-merge (squash) February 13, 2024 16:16
@samtay samtay merged commit 14ce61f into main Feb 13, 2024
4 checks passed
@ryanorendorff ryanorendorff deleted the samtay/diverge_link_methods branch February 13, 2024 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants