diff --git a/README.md b/README.md index 8831761..e0e6a25 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,149 @@ - +Содержит реализацию бинарного протокола v1.0, 6-битную оптимизацию текста, генерацию асимметричных ключей и подписей Ed25519, а также средства сериализации/десериализации. -TODO: Put a short description of the package here that helps potential users -know whether this package might be useful for them. +--- -## Features +## Подключение к проектам -TODO: List what your package can do. Maybe include images, gifs, or videos. +Добавление заывисимости в `pubspec.yaml`: -## Getting started - -TODO: List prerequisites and provide or point to information on how to -start using the package. - -## Usage - -TODO: Include short and useful examples for package users. Add longer examples -to `/example` folder. - -```dart -const like = 'sample'; +```yaml +dependencies: + potato_pass_core: + git: + url: https://git.mr-potato.ru/PotatoPass/PotatoPassCore.git + ref: stable ``` -## Additional information +--- -TODO: Tell users more about the package: where to find more information, how to -contribute to the package, how to file issues, what response they can expect -from the package authors, and more. +## Спецификация Бинарного Протокола + +Формат разработан для сверхплотной упаковки данных пропуска в 2D-коды + +### Структура Байтового Массива (Binary Layout) + +| Секция | Длина (Байты) | Описание | +| :--- | :--- | :--- | +| **1. Текстовый блок** | Динамическая (~20–45B) | 5 полей текста с 1-байтовым префиксом длины (6-битное кодирование) | +| **2. Блок доступа** | Динамическая (~3–33B) | `1B` длина маски $N$ + $N$ байт битовой маски зон ($1 \text{ бит} = 1 \text{ зона}$) | +| **3. Публичный ключ** | `32B` | 32 байта Ed25519 Public Key клиента (уникальный ID пропуска) | +| **4. Подпись СБ** | `64B` | Подпись Службы Безопасности (подписывает секции с 1 по 3) | +| **5. Подпись Соли** | `64B` | Подпись Клиента (подписывает `Соль (16B)` + `Подпись СБ (64B)`) | + +--- + +## 6-битный кодировщик текста (`CompactTextEncoder`) + +Для кириллицы стандартный UTF-8 использует 2 байта (16 бит) на символ. `CompactTextEncoder` сжимает 4 символа в 3 байта (6 бит на символ), давая **62% экономии места**. + +### Словарь символов (64 значения = $2^6$): + +```text +0..32 : А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я +33..58 : A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +59..63 : [Пробел] - . , _ (подчеркивание/заполнитель) +``` + +--- + +## Криптографическая модель подписей (Ed25519) + +В системе используются две цифровые подписи для защиты от подделки и копирования: + +```text +1. [ Текст + Зоны + PubKey Клиента ] ──────────────► Подпись СБ (64B) + +2. [ Challenge Salt (16B) + Подпись СБ (64B) ] ───────────────► Подпись Соли Клиентом (64B) + + +``` + +1. **`securityDepartmentSignature` (Подпись СБ):** Доказывает, что ФИО, должность и зоны доступа утверждены Службой Безопасности и не изменены владельцем. +2. **`challengeSignature` (Подпись Соли):** Доказывает, что пропуск предъявляет именно его владелец с помощью своего приватного ключа. Одноразовая соль (16B) сгорает каждые 10 секунд, делая скриншоты и фото кода бесполезными. + +--- + +## Примеры использования API + +### 1. Работа с 6-битным кодировщиком текста + +```dart +import 'dart:typed_data'; +import 'package:potato_pass_core/potato_pass_core.dart'; + +void main() { + // Упаковка строки в 6-битные байты + final Uint8List encoded = CompactTextEncoder.encode('Иванов Иван'); + + // Распаковка обратно в строку + final String decoded = CompactTextEncoder.decode(encoded); // "ИВАНОВ ИВАН" +} +``` + +### 2. Генерация ключей и подпись (Ed25519) + +```dart +import 'dart:typed_data'; +import 'package:cryptography/cryptography.dart'; +import 'package:potato_pass_core/potato_pass_core.dart'; + +void main() async { + // Генерация пары ключей + final SimpleKeyPair keyPair = await CryptoService.generateKeyPair(); + final Uint8List pubKeyBytes = await CryptoService.getPublicKeyBytes(keyPair); + + // Подпись сообщения + final List message = [1, 2, 3, 4, 5]; + final Uint8List signature = await CryptoService.sign( + message: message, + keyPair: keyPair, + ); + + // Проверка подписи + final bool isValid = await CryptoService.verify( + message: message, + signatureBytes: signature, + publicKeyBytes: pubKeyBytes, + ); +} +``` + +### 3. Полный цикл сериализации и проверки пропуска + +```dart +import 'dart:typed_data'; +import 'package:potato_pass_core/potato_pass_core.dart'; + +void main() async { + // Генерация маски зон доступа (разрешаем зоны 1, 5, 10) + final Uint8List zoneMask = PassPayload.createZoneMask([1, 5, 10]); + + // Создание объекта пропуска + final pass = PassPayload( + lastName: 'Иванов', + firstName: 'Иван', + middleName: 'Иванович', + position: 'Инженер', + department: 'Отдел ИТ', + zoneMask: zoneMask, + clientPublicKey: clientPubKeyBytes, + securityDepartmentSignature: sbSignatureBytes, + challengeSignature: clientChallengeSigBytes, + ); + + // Упаковка в байты для DataMatrix / BLE + final Uint8List binaryPayload = BinarySerializer.serialize(pass); + + // Распаковка из байтов на стороне Контролера + final PassPayload restoredPass = BinarySerializer.deserialize(binaryPayload); + + // Проверка прав доступа в зону 5 + if (restoredPass.hasZoneAccess(5)) { + print('Доступ разрешен!'); + } +} +``` \ No newline at end of file