Botan 3.0.0
Crypto and TLS for C&
cascade.cpp
Go to the documentation of this file.
1/*
2* Block Cipher Cascade
3* (C) 2010 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/cascade.h>
9#include <botan/internal/fmt.h>
10
11namespace Botan {
12
13void Cascade_Cipher::encrypt_n(const uint8_t in[], uint8_t out[],
14 size_t blocks) const
15 {
16 size_t c1_blocks = blocks * (block_size() / m_cipher1->block_size());
17 size_t c2_blocks = blocks * (block_size() / m_cipher2->block_size());
18
19 m_cipher1->encrypt_n(in, out, c1_blocks);
20 m_cipher2->encrypt_n(out, out, c2_blocks);
21 }
22
23void Cascade_Cipher::decrypt_n(const uint8_t in[], uint8_t out[],
24 size_t blocks) const
25 {
26 size_t c1_blocks = blocks * (block_size() / m_cipher1->block_size());
27 size_t c2_blocks = blocks * (block_size() / m_cipher2->block_size());
28
29 m_cipher2->decrypt_n(in, out, c2_blocks);
30 m_cipher1->decrypt_n(out, out, c1_blocks);
31 }
32
33void Cascade_Cipher::key_schedule(const uint8_t key[], size_t /*length*/)
34 {
35 const uint8_t* key2 = key + m_cipher1->maximum_keylength();
36
37 m_cipher1->set_key(key , m_cipher1->maximum_keylength());
38 m_cipher2->set_key(key2, m_cipher2->maximum_keylength());
39 }
40
42 {
43 m_cipher1->clear();
44 m_cipher2->clear();
45 }
46
47std::string Cascade_Cipher::name() const
48 {
49 return fmt("Cascade({},{})", m_cipher1->name(), m_cipher2->name());
50 }
51
53 {
54 return m_cipher1->has_keying_material() &&
55 m_cipher2->has_keying_material();
56 }
57
58std::unique_ptr<BlockCipher> Cascade_Cipher::new_object() const
59 {
60 return std::make_unique<Cascade_Cipher>(m_cipher1->new_object(),
61 m_cipher2->new_object());
62 }
63
64namespace {
65
66size_t euclids_algorithm(size_t a, size_t b)
67 {
68 while(b != 0)
69 {
70 size_t t = b;
71 b = a % b;
72 a = t;
73 }
74
75 return a;
76 }
77
78size_t block_size_for_cascade(size_t bs, size_t bs2)
79 {
80 if(bs == bs2)
81 return bs;
82
83 const size_t gcd = euclids_algorithm(bs, bs2);
84
85 return (bs * bs2) / gcd;
86 }
87
88}
89
90Cascade_Cipher::Cascade_Cipher(std::unique_ptr<BlockCipher> cipher1,
91 std::unique_ptr<BlockCipher> cipher2) :
92 m_cipher1(std::move(cipher1)),
93 m_cipher2(std::move(cipher2)),
94 m_block_size(block_size_for_cascade(m_cipher1->block_size(), m_cipher2->block_size()))
95 {
96 BOTAN_ASSERT(m_block_size % m_cipher1->block_size() == 0 &&
97 m_block_size % m_cipher2->block_size() == 0,
98 "Combined block size is a multiple of each ciphers block");
99 }
100
101}
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:54
bool has_keying_material() const override
Definition: cascade.cpp:52
std::string name() const override
Definition: cascade.cpp:47
Cascade_Cipher(std::unique_ptr< BlockCipher > cipher1, std::unique_ptr< BlockCipher > cipher2)
Definition: cascade.cpp:90
std::unique_ptr< BlockCipher > new_object() const override
Definition: cascade.cpp:58
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: cascade.cpp:13
void clear() override
Definition: cascade.cpp:41
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: cascade.cpp:23
size_t block_size() const override
Definition: cascade.h:24
Definition: alg_id.cpp:12
std::string fmt(std::string_view format, const T &... args)
Definition: fmt.h:60
BigInt gcd(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:220
Definition: bigint.h:1092