Я думаю, что следующее является относительно простым способом для достижения своих целей (по крайней мере, очень близко к нему). Для этого требуется поставщик данных, чтобы узнать, как вы раскалываетесь данные, по крайней мере, на каком-то уровне детализации. Каждый из этих блоков данных не может изменить, но вы можете смешивать и сочетать любые комбинации гранулированным блока.
Так что если у вас есть терабайт полные данные, то говорят, 1MB самый маленький блок. вам потребуется 1 млн хэшей, но с 30 000: 1 сокращения размера, может быть, это приемлемо. Это решение компромисса, который не влияет на расчет. Больше, наименьший блок (позволяет называть его sblock), тем меньше гибкость, чтобы распределить его, тем меньше sblock, тем больше гибкость, но и более элементов должны быть сохранены.
Создателю данных необходимо знать размер sblock и применить то же вычисление, как вы делаете, а затем подписать его так, у вас есть доказательства того, что это то, что было доставлено.
Для каждого sblock ценности данных (мы предполагаем, что последний блок zerofilled) делаем SHA256 хэш, а затем рассматривать это как curve25519 элемент поля. Пять битов необходимо будет жестко, но есть еще 251 бит и вероятность столкновения чрезвычайно малы.
Следующий код предполагает 64-разрядных CPU и должен быть близок к расчету рабочего sblocks:
/ ************************************************* *****************************
* Copyright © 2014-2016 Надсеть Разработчики. *
* *
* См АВТОРОВ, Девелопер-ДОГОВОР и ЛИЦЕНЗИОННЫЕ файлы *
* Каталог верхнего уровня этого распределения для индивидуального авторского права *
* Держатель информация и политика разработчиков в области авторского права и лицензирование. *
* *
* Если иное не оговорено в лицензионном соглашении на заказ, ни одна часть *
* Надсеть программного обеспечения, в том числе и этот файл может быть скопирована, изменена, размножают *
* Или распространяться только в соответствии с условиями, содержащимися в файле ЛИЦЕНЗИИ *
* *
* Удаление или модификация этого уведомления об авторском праве запрещено. *
* *
************************************************** **************************** /
#включают
#включают
#включают
#включают
sha256_vstate структура {uint64_t длины; uint32_t состояния [8], curlen; uint8_t ЬиЕ [64]; };
объединение _bits256 {uint8_t байт [32]; uint16_t ushorts [16]; uint32_t uints [8]; uint64_t ulongs [4]; uint64_t TXID; };
ЬурейеЕ союз _bits256 bits256;
объединение _bits320 {uint8_t байт [40]; uint16_t ushorts [20]; uint32_t uints [10]; uint64_t ulongs [5]; uint64_t TXID; };
ЬурейеЕ союз _bits320 bits320;
// специальный НКУ режим для 128-битных целых чисел
ЬурейеЕ беззнаковое uint128_t __attribute __ ((режим (TI)));
// sha256 портирован из libtom, то curve25519 будет переработан donna_curve25519.c
#define STORE32L (х, у) \
{(У) [3] = (uint8_t) (((х)>>24)&255); (У) [2] = (uint8_t) (((х)>>16)&255); \
(У) [1] = (uint8_t) (((х)>>8)&255); (У) [0] = (uint8_t) ((х)&255); }
#define LOAD32L (х, у) \
\
((Uint32_t) ((у) [0] & 255)));
#define STORE64L (х, у) \
{(У) [7] = (uint8_t) (((х)>>56)&255); (У) [6] = (uint8_t) (((х)>>48)&255); \
(У) [5] = (uint8_t) (((х)>>40)&255); (У) [4] = (uint8_t) (((х)>>32)&255); \
(У) [3] = (uint8_t) (((х)>>24)&255); (У) [2] = (uint8_t) (((х)>>16)&255); \
(У) [1] = (uint8_t) (((х)>>8)&255); (У) [0] = (uint8_t) ((х)&255); }
#define LOAD64L (х, у) \
\
(((Uint64_t) ((у) [1] & 255))<<8)
#define STORE32H (х, у) \
{(У) [0] = (uint8_t) (((х)>>24)&255); (У) [1] = (uint8_t) (((х)>>16)&255); \
(У) [2] = (uint8_t) (((х)>>8)&255); (У) [3] = (uint8_t) ((х)&255); }
#define LOAD32H (х, у) \
\
((Uint32_t) ((у) [2] & 255)<<8)
#define STORE64H (х, у) \
{(У) [0] = (uint8_t) (((х)>>56)&255); (У) [1] = (uint8_t) (((х)>>48)&255); \
(У) [2] = (uint8_t) (((х)>>40)&255); (У) [3] = (uint8_t) (((х)>>32)&255); \
(У) [4] = (uint8_t) (((х)>>24)&255); (У) [5] = (uint8_t) (((х)>>16)&255); \
(У) [6] = (uint8_t) (((х)>>8)&255); (У) [7] = (uint8_t) ((х)&255); }
#define LOAD64H (х, у) \
х = (((uint64_t) ((у) [0] & 255))<<56)
// Различные логические функции
#define RORC (х, у) (((((uint32_t) (х)&0xFFFFFFFFUL)>>(Uint32_t) ((у)&31)) | ((Uint32_t) (х)<<(Uint32_t) (32 - ((у)&31)))) & 0xFFFFFFFFUL)
#define Ch (х, у, г) (г ^ (х & (У ^ г)))
#define майор (х, у, г) (((х | у) & г) | (Икс & у))
#define S (х, п) RORC ((х), (п))
#define Р (х, п) (((х)&0xFFFFFFFFUL)>>(П))
#define Sigma0 (х) (S (х, 2) ^ S (х, 13) ^ S (X, 22))
#define Sigma1 (х) (С (х, 6) ^ S (X, 11) ^ S (X, 25))
#define Gamma0 (х) (S (х, 7) ^ S (х, 18) ^ Р (х, 3))
#define Gamma1 (х) (С (х, 17) ^ S (х, 19) ^ Р (х, 10))
#define MIN (х, у) (((х)<(У))? (Х) :( у))
int32_t sha256_vcompress (STRUCT sha256_vstate * мкр, uint8_t * ЬиЕ)
{
uint32_t S [8], Вт [64], t0, t1, я;
для (я = 0; я<8; я ++) // скопировать состояние в S
S [I] = MD->состояние [I];
для (я = 0; я<16; я ++) // скопировать состояние на 512 битов в W [0..15]
LOAD32H (W [I], ЬиЕ + (4 * я));
для (I = 16; я<64; я ++) // заполнить W [16..63]
W [I] = Gamma1 (Ш [я - 2]) + W [I - 7] + Gamma0 (Ш [я - 15]) + W [I - 16];
#define RND (а, б, в, г, д, е, ж, з, и, ки) \
t0 = H + Sigma1 (е) + Ч. (д, е, ж) + ки + W [I]; \
t1 = Sigma0 (а) + Maj (а, б, в); \
D + = t0; \
ч = t0 + t1;
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 0,0x428a2f98);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 1,0x71374491);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 2,0xb5c0fbcf);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 3,0xe9b5dba5);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 4,0x3956c25b);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 5,0x59f111f1);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 6,0x923f82a4);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 7,0xab1c5ed5);
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 8,0xd807aa98);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 9,0x12835b01);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 10,0x243185be);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 11,0x550c7dc3);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 12,0x72be5d74);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 13,0x80deb1fe);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 14,0x9bdc06a7);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 15,0xc19bf174);
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 16,0xe49b69c1);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 17,0xefbe4786);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 18,0x0fc19dc6);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 19,0x240ca1cc);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 20,0x2de92c6f);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 21,0x4a7484aa);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 22,0x5cb0a9dc);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 23,0x76f988da);
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 24,0x983e5152);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 25,0xa831c66d);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 26,0xb00327c8);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 27,0xbf597fc7);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 28,0xc6e00bf3);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 29,0xd5a79147);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 30,0x06ca6351);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 31,0x14292967);
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 32,0x27b70a85);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 33,0x2e1b2138);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 34,0x4d2c6dfc);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 35,0x53380d13);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 36,0x650a7354);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 37,0x766a0abb);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 38,0x81c2c92e);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 39,0x92722c85);
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 40,0xa2bfe8a1);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 41,0xa81a664b);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 42,0xc24b8b70);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 43,0xc76c51a3);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 44,0xd192e819);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 45,0xd6990624);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 46,0xf40e3585);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 47,0x106aa070);
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 48,0x19a4c116);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 49,0x1e376c08);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 50,0x2748774c);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 51,0x34b0bcb5);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 52,0x391c0cb3);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 53,0x4ed8aa4a);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 54,0x5b9cca4f);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 55,0x682e6ff3);
RND (S [0], S [1], S [2], S [3], S [4], S [5], S [6], S [7], 56,0x748f82ee);
RND (S [7], S [0], S [1], S [2], S [3], S [4], S [5], S [6], 57,0x78a5636f);
RND (S [6], S [7], S [0], S [1], S [2], S [3], S [4], S [5], 58,0x84c87814);
RND (S [5], S [6], S [7], S [0], S [1], S [2], S [3], S [4], 59,0x8cc70208);
RND (S [4], S [5], S [6], S [7], S [0], S [1], S [2], S [3], 60,0x90befffa);
RND (S [3], S [4], S [5], S [6], S [7], S [0], S [1], S [2], 61,0xa4506ceb);
RND (S [2], S [3], S [4], S [5], S [6], S [7], S [0], S [1], 62,0xbef9a3f7);
RND (S [1], S [2], S [3], S [4], S [5], S [6], S [7], S [0], 63,0xc67178f2);
#undef RND
для (я = 0; я<8; я ++) // обратная связь
MD->состояние [I] = MD->состояние [I] + S [I];
Возвращение (0);
}
#undef RORC
#undef Ch
#undef майор
#undef S
#undef R
#undef Sigma0
#undef Sigma1
#undef Gamma0
#undef Gamma1
недействительным sha256_vinit (структура sha256_vstate * мкр)
{
MD->curlen = 0;
MD->длина = 0;
MD->состояние [0] = 0x6A09E667UL;
MD->состояние [1] = 0xBB67AE85UL;
MD->состояние [2] = 0x3C6EF372UL;
MD->состояние [3] = 0xA54FF53AUL;
MD->состояние [4] = 0x510E527FUL;
MD->состояние [5] = 0x9B05688CUL;
MD->состояние [6] = 0x1F83D9ABUL;
MD->состояние [7] = 0x5BE0CD19UL;
}
int32_t sha256_vprocess (структура sha256_vstate * мкр, Const uint8_t * в, uint64_t inlen)
{
uint64_t н; int32_t заблуждается;
если (MD->curlen > SizeOf (MD->ЬиЕ))
Возвращение (-1);
в то время как (inlen > 0)
{
если (MD->curlen == 0 && inlen >= 64)
{
если ((ERR = sha256_vcompress (мкр (uint8_t *) в))! = 0)
возвращать (ERR);
MD->Длина + = 64 * 8, в + = 64, inlen - = 64;
}
еще
{
п = MIN (inlen, 64 - MD->curlen);
тетср (MD->ЬиЕ + MD->curlen, в, (size_t) N);
MD->curlen + = п, в + = п, inlen - = п;
если (MD->curlen == 64)
{
если ((ERR = sha256_vcompress (мД, MD->ЬиЕ))! = 0)
возвращать (ERR);
MD->Длина + = 8 * 64;
MD->curlen = 0;
}
}
}
Возвращение (0);
}
int32_t sha256_vdone (структура sha256_vstate * мкр, uint8_t * вне)
{
int32_t я;
если (MD->curlen >= SizeOf (MD->ЬиЕ))
Возвращение (-1);
MD->Длина + = MD->curlen * 8; // увеличить длину сообщения
MD->ЬиЕ [MD->curlen ++] = (uint8_t) 0x80; // добавить немного «1»
// если Len > 56 байт мы добавляем нули затем сжать. Тогда мы можем упасть обратно заполнение нулей и кодирование длины, как нормальные.
если (MD->curlen > 56)
{
в то время как (MD->curlen < 64)
MD->ЬиЕ [MD->curlen ++] = (uint8_t) 0;
sha256_vcompress (мкр, MD->ЬиЕ);
MD->curlen = 0;
}
в то время как (MD->curlen < 56) // подушечка ДО 56 байт нулей
MD->ЬиЕ [MD->curlen ++] = (uint8_t) 0;
STORE64H (MD->длина, MD->ЬиЕ + 56); // длина магазин
sha256_vcompress (мкр, MD->ЬиЕ);
для (я = 0; я<8; я ++) // выводим копия
STORE32H (MD->состояние [I], выход + (4 * я));
Возвращение (0);
}
недействительным store_limb (uint8_t * вне, uint64_t в)
{
int32_t я;
для (я = 0; я<8; я ++, в>>= 8)
из [I] = (в & 0xff);
}
uint64_t load_limb (uint8_t * в)
(((Uint64_t) в [4]) << 32)
// Возьмите немного-Endian, номер 32-байтный и развернуть его в виде многочлена
bits320 fexpand (bits256 Basepoint)
{
bits320 вне;
out.ulongs [0] = load_limb (basepoint.bytes) & 0x7ffffffffffffLL;
out.ulongs [1] = (load_limb (basepoint.bytes + 6) >> 3) & 0x7ffffffffffffLL;
out.ulongs [2] = (load_limb (basepoint.bytes + 12) >> 6) & 0x7ffffffffffffLL;
out.ulongs [3] = (load_limb (basepoint.bytes + 19) >> 1) & 0x7ffffffffffffLL;
out.ulongs [4] = (load_limb (basepoint.bytes + 24) >> 12) & 0x7ffffffffffffLL;
возврат (выход);
}
недействительный fcontract_iter (uint128_t т [5], int32_t флаг)
{
int32_t я; uint64_t маска = 0x7ffffffffffffLL;
для (я = 0; я<4; я ++)
т [г + 1] = т [г] >> 51, т [I] &= Маска;
если (флаг! = 0)
т [0] + = 19 * (т [4] >> 51); т [4] &= Маска;
}
// Возьмите полностью уменьшенную полиномиальное номер формы и контракт его в прямой порядок байтов, 32-байтовый массив
bits256 fcontract (Const bits320 вход)
uint128_t т [5]; int32_t я; bits256 вне;
для (я = 0; я<5; я ++)
T [I] = input.ulongs [I];
fcontract_iter (т, 1), fcontract_iter (т, 1);
// донна: в настоящее время т составляет от 0 до 2 ^ 255-1, правильно выполняется.
// донна: случай 1: от 0 до 2 ^ 255-20. Случай 2: между 2 ^ 255-19 и 2 ^ 255-1.
т [0] + = 19, fcontract_iter (т, 1);
// теперь между 19 и 2 ^ 255-1 в обоих случаях, и смещение на 19.
т [0] + = 0x8000000000000 - 19;
для (я = 1; я<5; я ++)
т [г] + = 0x8000000000000 - 1;
// теперь между 2 ^ 255 и 2 ^ 256-20, а компенсировано 2 ^ 255.
fcontract_iter (т, 0);
store_limb (out.bytes, т [0]
// Умножить два числа: выход = in2 * в
// выход должен быть отличным для обоих входов. Входы снижается коэффициент формы, выход не является.
// Предполагается, что в [я] < 2 ** 55 и также для in2. По возвращению, выход [I] < 2 ** 52
bits320 FMUL (Const bits320 дюйм2, Const bits320 в)
{
uint128_t т [5]; uint64_t R0, R1, R2, R3, R4, s0, s1, s2, s3, s4, с; bits320 вне;
r0 = in.ulongs [0], R1 = in.ulongs [1], г2 = in.ulongs [2], г3 = in.ulongs [3], r4 = in.ulongs [4];
s0 = in2.ulongs [0], s1 = in2.ulongs [1], с2 = in2.ulongs [2], s3 = in2.ulongs [3], s4 = in2.ulongs [4];
т [0] = ((uint128_t) г0) * s0;
т [1] = ((uint128_t) г0) * S1 + ((uint128_t) г1) * s0;
T [2] = ((uint128_t) г0) * s2 + ((uint128_t) г2) * S0 + ((uint128_t) г1) * s1;
т [3] = ((uint128_t) г0) * s3 + ((uint128_t) г3) * S0 + ((uint128_t) г1) * s2 + ((uint128_t) г2) * s1;
т [4] = ((uint128_t) г0) * s4 + ((uint128_t) г4) * S0 + ((uint128_t) г3) * S1 + ((uint128_t) г1) * s3 + ((uint128_t) г2) * с2;
r4 = 19, r 1 * = 19, r 2 * = 19, г3 * = 19;
т [0] + = ((uint128_t) г4) * S1 + ((uint128_t) г1) * s4 + ((uint128_t) г2) * s3 + ((uint128_t) г3) * с2;
т [1] + = ((uint128_t) г4) * s2 + ((uint128_t) г2) * s4 + ((uint128_t) г3) * s3;
T [2] + = ((uint128_t) г4) * s3 + ((uint128_t) г3) * s4;
т [3] + = ((uint128_t) г4) * s4;
г0 = (uint64_t) т [0] & 0x7ffffffffffffLL; с = (uint64_t) (т [0] >> 51);
т [1] + = с; R1 = (uint64_t) т [1] & 0x7ffffffffffffLL; с = (uint64_t) (т [1] >> 51);
T [2] + = с; r 2 = (uint64_t) т [2] & 0x7ffffffffffffLL; с = (uint64_t) (т [2] >> 51);
т [3] + = с; r3 = (uint64_t) т [3] & 0x7ffffffffffffLL; с = (uint64_t) (т [3] >> 51);
т [4] + = с; r4 = (uint64_t) т [4] & 0x7ffffffffffffLL; с = (uint64_t) (т [4] >> 51);
г0 + = с * 19; с = г0 >> 51; г0 = г0 & 0x7ffffffffffffLL;
R1 + = с; с = r1 >> 51; r1 = r1 & 0x7ffffffffffffLL;
R2 + = с;
out.ulongs [0] = г0, out.ulongs [1] = r1, out.ulongs [2] = г2, out.ulongs [3] = г3, out.ulongs [4] = r4;
возврат (выход);
}
ИНТ основной (интермедиат ARGC, Const символ * ARGV [])
{
int32_t sblocksize, длина; uint8_t * ЬиЕ; bits320 прод; bits256 TMP, хэш;
структура sha256_vstate мкр; FILE * Ф.П. * sblocks;
если (ARGC < 2)
Е ("Использование:% S файл данных [sblocksize] \ п", ARGV [0]);
иначе если (ARGC > 3 && (Sblocksize = atoi (ARGV [2])) < 32)
Е ("Использование:% S файл данных [sblocksize] # мин sblocksize 32 \ п", ARGV [0]);
иначе, если ((Fp = Еореп (ARGV [1],"Р.Б.")) == 0)
Е ("Использование:% S файл данные [sblocksize] # не может найти% s \ п", ARGV [0], ARGV [1]);
еще
{
если ((sblocks = Еореп ("sblocks","термометру")) == 0)
{
Е ("Ошибка при создании sblocks выходного файла \ п");
Выход (-1);
}
если (sblocksize == 0)
sblocksize = 1024 * 1024;
Е ("вычисления для sblocks% S \ N", ARGV [1]);
MemSet (tmp.bytes, 0, SizeOf (TMP)), tmp.bytes [0] = 9;
прод = fexpand (TMP); // начать с действительным элементом поля. может потребоваться использовать единичный элемент
ЬиЕ = calloc (1, sblocksize);
в то время как ((Len = (int32_t) Fread (BUF, 1, sblocksize, FP)) > 0)
sha256_vinit (&мкр), sha256_vprocess (&мкр, ЬиЕ, sblocksize), sha256_vdone (&MD, hash.bytes);
FWRITE (hash.bytes, 1, SizeOf (хэш), sblocks); // сохранить SHA256 из sblock
hash.bytes [0] &= 0xf8, hash.bytes [31] &= 0x7F, hash.bytes [31]
TMP = fcontract (прод);
FWRITE (tmp.bytes, 1, SizeOf (TMP), sblocks); // это значение всех данных
бесплатно (BUF);
fclose (FP);
fclose (sblocks);
Возвращение (0);
}
Возвращение (-1);
}
Я не имел шанс проверить это, но все это делает это вычисление SHA256 хэш каждого sblock, отображение его на элемент поля и умножив его на общую сумму. Операции на местах работают на 320 размере бита, так что 256-битный хэш должны быть расширен, и по контракту.
Так как это чисто поле умножения, он не имеет никакой другой защиты, подписи и этажерки должны быть добавлены на вершине этого. Обратите внимание, что это неупорядоченное как FMUL просто чистая многократно, если вам это нужно заказывать, а затем просто включить номер последовательности в расчет SHA256.
Это полностью автономный портативный C так, чтобы сохранить файл, а затем GCC это сделать исполняемый файл. Выход является sblocks файл, который имеет соответствующий хэш для каждого sblock вместе с общим в конце.
Надеемся, что она работает для того, что вам нужно. Это просто быстрое доказательство концептуального кода, но если какое-либо бит изменяется в любом из sblocks, хэш изменится, который изменит комбинированный продукт. Совершая к sblock хэш, вы можете доказать, что вы штрафную коррумпированные данные, которые вы получили, пока поставщик данных также выполняет ту же программу, и подписывает его. Любое подмножество, которое поставляется может быть проверено независимо, чтобы соответствовать вашему размещенному набору sblock хэш.
Я думаю, что удовлетворяет вашим требованиям?
Джеймс
Постскриптум Если вероятность столкновения (около 1 в 2 ^ 120) слишком высок, то второй хэш может быть использована для создания двух элементов на sblock. Коэффициенты два различных хэш столкновений с теми же данными, исчезающе малы.