/* 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>

#include "internal.h"


BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
  // Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm
  // (cf. Henri Cohen, "A Course in Algebraic Computational Number Theory",
  // algorithm 1.5.1). |p| is assumed to be a prime.

  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 ||
          !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 ||
        !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_mont(ret, A, q, p, ctx, NULL)) {
      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_consttime(t, A, p, ctx)) {
      goto end;
    }

    // b := (2*a)^((|p|-5)/8)
    if (!BN_rshift(q, p, 3)) {
      goto end;
    }
    q->neg = 0;
    if (!BN_mod_exp_mont(b, t, q, p, ctx, NULL)) {
      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_jacobi(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_mont(y, y, q, p, ctx, NULL)) {
    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_mont(x, A, t, p, ctx, NULL)) {
      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 the smallest i, 0 < i < e, such that b^(2^i) = 1
    for (i = 1; i < e; i++) {
      if (i == 1) {
        if (!BN_mod_sqr(t, b, p, ctx)) {
          goto end;
        }
      } else {
        if (!BN_mod_mul(t, t, t, p, ctx)) {
          goto end;
        }
      }
      if (BN_is_one(t)) {
        break;
      }
    }
    // If not found, a is not a square or p is not a prime.
    if (i >= e) {
      OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
      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 decreases each iteration, so this loop will terminate.
    assert(i < e);
    e = i;
  }

vrfy:
  if (!err) {
    // Verify the result. The input might have been not a square.
    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}.
  if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) {
    goto err;
  }

  // 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;
}
