暗号化と復号化に RC4 ストリーム暗号を使用するカスタム iostream (つまり、読み取り、書き込み、シーク、およびクローズ) を実装しています。このストリームのコントラクトの 1 つは、双方向であり、呼び出し元のコードは、実際の読み取りまたは書き込みを行う前に、ストリーム内の任意の位置を任意にシークできる必要があるということです。
RC4 は、指定された「tell」位置までの以前のすべてのスワップ操作に依存するキーを使用するため、任意の位置を任意にシークする機能をどのように組み込むことができますか?
明らかに、実際の xor 変換プロセスを実行する前に、特定のシーク オフセット (次の例ではTHIS BITでマークされている) の位置までシークすることができます。たとえば、次のようになります。
/**
* @brief called from a stream's read or write function
* @param in the input buffer
* @param out the output buffer
* @param startPosition the current stream position (obtained via the streams
* tellg or tellp functions for read and write respectively)
* @param length the number of bytes to transform
*/
void transform(char *in, char *out,
std::ios_base::streamoff startPosition,
long length)
{
// need to reset sbox from member s_box each time this
// function is called
long sbox[256];
for (int i = 0; i<256; ++i) {
sbox[i]=m_sbox[i];
}
// ***THIS BIT***
// need to run the swap operation startPosition times
// to get sbox integer sequence in order
int i = 0, j = 0, k = 0;
for (int a=0; a < startPosition; ++a) {
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
swapints(sbox, i, j);
}
// now do the actual xoring process up to the length
// of how many bytes are being read or written
for (int a=0; a < length; ++a) {
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
swapints(sbox, i, j);
k = sbox[(sbox[i] + sbox[j]) % 256];
out[a] = in[a] ^ k;
}
}
次に、ストリーム実装の読み取りまたは書き込みから変換が呼び出されます。次のようになります。
MyStream&
MyStream::read(char * const buf, std::streamsize const n)
{
std::ios_base::streamoff start = m_stream.tellg();
std::vector<char> in;
in.resize(n);
(void)m_stream.read(&in.front(), n);
m_byteTransformer->transform(&in.front(), buf, start, n);
return *this;
}
編集: ストリームには、変換関数がどのように機能するかについての知識がありません。変換機能は完全に独立しており、さまざまな変換の実装を自由に交換できるはずです。
編集: 関数 swapints は次のようになります。
void swapints(long *array, long ndx1, long ndx2)
{
int temp = array[ndx1];
array[ndx1] = array[ndx2];
array[ndx2] = temp;
}
上記の変換関数の実際の問題は、xor 変換が適切に実行される前に startPosition 初期スワップ操作を実行する必要があるため、その遅さにあります。これは、多くのシーク操作が実行される場合に非常に問題になります。RC4 は高速であることを意図していると聞いたことがありますが、スワップ操作の初期セットを考えると、私の (おそらく悪い実装) は別の方法を提案しています。
だから私の本当の質問は、必要な操作の数を減らすために上記のコードを最適化するにはどうすればよいですか? 理想的には、スワップ操作の最初の (" THIS BIT ") セットを排除したいと考えています。
編集: 初期の sbox 設定を最適化することはおそらく些細なことです (たとえば、egur が提案するように memcpy を使用します)。私が考える重要な最適化は、THIS BITでマークされたループを最適化する方法です。おそらく、これらすべてのスワップ int は、for ループを必要とせずに、より簡潔にプログラムできます。
ありがとう、
ベン