В библиотеке Stanford JS Crypto Library (SJCL) схема разделения секрета обычно основана на подходе Шамира: исходное значение преобразуется в коэффициенты многочлена, а каждая доля представляет собой точку на этом многочлене.
Типичная структура доли включает:
Пример представления:
{
id: 1,
value: "0x8f3a91c2..."
}
Корректность таких долей критична, поскольку любая искажённая точка может привести к невозможности восстановления секрета или, хуже, к подмене результата реконструкции.
Первый уровень проверки — синтаксический и структурный. Он не требует криптографии, но отсекает некорректные или повреждённые данные.
Проверяются следующие свойства:
null значенийfunction validateShare(share) {
if (!share) return false;
if (typeof share.id !== "number") return false;
if (typeof share.value !== "string") return false;
if (share.id <= 0) return false;
if (share.value.length === 0) return false;
return true;
}
На этом этапе отбрасываются повреждённые или неполные доли, но не выявляется подмена.
В схемах Шамира каждая доля соответствует уникальной точке.
Повторяющиеся id нарушают корректность системы.
Основные проверки:
function checkUniqueIds(shares) {
const ids = new Set();
for (const s of shares) {
if (ids.has(s.id)) return false;
ids.add(s.id);
}
return true;
}
Также важно учитывать пороговое значение t (threshold).
Если доступных уникальных долей меньше порога, восстановление невозможно
даже при идеальных данных.
В SJCL значения долей обычно представлены как элементы конечного поля или закодированные бинарные массивы.
Ключевые проверки:
function checkValueFormat(value) {
return /^0x[0-9a-fA-F]+$/.test(value);
}
Ошибки на этом уровне часто возникают из-за повреждения транспорта данных (JSON, сеть, хранилище).
Наиболее надёжный способ проверки корректности долей — частичная реконструкция секрета из подмножеств.
Идея:
Если доли корректны, все реконструкции дают одинаковый результат.
function tryReconstruction(combine, shares, threshold) {
const subset = shares.slice(0, threshold);
const secret1 = combine(subset);
const subset2 = shares.slice(1, threshold + 1);
const secret2 = combine(subset2);
return secret1 === secret2;
}
Этот метод выявляет:
В основе схемы лежит многочлен степени t-1. Каждая доля
должна удовлетворять уравнению:
y = f(x)
где f(x) — секретный многочлен.
Проверка корректности сводится к проверке существования единственного многочлена, проходящего через все точки.
Практическая реализация:
function verifyPolynomialConsistency(reconstruct, shares) {
try {
const secret = reconstruct(shares);
return secret !== undefined && secret !== null;
} catch (e) {
return false;
}
}
Если хотя бы одна точка фальсифицирована, система либо выдаёт другой результат, либо не сходится.
Сам SJCL в базовой форме не всегда добавляет встроенную аутентификацию каждой доли, поэтому часто используется внешний слой:
Пример расширенной структуры:
{
id: 3,
value: "0x9a12ff...",
mac: "b1946ac92492d2347c6235b4d2611184"
}
Проверка:
function verifyMac(share, hmacFn, key) {
const computed = hmacFn(key, share.id + ":" + share.value);
return computed === share.mac;
}
Это защищает от:
Некоторые повреждения не делают долю полностью недействительной, но искажают её значение.
Методы выявления:
Пример эвристики:
function sanityCheck(value) {
const bytes = value.length / 2;
return bytes >= 16 && bytes <= 256;
}
Корректность системы определяется не отдельными долями, а их набором.
Основные свойства:
Формально набор должен удовлетворять:
n t
где n — число доступных долей, t — порог
восстановления.
При активных атаках возможны ситуации, когда часть долей намеренно искажена.
Признаки:
Метод анализа:
function detectAnomalies(combine, shares, threshold) {
const results = [];
for (let i = 0; i < shares.length - threshold + 1; i++) {
const subset = shares.slice(i, i + threshold);
results.push(combine(subset));
}
return new Set(results).size === 1;
}
Полная схема проверки включает последовательные уровни:
Совокупность этих этапов позволяет обнаруживать как случайные ошибки передачи, так и преднамеренные искажения данных в системе разделения секрета на базе SJCL.