Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
briar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Julian Dehm
briar
Commits
9586e0de
Commit
9586e0de
authored
13 years ago
by
akwizgran
Browse files
Options
Downloads
Patches
Plain Diff
Unit tests for CTR-mode encryption.
parent
cee4956b
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
test/net/sf/briar/crypto/CounterModeTest.java
+163
-0
163 additions, 0 deletions
test/net/sf/briar/crypto/CounterModeTest.java
with
163 additions
and
0 deletions
test/net/sf/briar/crypto/CounterModeTest.java
0 → 100644
+
163
−
0
View file @
9586e0de
package
net.sf.briar.crypto
;
import
java.security.GeneralSecurityException
;
import
java.security.SecureRandom
;
import
java.security.Security
;
import
java.util.HashSet
;
import
java.util.Set
;
import
javax.crypto.Cipher
;
import
javax.crypto.spec.IvParameterSpec
;
import
javax.crypto.spec.SecretKeySpec
;
import
junit.framework.TestCase
;
import
net.sf.briar.api.serial.Bytes
;
import
org.bouncycastle.jce.provider.BouncyCastleProvider
;
import
org.junit.Test
;
public
class
CounterModeTest
extends
TestCase
{
private
static
final
String
CIPHER_ALGO
=
"AES"
;
private
static
final
String
CIPHER_MODE
=
"AES/CTR/NoPadding"
;
private
static
final
String
PROVIDER
=
"BC"
;
private
static
final
int
KEY_SIZE_BYTES
=
32
;
// AES-256
private
static
final
int
BLOCK_SIZE_BYTES
=
16
;
private
final
SecureRandom
random
;
private
final
byte
[]
keyBytes
;
private
final
SecretKeySpec
key
;
public
CounterModeTest
()
{
super
();
Security
.
addProvider
(
new
BouncyCastleProvider
());
random
=
new
SecureRandom
();
keyBytes
=
new
byte
[
KEY_SIZE_BYTES
];
random
.
nextBytes
(
keyBytes
);
key
=
new
SecretKeySpec
(
keyBytes
,
CIPHER_ALGO
);
}
@Test
public
void
testEveryBitOfIvIsSignificant
()
throws
GeneralSecurityException
{
// Set each bit of the IV in turn, encrypt the same plaintext and check
// that all the resulting ciphertexts are distinct
byte
[]
plaintext
=
new
byte
[
BLOCK_SIZE_BYTES
];
random
.
nextBytes
(
plaintext
);
Set
<
Bytes
>
ciphertexts
=
new
HashSet
<
Bytes
>();
for
(
int
i
=
0
;
i
<
BLOCK_SIZE_BYTES
*
8
;
i
++)
{
// Set the i^th bit of the IV
byte
[]
ivBytes
=
new
byte
[
BLOCK_SIZE_BYTES
];
ivBytes
[
i
/
8
]
|=
(
byte
)
(
128
>>
i
%
8
);
IvParameterSpec
iv
=
new
IvParameterSpec
(
ivBytes
);
// Encrypt the plaintext
Cipher
cipher
=
Cipher
.
getInstance
(
CIPHER_MODE
,
PROVIDER
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
,
iv
);
byte
[]
ciphertext
=
new
byte
[
cipher
.
getOutputSize
(
plaintext
.
length
)];
cipher
.
doFinal
(
plaintext
,
0
,
plaintext
.
length
,
ciphertext
,
0
);
ciphertexts
.
add
(
new
Bytes
(
ciphertext
));
}
// All the ciphertexts should be distinct using Arrays.equals()
assertEquals
(
BLOCK_SIZE_BYTES
*
8
,
ciphertexts
.
size
());
}
@Test
public
void
testRepeatedIvsProduceRepeatedCiphertexts
()
throws
GeneralSecurityException
{
// This is the inverse of the previous test, to check that the
// distinct ciphertexts were due to using distinct IVs
byte
[]
plaintext
=
new
byte
[
BLOCK_SIZE_BYTES
];
random
.
nextBytes
(
plaintext
);
byte
[]
ivBytes
=
new
byte
[
BLOCK_SIZE_BYTES
];
random
.
nextBytes
(
ivBytes
);
IvParameterSpec
iv
=
new
IvParameterSpec
(
ivBytes
);
Set
<
Bytes
>
ciphertexts
=
new
HashSet
<
Bytes
>();
for
(
int
i
=
0
;
i
<
BLOCK_SIZE_BYTES
*
8
;
i
++)
{
Cipher
cipher
=
Cipher
.
getInstance
(
CIPHER_MODE
,
PROVIDER
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
,
iv
);
byte
[]
ciphertext
=
new
byte
[
cipher
.
getOutputSize
(
plaintext
.
length
)];
cipher
.
doFinal
(
plaintext
,
0
,
plaintext
.
length
,
ciphertext
,
0
);
ciphertexts
.
add
(
new
Bytes
(
ciphertext
));
}
assertEquals
(
1
,
ciphertexts
.
size
());
}
@Test
public
void
testLeastSignificantBitsUsedAsCounter
()
throws
GeneralSecurityException
{
// Initialise the least significant 32 bits of the IV to zero and
// encrypt ten blocks of zeroes
byte
[]
plaintext
=
new
byte
[
BLOCK_SIZE_BYTES
*
10
];
byte
[]
ivBytes
=
new
byte
[
BLOCK_SIZE_BYTES
];
random
.
nextBytes
(
ivBytes
);
for
(
int
i
=
BLOCK_SIZE_BYTES
-
4
;
i
<
BLOCK_SIZE_BYTES
;
i
++)
{
ivBytes
[
i
]
=
0
;
}
IvParameterSpec
iv
=
new
IvParameterSpec
(
ivBytes
);
Cipher
cipher
=
Cipher
.
getInstance
(
CIPHER_MODE
,
PROVIDER
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
,
iv
);
byte
[]
ciphertext
=
new
byte
[
cipher
.
getOutputSize
(
plaintext
.
length
)];
cipher
.
doFinal
(
plaintext
,
0
,
plaintext
.
length
,
ciphertext
,
0
);
// Initialise the least significant 32 bits of the IV to one and
// encrypt another ten blocks of zeroes
for
(
int
i
=
BLOCK_SIZE_BYTES
-
4
;
i
<
BLOCK_SIZE_BYTES
;
i
++)
{
assertEquals
(
0
,
ivBytes
[
i
]);
}
ivBytes
[
BLOCK_SIZE_BYTES
-
1
]
=
1
;
iv
=
new
IvParameterSpec
(
ivBytes
);
cipher
=
Cipher
.
getInstance
(
CIPHER_MODE
,
PROVIDER
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
,
iv
);
byte
[]
ciphertext1
=
new
byte
[
cipher
.
getOutputSize
(
plaintext
.
length
)];
cipher
.
doFinal
(
plaintext
,
0
,
plaintext
.
length
,
ciphertext1
,
0
);
// The last nine blocks of the first ciphertext should be identical to
// the first nine blocks of the second ciphertext
for
(
int
i
=
0
;
i
<
BLOCK_SIZE_BYTES
*
9
;
i
++)
{
assertEquals
(
ciphertext
[
i
+
BLOCK_SIZE_BYTES
],
ciphertext1
[
i
]);
}
}
@Test
public
void
testCounterUsesMoreThan32Bits
()
throws
GeneralSecurityException
{
// Initialise the least significant bits of the IV to 2^32-1 and
// encrypt ten blocks of zeroes
byte
[]
plaintext
=
new
byte
[
BLOCK_SIZE_BYTES
*
10
];
byte
[]
ivBytes
=
new
byte
[
BLOCK_SIZE_BYTES
];
random
.
nextBytes
(
ivBytes
);
ivBytes
[
BLOCK_SIZE_BYTES
-
5
]
=
0
;
for
(
int
i
=
BLOCK_SIZE_BYTES
-
4
;
i
<
BLOCK_SIZE_BYTES
;
i
++)
{
ivBytes
[
i
]
=
(
byte
)
255
;
}
IvParameterSpec
iv
=
new
IvParameterSpec
(
ivBytes
);
Cipher
cipher
=
Cipher
.
getInstance
(
CIPHER_MODE
,
PROVIDER
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
,
iv
);
byte
[]
ciphertext
=
new
byte
[
cipher
.
getOutputSize
(
plaintext
.
length
)];
cipher
.
doFinal
(
plaintext
,
0
,
plaintext
.
length
,
ciphertext
,
0
);
// Initialise the least significant bits of the IV to 2^32 and
// encrypt another ten blocks of zeroes
assertEquals
(
0
,
ivBytes
[
BLOCK_SIZE_BYTES
-
5
]);
for
(
int
i
=
BLOCK_SIZE_BYTES
-
4
;
i
<
BLOCK_SIZE_BYTES
;
i
++)
{
assertEquals
((
byte
)
255
,
ivBytes
[
i
]);
}
ivBytes
[
BLOCK_SIZE_BYTES
-
5
]
=
1
;
for
(
int
i
=
BLOCK_SIZE_BYTES
-
4
;
i
<
BLOCK_SIZE_BYTES
;
i
++)
{
ivBytes
[
i
]
=
0
;
}
iv
=
new
IvParameterSpec
(
ivBytes
);
cipher
=
Cipher
.
getInstance
(
CIPHER_MODE
,
PROVIDER
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
,
iv
);
byte
[]
ciphertext1
=
new
byte
[
cipher
.
getOutputSize
(
plaintext
.
length
)];
cipher
.
doFinal
(
plaintext
,
0
,
plaintext
.
length
,
ciphertext1
,
0
);
// The last nine blocks of the first ciphertext should be identical to
// the first nine blocks of the second ciphertext
for
(
int
i
=
0
;
i
<
BLOCK_SIZE_BYTES
*
9
;
i
++)
{
assertEquals
(
ciphertext
[
i
+
BLOCK_SIZE_BYTES
],
ciphertext1
[
i
]);
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment