mirror of
https://github.com/monero-project/monero.git
synced 2025-01-09 20:40:11 +00:00
add seraphis crypto utils
This commit is contained in:
parent
059028a30a
commit
a22473706c
4 changed files with 457 additions and 1 deletions
|
@ -27,7 +27,7 @@
|
||||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
set(seraphis_crypto_sources
|
set(seraphis_crypto_sources
|
||||||
dummy.cpp)
|
sp_crypto_utils.cpp)
|
||||||
|
|
||||||
monero_find_all_headers(seraphis_crypto_headers, "${CMAKE_CURRENT_SOURCE_DIR}")
|
monero_find_all_headers(seraphis_crypto_headers, "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
|
|
286
src/seraphis_crypto/sp_crypto_utils.cpp
Normal file
286
src/seraphis_crypto/sp_crypto_utils.cpp
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
// Copyright (c) 2022, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//paired header
|
||||||
|
#include "sp_crypto_utils.h"
|
||||||
|
|
||||||
|
//local headers
|
||||||
|
#include "crypto/crypto.h"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include "crypto/crypto-ops.h"
|
||||||
|
}
|
||||||
|
#include "crypto/x25519.h"
|
||||||
|
#include "misc_log_ex.h"
|
||||||
|
#include "ringct/rctOps.h"
|
||||||
|
#include "ringct/rctTypes.h"
|
||||||
|
|
||||||
|
//third party headers
|
||||||
|
#include "boost/multiprecision/cpp_int.hpp"
|
||||||
|
|
||||||
|
//standard headers
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||||
|
#define MONERO_DEFAULT_LOG_CATEGORY "seraphis"
|
||||||
|
|
||||||
|
namespace sp
|
||||||
|
{
|
||||||
|
|
||||||
|
/// File-scope data
|
||||||
|
|
||||||
|
// Useful scalar and group constants
|
||||||
|
static const rct::key ZERO = rct::zero();
|
||||||
|
static const rct::key ONE = rct::identity();
|
||||||
|
/// scalar: -1 mod q
|
||||||
|
static const rct::key MINUS_ONE = { {0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
|
||||||
|
0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10} };
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Helper function for scalar inversion
|
||||||
|
// return: x*(y^2^n)
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
static rct::key sm(rct::key y, int n, const rct::key &x)
|
||||||
|
{
|
||||||
|
while (n--)
|
||||||
|
sc_mul(y.bytes, y.bytes, y.bytes);
|
||||||
|
sc_mul(y.bytes, y.bytes, x.bytes);
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
rct::key minus_one()
|
||||||
|
{
|
||||||
|
return MINUS_ONE;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
rct::key invert(const rct::key &x)
|
||||||
|
{
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(!(x == ZERO), "Cannot invert zero!");
|
||||||
|
|
||||||
|
rct::key _1, _10, _100, _11, _101, _111, _1001, _1011, _1111;
|
||||||
|
|
||||||
|
_1 = x;
|
||||||
|
sc_mul(_10.bytes, _1.bytes, _1.bytes);
|
||||||
|
sc_mul(_100.bytes, _10.bytes, _10.bytes);
|
||||||
|
sc_mul(_11.bytes, _10.bytes, _1.bytes);
|
||||||
|
sc_mul(_101.bytes, _10.bytes, _11.bytes);
|
||||||
|
sc_mul(_111.bytes, _10.bytes, _101.bytes);
|
||||||
|
sc_mul(_1001.bytes, _10.bytes, _111.bytes);
|
||||||
|
sc_mul(_1011.bytes, _10.bytes, _1001.bytes);
|
||||||
|
sc_mul(_1111.bytes, _100.bytes, _1011.bytes);
|
||||||
|
|
||||||
|
rct::key inv;
|
||||||
|
sc_mul(inv.bytes, _1111.bytes, _1.bytes);
|
||||||
|
|
||||||
|
inv = sm(inv, 123 + 3, _101);
|
||||||
|
inv = sm(inv, 2 + 2, _11);
|
||||||
|
inv = sm(inv, 1 + 4, _1111);
|
||||||
|
inv = sm(inv, 1 + 4, _1111);
|
||||||
|
inv = sm(inv, 4, _1001);
|
||||||
|
inv = sm(inv, 2, _11);
|
||||||
|
inv = sm(inv, 1 + 4, _1111);
|
||||||
|
inv = sm(inv, 1 + 3, _101);
|
||||||
|
inv = sm(inv, 3 + 3, _101);
|
||||||
|
inv = sm(inv, 3, _111);
|
||||||
|
inv = sm(inv, 1 + 4, _1111);
|
||||||
|
inv = sm(inv, 2 + 3, _111);
|
||||||
|
inv = sm(inv, 2 + 2, _11);
|
||||||
|
inv = sm(inv, 1 + 4, _1011);
|
||||||
|
inv = sm(inv, 2 + 4, _1011);
|
||||||
|
inv = sm(inv, 6 + 4, _1001);
|
||||||
|
inv = sm(inv, 2 + 2, _11);
|
||||||
|
inv = sm(inv, 3 + 2, _11);
|
||||||
|
inv = sm(inv, 3 + 2, _11);
|
||||||
|
inv = sm(inv, 1 + 4, _1001);
|
||||||
|
inv = sm(inv, 1 + 3, _111);
|
||||||
|
inv = sm(inv, 2 + 4, _1111);
|
||||||
|
inv = sm(inv, 1 + 4, _1011);
|
||||||
|
inv = sm(inv, 3, _101);
|
||||||
|
inv = sm(inv, 2 + 4, _1111);
|
||||||
|
inv = sm(inv, 3, _101);
|
||||||
|
inv = sm(inv, 1 + 2, _11);
|
||||||
|
|
||||||
|
// Confirm inversion
|
||||||
|
rct::key temp;
|
||||||
|
sc_mul(temp.bytes, x.bytes, inv.bytes);
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(temp == ONE, "Scalar inversion failed!");
|
||||||
|
|
||||||
|
return inv;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
void decompose(const std::size_t val, const std::size_t base, const std::size_t size, std::vector<std::size_t> &r_out)
|
||||||
|
{
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(base > 1, "Bad decomposition parameters!");
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(size > 0, "Bad decomposition parameters!");
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(r_out.size() == size, "Bad decomposition result vector size!");
|
||||||
|
|
||||||
|
std::size_t temp = val;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
std::size_t slot = std::pow(base, size - i - 1);
|
||||||
|
r_out[size - i - 1] = temp/slot;
|
||||||
|
temp -= slot*r_out[size - i - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
rct::key kronecker_delta(const std::size_t x, const std::size_t y)
|
||||||
|
{
|
||||||
|
if (x == y)
|
||||||
|
return ONE;
|
||||||
|
else
|
||||||
|
return ZERO;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
rct::keyV convolve(const rct::keyV &x, const rct::keyV &y, const std::size_t m)
|
||||||
|
{
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(x.size() >= m, "Bad convolution parameters!");
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(y.size() == 2, "Bad convolution parameters!");
|
||||||
|
|
||||||
|
rct::key temp;
|
||||||
|
rct::keyV result;
|
||||||
|
result.resize(m + 1, ZERO);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < m; ++i)
|
||||||
|
{
|
||||||
|
for (std::size_t j = 0; j < 2; ++j)
|
||||||
|
{
|
||||||
|
sc_mul(temp.bytes, x[i].bytes, y[j].bytes);
|
||||||
|
sc_add(result[i + j].bytes, result[i + j].bytes, temp.bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
rct::keyV powers_of_scalar(const rct::key &scalar, const std::size_t num_pows, const bool negate_all)
|
||||||
|
{
|
||||||
|
if (num_pows == 0)
|
||||||
|
return rct::keyV{};
|
||||||
|
|
||||||
|
rct::keyV pows;
|
||||||
|
pows.resize(num_pows);
|
||||||
|
|
||||||
|
if (negate_all)
|
||||||
|
pows[0] = MINUS_ONE;
|
||||||
|
else
|
||||||
|
pows[0] = ONE;
|
||||||
|
|
||||||
|
for (std::size_t i = 1; i < num_pows; ++i)
|
||||||
|
{
|
||||||
|
sc_mul(pows[i].bytes, pows[i - 1].bytes, scalar.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pows;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
void generate_proof_nonce(const rct::key &base, crypto::secret_key &nonce_out, rct::key &nonce_pub_out)
|
||||||
|
{
|
||||||
|
// make proof nonce as crypto::secret_key
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(!(base == rct::identity()), "Bad base for generating proof nonce!");
|
||||||
|
|
||||||
|
nonce_out = rct::rct2sk(ZERO);
|
||||||
|
|
||||||
|
while (nonce_out == rct::rct2sk(ZERO) || nonce_pub_out == rct::identity())
|
||||||
|
{
|
||||||
|
nonce_out = rct::rct2sk(rct::skGen());
|
||||||
|
rct::scalarmultKey(nonce_pub_out, base, rct::sk2rct(nonce_out));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
void generate_proof_nonce(const rct::key &base, rct::key &nonce_out, rct::key &nonce_pub_out)
|
||||||
|
{
|
||||||
|
// make proof nonce as rct::key
|
||||||
|
crypto::secret_key temp;
|
||||||
|
generate_proof_nonce(base, temp, nonce_pub_out);
|
||||||
|
nonce_out = rct::sk2rct(temp);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
void subtract_secret_key_vectors(const std::vector<crypto::secret_key> &keys_A,
|
||||||
|
const std::vector<crypto::secret_key> &keys_B,
|
||||||
|
crypto::secret_key &result_out)
|
||||||
|
{
|
||||||
|
result_out = rct::rct2sk(rct::zero());
|
||||||
|
|
||||||
|
// add keys_A
|
||||||
|
for (const crypto::secret_key &key_A : keys_A)
|
||||||
|
sc_add(to_bytes(result_out), to_bytes(result_out), to_bytes(key_A));
|
||||||
|
|
||||||
|
// subtract keys_B
|
||||||
|
for (const crypto::secret_key &key_B : keys_B)
|
||||||
|
sc_sub(to_bytes(result_out), to_bytes(result_out), to_bytes(key_B));
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
void mask_key(const crypto::secret_key &mask, const rct::key &key, rct::key &masked_key_out)
|
||||||
|
{
|
||||||
|
// K" = mask G + K
|
||||||
|
rct::addKeys1(masked_key_out, rct::sk2rct(mask), key);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
crypto::secret_key add_secrets(const crypto::secret_key &a, const crypto::secret_key &b)
|
||||||
|
{
|
||||||
|
crypto::secret_key temp;
|
||||||
|
sc_add(to_bytes(temp), to_bytes(a), to_bytes(b));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool key_domain_is_prime_subgroup(const rct::key &check_key)
|
||||||
|
{
|
||||||
|
// l*K ?= identity
|
||||||
|
ge_p3 check_key_p3;
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&check_key_p3, check_key.bytes) == 0, "ge_frombytes_vartime failed");
|
||||||
|
ge_scalarmult_p3(&check_key_p3, rct::curveOrder().bytes, &check_key_p3);
|
||||||
|
|
||||||
|
return (ge_p3_is_point_at_infinity_vartime(&check_key_p3) != 0);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool balance_check_equality(const rct::keyV &commitment_set1, const rct::keyV &commitment_set2)
|
||||||
|
{
|
||||||
|
// balance check method chosen from perf test: tests/performance_tests/balance_check.h
|
||||||
|
return rct::equalKeys(rct::addKeys(commitment_set1), rct::addKeys(commitment_set2));
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool balance_check_in_out_amnts(const std::vector<rct::xmr_amount> &input_amounts,
|
||||||
|
const std::vector<rct::xmr_amount> &output_amounts,
|
||||||
|
const rct::xmr_amount transaction_fee)
|
||||||
|
{
|
||||||
|
boost::multiprecision::uint128_t input_sum{0};
|
||||||
|
boost::multiprecision::uint128_t output_sum{0};
|
||||||
|
|
||||||
|
for (const auto amnt : input_amounts)
|
||||||
|
input_sum += amnt;
|
||||||
|
|
||||||
|
for (const auto amnt : output_amounts)
|
||||||
|
output_sum += amnt;
|
||||||
|
output_sum += transaction_fee;
|
||||||
|
|
||||||
|
return input_sum == output_sum;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
|
} //namespace sp
|
170
src/seraphis_crypto/sp_crypto_utils.h
Normal file
170
src/seraphis_crypto/sp_crypto_utils.h
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
// Copyright (c) 2022, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Miscellaneous crypto utils for seraphis (also includes some more basic math utils).
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//local headers
|
||||||
|
#include "crypto/crypto.h"
|
||||||
|
#include "ringct/rctTypes.h"
|
||||||
|
|
||||||
|
//third party headers
|
||||||
|
|
||||||
|
//standard headers
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
//forward declarations
|
||||||
|
|
||||||
|
|
||||||
|
namespace sp
|
||||||
|
{
|
||||||
|
|
||||||
|
/// sortable key (e.g. for hash maps)
|
||||||
|
struct sortable_key
|
||||||
|
{
|
||||||
|
unsigned char bytes[32];
|
||||||
|
|
||||||
|
sortable_key() = default;
|
||||||
|
sortable_key(const rct::key &rct_key) { memcpy(bytes, rct_key.bytes, 32); }
|
||||||
|
bool operator<(const sortable_key &other) const { return memcmp(bytes, other.bytes, 32) < 0; }
|
||||||
|
};
|
||||||
|
inline const rct::key& sortable2rct(const sortable_key &k) { return reinterpret_cast<const rct::key&>(k); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* brief: minus_one - -1 mod q
|
||||||
|
* return: -1 mod q
|
||||||
|
*/
|
||||||
|
rct::key minus_one();
|
||||||
|
/**
|
||||||
|
* brief: invert - invert a nonzero scalar
|
||||||
|
* param: x - scalar to invert
|
||||||
|
* return: (1/x) mod l
|
||||||
|
*/
|
||||||
|
rct::key invert(const rct::key &x);
|
||||||
|
/**
|
||||||
|
* brief: decompose - decompose an integer with a fixed base and size
|
||||||
|
* val -> [_, _, ... ,_]
|
||||||
|
* - num slots = 'size'
|
||||||
|
* - numeric base = 'base'
|
||||||
|
* - PRECONDITION: 'size' must be large enough to accomodate all digits of the decomposed value; if it is too small then
|
||||||
|
* the last digit will not be mod the base
|
||||||
|
* e.g. if base = 2 then convert val to binary, if base = 10 then put its decimal digits into the return vector
|
||||||
|
* param: val - value to decompose
|
||||||
|
* param: base - numeric base for decomposing the value
|
||||||
|
* param: size - number of digits to record the value in
|
||||||
|
* outparam: r_out - decomposed val (little endian)
|
||||||
|
*/
|
||||||
|
void decompose(const std::size_t val, const std::size_t base, const std::size_t size, std::vector<std::size_t> &r_out);
|
||||||
|
/**
|
||||||
|
* brief: kronecker_delta - Kronecker delta
|
||||||
|
* param: x - first integer
|
||||||
|
* param: y - second integer
|
||||||
|
* return: 1 if x == y, else 0
|
||||||
|
*/
|
||||||
|
rct::key kronecker_delta(const std::size_t x, const std::size_t y);
|
||||||
|
/**
|
||||||
|
* brief: convolve - compute a convolution with a degree-one polynomial
|
||||||
|
* param: x - x_1, x_2, ..., x_m
|
||||||
|
* param: y - a, b
|
||||||
|
* param: m - number of elements to look at from x (only access up to x[m-1] in case x.size() > m)
|
||||||
|
* return: [a*x_1], [b*x_1 + a*x_2], ..., [b*x_{m - 2} + a*x_{m - 1}], [b*x_m]
|
||||||
|
*/
|
||||||
|
rct::keyV convolve(const rct::keyV &x, const rct::keyV &y, const std::size_t m);
|
||||||
|
/**
|
||||||
|
* brief: powers_of_scalar - powers of a scalar
|
||||||
|
* param: scalar - scalar to take powers of
|
||||||
|
* param: num_pows - number of powers to take (0-indexed)
|
||||||
|
* param: negate_all - bool flag for negating all returned values
|
||||||
|
* return: (negate ? -1 : 1)*([scalar^0], [scalar^1], ..., [scalar^{num_pows - 1}])
|
||||||
|
*/
|
||||||
|
rct::keyV powers_of_scalar(const rct::key &scalar, const std::size_t num_pows, const bool negate_all = false);
|
||||||
|
/**
|
||||||
|
* brief: generate_proof_nonce - generate a random scalar and corresponding pubkey for use in a Schnorr-like signature
|
||||||
|
* opening
|
||||||
|
* param: base - base EC pubkey for the nonce term
|
||||||
|
* outparam: nonce_out - private key 'nonce'
|
||||||
|
* outparam: nonce_pub_out - public key 'nonce * base'
|
||||||
|
*/
|
||||||
|
void generate_proof_nonce(const rct::key &base, crypto::secret_key &nonce_out, rct::key &nonce_pub_out);
|
||||||
|
void generate_proof_nonce(const rct::key &base, rct::key &nonce_out, rct::key &nonce_pub_out);
|
||||||
|
/**
|
||||||
|
* brief: subtract_secret_key_vectors - subtract one vector of secret keys from another
|
||||||
|
* sum(A) - sum(B)
|
||||||
|
* param: keys_A - first vector (addors)
|
||||||
|
* param: keys_B - second vector (subtractors)
|
||||||
|
* outparam: result_out - 'sum(A) - sum(B)'
|
||||||
|
*/
|
||||||
|
void subtract_secret_key_vectors(const std::vector<crypto::secret_key> &keys_A,
|
||||||
|
const std::vector<crypto::secret_key> &keys_B,
|
||||||
|
crypto::secret_key &result_out);
|
||||||
|
/**
|
||||||
|
* brief: mask_key - commit to an EC key
|
||||||
|
* K" = mask G + K
|
||||||
|
* param: mask - commitment mask/blinding factor
|
||||||
|
* param: key - EC key to commit to
|
||||||
|
* outparam: masked_key_out - K", the masked key
|
||||||
|
*/
|
||||||
|
void mask_key(const crypto::secret_key &mask, const rct::key &key, rct::key &masked_key_out);
|
||||||
|
/**
|
||||||
|
* brief: add_secrets - v = a + b
|
||||||
|
* K" = mask G + K
|
||||||
|
* param: mask - commitment mask/blinding factor
|
||||||
|
* param: key - EC key to commit to
|
||||||
|
* outparam: masked_key_out - K", the masked key
|
||||||
|
*/
|
||||||
|
crypto::secret_key add_secrets(const crypto::secret_key &a, const crypto::secret_key &b);
|
||||||
|
/**
|
||||||
|
* brief: key_domain_is_prime_subgroup - check that input key is in the prime order EC subgroup
|
||||||
|
* l*K ?= identity
|
||||||
|
* param: check_key - key to check
|
||||||
|
* result: true if input key is in prime order EC subgroup
|
||||||
|
*/
|
||||||
|
bool key_domain_is_prime_subgroup(const rct::key &check_key);
|
||||||
|
/**
|
||||||
|
* brief: balance_check_equality - balance check between two commitment sets using an equality test
|
||||||
|
* - i.e. sum(inputs) ?= sum(outputs)
|
||||||
|
* param: commitment_set1 -
|
||||||
|
* param: commitment_set2 -
|
||||||
|
* return: true/false on balance check result
|
||||||
|
*/
|
||||||
|
bool balance_check_equality(const rct::keyV &commitment_set1, const rct::keyV &commitment_set2);
|
||||||
|
/**
|
||||||
|
* brief: balance_check_in_out_amnts - balance check between two sets of amounts
|
||||||
|
* - i.e. sum(inputs) ?= sum(outputs) + transaction_fee
|
||||||
|
* param: input_amounts -
|
||||||
|
* param: output_amounts -
|
||||||
|
* param: transaction_fee -
|
||||||
|
* return: true/false on balance check result
|
||||||
|
*/
|
||||||
|
bool balance_check_in_out_amnts(const std::vector<rct::xmr_amount> &input_amounts,
|
||||||
|
const std::vector<rct::xmr_amount> &output_amounts,
|
||||||
|
const rct::xmr_amount transaction_fee);
|
||||||
|
|
||||||
|
} //namespace sp
|
Loading…
Reference in a new issue