You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
2.8 KiB
123 lines
2.8 KiB
/** @file
|
|
*****************************************************************************
|
|
|
|
Implementation of interfaces for wNAF ("weighted Non-Adjacent Form") exponentiation routines.
|
|
|
|
See wnaf.hpp .
|
|
|
|
*****************************************************************************
|
|
* @author This file is part of libsnark, developed by SCIPR Lab
|
|
* and contributors (see AUTHORS).
|
|
* @copyright MIT license (see LICENSE file)
|
|
*****************************************************************************/
|
|
|
|
#ifndef WNAF_TCC_
|
|
#define WNAF_TCC_
|
|
|
|
namespace libsnark {
|
|
|
|
template<mp_size_t n>
|
|
std::vector<long> find_wnaf(const size_t window_size, const bigint<n> &scalar)
|
|
{
|
|
const size_t length = scalar.max_bits(); // upper bound
|
|
std::vector<long> res(length+1);
|
|
bigint<n> c = scalar;
|
|
long j = 0;
|
|
while (!c.is_zero())
|
|
{
|
|
long u;
|
|
if ((c.data[0] & 1) == 1)
|
|
{
|
|
u = c.data[0] % (1u << (window_size+1));
|
|
if (u > (1 << window_size))
|
|
{
|
|
u = u - (1 << (window_size+1));
|
|
}
|
|
|
|
if (u > 0)
|
|
{
|
|
mpn_sub_1(c.data, c.data, n, u);
|
|
}
|
|
else
|
|
{
|
|
mpn_add_1(c.data, c.data, n, -u);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
u = 0;
|
|
}
|
|
res[j] = u;
|
|
++j;
|
|
|
|
mpn_rshift(c.data, c.data, n, 1); // c = c/2
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
template<typename T, mp_size_t n>
|
|
T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint<n> &scalar)
|
|
{
|
|
std::vector<long> naf = find_wnaf(window_size, scalar);
|
|
std::vector<T> table(1ul<<(window_size-1));
|
|
T tmp = base;
|
|
T dbl = base.dbl();
|
|
for (size_t i = 0; i < 1ul<<(window_size-1); ++i)
|
|
{
|
|
table[i] = tmp;
|
|
tmp = tmp + dbl;
|
|
}
|
|
|
|
T res = T::zero();
|
|
bool found_nonzero = false;
|
|
for (long i = naf.size()-1; i >= 0; --i)
|
|
{
|
|
if (found_nonzero)
|
|
{
|
|
res = res.dbl();
|
|
}
|
|
|
|
if (naf[i] != 0)
|
|
{
|
|
found_nonzero = true;
|
|
if (naf[i] > 0)
|
|
{
|
|
res = res + table[naf[i]/2];
|
|
}
|
|
else
|
|
{
|
|
res = res - table[(-naf[i])/2];
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
template<typename T, mp_size_t n>
|
|
T opt_window_wnaf_exp(const T &base, const bigint<n> &scalar, const size_t scalar_bits)
|
|
{
|
|
size_t best = 0;
|
|
for (long i = T::wnaf_window_table.size() - 1; i >= 0; --i)
|
|
{
|
|
if (scalar_bits >= T::wnaf_window_table[i])
|
|
{
|
|
best = i+1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (best > 0)
|
|
{
|
|
return fixed_window_wnaf_exp(best, base, scalar);
|
|
}
|
|
else
|
|
{
|
|
return scalar * base;
|
|
}
|
|
}
|
|
|
|
} // libsnark
|
|
|
|
#endif // WNAF_TCC_
|
|
|