-
Notifications
You must be signed in to change notification settings - Fork 5
Description
(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
- Add data classes
OpaqueCiphertext(etc.) that contain aRepresentationobject. Add methodsOpaqueCiphertext encryptOpaque(OpaquePlaintext, OpaqueEncryptionKey)(etc.) to theEncryptionSchemeinterface with adefaultimplementation that callsencryptand wraps theRepresentationof the result in anOpaqueCiphertext. - Make opaque types the norm (i.e.
Ciphertextthat is returned byencryptdoes not contain scheme-specific group elements, but is just this generic data class). Add a method toEncryptionSchemethat converts an opaque type to a transparent type (containing group elements). - Keep both worlds intact, write an
OpaqueEncryptionSchemethat generically wraps anEncryptionSchemeand outputsOpaqueCiphertextfor itsencrypt(). - [at]feidens: We can give the
Ciphertextthe ability to create anOpaqueCiphertextgiven the scheme.
If someone wants to send it over the wire he callsgetOpaqueCiphertext.
(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
- We can give the
Ciphertextthe ability to create anOpaqueCiphertextgiven the scheme.
If someone wants to send it over the wire he calls getOpaqueCiphertext.
Comment by Jan Bobolz
We can give the
Ciphertextthe ability to create anOpaqueCiphertextgiven the scheme.
Good suggestion! I like it.