/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
 * and Bodo Moeller for the OpenSSL project. */
/* ====================================================================
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com). */

#include <openssl/bn.h>

#include <openssl/err.h>


/* Returns 'ret' such that
 *      ret^2 == a (mod p),
 * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
 * in Algebraic Computational Number Theory", algorithm 1.5.1).
 * 'p' must be prime! */
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
  BIGNUM *ret = in;
  int err = 1;
  int r;
  BIGNUM *A, *b, *q, *t, *x, *y;
  int e, i, j;

  if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
    if (BN_abs_is_word(p, 2)) {
      if (ret == NULL) {
        ret = BN_new();
      }
      if (ret == NULL) {
        goto end;
      }
      if (!BN_set_word(ret, BN_is_bit_set(a, 0))) {
        if (ret != in) {
          BN_free(ret);
        }
        return NULL;
      }
      return ret;
    }

    OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
    return (NULL);
  }

  if (BN_is_zero(a) || BN_is_one(a)) {
    if (ret == NULL) {
      ret = BN_new();
    }
    if (ret == NULL) {
      goto end;
    }
    if (!BN_set_word(ret, BN_is_one(a))) {
      if (ret != in) {
        BN_free(ret);
      }
      return NULL;
    }
    return ret;
  }

  BN_CTX_start(ctx);
  A = BN_CTX_get(ctx);
  b = BN_CTX_get(ctx);
  q = BN_CTX_get(ctx);
  t = BN_CTX_get(ctx);
  x = BN_CTX_get(ctx);
  y = BN_CTX_get(ctx);
  if (y == NULL) {
    goto end;
  }

  if (ret == NULL) {
    ret = BN_new();
  }
  if (ret == NULL) {
    goto end;
  }

  /* A = a mod p */
  if (!BN_nnmod(A, a, p, ctx)) {
    goto end;
  }

  /* now write  |p| - 1  as  2^e*q  where  q  is odd */
  e = 1;
  while (!BN_is_bit_set(p, e)) {
    e++;
  }
  /* we'll set  q  later (if needed) */

  if (e == 1) {
    /* The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
     * modulo  (|p|-1)/2,  and square roots can be computed
     * directly by modular exponentiation.
     * We have
     *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
     * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
     */
    if (!BN_rshift(q, p, 2)) {
      goto end;
    }
    q->neg = 0;
    if (!BN_add_word(q, 1) ||
        !BN_mod_exp(ret, A, q, p, ctx)) {
      goto end;
    }
    err = 0;
    goto vrfy;
  }

  if (e == 2) {
    /* |p| == 5  (mod 8)
     *
     * In this case  2  is always a non-square since
     * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
     * So if  a  really is a square, then  2*a  is a non-square.
     * Thus for
     *      b := (2*a)^((|p|-5)/8),
     *      i := (2*a)*b^2
     * we have
     *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
     *         = (2*a)^((p-1)/2)
     *         = -1;
     * so if we set
     *      x := a*b*(i-1),
     * then
     *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
     *         = a^2 * b^2 * (-2*i)
     *         = a*(-i)*(2*a*b^2)
     *         = a*(-i)*i
     *         = a.
     *
     * (This is due to A.O.L. Atkin,
     * <URL:
     *http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
     * November 1992.)
     */

    /* t := 2*a */
    if (!BN_mod_lshift1_quick(t, A, p)) {
      goto end;
    }

    /* b := (2*a)^((|p|-5)/8) */
    if (!BN_rshift(q, p, 3)) {
      goto end;
    }
    q->neg = 0;
    if (!BN_mod_exp(b, t, q, p, ctx)) {
      goto end;
    }

    /* y := b^2 */
    if (!BN_mod_sqr(y, b, p, ctx)) {
      goto end;
    }

    /* t := (2*a)*b^2 - 1*/
    if (!BN_mod_mul(t, t, y, p, ctx) ||
        !BN_sub_word(t, 1)) {
      goto end;
    }

    /* x = a*b*t */
    if (!BN_mod_mul(x, A, b, p, ctx) ||
        !BN_mod_mul(x, x, t, p, ctx)) {
      goto end;
    }

    if (!BN_copy(ret, x)) {
      goto end;
    }
    err = 0;
    goto vrfy;
  }

  /* e > 2, so we really have to use the Tonelli/Shanks algorithm.
   * First, find some  y  that is not a square. */
  if (!BN_copy(q, p)) {
    goto end; /* use 'q' as temp */
  }
  q->neg = 0;
  i = 2;
  do {
    /* For efficiency, try small numbers first;
     * if this fails, try random numbers.
     */
    if (i < 22) {
      if (!BN_set_word(y, i)) {
        goto end;
      }
    } else {
      if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) {
        goto end;
      }
      if (BN_ucmp(y, p) >= 0) {
        if (!(p->neg ? BN_add : BN_sub)(y, y, p)) {
          goto end;
        }
      }
      /* now 0 <= y < |p| */
      if (BN_is_zero(y)) {
        if (!BN_set_word(y, i)) {
          goto end;
        }
      }
    }

    r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
    if (r < -1) {
      goto end;
    }
    if (r == 0) {
      /* m divides p */
      OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
      goto end;
    }
  } while (r == 1 && ++i < 82);

  if (r != -1) {
    /* Many rounds and still no non-square -- this is more likely
     * a bug than just bad luck.
     * Even if  p  is not prime, we should have found some  y
     * such that r == -1.
     */
    OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
    goto end;
  }

  /* Here's our actual 'q': */
  if (!BN_rshift(q, q, e)) {
    goto end;
  }

  /* Now that we have some non-square, we can find an element
   * of order  2^e  by computing its q'th power. */
  if (!BN_mod_exp(y, y, q, p, ctx)) {
    goto end;
  }
  if (BN_is_one(y)) {
    OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
    goto end;
  }

  /* Now we know that (if  p  is indeed prime) there is an integer
   * k,  0 <= k < 2^e,  such that
   *
   *      a^q * y^k == 1   (mod p).
   *
   * As  a^q  is a square and  y  is not,  k  must be even.
   * q+1  is even, too, so there is an element
   *
   *     X := a^((q+1)/2) * y^(k/2),
   *
   * and it satisfies
   *
   *     X^2 = a^q * a     * y^k
   *         = a,
   *
   * so it is the square root that we are looking for.
   */

  /* t := (q-1)/2  (note that  q  is odd) */
  if (!BN_rshift1(t, q)) {
    goto end;
  }

  /* x := a^((q-1)/2) */
  if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
  {
    if (!BN_nnmod(t, A, p, ctx)) {
      goto end;
    }
    if (BN_is_zero(t)) {
      /* special case: a == 0  (mod p) */
      BN_zero(ret);
      err = 0;
      goto end;
    } else if (!BN_one(x)) {
      goto end;
    }
  } else {
    if (!BN_mod_exp(x, A, t, p, ctx)) {
      goto end;
    }
    if (BN_is_zero(x)) {
      /* special case: a == 0  (mod p) */
      BN_zero(ret);
      err = 0;
      goto end;
    }
  }

  /* b := a*x^2  (= a^q) */
  if (!BN_mod_sqr(b, x, p, ctx) ||
      !BN_mod_mul(b, b, A, p, ctx)) {
    goto end;
  }

  /* x := a*x    (= a^((q+1)/2)) */
  if (!BN_mod_mul(x, x, A, p, ctx)) {
    goto end;
  }

  while (1) {
    /* Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
     * where  E  refers to the original value of  e,  which we
     * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
     *
     * We have  a*b = x^2,
     *    y^2^(e-1) = -1,
     *    b^2^(e-1) = 1.
     */

    if (BN_is_one(b)) {
      if (!BN_copy(ret, x)) {
        goto end;
      }
      err = 0;
      goto vrfy;
    }


    /* find smallest  i  such that  b^(2^i) = 1 */
    i = 1;
    if (!BN_mod_sqr(t, b, p, ctx)) {
      goto end;
    }
    while (!BN_is_one(t)) {
      i++;
      if (i == e) {
        OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
        goto end;
      }
      if (!BN_mod_mul(t, t, t, p, ctx)) {
        goto end;
      }
    }


    /* t := y^2^(e - i - 1) */
    if (!BN_copy(t, y)) {
      goto end;
    }
    for (j = e - i - 1; j > 0; j--) {
      if (!BN_mod_sqr(t, t, p, ctx)) {
        goto end;
      }
    }
    if (!BN_mod_mul(y, t, t, p, ctx) ||
        !BN_mod_mul(x, x, t, p, ctx) ||
        !BN_mod_mul(b, b, y, p, ctx)) {
      goto end;
    }
    e = i;
  }

vrfy:
  if (!err) {
    /* verify the result -- the input might have been not a square
     * (test added in 0.9.8) */

    if (!BN_mod_sqr(x, ret, p, ctx)) {
      err = 1;
    }

    if (!err && 0 != BN_cmp(x, A)) {
      OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
      err = 1;
    }
  }

end:
  if (err) {
    if (ret != in) {
      BN_clear_free(ret);
    }
    ret = NULL;
  }
  BN_CTX_end(ctx);
  return ret;
}

int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
  BIGNUM *estimate, *tmp, *delta, *last_delta, *tmp2;
  int ok = 0, last_delta_valid = 0;

  if (in->neg) {
    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
    return 0;
  }
  if (BN_is_zero(in)) {
    BN_zero(out_sqrt);
    return 1;
  }

  BN_CTX_start(ctx);
  if (out_sqrt == in) {
    estimate = BN_CTX_get(ctx);
  } else {
    estimate = out_sqrt;
  }
  tmp = BN_CTX_get(ctx);
  last_delta = BN_CTX_get(ctx);
  delta = BN_CTX_get(ctx);
  if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) {
    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  /* We estimate that the square root of an n-bit number is 2^{n/2}. */
  BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2);

  /* This is Newton's method for finding a root of the equation |estimate|^2 -
   * |in| = 0. */
  for (;;) {
    /* |estimate| = 1/2 * (|estimate| + |in|/|estimate|) */
    if (!BN_div(tmp, NULL, in, estimate, ctx) ||
        !BN_add(tmp, tmp, estimate) ||
        !BN_rshift1(estimate, tmp) ||
        /* |tmp| = |estimate|^2 */
        !BN_sqr(tmp, estimate, ctx) ||
        /* |delta| = |in| - |tmp| */
        !BN_sub(delta, in, tmp)) {
      OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
      goto err;
    }

    delta->neg = 0;
    /* The difference between |in| and |estimate| squared is required to always
     * decrease. This ensures that the loop always terminates, but I don't have
     * a proof that it always finds the square root for a given square. */
    if (last_delta_valid && BN_cmp(delta, last_delta) >= 0) {
      break;
    }

    last_delta_valid = 1;

    tmp2 = last_delta;
    last_delta = delta;
    delta = tmp2;
  }

  if (BN_cmp(tmp, in) != 0) {
    OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
    goto err;
  }

  ok = 1;

err:
  if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) {
    ok = 0;
  }
  BN_CTX_end(ctx);
  return ok;
}
