import 'package:flutter_test/flutter_test.dart'; import 'package:friendly_map/modules/keys/keys.dart'; Future> deriverFor(int seed) async => List.generate(32, (i) => (i + seed) % 256); Future keysOf(int seed) async => IdentityKeys((label) async { final base = await deriverFor(seed); return [...base.take(31), label.length % 256]; }); void main() { test('같은 기본 비밀이면 같은 공개 키, 다르면 다른 공개 키', () async { final a1 = LocalIdentityProvider(await keysOf(1)); final a2 = LocalIdentityProvider(await keysOf(1)); final b = LocalIdentityProvider(await keysOf(2)); expect(await a1.myPublicKey(), await a2.myPublicKey()); expect(await a1.myPublicKey() == await b.myPublicKey(), false); }); test('둘만 아는 키: 서로 잠근 것을 서로 풀 수 있다', () async { final ka = await keysOf(1), kb = await keysOf(2); final pubA = await LocalIdentityProvider(ka).myPublicKey(); final pubB = await LocalIdentityProvider(kb).myPublicKey(); final a = SharedPayloadCipher(ka), b = SharedPayloadCipher(kb); final sealed = await a.seal(plain: '안녕 😀', peerPublicKey: pubB, context: 'room1'); expect(sealed.contains('안녕'), false); expect(await b.open(sealed: sealed, peerPublicKey: pubA, context: 'room1'), '안녕 😀'); final back = await b.seal(plain: '답', peerPublicKey: pubA, context: 'room1'); expect(await a.open(sealed: back, peerPublicKey: pubB, context: 'room1'), '답'); }); test('단위(대화방)가 다르면 풀리지 않는다', () async { final ka = await keysOf(1), kb = await keysOf(2); final pubA = await LocalIdentityProvider(ka).myPublicKey(); final pubB = await LocalIdentityProvider(kb).myPublicKey(); final sealed = await SharedPayloadCipher(ka).seal(plain: 'x', peerPublicKey: pubB, context: 'room1'); expect(await SharedPayloadCipher(kb).open(sealed: sealed, peerPublicKey: pubA, context: 'room2'), null); }); test('제3자는 풀지 못하고, 중간에 바뀐 내용은 거절', () async { final ka = await keysOf(1), kb = await keysOf(2), kc = await keysOf(3); final pubA = await LocalIdentityProvider(ka).myPublicKey(); final pubB = await LocalIdentityProvider(kb).myPublicKey(); final sealed = await SharedPayloadCipher(ka).seal(plain: 'x', peerPublicKey: pubB, context: 'r'); expect(await SharedPayloadCipher(kc).open(sealed: sealed, peerPublicKey: pubA, context: 'r'), null); final tampered = '${sealed.substring(0, sealed.length - 4)}AAAA'; expect(await SharedPayloadCipher(kb).open(sealed: tampered, peerPublicKey: pubA, context: 'r'), null); expect(await SharedPayloadCipher(kb).open(sealed: 'not base64!!', peerPublicKey: pubA, context: 'r'), null); }); }