Permalink
Browse files

bn: Use int instead of u32 for sizes

The loops relied on unsigned integer overflow, which is not immediately
obvious. Replace them with less clever variants that are clearer.

Also implement bn_compare using std::memcmp.
  • Loading branch information...
leoetlino committed May 15, 2018
1 parent 56e91bf commit b9dd94b9b2a409459d6231cb6f196dfeefc85c34
Showing with 32 additions and 51 deletions.
  1. +26 −45 Source/Core/Common/Crypto/bn.cpp
  2. +6 −6 Source/Core/Common/Crypto/bn.h
@@ -3,61 +3,43 @@
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include <cstdio>
#include <string.h>
#include <cstring>
#include "Common/CommonTypes.h"
#include "Common/Crypto/bn.h"
static void bn_zero(u8* d, u32 n)
static void bn_zero(u8* d, int n)
{
memset(d, 0, n);
std::memset(d, 0, n);
}
static void bn_copy(u8* d, const u8* a, u32 n)
static void bn_copy(u8* d, const u8* a, int n)
{
memcpy(d, a, n);
std::memcpy(d, a, n);
}
int bn_compare(const u8* a, const u8* b, u32 n)
int bn_compare(const u8* a, const u8* b, int n)
{
u32 i;
for (i = 0; i < n; i++)
{
if (a[i] < b[i])
return -1;
if (a[i] > b[i])
return 1;
}
return 0;
return std::memcmp(a, b, n);
}
void bn_sub_modulus(u8* a, const u8* N, u32 n)
void bn_sub_modulus(u8* a, const u8* N, int n)
{
u32 i;
u32 dig;
u8 c;
c = 0;
for (i = n - 1; i < n; i--)
u8 c = 0;
for (int i = n - 1; i >= 0; --i)
{
dig = N[i] + c;
u32 dig = N[i] + c;
c = (a[i] < dig);
a[i] -= dig;
}
}
void bn_add(u8* d, const u8* a, const u8* b, const u8* N, u32 n)
void bn_add(u8* d, const u8* a, const u8* b, const u8* N, int n)
{
u32 i;
u32 dig;
u8 c;
c = 0;
for (i = n - 1; i < n; i--)
u8 c = 0;
for (int i = n - 1; i >= 0; --i)
{
dig = a[i] + b[i] + c;
u32 dig = a[i] + b[i] + c;
c = (dig >= 0x100);
d[i] = dig;
}
@@ -69,43 +51,42 @@ void bn_add(u8* d, const u8* a, const u8* b, const u8* N, u32 n)
bn_sub_modulus(d, N, n);
}
void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, u32 n)
void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, int n)
{
u32 i;
u8 mask;
bn_zero(d, n);
for (i = 0; i < n; i++)
for (mask = 0x80; mask != 0; mask >>= 1)
for (int i = 0; i < n; i++)
{
for (u8 mask = 0x80; mask != 0; mask >>= 1)
{
bn_add(d, d, d, N, n);
if ((a[i] & mask) != 0)
bn_add(d, d, b, N, n);
}
}
}
void bn_exp(u8* d, const u8* a, const u8* N, u32 n, const u8* e, u32 en)
void bn_exp(u8* d, const u8* a, const u8* N, int n, const u8* e, int en)
{
u8 t[512];
u32 i;
u8 mask;
bn_zero(d, n);
d[n - 1] = 1;
for (i = 0; i < en; i++)
for (mask = 0x80; mask != 0; mask >>= 1)
for (int i = 0; i < en; i++)
{
for (u8 mask = 0x80; mask != 0; mask >>= 1)
{
bn_mul(t, d, d, N, n);
if ((e[i] & mask) != 0)
bn_mul(d, t, a, N, n);
else
bn_copy(d, t, n);
}
}
}
// only for prime N -- stupid but lazy, see if I care
void bn_inv(u8* d, const u8* a, const u8* N, u32 n)
void bn_inv(u8* d, const u8* a, const u8* N, int n)
{
u8 t[512], s[512];
@@ -8,9 +8,9 @@
// bignum arithmetic
int bn_compare(const u8* a, const u8* b, u32 n);
void bn_sub_modulus(u8* a, const u8* N, u32 n);
void bn_add(u8* d, const u8* a, const u8* b, const u8* N, u32 n);
void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, u32 n);
void bn_inv(u8* d, const u8* a, const u8* N, u32 n); // only for prime N
void bn_exp(u8* d, const u8* a, const u8* N, u32 n, const u8* e, u32 en);
int bn_compare(const u8* a, const u8* b, int n);
void bn_sub_modulus(u8* a, const u8* N, int n);
void bn_add(u8* d, const u8* a, const u8* b, const u8* N, int n);
void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, int n);
void bn_inv(u8* d, const u8* a, const u8* N, int n); // only for prime N
void bn_exp(u8* d, const u8* a, const u8* N, int n, const u8* e, int en);

0 comments on commit b9dd94b

Please sign in to comment.