/* * Copyright (C) 2016 Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 COPYRIGHT * OWNER OR 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. * */ #if !defined(_CP_BN_H) #define _CP_BN_H #include "pcpbnuimpl.h" #include "pcpbnuarith.h" #include "pcpbnumisc.h" #include "pcpbnu32arith.h" #include "pcpbnu32misc.h" /* // Big Number context */ struct _cpBigNum { IppCtxId idCtx; /* BigNum ctx id */ IppsBigNumSGN sgn; /* sign */ cpSize size; /* BigNum size (BNU_CHUNK_T) */ cpSize room; /* BigNum max size (BNU_CHUNK_T) */ BNU_CHUNK_T* number; /* BigNum value */ BNU_CHUNK_T* buffer; /* temporary buffer */ }; /* BN accessory macros */ #define BN_ID(pBN) ((pBN)->idCtx) #define BN_SIGN(pBN) ((pBN)->sgn) #define BN_POSITIVE(pBN) (BN_SIGN(pBN)==ippBigNumPOS) #define BN_NEGATIVE(pBN) (BN_SIGN(pBN)==ippBigNumNEG) #define BN_NUMBER(pBN) ((pBN)->number) #define BN_BUFFER(pBN) ((pBN)->buffer) #define BN_ROOM(pBN) ((pBN)->room) #define BN_SIZE(pBN) ((pBN)->size) #define BN_SIZE32(pBN) ((pBN)->size*(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))) //#define BN_SIZE32(pBN) (BITS2WORD32_SIZE( BITSIZE_BNU(BN_NUMBER((pBN)),BN_SIZE((pBN))))) #define BN_VALID_ID(pBN) (BN_ID((pBN))==idCtxBigNum) #define INVERSE_SIGN(s) (((s)==ippBigNumPOS)? ippBigNumNEG : ippBigNumPOS) #define BN_ALIGNMENT ((int)sizeof(void*)) /* pack-unpack context */ void cpPackBigNumCtx(const IppsBigNumState* pBN, Ipp8u* pBuffer); void cpUnpackBigNumCtx(const Ipp8u* pBuffer, IppsBigNumState* pBN); /* copy BN */ __INLINE IppsBigNumState* cpBN_copy(IppsBigNumState* pDst, const IppsBigNumState* pSrc) { BN_SIGN(pDst) = BN_SIGN(pSrc); BN_SIZE(pDst) = BN_SIZE(pSrc); ZEXPAND_COPY_BNU(BN_NUMBER(pDst), BN_ROOM(pDst), BN_NUMBER(pSrc), BN_SIZE(pSrc)); return pDst; } /* set BN to zero */ __INLINE IppsBigNumState* cpBN_zero(IppsBigNumState* pBN) { BN_SIGN(pBN) = ippBigNumPOS; BN_SIZE(pBN) = 1; ZEXPAND_BNU(BN_NUMBER(pBN),0, (int)BN_ROOM(pBN)); return pBN; } /* fixup BN */ __INLINE IppsBigNumState* cpBN_fix(IppsBigNumState* pBN) { cpSize len = BN_SIZE(pBN); FIX_BNU(BN_NUMBER(pBN), len); BN_SIZE(pBN) = len; return pBN; } /* set BN to chunk */ __INLINE IppsBigNumState* cpBN_chunk(IppsBigNumState* pBN, BNU_CHUNK_T a) { BN_SIGN(pBN) = ippBigNumPOS; BN_SIZE(pBN) = 1; ZEXPAND_BNU(BN_NUMBER(pBN),0, (int)BN_ROOM(pBN)); BN_NUMBER(pBN)[0] = a; return pBN; } /* set BN to 2^m */ __INLINE IppsBigNumState* cpBN_power2(IppsBigNumState* pBN, int power) { cpSize size = BITS_BNU_CHUNK(power+1); if(BN_ROOM(pBN) >= size) { BN_SIGN(pBN) = ippBigNumPOS; BN_SIZE(pBN) = size; ZEXPAND_BNU(BN_NUMBER(pBN),0, BN_ROOM(pBN)); SET_BIT(BN_NUMBER(pBN), power); return pBN; } else return NULL; } /* bitsize of BN */ __INLINE int cpBN_bitsize(const IppsBigNumState* pA) { int bitsize = BITSIZE_BNU(BN_NUMBER(pA), BN_SIZE(pA)); return bitsize; } /* returns -1/0/+1 depemding on A~B comparison */ __INLINE int cpBN_cmp(const IppsBigNumState* pA, const IppsBigNumState* pB) { IppsBigNumSGN signA = BN_SIGN(pA); IppsBigNumSGN signB = BN_SIGN(pB); if(signA==signB) { int result = cpCmp_BNU(BN_NUMBER(pA), BN_SIZE(pA), BN_NUMBER(pB), BN_SIZE(pB)); return (ippBigNumPOS==signA)? result : -result; } return (ippBigNumPOS==signA)? 1 : -1; } /* returns -1/0/+1 depemding on A comparison 00 */ __INLINE int cpBN_tst(const IppsBigNumState* pA) { if(1==BN_SIZE(pA) && 0==BN_NUMBER(pA)[0]) return 0; else return BN_POSITIVE(pA)? 1 : -1; } // some addtition functions __INLINE int IsZero_BN(const IppsBigNumState* pA) { return ( BN_SIZE(pA)==1 ) && ( BN_NUMBER(pA)[0]==0 ); } __INLINE int IsOdd_BN(const IppsBigNumState* pA) { return BN_NUMBER(pA)[0] & 1; } __INLINE IppsBigNumState* BN_Word(IppsBigNumState* pBN, BNU_CHUNK_T w) { BN_SIGN(pBN) = ippBigNumPOS; BN_SIZE(pBN) = 1; ZEXPAND_BNU(BN_NUMBER(pBN),0, BN_ROOM(pBN)); BN_NUMBER(pBN)[0] = w; return pBN; } __INLINE IppsBigNumState* BN_Set(const BNU_CHUNK_T* pData, cpSize len, IppsBigNumState* pBN) { BN_SIGN(pBN) = ippBigNumPOS; BN_SIZE(pBN) = len; ZEXPAND_COPY_BNU(BN_NUMBER(pBN), BN_ROOM(pBN), pData, len); return pBN; } __INLINE IppsBigNumState* BN_Make(BNU_CHUNK_T* pData, BNU_CHUNK_T* pBuffer, cpSize len, IppsBigNumState* pBN) { BN_ID(pBN) = idCtxBigNum; BN_SIGN(pBN) = ippBigNumPOS; BN_SIZE(pBN) = 1; BN_ROOM(pBN) = len; BN_NUMBER(pBN) = pData; BN_BUFFER(pBN) = pBuffer; return pBN; } /* // fixed single chunk BN */ typedef struct _ippcpBigNumChunk { IppsBigNumState bn; BNU_CHUNK_T value; BNU_CHUNK_T temporary; } IppsBigNumStateChunk; /* reference to BN(1) and BN(2) */ IppsBigNumState* cpBN_OneRef(void); IppsBigNumState* cpBN_TwoRef(void); IppsBigNumState* cpBN_ThreeRef(void); #define BN_ONE_REF() cpBN_OneRef() #define BN_TWO_REF() cpBN_TwoRef() #define BN_THREE_REF() cpBN_ThreeRef() #endif /* _CP_BN_H */