Skip to content

Opaque signatures, ciphertexts, etc. #61

@rheitjoh

Description

@rheitjoh

(This issue has been imported from the Gitlab repository because it seems to not have been addressed yet)

Original Text (Issue 185)

Using the example of ciphertexts: currently, the contract for EncryptionScheme is that encrypt returns a Ciphertext. A Ciphertext contains (usually) several group elements. The ciphertext can be serialized by calling getRepresentation() on it and deserialized by calling EncryptionScheme::getCiphertext(Representation).

Some applications may not care about the exact structure of the Ciphertext that they are given. For them, this flow looks like this:

EncryptionScheme --Ciphertext--> [internal stuff] --Ciphertext--> webserver software --Representation--> network
... network receiver --Representation--> webserver software --Representation--> ... --Representation--> EncryptionScheme

So when internally passing around the object on the receiver side, it has type Representation, which defies type safety. This is because it can only be deserialized to anything with proper type when it eventually reaches the EncryptionScheme.

This ticket suggests to introduce the notion of opaque objects for things like ciphertexts, signatures, etc.
An OpaqueCiphertext would basically be a fancy byte[], i.e. it has no well-defined structure and it's easily serializable through any standard serialization frameworks without knowledge of any groups etc.
Suppose encryptOpaque outputs an OpaqueCiphertext. Now the picture above looks more sane:

EncryptionScheme --OpaqueCiphertext--> [internal stuff] --OpaqueCiphertext--> webserver software --byte[]--> network
... network receiver --byte[]--> webserver software --OpaqueCiphertext--> ... --OpaqueCiphertext--> EncryptionScheme

Now all parties can properly talk about ciphertexts that they're handing around. This makes it more clear what's going on.
The simplest way of implementing an OpaqueCiphertext is as a data class containing exactly Ciphertext.getRepresentation().

There are several ways to go about this

  1. Add data classes OpaqueCiphertext (etc.) that contain a Representation object. Add methods OpaqueCiphertext encryptOpaque(OpaquePlaintext, OpaqueEncryptionKey) (etc.) to the EncryptionScheme interface with a default implementation that calls encrypt and wraps the Representation of the result in an OpaqueCiphertext.
  2. Make opaque types the norm (i.e. Ciphertext that is returned by encrypt does not contain scheme-specific group elements, but is just this generic data class). Add a method to EncryptionScheme that converts an opaque type to a transparent type (containing group elements).
  3. Keep both worlds intact, write an OpaqueEncryptionScheme that generically wraps an EncryptionScheme and outputs OpaqueCiphertext for its encrypt().
  4. [at]feidens: We can give the Ciphertext the ability to create an OpaqueCiphertext given the scheme.
    If someone wants to send it over the wire he calls getOpaqueCiphertext.

(1) looks a bit weirder to users of a generic encryption scheme (as they need to call "encryptOpaque" instead of encrypt for their standard use case, which is somewhat unintuitive). (2) looks a bit weird for the programmer of the EncryptionScheme, as they need to output their ciphertext not as a nice assortment of group elements, but as some opaque bit string stuff. (3) may be somewhat difficult to explain to people why they should instantiate the wrapper instead of the actual EncryptionScheme.

So overall, we have two groups of people: those who just use encryption generically (those would prefer OpaqueCiphertexts to be the "standard" thing) and those who do stuff like proving knowledge of ciphertexts (those would prefer our current Ciphertexts to be the "standard" thing).

Comment by Fabian Eidens

  1. We can give the Ciphertext the ability to create an OpaqueCiphertext given the scheme.

If someone wants to send it over the wire he calls getOpaqueCiphertext.

Comment by Jan Bobolz

We can give the Ciphertext the ability to create an OpaqueCiphertext given the scheme.

Good suggestion! I like it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GitlabOld issue moved over from Gitlab repository

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions