blob: c459785cdc35d4e459cf1c378d6d1ca641192be6 [file] [log] [blame]
import 'dart:typed_data';
import 'package:pointycastle/digests/cshake.dart';
import 'package:pointycastle/digests/shake.dart';
import 'package:test/test.dart';
import '../test/src/helpers.dart';
void main() {
performTest();
performZeroPadTest();
performDoFinalTest();
testCSHAKESizeEnforcement();
var empty = Uint8List(0);
group('misc cshake', () {
test('cshake / shake equality', () {
checkSHAKE(128, CSHAKEDigest(128, Uint8List(0), empty),
createUint8ListFromHexString('eeaabeef'));
checkSHAKE(256, CSHAKEDigest(256, empty, null),
createUint8ListFromHexString('eeaabeef'));
checkSHAKE(128, CSHAKEDigest(128, null, empty),
createUint8ListFromHexString('eeaabeef'));
checkSHAKE(128, CSHAKEDigest(128, null, null),
createUint8ListFromHexString('eeaabeef'));
checkSHAKE(256, CSHAKEDigest(256, null, null),
createUint8ListFromHexString('eeaabeef'));
});
});
}
String formatBytesAsHexString(Uint8List bytes) {
var result = StringBuffer();
for (var i = 0; i < bytes.lengthInBytes; i++) {
var part = bytes[i];
result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
}
return result.toString();
}
void checkSHAKE(int bitSize, CSHAKEDigest cshake, Uint8List msg) {
var ref = SHAKEDigest(bitSize);
ref.update(msg, 0, msg.length);
cshake.update(msg, 0, msg.length);
var res1 = Uint8List(32);
var res2 = Uint8List(32);
ref.doFinalRange(res1, 0, res1.length);
cshake.doFinalRange(res2, 0, res2.length);
expect(res1, equals(res2));
}
void performDoFinalTest() {
group('CSHAKE doFinalTest', () {
test('doOutput no change on update until doFinal', () {
var cshake = CSHAKEDigest(
128, Uint8List(0), Uint8List.fromList('Email Signature'.codeUnits));
cshake.update(createUint8ListFromHexString('00010203'), 0, 4);
var res = Uint8List(32);
cshake.doOutput(res, 0, res.length);
expect(
res,
equals(createUint8ListFromHexString(
'c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5')));
cshake.doOutput(res, 0, res.length);
expect(
res,
isNot(createUint8ListFromHexString(
'c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5')));
cshake.doFinalRange(res, 0, res.length);
cshake.update(createUint8ListFromHexString('00010203'), 0, 4);
cshake.doFinalRange(res, 0, res.length);
expect(
res,
equals(createUint8ListFromHexString(
'c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5')));
cshake.update(createUint8ListFromHexString('00010203'), 0, 4);
cshake.doOutput(res, 0, res.length);
expect(
res,
equals(createUint8ListFromHexString(
'c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5')));
cshake.doFinalRange(res, 0, res.length);
expect(
res,
equals(createUint8ListFromHexString(
'9cbce830079c452abdeb875366a49ebfe75b89ef17396e34898e904830b0e136')));
});
});
}
void performZeroPadTest() {
group('CSHAKE checkZeroPadZ', () {
test('256 no function name (N)', () {
var buf = Uint8List(20);
var cshake1 = CSHAKEDigest(256, Uint8List(0), Uint8List(265));
cshake1.doOutput(buf, 0, buf.length);
expect(
buf,
equals(createUint8ListFromHexString(
'6e393540387004f087c4180db008acf6825190cf')));
});
test('128 no function name (N)', () {
var buf = Uint8List(20);
var cshake1 = CSHAKEDigest(128, Uint8List(0), Uint8List(329));
cshake1.doOutput(buf, 0, buf.length);
expect(
buf,
equals(createUint8ListFromHexString(
'309bd7c285fcf8b839c9686b2cc00bd578947bee')));
});
test('128 with function name (N)', () {
var buf = Uint8List(20);
var cshake1 = CSHAKEDigest(128, Uint8List(29), Uint8List(300));
cshake1.doOutput(buf, 0, buf.length);
expect(
buf,
equals(createUint8ListFromHexString(
'ff6aafd83b8d22fc3e2e9b9948b581967ed9c5e7')));
});
});
}
void performTest() {
group('CSHAKE 128', () {
test('test 1', () {
var cshake = CSHAKEDigest(
128, Uint8List(0), Uint8List.fromList('Email Signature'.codeUnits));
cshake.update(createUint8ListFromHexString('00010203'), 0, 4);
var res = Uint8List(32);
cshake.doOutput(res, 0, res.length);
expect(
createUint8ListFromHexString(
'c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5'),
equals(res));
});
test('test 2', () {
var cshake = CSHAKEDigest(
128, Uint8List(0), Uint8List.fromList('Email Signature'.codeUnits));
cshake.update(
createUint8ListFromHexString('''000102030405060708090A0B0C0D0E0F
101112131415161718191A1B1C1D1E1F
202122232425262728292A2B2C2D2E2F
303132333435363738393A3B3C3D3E3F
404142434445464748494A4B4C4D4E4F
505152535455565758595A5B5C5D5E5F
606162636465666768696A6B6C6D6E6F
707172737475767778797A7B7C7D7E7F
808182838485868788898A8B8C8D8E8F
909192939495969798999A9B9C9D9E9F
A0A1A2A3A4A5A6A7A8A9AAABACADAEAF
B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
C0C1C2C3C4C5C6C7'''), 0, 1600 ~/ 8);
var res = Uint8List(32);
cshake.doOutput(res, 0, res.length);
expect(
createUint8ListFromHexString(
'C5221D50E4F822D96A2E8881A961420F294B7B24FE3D2094BAED2C6524CC166B'),
equals(res));
});
});
group('CSHAKE 256', () {
test('test 1', () {
var cshake = CSHAKEDigest(
256, Uint8List(0), Uint8List.fromList('Email Signature'.codeUnits));
cshake.update(createUint8ListFromHexString('00010203'), 0, 4);
var res = Uint8List(64);
cshake.doOutput(res, 0, res.length);
expect(createUint8ListFromHexString('''D008828E2B80AC9D2218FFEE1D070C48
B8E4C87BFF32C9699D5B6896EEE0EDD1
64020E2BE0560858D9C00C037E34A969
37C561A74C412BB4C746469527281C8C'''), equals(res));
});
test('test 2', () {
var cshake = CSHAKEDigest(
256, Uint8List(0), Uint8List.fromList('Email Signature'.codeUnits));
cshake.update(
createUint8ListFromHexString('''000102030405060708090A0B0C0D0E0F
101112131415161718191A1B1C1D1E1F
202122232425262728292A2B2C2D2E2F
303132333435363738393A3B3C3D3E3F
404142434445464748494A4B4C4D4E4F
505152535455565758595A5B5C5D5E5F
606162636465666768696A6B6C6D6E6F
707172737475767778797A7B7C7D7E7F
808182838485868788898A8B8C8D8E8F
909192939495969798999A9B9C9D9E9F
A0A1A2A3A4A5A6A7A8A9AAABACADAEAF
B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
C0C1C2C3C4C5C6C7'''), 0, 1600 ~/ 8);
var res = Uint8List(64);
cshake.doOutput(res, 0, res.length);
expect(createUint8ListFromHexString('''07DC27B11E51FBAC75BC7B3C1D983E8B
4B85FB1DEFAF218912AC864302730917
27F42B17ED1DF63E8EC118F04B23633C
1DFB1574C8FB55CB45DA8E25AFB092BB'''), equals(res));
});
});
}
void testCSHAKESizeEnforcement() {
group('CSHAKE Tests', () {
test('enforcement of valid CSHAKE sizes', () {
CSHAKEDigest(128);
CSHAKEDigest(256);
var bitLen = 123;
try {
CSHAKEDigest(bitLen);
fail('Invalid CSHAKE bitlen accepted');
} on StateError catch (se) {
expect(se.message,
'invalid bitLength ($bitLen) for CSHAKE must only be 128 or 256');
}
});
});
}