Document streaming signature state ownership and retries
This commit is contained in:
1 parent
5d11f90cd4
commit
44acb5aecf
1 file changed
+31
-16
@@ -122,23 +122,38 @@ int ok = sc_ed25519_verify(pubkey, msg, msg_len, sig); // SC_OK при успе
|
||||
|
||||
**Стриминговая (потоковая) подпись:** SHA-512 аккумулятор + one-shot Ed25519 в финале. Подходит для данных любого размера (память O(1)):
|
||||
```c
|
||||
struct sc_stream_sign_state state;
|
||||
struct sc_stream_sign_state state = {0};
|
||||
uint8_t stream_sig[SC_SIGN_SIZE];
|
||||
size_t sig_len = sizeof(stream_sig);
|
||||
int result;
|
||||
|
||||
// Подпись
|
||||
sc_stream_sign_init(&ctx, &state);
|
||||
sc_stream_sign_update(&state, chunk1, len1);
|
||||
sc_stream_sign_update(&state, chunk2, len2);
|
||||
sc_stream_sign_final(&state, stream_sig, &sig_len); // sig_len — capacity на входе, длина подписи на выходе; cleanup
|
||||
if ((result = sc_stream_sign_init(&ctx, &state)) != SC_OK) goto stream_done;
|
||||
if ((result = sc_stream_sign_update(&state, chunk1, len1)) != SC_OK) goto stream_done;
|
||||
if ((result = sc_stream_sign_update(&state, chunk2, len2)) != SC_OK) goto stream_done;
|
||||
if ((result = sc_stream_sign_final(&state, stream_sig, &sig_len)) != SC_OK) goto stream_done;
|
||||
|
||||
// Верификация
|
||||
sc_stream_sign_verify_init(&state, ed25519_pubkey);
|
||||
sc_stream_sign_update(&state, chunk1, len1);
|
||||
sc_stream_sign_update(&state, chunk2, len2);
|
||||
int result = sc_stream_sign_verify(&state, stream_sig, sig_len); // SC_OK при успехе, отрицательный SC_ERR_* при ошибке
|
||||
if ((result = sc_stream_sign_verify_init(&state, ed25519_pubkey)) != SC_OK) goto stream_done;
|
||||
if ((result = sc_stream_sign_update(&state, chunk1, len1)) != SC_OK) goto stream_done;
|
||||
if ((result = sc_stream_sign_update(&state, chunk2, len2)) != SC_OK) goto stream_done;
|
||||
result = sc_stream_sign_verify(&state, stream_sig, sig_len);
|
||||
|
||||
stream_done:
|
||||
sc_stream_sign_cleanup(&state); // Безопасно после ошибок, final/verify и предыдущей очистки.
|
||||
// result: SC_OK при успехе, отрицательный SC_ERR_* при ошибке.
|
||||
```
|
||||
|
||||
Перед первым использованием состояние обнуляют. `init` требует пустого состояния и создаёт ресурсы
|
||||
до его заполнения: отказ оставляет все поля пустыми. Повторный `init` активного состояния возвращает
|
||||
`SC_ERR_INVALID_ARG`, сохраняя ресурсы и накопленный хеш; для новой операции сначала нужен `cleanup`.
|
||||
Подписи достаточно локального ключа из инициализированного `ctx`; ECDH с пиром не требуется.
|
||||
|
||||
`final` проверяет capacity не менее 64 до финализации. NULL аргументы, недостаточная capacity и неверный
|
||||
режим не меняют состояние или выходной буфер. После начала финализации `final/verify` освобождают
|
||||
состояние при любом результате, в том числе неверной подписи. При ошибке EVP update нужна явная очистка.
|
||||
`cleanup` обнуляет все поля и допускает повторные вызовы и NULL.
|
||||
|
||||
**Деривация Ed25519-ключа из X25519:** `sc_derive_ed25519_pubkey(x25519_privkey, ed25519_pubkey)`
|
||||
берёт первые 32 байта `SHA512(x25519_privkey[32])` как Ed25519 seed и извлекает из него публичный ключ (32 байта).
|
||||
Потоковая подпись использует тот же производный ключ; one-shot API принимает непосредственно Ed25519-ключи.
|
||||
@@ -209,8 +224,8 @@ sc_sha_transcode(key, key_len, data, data_len);
|
||||
**`struct sc_stream_sign_state`** — состояние стриминговой подписи (Ed25519 + SHA-512):
|
||||
- `md_ctx` — `EVP_MD_CTX*` (SHA-512 аккумулятор, opaque)
|
||||
- `pkey` — `EVP_PKEY*` (Ed25519 ключ, opaque)
|
||||
- `initialized` — флаг инициализации
|
||||
- `is_sign` — 1 = режим подписи, 0 = режим верификации
|
||||
- `initialized` — 1 после успешного init; 0 в пустом состоянии
|
||||
- `is_sign` — в активном состоянии 1 = подпись, 0 = верификация; после cleanup равен 0
|
||||
|
||||
### 3.3. Функции
|
||||
|
||||
@@ -267,12 +282,12 @@ Nonce не зависит от часов, счётчиков контекста
|
||||
|
||||
| Функция | Описание |
|
||||
|---|---|
|
||||
| `sc_stream_sign_init(ctx, state)` | Инициализирует подпись. Ed25519 seed — первые 32 байта `SHA512(x25519_privkey[32])`. |
|
||||
| `sc_stream_sign_verify_init(state, ed25519_pubkey)` | Инициализирует верификацию с переданным Ed25519 pubkey. |
|
||||
| `sc_stream_sign_init(ctx, state)` | Инициализирует подпись в пустом state. Ed25519 seed — первые 32 байта `SHA512(x25519_privkey[32])`. Ошибка сохраняет state. |
|
||||
| `sc_stream_sign_verify_init(state, ed25519_pubkey)` | Инициализирует верификацию с переданным Ed25519 pubkey[32] в пустом state; ошибка сохраняет state. |
|
||||
| `sc_stream_sign_update(state, data, len)` | SHA-512 update (инкрементальный). Нулевая длина — no-op. |
|
||||
| `sc_stream_sign_final(state, sig_out, &sig_len)` | Завершает SHA-512 → one-shot Ed25519 подпись хэша → **автоматический cleanup**. На входе sig_len задаёт capacity sig_out (не менее 64), при успехе на выходе 64. |
|
||||
| `sc_stream_sign_verify(state, sig, sig_len)` | Завершает SHA-512 → one-shot Ed25519 проверка → **автоматический cleanup**. Возвращает `SC_OK` при успехе, отрицательный `SC_ERR_*` при ошибке. |
|
||||
| `sc_stream_sign_cleanup(state)` | Ручная очистка (если не вызван final/verify). |
|
||||
| `sc_stream_sign_final(state, sig_out, &sig_len)` | SHA-512 → one-shot Ed25519 подпись хэша. На входе capacity sig_out ≥64, при успехе на выходе 64. После начала финализации выполняет cleanup при любом результате. |
|
||||
| `sc_stream_sign_verify(state, sig, sig_len)` | SHA-512 → one-shot Ed25519 проверка. После начала финализации выполняет cleanup при любом результате. Возвращает `SC_OK` при успехе, отрицательный `SC_ERR_*` при ошибке. |
|
||||
| `sc_stream_sign_cleanup(state)` | Освобождает ресурсы, обнуляет все поля; безопасен для NULL, пустого state и повторных вызовов. |
|
||||
|
||||
**Потоковая схема:** Ed25519 внутри делает SHA-512 от данных, поэтому для стриминга нужно было бы грузить все данные в память. Вместо этого: `SHA-512(данные)` делается инкрементально через `EVP_DigestUpdate`, затем 64-байтный хэш подписывается one-shot `EVP_DigestSign`. Результат: `Ed25519(SHA-512(данные))` — консистентно с обеих сторон. Память O(1).
|
||||
|
||||
|
||||
Reference in new issue
Block a user