Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

So normally if you do encrypt('a') twice in a row you'll get the same result. But sometimes (as is the case in SSH) this is not desirable. You want encrypt('a') + encrypt('a') == encrypt('aa'). What is this called?

PHP does it with mcrypt:

<?php 
$mcrypt = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, ''); 
    mcrypt_generic_init($mcrypt, '@@@@@@@@', 'xxxxxxxx'); 
echo bin2hex(mcrypt_generic($mcrypt, 'dddddddd')); 
    echo "\r\n"; 
    echo bin2hex(mcrypt_generic($mcrypt, 'dddddddd'));

eg. you're encrypting dddddddd twice but getting a different result each time.

PHP does not do it with OpenSSL:

echo bin2hex(openssl_encrypt('dddddddd', 'des-cbc', '@@@@@@@@', OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, 'xxxxxxxx')); 
echo "\r\n"; 
echo bin2hex(openssl_encrypt('dddddddd', 'des-cbc', '@@@@@@@@', OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, 'xxxxxxxx'));

Given the API it makes since that OpenSSL wouldn't do it. It can certainly be emulated by changing the IV's but you'd have to do it manually.

Anyway, what is this called? Is it called progressive encryption? Continuous encryption?

share|improve this question
3  
What has the mentioned "encrypt('a') + encrypt('a') == encrypt('aa')" to do with the question? I don't really know what you're asking. Dou you want an encryption which would have two added (adding like in a sum or adding like in concatenating?) encryptions of the same input to be equal to the encryption of the concatenated inputs? Or do you want an encryption which output changes every time you encrypt something? If it is the last: Every good cipher operation mode like CBC should do that. –  Nova Jan 2 at 15:29
    
yyyyyyy seemed to understand the question just fine. You asked three questions so I'll answer them in order. For #2... no. I know how to do that. See the first of the two code samples I posted. For #3... see the second code snippet I posted. The output, in that example, does not change, even tho I'm encrypting the same thing twice. As I said in my OP this makes since given the API. I was just wanting to know how best to refer to the difference between the two code samples. Both code samples do CBC mode but only one of them gives different outputs for each "block". –  neubert Jan 2 at 15:45
2  
I still have no idea what the whole "encrypt('a') + encrypt('a') == encrypt('aa')" thing has to do with the question. No, I didn't ask three questions. The "last two questions" were only one, a whether-or question. You use two different cipher suits and get different output. Sounds pretty clear for me. Look for the definition of the two functions. –  Nova Jan 2 at 15:53
2  
@neubert: Concatenation only makes sense if we assume that a is exactly one block wide and the whole function doesn't has any further padding. The whole code is not purposeful, the whole question would be easier if you write: "How is the characteristic called if "encrypt('a') || encrypt('a') == encrypt('aa')" for "a" as a whole block and "encrypt" as normal block cipher with zero padding." (I did change the + to ||. That's (as far as I know) more common for concatenation. –  Nova Jan 2 at 18:20
1  
@neubert To be fair, I was also confused what you meant. You're in a forum with a variety of backgrounds. Most of us aren't PHP programmers and don't assume the + operator means string concatenation. There's a danger in assuming a context that "makes sense". It might make sense to you in a certain context, but you're always making assumptions for it to "make sense". That's why people prefer well defined problems, since you don't have to make assumptions that may or may not be accurate. –  Steve Sether Jan 6 at 17:29

4 Answers 4

up vote 2 down vote accepted

I don't think there is a dedicated name for this. If I had to find a word, it would probably be "stateful" or "with explicit state". What you observe is actually the usual case: The user initializes an encryption system with a key, resulting in some state of the system. Then, each time the user wishes to encrypt some data, he has to pass the current state along with it and the state gets updated by the encryption function. This way, one can encrypt messages that arrive in multiple pieces over time, resulting in greater flexibility (think live streaming!).

In your mcrypt example, the initialization is performed by mcrypt_generic_init, the state is stored in $mcrypt, and encryption is done by mcrypt_generic. In other languages, the state is encapsuled in "cipher objects", like those provided by, for instance, Python's Crypto.Cipher.* classes.

Then, there are special functions, like the OpenSSL example you provided, that are designed to encrypt just one single blob of data. They accept a key and a message as an argument and perform state initialization and encryption in one step, afterwards discarding the state and returning the ciphertext. The state is not exposed to the user, so he cannot continue encrypting more data. These functions exist solely for convenience, providing a simpler interface for the common case of encrypting one opaque message.

share|improve this answer
    
The user doesn't quite initialize with a key, they initialize with an IV (normally). The difference is that an IV is not secret. –  cpast Jan 2 at 18:00
    
That's not true. The user always supplies a key (what else would the algorithm use to encrypt data?), and depending on the particular cryptosystem, an IV may be needed in addition. This is of course heavily implementation-dependent, so other views might be valid as well. –  yyyyyyy Jan 2 at 18:13
    
But the key isn't used to initialize the state, at least for block ciphers; the state would be what carries over between blocks (changing with each block), while the key is the same for all blocks. –  cpast Jan 2 at 19:55
    
For instance, ECB has a key but is not stateful in this sense; the nonsecret IV is what lets CBC and other good modes achieve multiple ciphertexts for one plaintext and key. –  cpast Jan 2 at 20:03
    
Well, I guess we are both right. I was talking mainly about the way things are usually implemented, since the question was a very practical one (and mcrypt_generic_init, among many more examples, does expect both key and IV). You are right that in theoretical contexts, one usually does not consider the key part of the state; I guess this discrepancy is due to theory arguing mostly about one key/communication while implementations might have to deal with many simultaneous connections using different keys, so it is quite obvious to keep the key in the cipher state. –  yyyyyyy Jan 2 at 20:18

Your example is missing something: your two calls to the OpenSSL library are entirely entirely independent, but your calls to the mcrypt library reuse an existing handle. CBC has the property that identical plaintext blocks are exceedingly unlikely to encrypt to the same value due to chaining of the previous output into the next input.

Your OpenSSL calls cannot do this, because you are not preserving the CBC state between calls; two independent instances of the cipher are being initialized and used.

Additionally, even in independent calls, you almost never want encrypt('a') == encrypt('a'); this invalidates semantic security, and in many practical cryptosystems it allows an attacker to conduct a blockwise-adaptive chosen plaintext attack, which reveals the non-chosen plaintext contents. This is the fundamental reason why encryption modes use initialization vectors (which are non-secret, must be unique for the given key, and depending on the mode may need to be unpredictable): to ensure the encryption function has unique inputs even when the plaintext and key are the same.

share|improve this answer

In addition to yyyyyyy's answer, there is also probabilistic encryption, in which the encryption process incorporates some randomness. That allows many identical messages with the same key to be encrypted differently; it doesn't necessarily encrypt the same text differently in the same message (it might encrypt $a+a$ as $E(a)+E(a)$), but it does let you send the same plaintext multiple times with the same key without having it be the same ciphertext.

Probabilistic encryption is often done with stateful ciphers (by using a random and not-secret initialization vector to initialize the state of the cipher); it can also be done with hybrid crypto (a random key for the symmetric encryption), and certain algorithms are always probabilistic (e.g. ElGamal). Probabilistic encryption is different than just keeping track of state; you can do probabilistic encryption without keeping track of state (e.g. if you do hybrid encryption and your symmetric encryption is done in ECB mode, so within one message two identical blocks encrypt identically), and can keep track of state without doing probabilistic encryption (e.g. CBC mode with a fixed IV).

You mention that you'd have to change the IVs to get OpenSSL to do this; that's because you're supposed to change the IV every time you encrypt a new message. IVs are not secret, so you can just generate a new one for every message.

share|improve this answer

it's called homomorphic cryptography. A fully homomorphic cryptosystem allows E(a) +/* E(b) = E(a +/* b). This implies operations on encrypted data, which is a nice thing to have, an example is storing E(a) and E(b) on the server and you can query the server for E(a+b) without exposing plaintext a and b. This is an active research area since first practical solution of Gentry was done in 2009...

share|improve this answer
2  
The term "homomorphic encryption" is usually only applied to ring- or group-homomorphic encryptions, which is not what the question is about. –  yyyyyyy Jan 2 at 23:50
    
They are applied in general too. It is called "Partially Homomorphic Encryption" to be precise ! –  sashank Jan 3 at 2:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.