Пример #1
0
char *BN_bn2hex(const BIGNUM *bn) {
  int width = bn_minimal_width(bn);
  char *buf = OPENSSL_malloc(1 /* leading '-' */ + 1 /* zero is non-empty */ +
                             width * BN_BYTES * 2 + 1 /* trailing NUL */);
  if (buf == NULL) {
    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  char *p = buf;
  if (bn->neg) {
    *(p++) = '-';
  }

  if (BN_is_zero(bn)) {
    *(p++) = '0';
  }

  int z = 0;
  for (int i = width - 1; i >= 0; i--) {
    for (int j = BN_BITS2 - 8; j >= 0; j -= 8) {
      // strip leading zeros
      int v = ((int)(bn->d[i] >> (long)j)) & 0xff;
      if (z || v != 0) {
        *(p++) = hextable[v >> 4];
        *(p++) = hextable[v & 0x0f];
        z = 1;
      }
    }
  }
Пример #2
0
int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w) {
  switch (bn_minimal_width(bn)) {
    case 1:
      return bn->d[0] == w;
    case 0:
      return w == 0;
    default:
      return 0;
  }
}
Пример #3
0
int BN_is_pow2(const BIGNUM *bn) {
  int width = bn_minimal_width(bn);
  if (width == 0 || bn->neg) {
    return 0;
  }

  for (int i = 0; i < width - 1; i++) {
    if (bn->d[i] != 0) {
      return 0;
    }
  }

  return 0 == (bn->d[width-1] & (bn->d[width-1] - 1));
}
Пример #4
0
int BN_sub_word(BIGNUM *a, BN_ULONG w) {
  int i;

  // degenerate case: w is zero
  if (!w) {
    return 1;
  }

  // degenerate case: a is zero
  if (BN_is_zero(a)) {
    i = BN_set_word(a, w);
    if (i != 0) {
      BN_set_negative(a, 1);
    }
    return i;
  }

  // handle 'a' when negative
  if (a->neg) {
    a->neg = 0;
    i = BN_add_word(a, w);
    a->neg = 1;
    return i;
  }

  if ((bn_minimal_width(a) == 1) && (a->d[0] < w)) {
    a->d[0] = w - a->d[0];
    a->neg = 1;
    return 1;
  }

  i = 0;
  for (;;) {
    if (a->d[i] >= w) {
      a->d[i] -= w;
      break;
    } else {
      a->d[i] -= w;
      i++;
      w = 1;
    }
  }

  if ((a->d[i] == 0) && (i == (a->width - 1))) {
    a->width--;
  }

  return 1;
}
Пример #5
0
int BN_is_zero(const BIGNUM *bn) {
  return bn_minimal_width(bn) == 0;
}
Пример #6
0
int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
  int max, min, dif;
  register BN_ULONG t1, t2, *ap, *bp, *rp;
  int i, carry;

  max = bn_minimal_width(a);
  min = bn_minimal_width(b);
  dif = max - min;

  if (dif < 0)  // hmm... should not be happening
  {
    OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
    return 0;
  }

  if (!bn_wexpand(r, max)) {
    return 0;
  }

  ap = a->d;
  bp = b->d;
  rp = r->d;

  carry = 0;
  for (i = min; i != 0; i--) {
    t1 = *(ap++);
    t2 = *(bp++);
    if (carry) {
      carry = (t1 <= t2);
      t1 -= t2 + 1;
    } else {
      carry = (t1 < t2);
      t1 -= t2;
    }
    *(rp++) = t1;
  }

  if (carry)  // subtracted
  {
    if (!dif) {
      // error: a < b
      return 0;
    }

    while (dif) {
      dif--;
      t1 = *(ap++);
      t2 = t1 - 1;
      *(rp++) = t2;
      if (t1) {
        break;
      }
    }
  }

  if (dif > 0 && rp != ap) {
    OPENSSL_memcpy(rp, ap, sizeof(*rp) * dif);
  }

  r->width = max;
  r->neg = 0;
  bn_set_minimal_width(r);

  return 1;
}