/*
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#ifndef _XIL_BIGNUM_H_
#define _XIL_BIGNUM_H_

#include <openssl/opensslconf.h>
#include <openssl/ossl_typ.h>
#include <openssl/bn.h> 

/*
 * OpenSSL 1.1.0+ makes these structs opaque (forward declared only).
 * We need to define them here to access internal members.
 * 
 * However, some GCC installations have include-fixed directories with
 * old OpenSSL headers that define these structs. To avoid redefinition:
 * - Define XIL_BIGNUM_STRUCTS_DEFINED if your compiler's include-fixed
 *   already provides struct definitions (e.g., Batonroot GCC)
 * - Or ensure system OpenSSL headers take precedence with -isystem
 */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(XIL_BIGNUM_STRUCTS_DEFINED)

struct bignum_st {
    BN_ULONG *d;                /* Pointer to an array of 'BN_BITS2' bit
                                 * chunks. */
    int top;                    /* Index of last used d +1. */
    /* The next are internal book keeping for bn_expand. */
    int dmax;                   /* Size of the d array. */
    int neg;                    /* one if the number is negative */
    int flags;
};

/* Used for montgomery multiplication */
struct bn_mont_ctx_st {
    int ri;                     /* number of bits in R */
    BIGNUM RR;                  /* used to convert to montgomery form */
    BIGNUM N;                   /* The modulus */
    BIGNUM Ni;                  /* R*(1/R mod N) - N*Ni = 1 (Ni is only
                                 * stored for bignum algorithm) */
    BN_ULONG n0[2];             /* least significant word(s) of Ni; (type
                                 * changed with 0.9.9, was "BN_ULONG n0;"
                                 * before) */
    int flags;
};

#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L && !XIL_BIGNUM_STRUCTS_DEFINED */

#endif