Correct remaining crypto examples and streaming signature buffer contract
This commit is contained in:
1 parent
3afd31e561
commit
16a33ac9f7
2 files changed
+11
-9
No files matched your search
@@ -117,6 +117,7 @@ struct sc_stream_sign_state {
|
||||
sc_status_t sc_stream_sign_init(sc_context_t *ctx, struct sc_stream_sign_state *state);
|
||||
sc_status_t sc_stream_sign_verify_init(struct sc_stream_sign_state *state, const uint8_t *ed25519_pubkey);
|
||||
sc_status_t sc_stream_sign_update(struct sc_stream_sign_state *state, const uint8_t *data, size_t len);
|
||||
/* sig_len задаёт capacity sig_out (не менее 64), при успехе получает длину 64; завершение освобождает sign state. */
|
||||
sc_status_t sc_stream_sign_final(struct sc_stream_sign_state *state, uint8_t *sig_out, size_t *sig_len);
|
||||
sc_status_t sc_stream_sign_verify(struct sc_stream_sign_state *state, const uint8_t *sig, size_t sig_len);
|
||||
void sc_stream_sign_cleanup(struct sc_stream_sign_state *state);
|
||||
|
||||
@@ -123,18 +123,20 @@ 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;
|
||||
uint8_t stream_sig[SC_SIGN_SIZE];
|
||||
size_t sig_len = sizeof(stream_sig);
|
||||
|
||||
// Подпись
|
||||
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, sig, &sig_len); // автоматический cleanup
|
||||
sc_stream_sign_final(&state, stream_sig, &sig_len); // sig_len — capacity на входе, длина подписи на выходе; cleanup
|
||||
|
||||
// Верификация
|
||||
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, sig, sig_len); // SC_OK или SC_ERR_AUTH_FAILED
|
||||
int result = sc_stream_sign_verify(&state, stream_sig, sig_len); // SC_OK или SC_ERR_AUTH_FAILED
|
||||
```
|
||||
|
||||
**Деривация Ed25519-ключа из X25519:** `sc_derive_ed25519_pubkey(x25519_privkey, ed25519_pubkey)` — SHA-512 от X25519-приватного ключа даёт Ed25519-приватный ключ (32 байта), из которого извлекается Ed25519-публичный ключ. Это позволяет одному ключу обслуживать и ECDH, и подписи.
|
||||
@@ -142,8 +144,8 @@ int result = sc_stream_sign_verify(&state, sig, sig_len); // SC_OK или SC_ER
|
||||
### 2.5. Деривация node_id
|
||||
|
||||
```c
|
||||
uint64_t node_id = sc_derive_node_id(private_key);
|
||||
// SHA256(private_key) → первые 8 байт, старший бит обнулён (0x7FFFFFFFFFFFFFFF)
|
||||
uint64_t node_id = sc_derive_node_id_from_pubkey(public_key);
|
||||
// SHA256(X25519 public_key[32]) → первые 8 байт memcpy в uint64_t хоста, старший бит обнулён
|
||||
```
|
||||
|
||||
### 2.6. SHA256-based транскодирование
|
||||
@@ -266,7 +268,7 @@ Nonce не зависит от часов, счётчиков контекста
|
||||
| `sc_stream_sign_init(ctx, state)` | Инициализирует подпись. Извлекает Ed25519-ключ из X25519 через `SHA512(x25519_privkey)`. |
|
||||
| `sc_stream_sign_verify_init(state, ed25519_pubkey)` | Инициализирует верификацию с переданным Ed25519 pubkey. |
|
||||
| `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=64`. |
|
||||
| `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_AUTH_FAILED`. |
|
||||
| `sc_stream_sign_cleanup(state)` | Ручная очистка (если не вызван final/verify). |
|
||||
|
||||
@@ -353,15 +355,14 @@ Nonce не зависит от часов, счётчиков контекста
|
||||
```
|
||||
|
||||
- `session_ready` становится 1 только после успешного ECDH через `sc_set_peer_public_key()`
|
||||
- Контекст привязан к конкретному пиру (peer_public_key фиксирован)
|
||||
- Для смены пира нужен новый контекст
|
||||
- Успешный `sc_set_peer_public_key` сохраняет ключ текущего пира и заново вычисляет session_key
|
||||
- Счётчики не синхронизируются между сторонами — каждая сторона считает свои tx/rx независимо
|
||||
|
||||
---
|
||||
|
||||
## 6. Примечания по безопасности
|
||||
|
||||
- **Nonce должен быть уникальным** для каждого шифрования с одним ключом. Здесь nonce строится из `SHA256(random_seed || counter || время)`. При случайном seed и монотонном counter'е коллизии крайне маловероятны.
|
||||
- **CCM nonce** — 13 байт из OpenSSL RAND_bytes; при отказе CSPRNG encrypt возвращает ошибку без готового пакета.
|
||||
- **CRC32 — не криптографическая защита.** Он дополнительно ловит битовые ошибки после расшифровки (belt-and-suspenders), но основная защита целостности — CCM-тег.
|
||||
- **Обфускация pubkey — не шифрование.** Это XOR с детерминированным хэшем, обратима для любого, кто знает salt и второй pubkey. Защищает от пассивного наблюдения (не видно публичный ключ в открытом виде), но не от активной подмены.
|
||||
- **OpenSSL EVP API** используется для всех криптоопераций (реализации FIPS-сертифицированы при использовании FIPS-провайдера).
|
||||
- X25519, AES-CCM, AES-CTR и Ed25519 выполняются через OpenSSL EVP.
|
||||
Reference in new issue
Block a user