Skip to content

Commit

Permalink
increased test coverage by adding test for failing path
Browse files Browse the repository at this point in the history
  • Loading branch information
JannesNebendahl committed Aug 20, 2024
1 parent d4fcb24 commit 72fc048
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 29 deletions.
16 changes: 10 additions & 6 deletions integration_test/usage_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ void main() {
final keyPair = Dilithium.generateKeyPair(spec, randomSeed());
final altKeyPair = Dilithium.generateKeyPair(spec, randomSeed());

for(int i = 0; i < 10; i++){
final message = Uint8List.fromList(List<int>.generate(i, (_) => i));
for(int msgLength = 0; msgLength < 10; msgLength++){
final message = Uint8List.fromList(List<int>.generate(msgLength, (_) => msgLength));

final signature = Dilithium.sign(keyPair.privateKey, message);

Expand All @@ -32,11 +32,15 @@ void main() {
// Cannot verify with incorrect key
expect(Dilithium.verify(altKeyPair.publicKey, signature, message), isFalse);

// Cannot verify with incorrect signature length
Uint8List toShortSignature = signature.sublist(0, signature.length - 1);
expect(Dilithium.verify(keyPair.publicKey, toShortSignature, message), isFalse);

// Can detect any bit-level modifications of the message
for(int j=0; j < i; j++){
for(int k=0; k < 8; k++){
for(int modifiedByte=0; modifiedByte < msgLength; modifiedByte++){
for(int modifiedBit=0; modifiedBit < 8; modifiedBit++){
final modifiedMessage = message;
modifiedMessage[j] ^= 1 << k;
modifiedMessage[modifiedByte] ^= 1 << modifiedBit;

expect(Dilithium.verify(keyPair.publicKey, signature, modifiedMessage), isFalse);
}
Expand Down Expand Up @@ -114,5 +118,5 @@ void main() {
});
});
});

}
54 changes: 39 additions & 15 deletions lib/src/dilithium.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,14 @@ class Dilithium {
///
/// Returns:
/// - A `DilithiumKeyPair` containing the public and private keys.
///
/// Throws:
/// - `InvalidSeedLength` exception if the seed length is invalid. The seed needs to be `Dilithium.SEEDBYTES` bytes long.
static DilithiumKeyPair generateKeyPair(DilithiumParameterSpec spec, Uint8List seed) {
if (seed.length != SEEDBYTES) {
throw InvalidSeedLength(seed.length);
}

Uint8List zeta = seed;

Uint8List o = Utils.getSHAKE256Digest(2 * 32 + 64, [zeta]);
Expand Down Expand Up @@ -226,15 +233,12 @@ class Dilithium {
///
/// Returns:
/// - `true` if the signature is valid, `false` otherwise.
///
/// Throws:
/// - `InvalidSignature` exception if the signature length is invalid.
static bool verify(DilithiumPublicKey pk, Uint8List sig, Uint8List M) {
var spec = pk.spec;
var CRYPTO_BYTES = Utils.getSigLength(spec);

if (sig.length != CRYPTO_BYTES) {
throw InvalidSignature();
return false;
}

var t1 = pk.t1;
Expand All @@ -255,13 +259,16 @@ class Dilithium {
for (var i = 0; i < h.length; i++) {
h.poly[i] = Poly(N);

if ((sig[off + spec.omega + i] & 0xFF) < k || (sig[off + spec.omega + i] & 0xFF) > spec.omega)
throw InvalidSignature();
if ((sig[off + spec.omega + i] & 0xFF) < k || (sig[off + spec.omega + i] & 0xFF) > spec.omega){
return false;
}

for (var j = k; j < (sig[off + spec.omega + i] & 0xFF); j++) {
/* Coefficients are ordered for strong unforgeability */
if (j > k && (sig[off + j] & 0xFF) <= (sig[off + j - 1] & 0xFF))
throw InvalidSignature();
{
return false;
}
h.poly[i].coef[sig[off + j] & 0xFF] = 1;
}

Expand All @@ -270,12 +277,12 @@ class Dilithium {

for (var j = k; j < spec.omega; j++) {
if (sig[off + j] != 0) {
throw InvalidSignature();
return false;
}
}

if (z.chknorm(spec.gamma1 - spec.beta)) {
throw InvalidSignature();
return false;
}

var mu = Utils.crh(pk.serialize());
Expand All @@ -297,7 +304,11 @@ class Dilithium {
w.invnttTomont();
w.caddq();

w = _useHintPolyVec(spec.gamma2, w, h);
try{
w = _useHintPolyVec(spec.gamma2, w, h);
} on IllegalGamma2 {
return false;
}

var buf = Uint8List(PackingUtils.getPolyW1PackedBytes(spec.gamma2) * w.length);
PackingUtils.packw1(spec.gamma2, w, buf);
Expand Down Expand Up @@ -339,6 +350,9 @@ class Dilithium {
///
/// Returns:
/// - The adjusted polynomial vector.
///
/// Throws:
/// - `IllegalGamma2` exception if the gamma2 parameter is invalid.
static PolyVec _useHintPolyVec(int gamma2, PolyVec u, PolyVec h) {
PolyVec res = PolyVec(u.length);
for (int i = 0; i < res.length; i++) {
Expand All @@ -356,6 +370,9 @@ class Dilithium {
///
/// Returns:
/// - The adjusted polynomial.
///
/// Throws:
/// - `IllegalGamma2` exception if the gamma2 parameter is invalid.
static Poly _useHintPoly(int gamma2, Poly u, Poly h) {
Poly res = Poly(Dilithium.N);
for (int i = 0; i < Dilithium.N; i++) {
Expand All @@ -373,6 +390,9 @@ class Dilithium {
///
/// Returns:
/// - The adjusted coefficient.
///
/// Throws:
/// - `IllegalGamma2` exception if the gamma2 parameter is invalid.
static int _useHintInt(int gamma2, int a, int hint) {
int a0, a1;

Expand All @@ -394,15 +414,17 @@ class Dilithium {
}

if (gamma2 == (Dilithium.Q - 1) / 32) {
if (a0 > 0)
if (a0 > 0) {
return (a1 + 1) & 15;
else
} else {
return (a1 - 1) & 15;
}
} else if (gamma2 == (Dilithium.Q - 1) / 88) {
if (a0 > 0)
if (a0 > 0) {
return (a1 == 43) ? 0 : a1 + 1;
else
} else {
return (a1 == 0) ? 43 : a1 - 1;
}
} else {
throw IllegalGamma2(gamma2);
}
Expand Down Expand Up @@ -484,7 +506,9 @@ class Dilithium {
s.doOutput(buf, 0, buf.length);

signs = 0;
for (int i = 0; i < 8; i++) signs |= (buf[i] & 0xFF) << (8 * i);
for (int i = 0; i < 8; i++) {
signs |= (buf[i] & 0xFF) << (8 * i);
}
pos = 8;

for (int i = Dilithium.N - tau; i < Dilithium.N; ++i) {
Expand Down
6 changes: 4 additions & 2 deletions lib/src/dilithium_exceptions.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:dilithium/dilithium.dart';

/// Eta must be 2 or 4
class IllegalEta extends ArgumentError {
IllegalEta(int eta) : super('Illegal eta: $eta');
Expand All @@ -13,8 +15,8 @@ class IllegalGamma2 extends ArgumentError {
IllegalGamma2(int gamma2) : super('Illegal gamma2: $gamma2');
}

class InvalidSignature extends ArgumentError {
InvalidSignature() : super('Invalid signature');
class InvalidSeedLength extends ArgumentError {
InvalidSeedLength(int actualLength) : super('Invalid seed length, seed needs to be ${Dilithium.SEEDBYTES} bytes long but is $actualLength bytes long');
}

class PolyVectorLengthMismatch extends ArgumentError {
Expand Down
10 changes: 4 additions & 6 deletions test/dilithium_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ void main() {
expect(keyPair.privateKey.serialize(), prvBytes);
});

test('generateKeyPair throws InvalidSeedLength', (){
expect(() => Dilithium.generateKeyPair(spec, Uint8List(Dilithium.SEEDBYTES + 1)), throwsA(isA<InvalidSeedLength>()));
});

test('sign', (){
Uint8List actualSignature = Dilithium.sign(privateKey, message);

Expand All @@ -88,11 +92,5 @@ void main() {
expect(Dilithium.verify(publicKey, signature, message), true);
expect(Dilithium.verify(publicKey, signature, invalidMsg), false);
});

test('verify throws InvalidSignature', (){
Uint8List invalidSignature = Uint8List.fromList([0x49, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64]); // == "Invalid"

expect(() => Dilithium.verify(publicKey, invalidSignature, message), throwsA(isA<InvalidSignature>()));
});
});
}
4 changes: 4 additions & 0 deletions test/packing_utils_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ void main(){
expect(actual, expected);
});

test('packPrvKey throws IllegalEta',(){
expect(() => PackingUtils.packPrvKey(3, Uint8List(0), Uint8List(0), Uint8List(0), PolyVec(0), PolyVec(0), PolyVec(0)), throwsA(TypeMatcher<IllegalEta>()));
});

test('packPubKey',(){
Uint8List rho = Uint8List.fromList([0x69, 0xF0, 0x7C, 0x88, 0x40, 0xCE, 0x80, 0x2, 0x4D, 0xB3, 0x9, 0x39, 0x88, 0x2C, 0x3D, 0x5B, 0xBC, 0x9C, 0x98, 0xB3, 0xE3, 0x1E, 0x45, 0x13, 0xEB, 0xD2, 0xCA, 0x9B, 0x45, 0x3, 0xCD, 0xD3]);
PolyVec t = mockPolyVec([
Expand Down
6 changes: 6 additions & 0 deletions test/poly_vec_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ void main() {
expectPolyVecsAreEqual(expected, actual);
});

test('randomVec throws IllegalEta', (){
final rho = Uint8List.fromList([1, 2, 3]);

expect(() => PolyVec.randomVec(rho, 3, 1, 123), throwsA(isA<IllegalEta>()));
});

test('ntt', (){
List<int> coef = List<int>.generate(Dilithium.N, (index) => index + 1);
final pv = mockPolyVec([coef]);
Expand Down

0 comments on commit 72fc048

Please sign in to comment.