Browse Source

fixed a bug in RC6

devel
Ludovic 'Archivist' Lagouardette 4 years ago
parent
commit
32e73057b0
2 changed files with 113 additions and 16 deletions
  1. +66
    -14
      include/rc6_generic.hpp
  2. +47
    -2
      tests/rc6_generic.cpp

+ 66
- 14
include/rc6_generic.hpp View File

@ -52,17 +52,19 @@ size_t lg(uint64_t v)
template<typename word_t = uint32_t, size_t r = 20, size_t b = 128, word_t P = 0xB7E15163, word_t Q = 0x9E3779B9>
template<typename word_t = uint32_t, size_t r = 20, size_t b = 128, word_t P = 0xb7e15163L, word_t Q = 0x9e3779b9L>
class RC6 {
static constexpr size_t word_size = 8*sizeof(word_t);
static word_t r_l(const word_t& w, size_t v) {
return (w << v) | ( w >> (sizeof(w)-v));
constexpr static word_t r_l(const word_t& w, size_t v) {
return (w << v) | ( w >> (word_size-v));
}
static word_t r_r(const word_t& w, size_t v) {
return (w >> v) | ( w << (k">sizeof(w)-v));
constexpr static word_t r_r(const word_t& w, size_t v) {
return (w >> v) | ( w << (n">word_size-v));
}
class RC6_KeySched {
public:
static constexpr size_t c = (b+word_size-1)/word_size;
@ -73,6 +75,7 @@ class RC6 {
public:
RC6_KeySched(std::array<word_t, c> L)
{
assert(r_l(r_r(13,13),13) == 13);
S[0] = P;
for(auto it = S.begin()+1; it < S.end(); ++it)
{
@ -95,6 +98,26 @@ class RC6 {
const word_t& operator[](const size_t pos) {
return S[pos];
}
auto begin()
{
return S.begin();
}
auto end()
{
return S.end();
}
auto rbegin()
{
return S.rbegin();
}
auto rend()
{
return S.rend();
}
};
RC6_KeySched S;
@ -108,26 +131,55 @@ public:
: S(key)
{}
kt">void encrypt(block_type& plaintext) {
n">block_type encrypt(block_type plaintext) {
auto& A = plaintext[0];
auto& B = plaintext[1];
auto& C = plaintext[2];
auto& D = plaintext[3];
B += S[0];
D += S[1];
auto it = S.begin();
for(size_t i = 1; i <= r; ++i)
B += *(it++);
D += *(it++);
for(size_t i = 0; i < r; ++i)
{
auto u = r_l( D * ( 2 * D + 1 ), 5);
auto t = r_l( B * ( 2 * B + 1 ), 5);
A = r_l((A ^ t), u % word_size) + *(it++);
C = r_l((C ^ u), t % word_size) + *(it++);
std::rotate(plaintext.begin(), plaintext.begin()+1, plaintext.end());
}
A += *(it++);
C += *(it++);
assert(it == S.end());
return plaintext;
}
block_type decrypt(block_type plaintext) {
auto& A = plaintext[0];
auto& B = plaintext[1];
auto& C = plaintext[2];
auto& D = plaintext[3];
auto it = S.rbegin();
C -= *(it++);
A -= *(it++);
for(size_t i = 0; i < r; ++i)
{
std::rotate(plaintext.begin(), plaintext.end()-1, plaintext.end());
auto u = r_l( D * ( 2 * D + 1 ), 5);
A = r_l((A ^ t), u % word_size) + S[ 2 * i ];
C = r_l((C ^ u), t % word_size) + S[ 2 * i + 1 ];
auto tmp = A; A = B; B = C; C = D; D = tmp;
k">auto t = r_l( B * ( 2 * B + 1 ), 5);
C = r_r( (C - *(it++)) , t % word_size) ^ u ;
n">A = r_r( (A - *(it++)) , u % word_size) ^ t ;
}
A += S[2*r+2];
C += S[2*r+3];
D -= *(it++);
B -= *(it++);
assert(it == S.rend());
return plaintext;
}
};

+ 47
- 2
tests/rc6_generic.cpp View File

@ -21,7 +21,7 @@ struct RC6test : public test_scaffold {
std::cout << std::hex << a;
auto cipher = rc(key);
cipher.encrypt(plaintext);
plaintext = cipher.encrypt(plaintext);
std::cout<<"\nkey__:";
for(auto a : key)
@ -40,4 +40,49 @@ struct RC6test : public test_scaffold {
}
};
append_test dummy_szfhu5463(new RC6test{});
append_test dummy_szfhu5463(new RC6test{});
struct RC6test2 : public test_scaffold {
RC6test2() {
name = __FILE__ ":2";
}
virtual int run() {
using rc = RC6<>;
rc::key_type key = {0,0,0,0};
rc::block_type plaintext = {0,0,0,0};
rc::block_type expected{0,0,0,0};
std::cout<<"plain:";
for(auto a : plaintext)
std::cout << std::hex << a;
auto cipher = rc(key);
plaintext = cipher.encrypt(plaintext);
std::cout<<"\nkey__:";
for(auto a : key)
std::cout << std::hex << a;
std::cout<<"\nciphe:";
for(auto a : plaintext)
std::cout << std::hex << a;
plaintext = cipher.decrypt(plaintext);
std::cout<<"\ncidec:";
for(auto a : plaintext)
std::cout << std::hex << a;
std::cout<<"\nexpec:";
for(auto a : expected)
std::cout << std::hex << a;
std::cout << std::endl;
return plaintext != expected;
}
};
append_test dummy_szmltz63(new RC6test2{});

Loading…
Cancel
Save