diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-26 20:26:44 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-26 20:26:44 +0700 |
commit | 6f3de272501bd9153fdbc7b6c28a6de7c7dfbfae (patch) | |
tree | 40bc1f0d3b347511de311c08fe87179b52e4c3b3 /crypto/src | |
parent | Make class internal (diff) | |
download | BouncyCastle.NET-ed25519-6f3de272501bd9153fdbc7b6c28a6de7c7dfbfae.tar.xz |
When OCB is used with incrementing nonces, the cipher processing during initialization is only needed once every 64 inits.
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/crypto/modes/OCBBlockCipher.cs | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/crypto/src/crypto/modes/OCBBlockCipher.cs b/crypto/src/crypto/modes/OCBBlockCipher.cs index 3ee06b805..9f0e0f6bb 100644 --- a/crypto/src/crypto/modes/OCBBlockCipher.cs +++ b/crypto/src/crypto/modes/OCBBlockCipher.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Crypto.Modes { /** * An implementation of the "work in progress" Internet-Draft <a - * href="http://tools.ietf.org/html/draft-irtf-cfrg-ocb-03">The OCB Authenticated-Encryption + * href="http://tools.ietf.org/html/draft-irtf-cfrg-ocb-05">The OCB Authenticated-Encryption * Algorithm</a>, licensed per: * * <blockquote><p><a href="http://www.cs.ucdavis.edu/~rogaway/ocb/license1.pdf">License for @@ -45,7 +45,9 @@ namespace Org.BouncyCastle.Crypto.Modes /* * NONCE-DEPENDENT */ - private byte[] OffsetMAIN_0; + private byte[] KtopInput = null; + private byte[] Stretch = new byte[24]; + private byte[] OffsetMAIN_0 = new byte[16]; /* * PER-ENCRYPTION/DECRYPTION @@ -55,7 +57,7 @@ namespace Org.BouncyCastle.Crypto.Modes private long hashBlockCount, mainBlockCount; private byte[] OffsetHASH; private byte[] Sum; - private byte[] OffsetMAIN; + private byte[] OffsetMAIN = new byte[16]; private byte[] Checksum; // NOTE: The MAC value is preserved after doFinal @@ -165,25 +167,8 @@ namespace Org.BouncyCastle.Crypto.Modes * NONCE-DEPENDENT AND PER-ENCRYPTION/DECRYPTION INITIALISATION */ - byte[] nonce = new byte[16]; - Array.Copy(N, 0, nonce, nonce.Length - N.Length, N.Length); - nonce[0] = (byte)(macSize << 4); - nonce[15 - N.Length] |= 1; - - int bottom = nonce[15] & 0x3F; - - byte[] Ktop = new byte[16]; - nonce[15] &= 0xC0; - hashCipher.ProcessBlock(nonce, 0, Ktop, 0); + int bottom = ProcessNonce(N); - byte[] Stretch = new byte[24]; - Array.Copy(Ktop, 0, Stretch, 0, 16); - for (int i = 0; i < 8; ++i) - { - Stretch[16 + i] = (byte) (Ktop[i] ^ Ktop[i + 1]); - } - - this.OffsetMAIN_0 = new byte[16]; int bits = bottom % 8, bytes = bottom / 8; if (bits == 0) { @@ -207,7 +192,7 @@ namespace Org.BouncyCastle.Crypto.Modes this.OffsetHASH = new byte[16]; this.Sum = new byte[16]; - this.OffsetMAIN = Arrays.Clone(this.OffsetMAIN_0); + Array.Copy(OffsetMAIN_0, 0, OffsetMAIN, 0, 16); this.Checksum = new byte[16]; if (initialAssociatedText != null) @@ -216,6 +201,34 @@ namespace Org.BouncyCastle.Crypto.Modes } } + protected virtual int ProcessNonce(byte[] N) + { + byte[] nonce = new byte[16]; + Array.Copy(N, 0, nonce, nonce.Length - N.Length, N.Length); + nonce[0] = (byte)(macSize << 4); + nonce[15 - N.Length] |= 1; + + int bottom = nonce[15] & 0x3F; + nonce[15] &= 0xC0; + + /* + * When used with incrementing nonces, the cipher is only applied once every 64 inits. + */ + if (KtopInput == null || !Arrays.AreEqual(nonce, KtopInput)) + { + byte[] Ktop = new byte[16]; + KtopInput = nonce; + hashCipher.ProcessBlock(KtopInput, 0, Ktop, 0); + Array.Copy(Ktop, 0, Stretch, 0, 16); + for (int i = 0; i < 8; ++i) + { + Stretch[16 + i] = (byte)(Ktop[i] ^ Ktop[i + 1]); + } + } + + return bottom; + } + public virtual int GetBlockSize() { return BLOCK_SIZE; |