1
0
Fork 0
forked from lthn/blockchain

crypto: ge_double_scalarmult_base_vartime_p3, ge_scalarmult_vartime_p3, ge_scalarmult_vartime_p3_v2 added

This commit is contained in:
sowle 2021-03-02 00:33:28 +03:00
parent 40c52edf26
commit e73fdea5e5
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
2 changed files with 176 additions and 1 deletions

View file

@ -1,4 +1,5 @@
// Copyright (c) 2018-2020 Zano Project
// Copyright (c) 2018-2021 Zano Project
// Copyright (c) 2020-2021 sowle (val@zano.org, crypto.sowle@gmail.com)
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -1234,6 +1235,96 @@ void ge_double_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const g
}
}
/*
r = a * A + b * B
where a = a[0]+256*a[1]+...+256^31 a[31].
and b = b[0]+256*b[1]+...+256^31 b[31].
B is the Ed25519 base point (x,4/5) with x positive.
*/
void ge_double_scalarmult_base_vartime_p3(ge_p3 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) {
signed char aslide[256];
signed char bslide[256];
ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */
ge_p1p1 t;
ge_p3 u;
ge_p2 r_p2;
int i;
slide(aslide, a);
slide(bslide, b);
ge_dsm_precomp(Ai, A);
ge_p2_0(&r_p2);
for (i = 255; i >= 0; --i) {
if (aslide[i] || bslide[i]) break;
}
for (; i >= 0; --i) {
ge_p2_dbl(&t, &r_p2);
if (aslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Ai[aslide[i]/2]);
} else if (aslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Ai[(-aslide[i])/2]);
}
if (bslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_madd(&t, &u, &ge_Bi[bslide[i]/2]);
} else if (bslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_msub(&t, &u, &ge_Bi[(-bslide[i])/2]);
}
if (i != 0)
ge_p1p1_to_p2(&r_p2, &t);
else
ge_p1p1_to_p3(r, &t); // last step
}
}
void ge_scalarmult_vartime_p3(ge_p3 *r, const unsigned char *a, const ge_p3 *A) {
signed char aslide[256];
ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */
ge_p1p1 t;
ge_p3 u;
ge_p2 r_p2;
int i;
slide(aslide, a);
ge_dsm_precomp(Ai, A);
ge_p2_0(&r_p2);
ge_p3_0(r);
for (i = 255; i >= 0; --i) {
if (aslide[i]) break;
}
for (; i >= 0; --i) {
ge_p2_dbl(&t, &r_p2);
if (aslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Ai[aslide[i] / 2]);
}
else if (aslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
}
if (i != 0)
ge_p1p1_to_p2(&r_p2, &t);
else
ge_p1p1_to_p3(r, &t); // last step
}
}
/* From ge_frombytes.c, modified */
int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) {
@ -3760,3 +3851,84 @@ void ge_bytes_hash_to_ec(ge_p3 *res, const unsigned char *ge_bytes)
ge_mul8(&point2, &point);
ge_p1p1_to_p3(res, &point2);
}
// returns the most non-zero index of r
int slide_v2(signed char *r, const unsigned char *a)
{
int i;
int b;
int k;
int nzi = 0;
for (i = 0; i < 256; ++i) {
r[i] = 1 & (a[i >> 3] >> (i & 7));
}
for (i = 0; i < 256; ++i) {
if (r[i]) {
for (b = 1; b <= 6 && i + b < 256; ++b) {
if (r[i + b]) {
if (r[i] + (r[i + b] << b) <= 15) {
r[i] += r[i + b] << b; r[i + b] = 0;
}
else if (r[i] - (r[i + b] << b) >= -15) {
r[i] -= r[i + b] << b;
for (k = i + b; k < 256; ++k) {
if (!r[k]) {
r[k] = 1;
break;
}
r[k] = 0;
}
}
else
break;
}
}
if (r[i])
nzi = i;
}
}
return nzi;
}
void ge_scalarmult_vartime_p3_v2(ge_p3 *r, const unsigned char *a, const ge_p3 *A)
{
signed char aslide[256];
ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */
ge_p1p1 t;
ge_p3 u;
ge_p2 r_p2;
int i;
i = slide_v2(aslide, a);
if (i == 0)
{
ge_p3_0(r);
return;
}
ge_dsm_precomp(Ai, A);
ge_p2_0(&r_p2);
for (; i >= 0; --i)
{
ge_p2_dbl(&t, &r_p2);
if (aslide[i] > 0)
{
ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Ai[aslide[i] / 2]);
}
else if (aslide[i] < 0)
{
ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
}
if (i != 0)
ge_p1p1_to_p2(&r_p2, &t);
else
ge_p1p1_to_p3(r, &t);
}
}

View file

@ -110,6 +110,9 @@ void ge_bytes_hash_to_ec(ge_p3 *, const unsigned char *);
void ge_p3_0(ge_p3 *h);
void ge_sub(ge_p1p1 *, const ge_p3 *, const ge_cached *);
void ge_double_scalarmult_base_vartime_p3(ge_p3 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b);
void ge_scalarmult_vartime_p3(ge_p3 *r, const unsigned char *a, const ge_p3 *A);
void ge_scalarmult_vartime_p3_v2(ge_p3 *r, const unsigned char *a, const ge_p3 *A);
extern const fe fe_ma2;
extern const fe fe_ma;