| 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'); |
| } |
| }); |
| }); |
| } |