nkbmusic/test/song_cipher_test.dart
metatroncubeswdev 178d2d00ab Nanga Kathai: Flutter app, self-hosted backend and song tools
- Flutter app (Android/iOS): home, explore, albums, search, player with
  equalizer, mini player, sign up/sign in with email codes, profile,
  encrypted offline downloads, About page
- server/: one-command deploy of self-hosted Supabase behind HestiaCP/nginx
  (or Caddy), migrations, backups, email templates
- supabase/migrations: schema, row-level security, profiles
- tools/: song scanner and importer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:39:26 -04:00

39 lines
1.4 KiB
Dart

import 'dart:math';
import 'dart:typed_data';
import 'package:nanga_kathai/offline/song_cipher.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('decrypting any range after a seek returns the original bytes', () {
final r = Random(1);
final plain = Uint8List.fromList(List.generate(100000, (_) => r.nextInt(256)));
final cipher = SongCipher(SongCipher.newKey());
final nonce = SongCipher.newNonce();
// Encrypt in uneven chunks, the way a download arrives.
final enc = Uint8List.fromList(plain);
for (var off = 0; off < enc.length; off += 7777) {
final end = min(off + 7777, enc.length);
final part = Uint8List.sublistView(enc, off, end);
cipher.apply(part, off, nonce);
}
expect(enc, isNot(equals(plain)));
for (final (start, end) in [(0, 100000), (5, 21), (16, 32), (99990, 100000), (12345, 67891)]) {
final chunk = Uint8List.fromList(enc.sublist(start, end));
cipher.apply(chunk, start, nonce);
expect(chunk, equals(plain.sublist(start, end)), reason: 'range $start-$end');
}
});
test('a different key cannot decrypt', () {
final plain = Uint8List.fromList(List.generate(64, (i) => i));
final nonce = SongCipher.newNonce();
final enc = Uint8List.fromList(plain);
SongCipher(SongCipher.newKey()).apply(enc, 0, nonce);
SongCipher(SongCipher.newKey()).apply(enc, 0, nonce);
expect(enc, isNot(equals(plain)));
});
}