awesome-blockchain/src/ConfidentialTx/crypto/secp256k1/libsecp256k1/src/modules/bulletproofs/util.h

117 lines
3.5 KiB
C

/**********************************************************************
* Copyright (c) 2018 Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef SECP256K1_MODULE_BULLETPROOF_UTIL
#define SECP256K1_MODULE_BULLETPROOF_UTIL
/* floor(log2(n)) which returns 0 for 0, since this is used to estimate proof sizes */
SECP256K1_INLINE static size_t secp256k1_floor_lg(size_t n) {
switch (n) {
case 0: return 0;
case 1: return 0;
case 2: return 1;
case 3: return 1;
case 4: return 2;
case 5: return 2;
case 6: return 2;
case 7: return 2;
case 8: return 3;
default: {
size_t i = 0;
while (n > 1) {
n /= 2;
i++;
}
return i;
}
}
}
static void secp256k1_scalar_dot_product(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, size_t n) {
secp256k1_scalar_clear(r);
while(n--) {
secp256k1_scalar term;
secp256k1_scalar_mul(&term, &a[n], &b[n]);
secp256k1_scalar_add(r, r, &term);
}
}
static void secp256k1_scalar_inverse_all_var(secp256k1_scalar *r, const secp256k1_scalar *a, size_t len) {
secp256k1_scalar u;
size_t i;
if (len < 1) {
return;
}
VERIFY_CHECK((r + len <= a) || (a + len <= r));
r[0] = a[0];
i = 0;
while (++i < len) {
secp256k1_scalar_mul(&r[i], &r[i - 1], &a[i]);
}
secp256k1_scalar_inverse_var(&u, &r[--i]);
while (i > 0) {
size_t j = i--;
secp256k1_scalar_mul(&r[j], &r[i], &u);
secp256k1_scalar_mul(&u, &u, &a[j]);
}
r[0] = u;
}
SECP256K1_INLINE static void secp256k1_bulletproof_serialize_points(unsigned char *out, secp256k1_ge *pt, size_t n) {
const size_t bitveclen = (n + 7) / 8;
size_t i;
memset(out, 0, bitveclen);
for (i = 0; i < n; i++) {
secp256k1_fe pointx;
pointx = pt[i].x;
secp256k1_fe_normalize(&pointx);
secp256k1_fe_get_b32(&out[bitveclen + i*32], &pointx);
if (!secp256k1_fe_is_quad_var(&pt[i].y)) {
out[i/8] |= (1ull << (i % 8));
}
}
}
SECP256K1_INLINE static void secp256k1_bulletproof_deserialize_point(secp256k1_ge *pt, const unsigned char *data, size_t i, size_t n) {
const size_t bitveclen = (n + 7) / 8;
const size_t offset = bitveclen + i*32;
secp256k1_fe fe;
secp256k1_fe_set_b32(&fe, &data[offset]);
secp256k1_ge_set_xquad(pt, &fe);
if (data[i / 8] & (1 << (i % 8))) {
secp256k1_ge_neg(pt, pt);
}
}
static void secp256k1_bulletproof_update_commit(unsigned char *commit, const secp256k1_ge *lpt, const secp256k1_ge *rpt) {
secp256k1_fe pointx;
secp256k1_sha256 sha256;
unsigned char lrparity;
lrparity = (!secp256k1_fe_is_quad_var(&lpt->y) << 1) + !secp256k1_fe_is_quad_var(&rpt->y);
secp256k1_sha256_initialize(&sha256);
secp256k1_sha256_write(&sha256, commit, 32);
secp256k1_sha256_write(&sha256, &lrparity, 1);
pointx = lpt->x;
secp256k1_fe_normalize(&pointx);
secp256k1_fe_get_b32(commit, &pointx);
secp256k1_sha256_write(&sha256, commit, 32);
pointx = rpt->x;
secp256k1_fe_normalize(&pointx);
secp256k1_fe_get_b32(commit, &pointx);
secp256k1_sha256_write(&sha256, commit, 32);
secp256k1_sha256_finalize(&sha256, commit);
}
#endif