| // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // Test vectors are sourced from Project Wycheproof |
| // (https://github.com/C2SP/wycheproof). |
| // Copyright 2017-2026 Google LLC / C2SP. |
| // Licensed under the Apache License, Version 2.0. |
| // See third_party/wycheproof/LICENSE for full license text. |
| |
| /// Downloads HMAC test vectors from Project Wycheproof |
| /// (https://github.com/C2SP/wycheproof) and generates |
| /// `test/wycheproof_data.dart`. |
| library; |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| final _baseUrl = Uri.https( |
| 'raw.githubusercontent.com', |
| 'C2SP/wycheproof/main/testvectors_v1/', |
| ); |
| |
| const _hmacVectors = [ |
| 'hmac_sha256_test.json', |
| 'hmac_sha512_test.json', |
| 'hmac_sha384_test.json', |
| 'hmac_sha224_test.json', |
| 'hmac_sha512_224_test.json', |
| 'hmac_sha512_256_test.json', |
| 'hmac_sha1_test.json', |
| ]; |
| |
| Future<void> main() async { |
| final client = HttpClient(); |
| final vectorContents = <String, String>{}; |
| |
| for (final file in _hmacVectors) { |
| final uri = _baseUrl.resolve(file); |
| stdout.write('Fetching $file from $_baseUrl... '); |
| final request = await client.getUrl(uri); |
| final response = await request.close(); |
| if (response.statusCode != 200) { |
| stderr.writeln('FAILED (${response.statusCode})'); |
| exitCode = 1; |
| continue; |
| } |
| final content = await response.transform(utf8.decoder).join(); |
| vectorContents[file] = content; |
| stdout.writeln('DONE (${(content.length / 1024).toStringAsFixed(1)} KB)'); |
| } |
| client.close(); |
| |
| // Generate test/wycheproof_data.dart with wrapped base64-encoded strings |
| // (chunked at 70 chars) matching the pubviz asset-inlining pattern. |
| final buffer = StringBuffer() |
| ..writeln('// Test vectors are sourced from Project Wycheproof ' |
| '(https://github.com/C2SP/wycheproof).') |
| ..writeln('// Copyright 2017-2026 Google LLC / C2SP.') |
| ..writeln('// Licensed under the Apache License, Version 2.0.') |
| ..writeln('// See third_party/wycheproof/LICENSE for full license text.') |
| ..writeln() |
| ..writeln('// GENERATED CODE - DO NOT MODIFY BY HAND') |
| ..writeln('// Generated by tool/pull_wycheproof.dart') |
| ..writeln() |
| ..writeln('// ignore_for_file: lines_longer_than_80_chars') |
| ..writeln() |
| ..writeln('const wycheproofVectorsBase64 = <String, String>{'); |
| |
| for (final entry in vectorContents.entries) { |
| final base64String = base64.encode(utf8.encode(entry.value)); |
| buffer.writeln(" '${entry.key}':"); |
| |
| const chunkSize = 70; |
| for (var i = 0; i < base64String.length; i += chunkSize) { |
| final end = (i + chunkSize < base64String.length) |
| ? i + chunkSize |
| : base64String.length; |
| final chunk = base64String.substring(i, end); |
| final isLast = end == base64String.length; |
| buffer.writeln(" '$chunk'${isLast ? ',' : ''}"); |
| } |
| } |
| |
| buffer.writeln('};'); |
| |
| final targetFile = File('test/wycheproof_data.dart'); |
| await targetFile.writeAsString(buffer.toString()); |
| stdout.writeln( |
| 'Generated ${targetFile.path} ' |
| '(${(buffer.length / 1024).toStringAsFixed(1)} KB)', |
| ); |
| |
| final formatResult = await Process.run( |
| Platform.executable, |
| ['format', targetFile.path], |
| ); |
| if (formatResult.exitCode != 0) { |
| stderr |
| .writeln('Error formatting ${targetFile.path}: ${formatResult.stderr}'); |
| } |
| } |