77 lines
2.7 KiB
Dart
77 lines
2.7 KiB
Dart
// Needs the native libsignal library (FFI); skipped on builders without it (--exclude-tags ffi).
|
|
@Tags(['ffi'])
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:sepot/core/crypto/safety_number.dart';
|
|
import 'package:sepot/core/crypto/sepot_crypto.dart';
|
|
|
|
void main() {
|
|
setUpAll(() async {
|
|
await SepotCrypto.init();
|
|
});
|
|
|
|
Uint8List fixedKey(int seed) {
|
|
// deterministický „privátní klíč" → veřejný přes libsignal derivaci
|
|
final priv = Uint8List.fromList(List.generate(32, (i) => (i * 7 + seed) & 0xFF));
|
|
return SepotCrypto.derivePublicKey(priv);
|
|
}
|
|
|
|
test('obě strany vidí stejné číslo (symetrie)', () {
|
|
final a = fixedKey(1);
|
|
final b = fixedKey(2);
|
|
final fromA = SafetyNumber.compute(localIdentityKey: a, remoteIdentityKey: b);
|
|
final fromB = SafetyNumber.compute(localIdentityKey: b, remoteIdentityKey: a);
|
|
expect(fromA.display, fromB.display);
|
|
});
|
|
|
|
test('60 číslic, 12 bloků po 5', () {
|
|
final n = SafetyNumber.compute(
|
|
localIdentityKey: fixedKey(1),
|
|
remoteIdentityKey: fixedKey(2),
|
|
);
|
|
expect(n.display, matches(RegExp(r'^\d{60}$')));
|
|
expect(n.groups, hasLength(12));
|
|
expect(n.groups.every((g) => g.length == 5), isTrue);
|
|
});
|
|
|
|
test('jiný pár klíčů = jiné číslo', () {
|
|
final ab = SafetyNumber.compute(
|
|
localIdentityKey: fixedKey(1), remoteIdentityKey: fixedKey(2));
|
|
final ac = SafetyNumber.compute(
|
|
localIdentityKey: fixedKey(1), remoteIdentityKey: fixedKey(3));
|
|
expect(ab.display, isNot(ac.display));
|
|
});
|
|
|
|
test('QR compare: protistrany si odpovídají, cizí ne', () {
|
|
final a = fixedKey(1);
|
|
final b = fixedKey(2);
|
|
final mine = SafetyNumber.compute(localIdentityKey: a, remoteIdentityKey: b);
|
|
final theirs = SafetyNumber.compute(localIdentityKey: b, remoteIdentityKey: a);
|
|
final stranger = SafetyNumber.compute(
|
|
localIdentityKey: a, remoteIdentityKey: fixedKey(9));
|
|
|
|
expect(SafetyNumber.compare(mine.scannable, theirs.scannable), isTrue);
|
|
expect(SafetyNumber.compare(mine.scannable, stranger.scannable), isFalse);
|
|
// vadný vstup nesmí spadnout
|
|
expect(
|
|
SafetyNumber.compare(mine.scannable, Uint8List.fromList([1, 2, 3])),
|
|
isFalse,
|
|
);
|
|
});
|
|
|
|
test('KAT: zafixovaný výstup — změna = breaking change pro uživatele', () {
|
|
final n = SafetyNumber.compute(
|
|
localIdentityKey: fixedKey(1),
|
|
remoteIdentityKey: fixedKey(2),
|
|
);
|
|
// Vygenerováno libsignal 5.0.9 (iterations=5200, version=2,
|
|
// identifier=BLAKE2b-256(pubkey)). Pokud tenhle test spadne po
|
|
// upgradu, VŠEM uživatelům se změní safety numbers → stop ship.
|
|
expect(
|
|
n.display,
|
|
'289143504470406742912626343937385761080203728630218051783783',
|
|
);
|
|
});
|
|
}
|