mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
94 lines
2.2 KiB
C
94 lines
2.2 KiB
C
/*
|
|
* Copyright (C) 2017 Nagravision S.A.
|
|
*/
|
|
#include "batch.h"
|
|
|
|
#include "merkle.h"
|
|
|
|
int batch_init (struct batch_buf *buf) {
|
|
buf->count = 0;
|
|
return GRAVITY_OK;
|
|
}
|
|
|
|
int batch_append (struct batch_buf *buf, const uint8_t *msg, uint64_t len, uint32_t *index) {
|
|
if (buf->count == MAX_BATCH_COUNT) return GRAVITY_ERR_BATCH;
|
|
|
|
/* TODO: randomize this hash? */
|
|
hash_to_N (&buf->buf[buf->count], msg, len);
|
|
|
|
*index = buf->count;
|
|
++buf->count;
|
|
|
|
return GRAVITY_OK;
|
|
}
|
|
|
|
int batch_group (struct batch_group *group, struct batch_buf *buf) {
|
|
int height = LOG_MAX_BATCH_COUNT;
|
|
int n = 1 << height;
|
|
int offset = n - 1;
|
|
|
|
struct hash *src;
|
|
struct hash *dst;
|
|
uint32_t count;
|
|
int i;
|
|
|
|
/* Check batch count */
|
|
count = buf->count;
|
|
if (count == 0) return GRAVITY_ERR_BATCH;
|
|
group->count = count;
|
|
|
|
/* Leaves */
|
|
dst = &group->tree[offset];
|
|
|
|
hashcpyN (dst, buf->buf, count);
|
|
for (i = count; i < n; ++i) hashcpy (&dst[i], &buf->buf[0]);
|
|
|
|
/* Compress until root */
|
|
while (height > 0) {
|
|
offset >>= 1;
|
|
--height;
|
|
|
|
src = dst;
|
|
dst = &group->tree[offset];
|
|
hash_compress_pairs (dst, src, 1 << height);
|
|
}
|
|
|
|
return GRAVITY_OK;
|
|
}
|
|
|
|
int batch_extract (const struct batch_group *group, struct batch_auth *auth, uint32_t index) {
|
|
int height = LOG_MAX_BATCH_COUNT;
|
|
int n = 1 << height;
|
|
int offset = n - 1;
|
|
|
|
uint32_t count;
|
|
int i, sibling;
|
|
|
|
/* Check batch count */
|
|
count = group->count;
|
|
if (index >= count) return GRAVITY_ERR_BATCH;
|
|
|
|
/* Convert row index into tree index */
|
|
auth->index = offset + index;
|
|
|
|
/* Copy auth path */
|
|
for (i = 0; i < height; ++i) {
|
|
sibling = index ^ 1;
|
|
hashcpy (&auth->auth[i], &group->tree[offset + sibling]);
|
|
index >>= 1;
|
|
offset >>= 1;
|
|
}
|
|
|
|
return GRAVITY_OK;
|
|
}
|
|
|
|
void batch_compress_auth (struct hash *node,
|
|
const struct batch_auth *auth,
|
|
const uint8_t *msg,
|
|
uint64_t len) {
|
|
/* Compute Merkle tree root */
|
|
int height = LOG_MAX_BATCH_COUNT;
|
|
hash_to_N (node, msg, len);
|
|
merkle_compress_auth (node, auth->index, auth->auth, height);
|
|
}
|