forked from lthn/blockchain
Merge branch 'develop' into release
This commit is contained in:
commit
5337bdc69e
8 changed files with 926 additions and 39 deletions
|
|
@ -12,14 +12,14 @@ DISABLE_VS_WARNINGS(4146 4244)
|
|||
|
||||
/* Predeclarations */
|
||||
|
||||
static void fe_mul(fe, const fe, const fe);
|
||||
static void fe_sq(fe, const fe);
|
||||
static void fe_tobytes(unsigned char *, const fe);
|
||||
void fe_mul(fe, const fe, const fe);
|
||||
void fe_sq(fe, const fe);
|
||||
void fe_tobytes(unsigned char *, const fe);
|
||||
static void ge_madd(ge_p1p1 *, const ge_p3 *, const ge_precomp *);
|
||||
static void ge_msub(ge_p1p1 *, const ge_p3 *, const ge_precomp *);
|
||||
static void ge_p2_0(ge_p2 *);
|
||||
static void ge_p3_dbl(ge_p1p1 *, const ge_p3 *);
|
||||
static void ge_sub(ge_p1p1 *, const ge_p3 *, const ge_cached *);
|
||||
void ge_sub(ge_p1p1 *, const ge_p3 *, const ge_cached *);
|
||||
static void fe_divpowm1(fe, const fe, const fe);
|
||||
|
||||
/* Common functions */
|
||||
|
|
@ -48,7 +48,7 @@ static uint64_t load_4(const unsigned char *in)
|
|||
h = 0
|
||||
*/
|
||||
|
||||
static void fe_0(fe h) {
|
||||
void fe_0(fe h) {
|
||||
h[0] = 0;
|
||||
h[1] = 0;
|
||||
h[2] = 0;
|
||||
|
|
@ -232,7 +232,7 @@ static void fe_copy(fe h, const fe f) {
|
|||
|
||||
/* From fe_invert.c */
|
||||
|
||||
static void fe_invert(fe out, const fe z) {
|
||||
void fe_invert(fe out, const fe z) {
|
||||
fe t0;
|
||||
fe t1;
|
||||
fe t2;
|
||||
|
|
@ -351,7 +351,7 @@ Can get away with 11 carries, but then data flow is much deeper.
|
|||
With tighter constraints on inputs can squeeze carries into int32.
|
||||
*/
|
||||
|
||||
static void fe_mul(fe h, const fe f, const fe g) {
|
||||
void fe_mul(fe h, const fe f, const fe g) {
|
||||
int32_t f0 = f[0];
|
||||
int32_t f1 = f[1];
|
||||
int32_t f2 = f[2];
|
||||
|
|
@ -631,7 +631,7 @@ Postconditions:
|
|||
See fe_mul.c for discussion of implementation strategy.
|
||||
*/
|
||||
|
||||
static void fe_sq(fe h, const fe f) {
|
||||
void fe_sq(fe h, const fe f) {
|
||||
int32_t f0 = f[0];
|
||||
int32_t f1 = f[1];
|
||||
int32_t f2 = f[2];
|
||||
|
|
@ -1005,7 +1005,7 @@ Proof:
|
|||
so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
|
||||
*/
|
||||
|
||||
static void fe_tobytes(unsigned char *s, const fe h) {
|
||||
void fe_tobytes(unsigned char *s, const fe h) {
|
||||
int32_t h0 = h[0];
|
||||
int32_t h1 = h[1];
|
||||
int32_t h2 = h[2];
|
||||
|
|
@ -1398,7 +1398,7 @@ void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
|
|||
|
||||
/* From ge_p3_0.c */
|
||||
|
||||
static void ge_p3_0(ge_p3 *h) {
|
||||
void ge_p3_0(ge_p3 *h) {
|
||||
fe_0(h->X);
|
||||
fe_1(h->Y);
|
||||
fe_1(h->Z);
|
||||
|
|
@ -1565,7 +1565,7 @@ void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) {
|
|||
r = p - q
|
||||
*/
|
||||
|
||||
static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
||||
void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
||||
fe t0;
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
|
|
@ -2963,3 +2963,53 @@ int sc_isnonzero(const unsigned char *s) {
|
|||
s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] |
|
||||
s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1;
|
||||
}
|
||||
|
||||
// see implmentation of ge_frombytes_vartime above
|
||||
void fe_frombytes(fe h, const unsigned char *s)
|
||||
{
|
||||
/* From fe_frombytes.c */
|
||||
|
||||
int64_t h0 = load_4(s);
|
||||
int64_t h1 = load_3(s + 4) << 6;
|
||||
int64_t h2 = load_3(s + 7) << 5;
|
||||
int64_t h3 = load_3(s + 10) << 3;
|
||||
int64_t h4 = load_3(s + 13) << 2;
|
||||
int64_t h5 = load_4(s + 16);
|
||||
int64_t h6 = load_3(s + 20) << 7;
|
||||
int64_t h7 = load_3(s + 23) << 5;
|
||||
int64_t h8 = load_3(s + 26) << 4;
|
||||
int64_t h9 = (load_3(s + 29) & 8388607) << 2;
|
||||
int64_t carry0;
|
||||
int64_t carry1;
|
||||
int64_t carry2;
|
||||
int64_t carry3;
|
||||
int64_t carry4;
|
||||
int64_t carry5;
|
||||
int64_t carry6;
|
||||
int64_t carry7;
|
||||
int64_t carry8;
|
||||
int64_t carry9;
|
||||
|
||||
carry9 = (h9 + (int64_t)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
carry1 = (h1 + (int64_t)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
carry3 = (h3 + (int64_t)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
carry5 = (h5 + (int64_t)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
carry7 = (h7 + (int64_t)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
|
||||
carry0 = (h0 + (int64_t)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
carry2 = (h2 + (int64_t)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
carry4 = (h4 + (int64_t)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
carry6 = (h6 + (int64_t)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
carry8 = (h8 + (int64_t)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
|
||||
h[0] = h0;
|
||||
h[1] = h1;
|
||||
h[2] = h2;
|
||||
h[3] = h3;
|
||||
h[4] = h4;
|
||||
h[5] = h5;
|
||||
h[6] = h6;
|
||||
h[7] = h7;
|
||||
h[8] = h8;
|
||||
h[9] = h9;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,13 +104,17 @@ void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *);
|
|||
void ge_scalarmult_p3(ge_p3 *, const unsigned char *, const ge_p3 *);
|
||||
void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp);
|
||||
void ge_mul8(ge_p1p1 *, const ge_p2 *);
|
||||
void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *);
|
||||
void ge_p3_0(ge_p3 *h);
|
||||
void ge_sub(ge_p1p1 *, const ge_p3 *, const ge_cached *);
|
||||
|
||||
extern const fe fe_ma2;
|
||||
extern const fe fe_ma;
|
||||
extern const fe fe_fffb1;
|
||||
extern const fe fe_fffb2;
|
||||
extern const fe fe_fffb3;
|
||||
extern const fe fe_fffb4;
|
||||
void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *);
|
||||
|
||||
void sc_0(unsigned char *);
|
||||
void sc_reduce32(unsigned char *);
|
||||
void sc_add(unsigned char *, const unsigned char *, const unsigned char *);
|
||||
|
|
@ -118,3 +122,9 @@ void sc_sub(unsigned char *, const unsigned char *, const unsigned char *);
|
|||
void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *);
|
||||
int sc_check(const unsigned char *);
|
||||
int sc_isnonzero(const unsigned char *); /* Doesn't normalize */
|
||||
|
||||
void fe_sq(fe h, const fe f);
|
||||
void fe_mul(fe, const fe, const fe);
|
||||
void fe_frombytes(fe h, const unsigned char *s);
|
||||
void fe_invert(fe out, const fe z);
|
||||
void fe_tobytes(unsigned char *s, const fe h);
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ namespace crypto {
|
|||
uint8_t* const m_p_data;
|
||||
size_t m_data_used;
|
||||
bool m_ready;
|
||||
};
|
||||
}; // class stream_cn_hash
|
||||
|
||||
} // namespace crypto
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,11 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::is_seed_tracking(const std::string& seed_phrase)
|
||||
{
|
||||
return seed_phrase.find(':') != std::string::npos;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::is_seed_password_protected(const std::string& seed_phrase, bool& is_password_protected)
|
||||
{
|
||||
//cut the last timestamp word from restore_dats
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ namespace currency
|
|||
static std::string vector_of_chars_to_string(const std::vector<unsigned char>& v) { return std::string(v.begin(), v.end()); }
|
||||
static std::vector<unsigned char> string_to_vector_of_chars(const std::string& v) { return std::vector<unsigned char>(v.begin(), v.end()); }
|
||||
static bool is_seed_password_protected(const std::string& seed_phrase, bool& is_password_protected);
|
||||
static bool is_seed_tracking(const std::string& seed_phrase);
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(m_keys)
|
||||
|
|
|
|||
|
|
@ -27,27 +27,39 @@ namespace tools
|
|||
inline std::string get_seed_phrase_info(const std::string& seed_phrase, const std::string& seed_password, view::seed_phrase_info& result)
|
||||
{
|
||||
//cut the last timestamp word from restore_dats
|
||||
try{
|
||||
result.syntax_correct = currency::account_base::is_seed_password_protected(seed_phrase, result.require_password);
|
||||
try
|
||||
{
|
||||
//restore_from_tracking_seed
|
||||
bool is_tracking = currency::account_base::is_seed_tracking(seed_phrase);
|
||||
if (is_tracking)
|
||||
{
|
||||
currency::account_base acc;
|
||||
result.require_password = false;
|
||||
result.hash_sum_matched = false;
|
||||
result.syntax_correct = acc.restore_from_tracking_seed(seed_phrase);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.syntax_correct = currency::account_base::is_seed_password_protected(seed_phrase, result.require_password);
|
||||
if (result.syntax_correct && result.require_password)
|
||||
{
|
||||
if (seed_password.size())
|
||||
{
|
||||
currency::account_base acc;
|
||||
result.hash_sum_matched = acc.restore_from_seed_phrase(seed_phrase, seed_password);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.hash_sum_matched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
result.syntax_correct = false;
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
|
||||
if (result.syntax_correct && result.require_password)
|
||||
{
|
||||
if (seed_password.size())
|
||||
{
|
||||
currency::account_base acc;
|
||||
result.hash_sum_matched = acc.restore_from_seed_phrase(seed_phrase, seed_password);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.hash_sum_matched = false;
|
||||
}
|
||||
}
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
}
|
||||
|
|
@ -1060,16 +1060,22 @@ std::string wallets_manager::is_pos_allowed()
|
|||
}
|
||||
std::string wallets_manager::is_valid_brain_restore_data(const std::string& seed_phrase, const std::string& seed_password)
|
||||
{
|
||||
|
||||
currency::account_base acc;
|
||||
if (acc.restore_from_seed_phrase(seed_phrase, seed_password))
|
||||
return API_RETURN_CODE_TRUE;
|
||||
|
||||
currency::account_public_address addr;
|
||||
crypto::secret_key view_sec_key;
|
||||
uint64_t ts;
|
||||
if (currency::parse_tracking_seed(seed_phrase, addr, view_sec_key, ts))
|
||||
return API_RETURN_CODE_TRUE;
|
||||
if (!currency::account_base::is_seed_tracking(seed_phrase))
|
||||
{
|
||||
if (acc.restore_from_seed_phrase(seed_phrase, seed_password))
|
||||
return API_RETURN_CODE_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
currency::account_public_address addr = AUTO_VAL_INIT(addr);
|
||||
crypto::secret_key view_sec_key = AUTO_VAL_INIT(view_sec_key);
|
||||
uint64_t ts = 0;
|
||||
if (currency::parse_tracking_seed(seed_phrase, addr, view_sec_key, ts))
|
||||
return API_RETURN_CODE_TRUE;
|
||||
|
||||
}
|
||||
return API_RETURN_CODE_FALSE;
|
||||
}
|
||||
#ifndef MOBILE_WALLET_BUILD
|
||||
|
|
@ -1115,8 +1121,8 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std:
|
|||
currency::account_base acc;
|
||||
try
|
||||
{
|
||||
bool auditable_watch_only = seed_phrase.find(':') != std::string::npos;
|
||||
w->restore(path, password, seed_phrase, auditable_watch_only, seed_password);
|
||||
bool is_tracking = currency::account_base::is_seed_tracking(seed_phrase);
|
||||
w->restore(path, password, seed_phrase, is_tracking, seed_password);
|
||||
//owr.seed = w->get_account().get_seed_phrase();
|
||||
}
|
||||
catch (const tools::error::file_exists&)
|
||||
|
|
|
|||
803
tests/unit_tests/crypto_tests.cpp
Normal file
803
tests/unit_tests/crypto_tests.cpp
Normal file
|
|
@ -0,0 +1,803 @@
|
|||
// Copyright (c) 2020 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#define USE_INSECURE_RANDOM_RPNG_ROUTINES // turns on random manupulation for tests
|
||||
#include "gtest/gtest.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
extern "C" {
|
||||
#include "crypto/crypto-ops.h"
|
||||
void fe_reduce(fe u, const fe h)
|
||||
{
|
||||
/* From fe_frombytes.c */
|
||||
|
||||
// loading changed
|
||||
|
||||
int64_t h0 = h[0];
|
||||
int64_t h1 = h[1];
|
||||
int64_t h2 = h[2];
|
||||
int64_t h3 = h[3];
|
||||
int64_t h4 = h[4];
|
||||
int64_t h5 = h[5];
|
||||
int64_t h6 = h[6];
|
||||
int64_t h7 = h[7];
|
||||
int64_t h8 = h[8];
|
||||
int64_t h9 = h[9];
|
||||
int64_t carry0;
|
||||
int64_t carry1;
|
||||
int64_t carry2;
|
||||
int64_t carry3;
|
||||
int64_t carry4;
|
||||
int64_t carry5;
|
||||
int64_t carry6;
|
||||
int64_t carry7;
|
||||
int64_t carry8;
|
||||
int64_t carry9;
|
||||
|
||||
carry9 = (h9 + (int64_t)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
carry1 = (h1 + (int64_t)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
carry3 = (h3 + (int64_t)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
carry5 = (h5 + (int64_t)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
carry7 = (h7 + (int64_t)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
|
||||
carry0 = (h0 + (int64_t)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
carry2 = (h2 + (int64_t)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
carry4 = (h4 + (int64_t)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
carry6 = (h6 + (int64_t)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
carry8 = (h8 + (int64_t)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
|
||||
u[0] = h0;
|
||||
u[1] = h1;
|
||||
u[2] = h2;
|
||||
u[3] = h3;
|
||||
u[4] = h4;
|
||||
u[5] = h5;
|
||||
u[6] = h6;
|
||||
u[7] = h7;
|
||||
u[8] = h8;
|
||||
u[9] = h9;
|
||||
|
||||
/* End fe_frombytes.c */
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sc_mul(unsigned char *s, const unsigned char *a, const unsigned char *b)
|
||||
{
|
||||
unsigned char c[32];
|
||||
unsigned char neg_a[32];
|
||||
sc_0(c);
|
||||
sc_sub(neg_a, c, a);
|
||||
// s = c - ab
|
||||
sc_mulsub(s, neg_a, b, c);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
||||
unsigned char Lm2[32] = { 0xeb, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10 };
|
||||
|
||||
// out = z ^ s (mod l)
|
||||
void sc_exp(unsigned char* out, const unsigned char* z, const unsigned char* s)
|
||||
{
|
||||
sc_0(out);
|
||||
out[0] = 1;
|
||||
if (sc_isnonzero(s) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// calc position of the most significant bit of s
|
||||
size_t msb_s = 0;
|
||||
for (size_t i = 31; i != SIZE_MAX; --i)
|
||||
{
|
||||
if (s[i] != 0)
|
||||
{
|
||||
msb_s = 8 * i;
|
||||
uint8_t t = s[i] >> 1;
|
||||
while (t)
|
||||
{
|
||||
t >>= 1;
|
||||
++msb_s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//memcpy(out, z, sizeof(crypto::ec_scalar));
|
||||
|
||||
for (size_t i = msb_s; i != SIZE_MAX; --i)
|
||||
{
|
||||
sc_mul(out, out, out);
|
||||
std::cout << "sc_mul(out, out, out);" << std::endl;
|
||||
uint8_t bit = (s[i / 8] >> (i % 8)) & 1;
|
||||
if (bit)
|
||||
{
|
||||
sc_mul(out, out, z);
|
||||
std::cout << "sc_mul(out, out, z);" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sc_invert(unsigned char* out, const unsigned char* z)
|
||||
{
|
||||
memcpy(out, z, sizeof(crypto::ec_scalar));
|
||||
for(size_t i = 0; i < 128; ++i)
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
sc_mul(out, out, out);
|
||||
sc_mul(out, out, z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class pod_t>
|
||||
std::string pod_to_hex_big_endian(const pod_t &h)
|
||||
{
|
||||
constexpr char hexmap[] = "0123456789abcdef";
|
||||
const char* data = reinterpret_cast<const char*>(&h);
|
||||
size_t len = sizeof h;
|
||||
|
||||
std::string s(len * 2, ' ');
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
s[2 * i] = hexmap[(data[len - 1 - i] & 0xF0) >> 4];
|
||||
s[2 * i + 1] = hexmap[(data[len - 1 - i] & 0x0F)];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
int fe_cmp(const fe a, const fe b)
|
||||
{
|
||||
for (size_t i = 9; i != SIZE_MAX; --i)
|
||||
{
|
||||
if (reinterpret_cast<const uint32_t&>(a[i]) < reinterpret_cast<const uint32_t&>(b[i])) return -1;
|
||||
if (reinterpret_cast<const uint32_t&>(a[i]) > reinterpret_cast<const uint32_t&>(b[i])) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const fe scalar_L_fe = { 16110573, 10012311, -6632702, 16062397, 5471207, 0, 0, 0, 0, 4194304 };
|
||||
|
||||
|
||||
__declspec(align(32))
|
||||
struct scalar_t
|
||||
{
|
||||
//fe m_fe; // 40 bytes, array 10 * 4, optimized form
|
||||
union
|
||||
{
|
||||
uint64_t m_u64[4];
|
||||
unsigned char m_s[32];
|
||||
};
|
||||
// DONE! consider 1) change to aligned array of unsigned chars
|
||||
// consider 2) add 32 byte after to speed up sc_reduce by decreasing num of copy operations
|
||||
|
||||
scalar_t()
|
||||
{}
|
||||
|
||||
scalar_t(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3)
|
||||
{
|
||||
m_u64[0] = a0;
|
||||
m_u64[1] = a1;
|
||||
m_u64[2] = a2;
|
||||
m_u64[3] = a3;
|
||||
}
|
||||
|
||||
scalar_t(int64_t v)
|
||||
{
|
||||
zero();
|
||||
if (v == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//unsigned char bytes[32] = {0};
|
||||
reinterpret_cast<int64_t&>(m_s) = v;
|
||||
//fe_frombytes(m_fe, bytes);
|
||||
// do not need to call reduce as 2^64 < L
|
||||
}
|
||||
|
||||
unsigned char* data()
|
||||
{
|
||||
return &m_s[0];
|
||||
}
|
||||
|
||||
const unsigned char* data() const
|
||||
{
|
||||
return &m_s[0];
|
||||
}
|
||||
|
||||
operator crypto::secret_key() const
|
||||
{
|
||||
crypto::secret_key result;
|
||||
memcpy(result.data, &m_s, sizeof result.data);
|
||||
//fe_tobytes(reinterpret_cast<unsigned char*>(&result), m_fe);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool from_secret_key(const crypto::secret_key& sk)
|
||||
{
|
||||
//fe_frombytes(m_fe, reinterpret_cast<const unsigned char*>(&sk));
|
||||
return false;
|
||||
}
|
||||
|
||||
void zero()
|
||||
{
|
||||
//fe_0(m_fe);
|
||||
m_u64[0] = 0;
|
||||
m_u64[1] = 0;
|
||||
m_u64[2] = 0;
|
||||
m_u64[3] = 0;
|
||||
//memset(&m_s, 0, sizeof m_s);
|
||||
}
|
||||
|
||||
void make_random()
|
||||
{
|
||||
unsigned char tmp[64];
|
||||
crypto::generate_random_bytes(64, tmp);
|
||||
sc_reduce(tmp);
|
||||
memcpy(&m_s, tmp, 32);
|
||||
}
|
||||
|
||||
bool is_zero() const
|
||||
{
|
||||
return sc_isnonzero(&m_s[0]) == 0;
|
||||
}
|
||||
|
||||
scalar_t operator+(const scalar_t& v) const
|
||||
{
|
||||
scalar_t result;
|
||||
sc_add(reinterpret_cast<unsigned char*>(&result), reinterpret_cast<const unsigned char*>(&m_s), reinterpret_cast<const unsigned char*>(&v));
|
||||
return result;
|
||||
}
|
||||
|
||||
scalar_t operator-(const scalar_t& v) const
|
||||
{
|
||||
scalar_t result;
|
||||
sc_sub(reinterpret_cast<unsigned char*>(&result), reinterpret_cast<const unsigned char*>(&m_s), reinterpret_cast<const unsigned char*>(&v));
|
||||
return result;
|
||||
}
|
||||
|
||||
scalar_t operator*(const scalar_t& v) const
|
||||
{
|
||||
scalar_t result;
|
||||
sc_mul(reinterpret_cast<unsigned char*>(&result), reinterpret_cast<const unsigned char*>(&m_s), reinterpret_cast<const unsigned char*>(&v));
|
||||
return result;
|
||||
}
|
||||
|
||||
scalar_t reciprocal() const
|
||||
{
|
||||
/*unsigned char bytes[32] = {2};
|
||||
fe t;
|
||||
fe_frombytes(t, (unsigned char*)&bytes);
|
||||
fe r;
|
||||
fe_invert(r, t);
|
||||
fe m;
|
||||
fe_mul(m, r, t);
|
||||
|
||||
|
||||
fe r2;
|
||||
my_fe_invert(r2, t);
|
||||
fe m2;
|
||||
fe_mul(m2, r2, t);
|
||||
|
||||
scalar_t result;
|
||||
fe v_f;
|
||||
fe result_f;
|
||||
fe_frombytes(v_f, reinterpret_cast<const unsigned char*>(&m_s));
|
||||
my_fe_invert(result_f, v_f);
|
||||
fe_tobytes(reinterpret_cast<unsigned char*>(&result), result_f);
|
||||
//sc_reduce(reinterpret_cast<unsigned char*>(&result));
|
||||
fe result_check;
|
||||
fe_frombytes(result_check, reinterpret_cast<unsigned char*>(&result));
|
||||
fe v_check;
|
||||
fe_invert(v_check, result_check);
|
||||
//sc_reduce(reinterpret_cast<unsigned char*>(&result));
|
||||
return result;*/
|
||||
|
||||
scalar_t result;
|
||||
fe v_f;
|
||||
fe result_f;
|
||||
fe_frombytes(v_f, reinterpret_cast<const unsigned char*>(&m_s));
|
||||
fe_invert(result_f, v_f);
|
||||
|
||||
/*fe x2;
|
||||
fe_mul(x2, result_f, v_f);
|
||||
|
||||
fe_reduce(result_f, result_f);
|
||||
if (fe_cmp(result_f, scalar_L_fe) > 0)
|
||||
{
|
||||
// result_f > L
|
||||
fe_sub(result_f, result_f, scalar_L_fe);
|
||||
if (fe_cmp(result_f, scalar_L_fe) >= 0)
|
||||
return false; // fail
|
||||
}*/
|
||||
unsigned char tmp[64] = { 0 };
|
||||
fe_tobytes(reinterpret_cast<unsigned char*>(&tmp), result_f);
|
||||
sc_reduce(tmp);
|
||||
memcpy(&result, &tmp, sizeof result);
|
||||
return result;
|
||||
}
|
||||
|
||||
scalar_t operator/(const scalar_t& v) const
|
||||
{
|
||||
return operator*(v.reciprocal());
|
||||
}
|
||||
|
||||
bool operator==(const scalar_t& rhs) const
|
||||
{
|
||||
return
|
||||
m_u64[0] == rhs.m_u64[0] &&
|
||||
m_u64[1] == rhs.m_u64[1] &&
|
||||
m_u64[2] == rhs.m_u64[2] &&
|
||||
m_u64[3] == rhs.m_u64[3];
|
||||
}
|
||||
|
||||
bool operator<(const scalar_t& rhs) const
|
||||
{
|
||||
if (m_u64[3] < rhs.m_u64[3]) return true;
|
||||
if (m_u64[3] > rhs.m_u64[3]) return false;
|
||||
if (m_u64[2] < rhs.m_u64[2]) return true;
|
||||
if (m_u64[2] > rhs.m_u64[2]) return false;
|
||||
if (m_u64[1] < rhs.m_u64[1]) return true;
|
||||
if (m_u64[1] > rhs.m_u64[1]) return false;
|
||||
if (m_u64[0] < rhs.m_u64[0]) return true;
|
||||
if (m_u64[0] > rhs.m_u64[0]) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator>(const scalar_t& rhs) const
|
||||
{
|
||||
if (m_u64[3] < rhs.m_u64[3]) return false;
|
||||
if (m_u64[3] > rhs.m_u64[3]) return true;
|
||||
if (m_u64[2] < rhs.m_u64[2]) return false;
|
||||
if (m_u64[2] > rhs.m_u64[2]) return true;
|
||||
if (m_u64[1] < rhs.m_u64[1]) return false;
|
||||
if (m_u64[1] > rhs.m_u64[1]) return true;
|
||||
if (m_u64[0] < rhs.m_u64[0]) return false;
|
||||
if (m_u64[0] > rhs.m_u64[0]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& ss, const scalar_t &v)
|
||||
{
|
||||
return ss << "0x" << pod_to_hex_big_endian(v);
|
||||
}
|
||||
|
||||
}; // struct scalar_t
|
||||
|
||||
//__declspec(align(32))
|
||||
struct point_t
|
||||
{
|
||||
// A point(x, y) is represented in extended homogeneous coordinates (X, Y, Z, T)
|
||||
// with x = X / Z, y = Y / Z, x * y = T / Z.
|
||||
ge_p3 m_p3;
|
||||
|
||||
point_t()
|
||||
{
|
||||
}
|
||||
|
||||
void zero()
|
||||
{
|
||||
ge_p3_0(&m_p3);
|
||||
}
|
||||
|
||||
bool from_public_key(const crypto::public_key& pk)
|
||||
{
|
||||
return ge_frombytes_vartime(&m_p3, reinterpret_cast<const unsigned char*>(&pk)) == 0;
|
||||
}
|
||||
|
||||
operator crypto::public_key()
|
||||
{
|
||||
crypto::public_key result;
|
||||
ge_p3_tobytes((unsigned char*)&result, &m_p3);
|
||||
return result;
|
||||
}
|
||||
|
||||
point_t operator+(const point_t& rhs)
|
||||
{
|
||||
point_t result;
|
||||
ge_cached rhs_c;
|
||||
ge_p1p1 t;
|
||||
ge_p3_to_cached(&rhs_c, &rhs.m_p3);
|
||||
ge_add(&t, &m_p3, &rhs_c);
|
||||
ge_p1p1_to_p3(&result.m_p3, &t);
|
||||
return result;
|
||||
}
|
||||
|
||||
point_t operator-(const point_t& rhs)
|
||||
{
|
||||
point_t result;
|
||||
ge_cached rhs_c;
|
||||
ge_p1p1 t;
|
||||
ge_p3_to_cached(&rhs_c, &rhs.m_p3);
|
||||
ge_sub(&t, &m_p3, &rhs_c);
|
||||
ge_p1p1_to_p3(&result.m_p3, &t);
|
||||
return result;
|
||||
}
|
||||
|
||||
friend point_t operator*(const scalar_t& lhs, const point_t& rhs)
|
||||
{
|
||||
point_t result;
|
||||
ge_scalarmult_p3(&result.m_p3, reinterpret_cast<const unsigned char*>(&lhs), &rhs.m_p3);
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator==(const point_t& lhs, const point_t& rhs)
|
||||
{
|
||||
// convert to xy form, then compare components (because (z, y, z, t) representation is not unique)
|
||||
fe lrecip, lx, ly;
|
||||
fe rrecip, rx, ry;
|
||||
|
||||
fe_invert(lrecip, lhs.m_p3.Z);
|
||||
fe_invert(rrecip, rhs.m_p3.Z);
|
||||
|
||||
fe_mul(lx, lhs.m_p3.X, lrecip);
|
||||
fe_mul(rx, rhs.m_p3.X, rrecip);
|
||||
if (memcmp(&lx, &rx, sizeof lx) != 0)
|
||||
return false;
|
||||
|
||||
fe_mul(ly, lhs.m_p3.Y, lrecip);
|
||||
fe_mul(ry, rhs.m_p3.Y, rrecip);
|
||||
if (memcmp(&ly, &ry, sizeof ly) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
}; // struct point_t
|
||||
|
||||
struct point_g_t : public point_t
|
||||
{
|
||||
point_g_t()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
friend point_t operator*(const scalar_t& lhs, const point_g_t&)
|
||||
{
|
||||
point_t result;
|
||||
ge_scalarmult_base(&result.m_p3, reinterpret_cast<const unsigned char*>(&lhs));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*friend point_t operator*(const int64_t lhs, const point_g_t& rhs)
|
||||
{
|
||||
return operator*(scalar_t)
|
||||
}*/
|
||||
|
||||
static_assert(sizeof(crypto::public_key) == 32, "size error");
|
||||
|
||||
}; // struct point_g_t
|
||||
|
||||
static const point_g_t point_G;
|
||||
|
||||
static const scalar_t scalar_L = { 0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0x0, 0x1000000000000000 };
|
||||
static const scalar_t scalar_Lm1 = { 0x5812631a5cf5d3ec, 0x14def9dea2f79cd6, 0x0, 0x1000000000000000 };
|
||||
static const scalar_t scalar_P = { 0xffffffffffffffed, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff };
|
||||
static const scalar_t scalar_Pm1 = { 0xffffffffffffffec, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff };
|
||||
static const scalar_t scalar_256m1 = { 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff };
|
||||
|
||||
|
||||
/* temporary disable in order not to break the compilation
|
||||
TEST(crypto, scalar_basics)
|
||||
{
|
||||
scalar_t zero = 0;
|
||||
ASSERT_TRUE(zero.is_zero());
|
||||
scalar_t one = 1;
|
||||
ASSERT_FALSE(one.is_zero());
|
||||
ASSERT_TRUE(one > zero);
|
||||
scalar_t z = 0;
|
||||
for (size_t j = 0; j < 1000; ++j)
|
||||
{
|
||||
z.make_random();
|
||||
ASSERT_FALSE(z.is_zero());
|
||||
ASSERT_GT(z, z - 1);
|
||||
ASSERT_LT(z, z + 1);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(scalar_L > 0 && !(scalar_L < 0));
|
||||
ASSERT_TRUE(scalar_Lm1 > 0 && !(scalar_Lm1 < 0));
|
||||
ASSERT_TRUE(scalar_Lm1 < scalar_L);
|
||||
ASSERT_FALSE(scalar_Lm1 > scalar_L);
|
||||
ASSERT_TRUE(scalar_P > scalar_Pm1);
|
||||
ASSERT_FALSE(scalar_P < scalar_Pm1);
|
||||
|
||||
std::cout << "0 = " << zero << std::endl;
|
||||
std::cout << "1 = " << one << std::endl;
|
||||
std::cout << "L = " << scalar_L << std::endl;
|
||||
std::cout << "Lm1 = " << scalar_Lm1 << std::endl;
|
||||
std::cout << "P = " << scalar_P << std::endl;
|
||||
std::cout << "Pm1 = " << scalar_Pm1 << std::endl;
|
||||
|
||||
// check rolling over L for scalars arithmetics
|
||||
ASSERT_EQ(scalar_Lm1 + 1, 0);
|
||||
ASSERT_EQ(scalar_t(0) - 1, scalar_Lm1);
|
||||
ASSERT_EQ(scalar_Lm1 * 2, scalar_Lm1 - 1); // (L - 1) * 2 = L + L - 2 = (L - 1) - 1 (mod L)
|
||||
ASSERT_EQ(scalar_Lm1 * 100, scalar_Lm1 - 99);
|
||||
ASSERT_EQ(scalar_Lm1 * scalar_Lm1, 1); // (L - 1) * (L - 1) = L*L - 2L + 1 = 1 (mod L)
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
|
||||
fe L_fe;
|
||||
fe_frombytes(L_fe, &scalar_L.m_s[0]);
|
||||
|
||||
fe Pm1_fe;
|
||||
fe_frombytes(Pm1_fe, &scalar_Pm1.m_s[0]);
|
||||
|
||||
fe r;
|
||||
fe f_1 = { 1 };
|
||||
fe_add(r, Pm1_fe, f_1);
|
||||
|
||||
|
||||
|
||||
while(true)
|
||||
{
|
||||
static int ti = 2;
|
||||
static int pi = 3;
|
||||
scalar_t t = ti;
|
||||
scalar_t p = pi;
|
||||
scalar_t r = 0;
|
||||
//sc_exp(r.data(), t.data(), Lm2);
|
||||
|
||||
sc_invert(r.data(), t.data());
|
||||
|
||||
std::cout << ti << " ^ L-2" << " = " << r << std::endl;
|
||||
|
||||
r = r * 6;
|
||||
std::cout << r << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
scalar_t a = 2;
|
||||
a = a / 2;
|
||||
std::cout << "2 / 2 = " << a << std::endl;
|
||||
a = scalar_Lm1 / 2;
|
||||
std::cout << "L-1 / 2 = " << a << std::endl;
|
||||
a = a * 2;
|
||||
std::cout << "L-1 / 2 * 2 = " << a << std::endl;
|
||||
|
||||
}
|
||||
|
||||
TEST(crypto, point_basics)
|
||||
{
|
||||
scalar_t s = 4;
|
||||
point_t E = s * point_G;
|
||||
point_t X = 4 * E;
|
||||
point_t K = 193847 * point_G;
|
||||
point_t C = E + K;
|
||||
|
||||
ASSERT_TRUE(X == 16 * point_G);
|
||||
ASSERT_TRUE(C - K == E);
|
||||
ASSERT_TRUE(C - E == K);
|
||||
ASSERT_TRUE(C == 193851 * point_G);
|
||||
}
|
||||
|
||||
TEST(crypto, scalar_reciprocal)
|
||||
{
|
||||
int64_t test_nums[] = {1, 2, 10};
|
||||
|
||||
for (size_t i = 0; i < sizeof test_nums / sizeof test_nums[0]; ++i)
|
||||
{
|
||||
scalar_t s = test_nums[i];
|
||||
scalar_t z = s - s;
|
||||
ASSERT_TRUE(z.is_zero());
|
||||
}
|
||||
|
||||
scalar_t s = 20;
|
||||
scalar_t d = 5;
|
||||
scalar_t e = s / d;
|
||||
scalar_t m = e * d;
|
||||
|
||||
ASSERT_TRUE(m == s);
|
||||
}
|
||||
|
||||
|
||||
TEST(crypto, scalars)
|
||||
{
|
||||
scalar_t s = 20;
|
||||
scalar_t d = 5;
|
||||
scalar_t e = s / d;
|
||||
scalar_t m = e * d;
|
||||
|
||||
ASSERT_TRUE(m == s);
|
||||
}
|
||||
|
||||
*/
|
||||
Loading…
Add table
Reference in a new issue