⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 integer.cpp

📁 lots Elliptic curve cryptography codes. Use Visual c++ to compile
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// integer.cpp - written and placed in the public domain by Wei Dai// contains public domain code contributed by Alister Lee and Leonard Janke#include "pch.h"#ifndef CRYPTOPP_IMPORTS#include "integer.h"#include "modarith.h"#include "nbtheory.h"#include "asn.h"#include "oids.h"#include "words.h"#include "algparam.h"#include "pubkey.h"		// for P1363_KDF2#include "sha.h"#include "cpu.h"#include <iostream>#if _MSC_VER >= 1400	#include <intrin.h>#endif#ifdef __DECCXX	#include <c_asm.h>#endif#ifdef CRYPTOPP_MSVC6_NO_PP	#pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 instructions will be disabled.")#endif#define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86)NAMESPACE_BEGIN(CryptoPP)bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt){	if (valueType != typeid(Integer))		return false;	*reinterpret_cast<Integer *>(pInteger) = *reinterpret_cast<const int *>(pInt);	return true;}inline static int Compare(const word *A, const word *B, size_t N){	while (N--)		if (A[N] > B[N])			return 1;		else if (A[N] < B[N])			return -1;	return 0;}inline static int Increment(word *A, size_t N, word B=1){	assert(N);	word t = A[0];	A[0] = t+B;	if (A[0] >= t)		return 0;	for (unsigned i=1; i<N; i++)		if (++A[i])			return 0;	return 1;}inline static int Decrement(word *A, size_t N, word B=1){	assert(N);	word t = A[0];	A[0] = t-B;	if (A[0] <= t)		return 0;	for (unsigned i=1; i<N; i++)		if (A[i]--)			return 0;	return 1;}static void TwosComplement(word *A, size_t N){	Decrement(A, N);	for (unsigned i=0; i<N; i++)		A[i] = ~A[i];}static word AtomicInverseModPower2(word A){	assert(A%2==1);	word R=A%8;	for (unsigned i=3; i<WORD_BITS; i*=2)		R = R*(2-R*A);	assert(R*A==1);	return R;}// ********************************************************#if !defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE) || (defined(__x86_64__) && defined(CRYPTOPP_WORD128_AVAILABLE))	#define Declare2Words(x)			word x##0, x##1;	#define AssignWord(a, b)			a##0 = b; a##1 = 0;	#define Add2WordsBy1(a, b, c)		a##0 = b##0 + c; a##1 = b##1 + (a##0 < c);	#define LowWord(a)					a##0	#define HighWord(a)					a##1	#ifdef _MSC_VER		#define MultiplyWordsLoHi(p0, p1, a, b)		p0 = _umul128(a, b, &p1);		#ifndef __INTEL_COMPILER			#define Double3Words(c, d)		d##1 = __shiftleft128(d##0, d##1, 1); d##0 = __shiftleft128(c, d##0, 1); c *= 2;		#endif	#elif defined(__DECCXX)		#define MultiplyWordsLoHi(p0, p1, a, b)		p0 = a*b; p1 = asm("umulh %a0, %a1, %v0", a, b);	#elif defined(__x86_64__)		#ifdef __SUNPRO_CC			// Sun Studio's gcc-style inline assembly is heavily bugged as of version 5.9 Patch 124864-09 2008/12/16, but this one works			#define MultiplyWordsLoHi(p0, p1, a, b)		asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "r"(b) : "cc");		#else			#define MultiplyWordsLoHi(p0, p1, a, b)		asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc");			#define MulAcc(c, d, a, b)		asm ("mulq %6; addq %3, %0; adcq %4, %1; adcq $0, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1), "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc");			#define Double3Words(c, d)		asm ("addq %0, %0; adcq %1, %1; adcq %2, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1) : : "cc");			#define Acc2WordsBy1(a, b)		asm ("addq %2, %0; adcq $0, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b) : "cc");			#define Acc2WordsBy2(a, b)		asm ("addq %2, %0; adcq %3, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b##0), "r"(b##1) : "cc");			#define Acc3WordsBy2(c, d, e)	asm ("addq %5, %0; adcq %6, %1; adcq $0, %2;" : "+r"(c), "=r"(e##0), "=r"(e##1) : "1"(d##0), "2"(d##1), "r"(e##0), "r"(e##1) : "cc");		#endif	#endif	#define MultiplyWords(p, a, b)		MultiplyWordsLoHi(p##0, p##1, a, b)	#ifndef Double3Words		#define Double3Words(c, d)		d##1 = 2*d##1 + (d##0>>(WORD_BITS-1)); d##0 = 2*d##0 + (c>>(WORD_BITS-1)); c *= 2;	#endif	#ifndef Acc2WordsBy2		#define Acc2WordsBy2(a, b)		a##0 += b##0; a##1 += a##0 < b##0; a##1 += b##1;	#endif	#define AddWithCarry(u, a, b)		{word t = a+b; u##0 = t + u##1; u##1 = (t<a) + (u##0<t);}	#define SubtractWithBorrow(u, a, b)	{word t = a-b; u##0 = t - u##1; u##1 = (t>a) + (u##0>t);}	#define GetCarry(u)					u##1	#define GetBorrow(u)				u##1#else	#define Declare2Words(x)			dword x;	#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)		#define MultiplyWords(p, a, b)		p = __emulu(a, b);	#else		#define MultiplyWords(p, a, b)		p = (dword)a*b;	#endif	#define AssignWord(a, b)			a = b;	#define Add2WordsBy1(a, b, c)		a = b + c;	#define Acc2WordsBy2(a, b)			a += b;	#define LowWord(a)					word(a)	#define HighWord(a)					word(a>>WORD_BITS)	#define Double3Words(c, d)			d = 2*d + (c>>(WORD_BITS-1)); c *= 2;	#define AddWithCarry(u, a, b)		u = dword(a) + b + GetCarry(u);	#define SubtractWithBorrow(u, a, b)	u = dword(a) - b - GetBorrow(u);	#define GetCarry(u)					HighWord(u)	#define GetBorrow(u)				word(u>>(WORD_BITS*2-1))#endif#ifndef MulAcc	#define MulAcc(c, d, a, b)			MultiplyWords(p, a, b); Acc2WordsBy1(p, c); c = LowWord(p); Acc2WordsBy1(d, HighWord(p));#endif#ifndef Acc2WordsBy1	#define Acc2WordsBy1(a, b)			Add2WordsBy1(a, a, b)#endif#ifndef Acc3WordsBy2	#define Acc3WordsBy2(c, d, e)		Acc2WordsBy1(e, c); c = LowWord(e); Add2WordsBy1(e, d, HighWord(e));#endifclass DWord{public:	DWord() {}#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE	explicit DWord(word low)	{		m_whole = low;	}#else	explicit DWord(word low)	{		m_halfs.low = low;		m_halfs.high = 0;	}#endif	DWord(word low, word high)	{		m_halfs.low = low;		m_halfs.high = high;	}	static DWord Multiply(word a, word b)	{		DWord r;		#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE			r.m_whole = (dword)a * b;		#elif defined(MultiplyWordsLoHi)			MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b);		#endif		return r;	}	static DWord MultiplyAndAdd(word a, word b, word c)	{		DWord r = Multiply(a, b);		return r += c;	}	DWord & operator+=(word a)	{		#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE			m_whole = m_whole + a;		#else			m_halfs.low += a;			m_halfs.high += (m_halfs.low < a);		#endif		return *this;	}	DWord operator+(word a)	{		DWord r;		#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE			r.m_whole = m_whole + a;		#else			r.m_halfs.low = m_halfs.low + a;			r.m_halfs.high = m_halfs.high + (r.m_halfs.low < a);		#endif		return r;	}	DWord operator-(DWord a)	{		DWord r;		#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE			r.m_whole = m_whole - a.m_whole;		#else			r.m_halfs.low = m_halfs.low - a.m_halfs.low;			r.m_halfs.high = m_halfs.high - a.m_halfs.high - (r.m_halfs.low > m_halfs.low);		#endif		return r;	}	DWord operator-(word a)	{		DWord r;		#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE			r.m_whole = m_whole - a;		#else			r.m_halfs.low = m_halfs.low - a;			r.m_halfs.high = m_halfs.high - (r.m_halfs.low > m_halfs.low);		#endif		return r;	}	// returns quotient, which must fit in a word	word operator/(word divisor);	word operator%(word a);	bool operator!() const	{	#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE		return !m_whole;	#else		return !m_halfs.high && !m_halfs.low;	#endif	}	word GetLowHalf() const {return m_halfs.low;}	word GetHighHalf() const {return m_halfs.high;}	word GetHighHalfAsBorrow() const {return 0-m_halfs.high;}private:	union	{	#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE		dword m_whole;	#endif		struct		{		#ifdef IS_LITTLE_ENDIAN			word low;			word high;		#else			word high;			word low;		#endif		} m_halfs;	};};class Word{public:	Word() {}	Word(word value)	{		m_whole = value;	}	Word(hword low, hword high)	{		m_whole = low | (word(high) << (WORD_BITS/2));	}	static Word Multiply(hword a, hword b)	{		Word r;		r.m_whole = (word)a * b;		return r;	}	Word operator-(Word a)	{		Word r;		r.m_whole = m_whole - a.m_whole;		return r;	}	Word operator-(hword a)	{		Word r;		r.m_whole = m_whole - a;		return r;	}	// returns quotient, which must fit in a word	hword operator/(hword divisor)	{		return hword(m_whole / divisor);	}	bool operator!() const	{		return !m_whole;	}	word GetWhole() const {return m_whole;}	hword GetLowHalf() const {return hword(m_whole);}	hword GetHighHalf() const {return hword(m_whole>>(WORD_BITS/2));}	hword GetHighHalfAsBorrow() const {return 0-hword(m_whole>>(WORD_BITS/2));}	private:	word m_whole;};// do a 3 word by 2 word divide, returns quotient and leaves remainder in Atemplate <class S, class D>S DivideThreeWordsByTwo(S *A, S B0, S B1, D *dummy=NULL){	// assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S	assert(A[2] < B1 || (A[2]==B1 && A[1] < B0));	// estimate the quotient: do a 2 S by 1 S divide	S Q;	if (S(B1+1) == 0)		Q = A[2];	else		Q = D(A[1], A[2]) / S(B1+1);	// now subtract Q*B from A	D p = D::Multiply(B0, Q);	D u = (D) A[0] - p.GetLowHalf();	A[0] = u.GetLowHalf();	u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q);	A[1] = u.GetLowHalf();	A[2] += u.GetHighHalf();	// Q <= actual quotient, so fix it	while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0))	{		u = (D) A[0] - B0;		A[0] = u.GetLowHalf();		u = (D) A[1] - B1 - u.GetHighHalfAsBorrow();		A[1] = u.GetLowHalf();		A[2] += u.GetHighHalf();		Q++;		assert(Q);	// shouldn't overflow	}	return Q;}// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1template <class S, class D>inline D DivideFourWordsByTwo(S *T, const D &Al, const D &Ah, const D &B){	if (!B) // if divisor is 0, we assume divisor==2**(2*WORD_BITS)		return D(Ah.GetLowHalf(), Ah.GetHighHalf());	else	{		S Q[2];		T[0] = Al.GetLowHalf();		T[1] = Al.GetHighHalf(); 		T[2] = Ah.GetLowHalf();		T[3] = Ah.GetHighHalf();		Q[1] = DivideThreeWordsByTwo<S, D>(T+1, B.GetLowHalf(), B.GetHighHalf());		Q[0] = DivideThreeWordsByTwo<S, D>(T, B.GetLowHalf(), B.GetHighHalf());		return D(Q[0], Q[1]);	}}// returns quotient, which must fit in a wordinline word DWord::operator/(word a){	#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE		return word(m_whole / a);	#else		hword r[4];		return DivideFourWordsByTwo<hword, Word>(r, m_halfs.low, m_halfs.high, a).GetWhole();	#endif}inline word DWord::operator%(word a){	#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE		return word(m_whole % a);	#else		if (a < (word(1) << (WORD_BITS/2)))		{			hword h = hword(a);			word r = m_halfs.high % h;			r = ((m_halfs.low >> (WORD_BITS/2)) + (r << (WORD_BITS/2))) % h;			return hword((hword(m_halfs.low) + (r << (WORD_BITS/2))) % h);		}		else		{			hword r[4];			DivideFourWordsByTwo<hword, Word>(r, m_halfs.low, m_halfs.high, a);			return Word(r[0], r[1]).GetWhole();		}	#endif}// ********************************************************// use some tricks to share assembly code between MSVC and GCC#if defined(__GNUC__)	#define AddPrologue \		int result;	\		__asm__ __volatile__ \		( \			".intel_syntax noprefix;"	#define AddEpilogue \			".att_syntax prefix;" \					: "=a" (result)\					: "d" (C), "a" (A), "D" (B), "c" (N) \					: "%esi", "memory", "cc" \		);\		return result;	#define MulPrologue \		__asm__ __volatile__ \		( \			".intel_syntax noprefix;" \			AS1(	push	ebx) \			AS2(	mov		ebx, edx)	#define MulEpilogue \			AS1(	pop		ebx) \			".att_syntax prefix;" \			: \			: "d" (s_maskLow16), "c" (C), "a" (A), "D" (B) \			: "%esi", "memory", "cc" \		);	#define SquPrologue		MulPrologue	#define SquEpilogue	\			AS1(	pop		ebx) \			".att_syntax prefix;" \			: \			: "d" (s_maskLow16), "c" (C), "a" (A) \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -