#pike __REAL_VERSION__ |
#pragma strict_types |
|
|
|
|
|
|
|
|
|
|
|
inherit .Cipher; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected class _CTR |
{ |
|
|
inherit .Cipher; |
|
|
string(7bit) name() |
{ |
return global::name() + ".CTR"; |
} |
|
|
class State |
{ |
inherit ::this_program; |
|
protected zero|global::State obj; |
protected zero|Gmp.mpz iv; |
protected int(0..) _block_size; |
|
protected void create() |
{ |
obj = global::State(); |
_block_size = obj->block_size(); |
iv = Gmp.mpz(0); |
} |
|
string(8bit) name() |
{ |
return obj->name() + ".CTR"; |
} |
|
int(1..) block_size() |
{ |
return [int(1..)]_block_size; |
} |
|
int(1..) iv_size() |
{ |
return [int(1..)]_block_size; |
} |
|
int(0..) key_size() |
{ |
return obj->key_size(); |
} |
|
this_program set_encrypt_key(string(8bit) key, int|void flags) |
{ |
String.secure(key); |
obj->set_encrypt_key(key, flags); |
return this; |
} |
|
this_program set_decrypt_key(string(8bit) key, int|void flags) |
{ |
String.secure(key); |
obj->set_encrypt_key(key, flags); |
return this; |
} |
|
this_program set_iv(string(8bit) iv) |
{ |
String.secure(iv); |
this::iv = Gmp.mpz(iv, 256); |
} |
|
string(8bit) crypt(string(8bit) data) |
{ |
int len = sizeof(data); |
String.Buffer buf = String.Buffer(len); |
while (len > 0) { |
string(8bit) chunk = iv->digits(256); |
iv++; |
if (sizeof(chunk) < _block_size) { |
chunk = "\0"*(_block_size - sizeof(chunk)) + chunk; |
} |
chunk = obj->crypt(chunk); |
buf->add(chunk[..len-1]); |
len -= _block_size; |
} |
return [string(8bit)](data ^ (string(8bit))buf); |
} |
} |
|
protected State `()() |
{ |
return State(); |
} |
|
|
} |
|
_CTR CTR = _CTR(); |
|
|
|