Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf03a404 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Get rid of KEY_LENGTH_DWORDS_P192

Only KEY_LENGTH_DWORDS_P256 is used.

Test: compilation
Bug: 126463795
Change-Id: I32a80e4b012c4606a70994fa9d0b5c2602707bb3
parent 5e830f3a
Loading
Loading
Loading
Loading
+39 −43
Original line number Diff line number Diff line
@@ -25,11 +25,8 @@
#include <string.h>
#include "p_256_ecc_pp.h"

void p_256_init_curve(uint32_t keyLength) {
  elliptic_curve_t* ec;

  if (keyLength == KEY_LENGTH_DWORDS_P256) {
    ec = &curve_p256;
void p_256_init_curve() {
  elliptic_curve_t* ec = &curve_p256;

  ec->p[7] = 0xFFFFFFFF;
  ec->p[6] = 0x00000001;
@@ -74,4 +71,3 @@ void p_256_init_curve(uint32_t keyLength) {
  ec->G.y[1] = 0xcbb64068;
  ec->G.y[0] = 0x37bf51f5;
}
}
+79 −86
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ static void p_256_copy_point(Point* q, Point* p) {
}

// q=2q
static void ECC_Double(Point* q, Point* p, uint32_t keyLength) {
static void ECC_Double(Point* q, Point* p) {
  uint32_t t1[KEY_LENGTH_DWORDS_P256];
  uint32_t t2[KEY_LENGTH_DWORDS_P256];
  uint32_t t3[KEY_LENGTH_DWORDS_P256];
@@ -49,8 +49,8 @@ static void ECC_Double(Point* q, Point* p, uint32_t keyLength) {
  uint32_t* z1;
  uint32_t* z3;

  if (multiprecision_iszero(p->z, keyLength)) {
    multiprecision_init(q->z, keyLength);
  if (multiprecision_iszero(p->z)) {
    multiprecision_init(q->z);
    return;  // return infinity
  }

@@ -61,33 +61,33 @@ static void ECC_Double(Point* q, Point* p, uint32_t keyLength) {
  y3 = q->y;
  z3 = q->z;

  multiprecision_mersenns_squa_mod(t1, z1, keyLength);      // t1=z1^2
  multiprecision_sub_mod(t2, x1, t1, keyLength);            // t2=x1-t1
  multiprecision_add_mod(t1, x1, t1, keyLength);            // t1=x1+t1
  multiprecision_mersenns_mult_mod(t2, t1, t2, keyLength);  // t2=t2*t1
  multiprecision_lshift_mod(t3, t2, keyLength);
  multiprecision_add_mod(t2, t3, t2, keyLength);  // t2=3t2

  multiprecision_mersenns_mult_mod(z3, y1, z1, keyLength);  // z3=y1*z1
  multiprecision_lshift_mod(z3, z3, keyLength);

  multiprecision_mersenns_squa_mod(y3, y1, keyLength);  // y3=y1^2
  multiprecision_lshift_mod(y3, y3, keyLength);
  multiprecision_mersenns_mult_mod(t3, y3, x1, keyLength);  // t3=y3*x1=x1*y1^2
  multiprecision_lshift_mod(t3, t3, keyLength);
  multiprecision_mersenns_squa_mod(y3, y3, keyLength);  // y3=y3^2=y1^4
  multiprecision_lshift_mod(y3, y3, keyLength);

  multiprecision_mersenns_squa_mod(x3, t2, keyLength);      // x3=t2^2
  multiprecision_lshift_mod(t1, t3, keyLength);             // t1=2t3
  multiprecision_sub_mod(x3, x3, t1, keyLength);            // x3=x3-t1
  multiprecision_sub_mod(t1, t3, x3, keyLength);            // t1=t3-x3
  multiprecision_mersenns_mult_mod(t1, t1, t2, keyLength);  // t1=t1*t2
  multiprecision_sub_mod(y3, t1, y3, keyLength);            // y3=t1-y3
  multiprecision_mersenns_squa_mod(t1, z1);      // t1=z1^2
  multiprecision_sub_mod(t2, x1, t1);            // t2=x1-t1
  multiprecision_add_mod(t1, x1, t1);            // t1=x1+t1
  multiprecision_mersenns_mult_mod(t2, t1, t2);  // t2=t2*t1
  multiprecision_lshift_mod(t3, t2);
  multiprecision_add_mod(t2, t3, t2);  // t2=3t2

  multiprecision_mersenns_mult_mod(z3, y1, z1);  // z3=y1*z1
  multiprecision_lshift_mod(z3, z3);

  multiprecision_mersenns_squa_mod(y3, y1);  // y3=y1^2
  multiprecision_lshift_mod(y3, y3);
  multiprecision_mersenns_mult_mod(t3, y3, x1);  // t3=y3*x1=x1*y1^2
  multiprecision_lshift_mod(t3, t3);
  multiprecision_mersenns_squa_mod(y3, y3);  // y3=y3^2=y1^4
  multiprecision_lshift_mod(y3, y3);

  multiprecision_mersenns_squa_mod(x3, t2);      // x3=t2^2
  multiprecision_lshift_mod(t1, t3);             // t1=2t3
  multiprecision_sub_mod(x3, x3, t1);            // x3=x3-t1
  multiprecision_sub_mod(t1, t3, x3);            // t1=t3-x3
  multiprecision_mersenns_mult_mod(t1, t1, t2);  // t1=t1*t2
  multiprecision_sub_mod(y3, t1, y3);            // y3=t1-y3
}

// q=q+p,     zp must be 1
static void ECC_Add(Point* r, Point* p, Point* q, uint32_t keyLength) {
static void ECC_Add(Point* r, Point* p, Point* q) {
  uint32_t t1[KEY_LENGTH_DWORDS_P256];
  uint32_t t2[KEY_LENGTH_DWORDS_P256];
  uint32_t* x1;
@@ -111,58 +111,57 @@ static void ECC_Add(Point* r, Point* p, Point* q, uint32_t keyLength) {
  z3 = r->z;

  // if Q=infinity, return p
  if (multiprecision_iszero(z2, keyLength)) {
  if (multiprecision_iszero(z2)) {
    p_256_copy_point(r, p);
    return;
  }

  // if P=infinity, return q
  if (multiprecision_iszero(z1, keyLength)) {
  if (multiprecision_iszero(z1)) {
    p_256_copy_point(r, q);
    return;
  }

  multiprecision_mersenns_squa_mod(t1, z1, keyLength);      // t1=z1^2
  multiprecision_mersenns_mult_mod(t2, z1, t1, keyLength);  // t2=t1*z1
  multiprecision_mersenns_mult_mod(t1, x2, t1, keyLength);  // t1=t1*x2
  multiprecision_mersenns_mult_mod(t2, y2, t2, keyLength);  // t2=t2*y2
  multiprecision_mersenns_squa_mod(t1, z1);      // t1=z1^2
  multiprecision_mersenns_mult_mod(t2, z1, t1);  // t2=t1*z1
  multiprecision_mersenns_mult_mod(t1, x2, t1);  // t1=t1*x2
  multiprecision_mersenns_mult_mod(t2, y2, t2);  // t2=t2*y2

  multiprecision_sub_mod(t1, t1, x1, keyLength);  // t1=t1-x1
  multiprecision_sub_mod(t2, t2, y1, keyLength);  // t2=t2-y1
  multiprecision_sub_mod(t1, t1, x1);  // t1=t1-x1
  multiprecision_sub_mod(t2, t2, y1);  // t2=t2-y1

  if (multiprecision_iszero(t1, keyLength)) {
    if (multiprecision_iszero(t2, keyLength)) {
      ECC_Double(r, q, keyLength);
  if (multiprecision_iszero(t1)) {
    if (multiprecision_iszero(t2)) {
      ECC_Double(r, q);
      return;
    } else {
      multiprecision_init(z3, keyLength);
      multiprecision_init(z3);
      return;  // return infinity
    }
  }

  multiprecision_mersenns_mult_mod(z3, z1, t1, keyLength);  // z3=z1*t1
  multiprecision_mersenns_squa_mod(y3, t1, keyLength);      // t3=t1^2
  multiprecision_mersenns_mult_mod(z1, y3, t1, keyLength);  // t4=t3*t1
  multiprecision_mersenns_mult_mod(y3, y3, x1, keyLength);  // t3=t3*x1
  multiprecision_lshift_mod(t1, y3, keyLength);             // t1=2*t3
  multiprecision_mersenns_squa_mod(x3, t2, keyLength);      // x3=t2^2
  multiprecision_sub_mod(x3, x3, t1, keyLength);            // x3=x3-t1
  multiprecision_sub_mod(x3, x3, z1, keyLength);            // x3=x3-t4
  multiprecision_sub_mod(y3, y3, x3, keyLength);            // t3=t3-x3
  multiprecision_mersenns_mult_mod(y3, y3, t2, keyLength);  // t3=t3*t2
  multiprecision_mersenns_mult_mod(z1, z1, y1, keyLength);  // t4=t4*t1
  multiprecision_sub_mod(y3, y3, z1, keyLength);
  multiprecision_mersenns_mult_mod(z3, z1, t1);  // z3=z1*t1
  multiprecision_mersenns_squa_mod(y3, t1);      // t3=t1^2
  multiprecision_mersenns_mult_mod(z1, y3, t1);  // t4=t3*t1
  multiprecision_mersenns_mult_mod(y3, y3, x1);  // t3=t3*x1
  multiprecision_lshift_mod(t1, y3);             // t1=2*t3
  multiprecision_mersenns_squa_mod(x3, t2);      // x3=t2^2
  multiprecision_sub_mod(x3, x3, t1);            // x3=x3-t1
  multiprecision_sub_mod(x3, x3, z1);            // x3=x3-t4
  multiprecision_sub_mod(y3, y3, x3);            // t3=t3-x3
  multiprecision_mersenns_mult_mod(y3, y3, t2);  // t3=t3*t2
  multiprecision_mersenns_mult_mod(z1, z1, y1);  // t4=t4*t1
  multiprecision_sub_mod(y3, y3, z1);
}

// Computing the Non-Adjacent Form of a positive integer
static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k,
                    uint32_t keyLength) {
static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k) {
  uint32_t sign;
  int i = 0;
  int j;
  uint32_t var;

  while ((var = multiprecision_most_signbits(k, keyLength)) >= 1) {
  while ((var = multiprecision_most_signbits(k)) >= 1) {
    if (k[0] & 0x01)  // k is odd
    {
      sign = (k[0] & 0x03);  // 1 or 3
@@ -183,7 +182,7 @@ static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k,
    } else
      sign = 0;

    multiprecision_rshift(k, k, keyLength);
    multiprecision_rshift(k, k);
    naf[i / 4] |= (sign) << ((i % 4) * 2);
    i++;
  }
@@ -192,8 +191,7 @@ static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k,
}

// Binary Non-Adjacent Form for point multiplication
void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n,
                           uint32_t keyLength) {
void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) {
  uint32_t sign;
  uint8_t naf[256 / 4 + 1];
  uint32_t NumNaf;
@@ -201,69 +199,64 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n,
  Point r;
  uint32_t* modp;

  if (keyLength == KEY_LENGTH_DWORDS_P256) {
  modp = curve_p256.p;
  } else {
    modp = curve.p;
  }

  p_256_init_point(&r);
  multiprecision_init(p->z, keyLength);
  multiprecision_init(p->z);
  p->z[0] = 1;

  // initialization
  p_256_init_point(q);

  // -p
  multiprecision_copy(minus_p.x, p->x, keyLength);
  multiprecision_sub(minus_p.y, modp, p->y, keyLength);
  multiprecision_copy(minus_p.x, p->x);
  multiprecision_sub(minus_p.y, modp, p->y);

  multiprecision_init(minus_p.z, keyLength);
  multiprecision_init(minus_p.z);
  minus_p.z[0] = 1;

  // NAF
  memset(naf, 0, sizeof(naf));
  ECC_NAF(naf, &NumNaf, n, keyLength);
  ECC_NAF(naf, &NumNaf, n);

  for (int i = NumNaf - 1; i >= 0; i--) {
    p_256_copy_point(&r, q);
    ECC_Double(q, &r, keyLength);
    ECC_Double(q, &r);
    sign = (naf[i / 4] >> ((i % 4) * 2)) & 0x03;

    if (sign == 1) {
      p_256_copy_point(&r, q);
      ECC_Add(q, &r, p, keyLength);
      ECC_Add(q, &r, p);
    } else if (sign == 3) {
      p_256_copy_point(&r, q);
      ECC_Add(q, &r, &minus_p, keyLength);
      ECC_Add(q, &r, &minus_p);
    }
  }

  multiprecision_inv_mod(minus_p.x, q->z, keyLength);
  multiprecision_mersenns_squa_mod(q->z, minus_p.x, keyLength);
  multiprecision_mersenns_mult_mod(q->x, q->x, q->z, keyLength);
  multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength);
  multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
  multiprecision_inv_mod(minus_p.x, q->z);
  multiprecision_mersenns_squa_mod(q->z, minus_p.x);
  multiprecision_mersenns_mult_mod(q->x, q->x, q->z);
  multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x);
  multiprecision_mersenns_mult_mod(q->y, q->y, q->z);
}

bool ECC_ValidatePoint(const Point& pt) {
  const size_t kl = KEY_LENGTH_DWORDS_P256;
  p_256_init_curve(kl);
  p_256_init_curve();

  // Ensure y^2 = x^3 + a*x + b (mod p); a = -3

  // y^2 mod p
  uint32_t y2_mod[kl] = {0};
  multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, kl);
  uint32_t y2_mod[KEY_LENGTH_DWORDS_P256] = {0};
  multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y);

  // Right hand side calculation
  uint32_t rhs[kl] = {0};
  multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, kl);
  uint32_t three[kl] = {0};
  uint32_t rhs[KEY_LENGTH_DWORDS_P256] = {0};
  multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x);
  uint32_t three[KEY_LENGTH_DWORDS_P256] = {0};
  three[0] = 3;
  multiprecision_sub_mod(rhs, rhs, three, kl);
  multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, kl);
  multiprecision_add_mod(rhs, rhs, curve_p256.b, kl);
  multiprecision_sub_mod(rhs, rhs, three);
  multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x);
  multiprecision_add_mod(rhs, rhs, curve_p256.b);

  return multiprecision_compare(rhs, y2_mod, kl) == 0;
  return multiprecision_compare(rhs, y2_mod) == 0;
}
+3 −4
Original line number Diff line number Diff line
@@ -58,9 +58,8 @@ extern elliptic_curve_t curve_p256;

bool ECC_ValidatePoint(const Point& p);

void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength);
void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n);

#define ECC_PointMult(q, p, n, keyLength) \
  ECC_PointMult_Bin_NAF(q, p, n, keyLength)
#define ECC_PointMult(q, p, n) ECC_PointMult_Bin_NAF(q, p, n)

void p_256_init_curve(uint32_t keyLength);
void p_256_init_curve();
+73 −183
Original line number Diff line number Diff line
@@ -27,24 +27,24 @@
#include "bt_target.h"
#include "p_256_ecc_pp.h"

void multiprecision_init(uint32_t* c, uint32_t keyLength) {
  for (uint32_t i = 0; i < keyLength; i++) c[i] = 0;
void multiprecision_init(uint32_t* c) {
  for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = 0;
}

void multiprecision_copy(uint32_t* c, uint32_t* a, uint32_t keyLength) {
  for (uint32_t i = 0; i < keyLength; i++) c[i] = a[i];
void multiprecision_copy(uint32_t* c, uint32_t* a) {
  for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = a[i];
}

int multiprecision_compare(uint32_t* a, uint32_t* b, uint32_t keyLength) {
  for (int i = keyLength - 1; i >= 0; i--) {
int multiprecision_compare(uint32_t* a, uint32_t* b) {
  for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) {
    if (a[i] > b[i]) return 1;
    if (a[i] < b[i]) return -1;
  }
  return 0;
}

int multiprecision_iszero(uint32_t* a, uint32_t keyLength) {
  for (uint32_t i = 0; i < keyLength; i++)
int multiprecision_iszero(uint32_t* a) {
  for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++)
    if (a[i]) return 0;

  return 1;
@@ -58,30 +58,29 @@ uint32_t multiprecision_dword_bits(uint32_t a) {
  return i;
}

uint32_t multiprecision_most_signdwords(uint32_t* a, uint32_t keyLength) {
uint32_t multiprecision_most_signdwords(uint32_t* a) {
  int i;
  for (i = keyLength - 1; i >= 0; i--)
  for (i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--)
    if (a[i]) break;
  return (i + 1);
}

uint32_t multiprecision_most_signbits(uint32_t* a, uint32_t keyLength) {
uint32_t multiprecision_most_signbits(uint32_t* a) {
  int aMostSignDWORDs;

  aMostSignDWORDs = multiprecision_most_signdwords(a, keyLength);
  aMostSignDWORDs = multiprecision_most_signdwords(a);
  if (aMostSignDWORDs == 0) return 0;

  return (((aMostSignDWORDs - 1) << DWORD_BITS_SHIFT) +
          multiprecision_dword_bits(a[aMostSignDWORDs - 1]));
}

uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b,
                            uint32_t keyLength) {
uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b) {
  uint32_t carrier;
  uint32_t temp;

  carrier = 0;
  for (uint32_t i = 0; i < keyLength; i++) {
  for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) {
    temp = a[i] + carrier;
    carrier = (temp < carrier);
    temp += b[i];
@@ -93,13 +92,12 @@ uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b,
}

// c=a-b
uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b,
                            uint32_t keyLength) {
uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b) {
  uint32_t borrow;
  uint32_t temp;

  borrow = 0;
  for (uint32_t i = 0; i < keyLength; i++) {
  for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) {
    temp = a[i] - borrow;
    borrow = (temp > a[i]);
    c[i] = temp - b[i];
@@ -110,27 +108,20 @@ uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b,
}

// c = a << 1
void multiprecision_lshift_mod(uint32_t* c, uint32_t* a, uint32_t keyLength) {
void multiprecision_lshift_mod(uint32_t* c, uint32_t* a) {
  uint32_t carrier;
  uint32_t* modp;

  if (keyLength == KEY_LENGTH_DWORDS_P192) {
    modp = curve.p;
  } else if (keyLength == KEY_LENGTH_DWORDS_P256) {
    modp = curve_p256.p;
  } else
    return;
  uint32_t* modp = curve_p256.p;

  carrier = multiprecision_lshift(c, a, keyLength);
  carrier = multiprecision_lshift(c, a);
  if (carrier) {
    multiprecision_sub(c, c, modp, keyLength);
  } else if (multiprecision_compare(c, modp, keyLength) >= 0) {
    multiprecision_sub(c, c, modp, keyLength);
    multiprecision_sub(c, c, modp);
  } else if (multiprecision_compare(c, modp) >= 0) {
    multiprecision_sub(c, c, modp);
  }
}

// c=a>>1
void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) {
void multiprecision_rshift(uint32_t* c, uint32_t* a) {
  int j;
  uint32_t b = 1;

@@ -138,7 +129,7 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) {

  uint32_t carrier = 0;
  uint32_t temp;
  for (int i = keyLength - 1; i >= 0; i--) {
  for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) {
    temp = a[i];  // in case of c==a
    c[i] = (temp >> b) | carrier;
    carrier = temp << j;
@@ -147,64 +138,42 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) {

// Curve specific optimization when p is a pseudo-Mersenns prime,
// p=2^(KEY_LENGTH_BITS)-omega
void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b,
                                      uint32_t keyLength) {
void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b) {
  uint32_t cc[2 * KEY_LENGTH_DWORDS_P256];

  multiprecision_mult(cc, a, b, keyLength);
  if (keyLength == 6) {
    multiprecision_fast_mod(c, cc);
  } else if (keyLength == 8) {
  multiprecision_mult(cc, a, b);
  multiprecision_fast_mod_P256(c, cc);
}
}

// Curve specific optimization when p is a pseudo-Mersenns prime
void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a,
                                      uint32_t keyLength) {
  multiprecision_mersenns_mult_mod(c, a, a, keyLength);
void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a) {
  multiprecision_mersenns_mult_mod(c, a, a);
}

// c=(a+b) mod p, b<p, a<p
void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b,
                            uint32_t keyLength) {
void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b) {
  uint32_t carrier;
  uint32_t* modp;

  if (keyLength == KEY_LENGTH_DWORDS_P192) {
    modp = curve.p;
  } else if (keyLength == KEY_LENGTH_DWORDS_P256) {
    modp = curve_p256.p;
  } else
    return;
  uint32_t* modp = curve_p256.p;

  carrier = multiprecision_add(c, a, b, keyLength);
  carrier = multiprecision_add(c, a, b);
  if (carrier) {
    multiprecision_sub(c, c, modp, keyLength);
  } else if (multiprecision_compare(c, modp, keyLength) >= 0) {
    multiprecision_sub(c, c, modp, keyLength);
    multiprecision_sub(c, c, modp);
  } else if (multiprecision_compare(c, modp) >= 0) {
    multiprecision_sub(c, c, modp);
  }
}

// c=(a-b) mod p, a<p, b<p
void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b,
                            uint32_t keyLength) {
void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b) {
  uint32_t borrow;
  uint32_t* modp;

  if (keyLength == KEY_LENGTH_DWORDS_P192) {
    modp = curve.p;
  } else if (keyLength == KEY_LENGTH_DWORDS_P256) {
    modp = curve_p256.p;
  } else
    return;
  uint32_t* modp = curve_p256.p;

  borrow = multiprecision_sub(c, a, b, keyLength);
  if (borrow) multiprecision_add(c, c, modp, keyLength);
  borrow = multiprecision_sub(c, a, b);
  if (borrow) multiprecision_add(c, c, modp);
}

// c=a<<b, b<DWORD_BITS, c has a buffer size of Numuint32_ts+1
uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) {
uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a) {
  int j;
  uint32_t b = 1;
  j = DWORD_BITS - b;
@@ -212,7 +181,7 @@ uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) {
  uint32_t carrier = 0;
  uint32_t temp;

  for (uint32_t i = 0; i < keyLength; i++) {
  for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) {
    temp = a[i];  // in case c==a
    c[i] = (temp << b) | carrier;
    carrier = temp >> j;
@@ -222,19 +191,18 @@ uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) {
}

// c=a*b; c must have a buffer of 2*Key_LENGTH_uint32_tS, c != a != b
void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b,
                         uint32_t keyLength) {
void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b) {
  uint32_t W;
  uint32_t U;
  uint32_t V;

  U = V = W = 0;
  multiprecision_init(c, keyLength);
  multiprecision_init(c);

  // assume little endian right now
  for (uint32_t i = 0; i < keyLength; i++) {
  for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) {
    U = 0;
    for (uint32_t j = 0; j < keyLength; j++) {
    for (uint32_t j = 0; j < KEY_LENGTH_DWORDS_P256; j++) {
      uint64_t result;
      result = ((uint64_t)a[i]) * ((uint64_t)b[j]);
      W = result >> 32;
@@ -246,78 +214,7 @@ void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b,
      U += (V < c[i + j]);
      c[i + j] = V;
    }
    c[i + keyLength] = U;
  }
}

void multiprecision_fast_mod(uint32_t* c, uint32_t* a) {
  uint32_t U;
  uint32_t V;
  uint32_t* modp = curve.p;

  c[0] = a[0] + a[6];
  U = c[0] < a[0];
  c[0] += a[10];
  U += c[0] < a[10];

  c[1] = a[1] + U;
  U = c[1] < a[1];
  c[1] += a[7];
  U += c[1] < a[7];
  c[1] += a[11];
  U += c[1] < a[11];

  c[2] = a[2] + U;
  U = c[2] < a[2];
  c[2] += a[6];
  U += c[2] < a[6];
  c[2] += a[8];
  U += c[2] < a[8];
  c[2] += a[10];
  U += c[2] < a[10];

  c[3] = a[3] + U;
  U = c[3] < a[3];
  c[3] += a[7];
  U += c[3] < a[7];
  c[3] += a[9];
  U += c[3] < a[9];
  c[3] += a[11];
  U += c[3] < a[11];

  c[4] = a[4] + U;
  U = c[4] < a[4];
  c[4] += a[8];
  U += c[4] < a[8];
  c[4] += a[10];
  U += c[4] < a[10];

  c[5] = a[5] + U;
  U = c[5] < a[5];
  c[5] += a[9];
  U += c[5] < a[9];
  c[5] += a[11];
  U += c[5] < a[11];

  c[0] += U;
  V = c[0] < U;
  c[1] += V;
  V = c[1] < V;
  c[2] += V;
  V = c[2] < V;
  c[2] += U;
  V = c[2] < U;
  c[3] += V;
  V = c[3] < V;
  c[4] += V;
  V = c[4] < V;
  c[5] += V;
  V = c[5] < V;

  if (V) {
    multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P192);
  } else if (multiprecision_compare(c, modp, KEY_LENGTH_DWORDS_P192) >= 0) {
    multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P192);
    c[i + KEY_LENGTH_DWORDS_P256] = U;
  }
}

@@ -541,74 +438,67 @@ void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) {

  if (U & 0x80000000) {
    while (U) {
      multiprecision_add(c, c, modp, KEY_LENGTH_DWORDS_P256);
      multiprecision_add(c, c, modp);
      U++;
    }
  } else if (U) {
    while (U) {
      multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P256);
      multiprecision_sub(c, c, modp);
      U--;
    }
  }

  if (multiprecision_compare(c, modp, KEY_LENGTH_DWORDS_P256) >= 0)
    multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P256);
  if (multiprecision_compare(c, modp) >= 0) multiprecision_sub(c, c, modp);
}

void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u, uint32_t keyLength) {
void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u) {
  uint32_t v[KEY_LENGTH_DWORDS_P256];
  uint32_t A[KEY_LENGTH_DWORDS_P256 + 1];
  uint32_t C[KEY_LENGTH_DWORDS_P256 + 1];
  uint32_t* modp;

  if (keyLength == KEY_LENGTH_DWORDS_P256) {
    modp = curve_p256.p;
  } else {
    modp = curve.p;
  }
  uint32_t* modp = curve_p256.p;

  multiprecision_copy(v, modp, keyLength);
  multiprecision_init(A, keyLength);
  multiprecision_init(C, keyLength);
  multiprecision_copy(v, modp);
  multiprecision_init(A);
  multiprecision_init(C);
  A[0] = 1;

  while (!multiprecision_iszero(u, keyLength)) {
  while (!multiprecision_iszero(u)) {
    while (!(u[0] & 0x01))  // u is even
    {
      multiprecision_rshift(u, u, keyLength);
      multiprecision_rshift(u, u);
      if (!(A[0] & 0x01))  // A is even
        multiprecision_rshift(A, A, keyLength);
        multiprecision_rshift(A, A);
      else {
        A[keyLength] = multiprecision_add(A, A, modp, keyLength);  // A =A+p
        multiprecision_rshift(A, A, keyLength);
        A[keyLength - 1] |= (A[keyLength] << 31);
        A[KEY_LENGTH_DWORDS_P256] = multiprecision_add(A, A, modp);  // A =A+p
        multiprecision_rshift(A, A);
        A[KEY_LENGTH_DWORDS_P256 - 1] |= (A[KEY_LENGTH_DWORDS_P256] << 31);
      }
    }

    while (!(v[0] & 0x01))  // v is even
    {
      multiprecision_rshift(v, v, keyLength);
      multiprecision_rshift(v, v);
      if (!(C[0] & 0x01))  // C is even
      {
        multiprecision_rshift(C, C, keyLength);
        multiprecision_rshift(C, C);
      } else {
        C[keyLength] = multiprecision_add(C, C, modp, keyLength);  // C =C+p
        multiprecision_rshift(C, C, keyLength);
        C[keyLength - 1] |= (C[keyLength] << 31);
        C[KEY_LENGTH_DWORDS_P256] = multiprecision_add(C, C, modp);  // C =C+p
        multiprecision_rshift(C, C);
        C[KEY_LENGTH_DWORDS_P256 - 1] |= (C[KEY_LENGTH_DWORDS_P256] << 31);
      }
    }

    if (multiprecision_compare(u, v, keyLength) >= 0) {
      multiprecision_sub(u, u, v, keyLength);
      multiprecision_sub_mod(A, A, C, keyLength);
    if (multiprecision_compare(u, v) >= 0) {
      multiprecision_sub(u, u, v);
      multiprecision_sub_mod(A, A, C);
    } else {
      multiprecision_sub(v, v, u, keyLength);
      multiprecision_sub_mod(C, C, A, keyLength);
      multiprecision_sub(v, v, u);
      multiprecision_sub_mod(C, C, A);
    }
  }

  if (multiprecision_compare(C, modp, keyLength) >= 0)
    multiprecision_sub(aminus, C, modp, keyLength);
  if (multiprecision_compare(C, modp) >= 0)
    multiprecision_sub(aminus, C, modp);
  else
    multiprecision_copy(aminus, C, keyLength);
    multiprecision_copy(aminus, C);
}
+22 −33

File changed.

Preview size limit exceeded, changes collapsed.

Loading