Example #1
0
/*
        Функция шифрует сообщение m, отдает пару m2[2]{r,e}
        При m >= p  возвращает ошибку
*/
int eg_send(long long P, long long g, long long key, long long m, long long *m2)
{
        long long k;
        
        if(m >= P)
                return -1;
        
        k = Random32() / (P - 2) + 1;
        
        m2[0] = PowMod(g, k, P);
        m2[1] = m * PowMod(key, k, P);
        
        return 0;
}
Example #2
0
int main()
{
    // printf("hello, world");

    char result[BUFFER_SIZE];
    char remainder[BUFFER_SIZE];

    // please make sure the bit length is enough before calculate
    // especially when you do a large power operation
    // you can change it by define: BIG_INT_BIT_LEN
    // the default bit length for BigInt is 1024

    // routine test
    puts(Add("2010", "4", result));
    puts(Sub("0", "2014", result));
    puts(Mul("2", "43", result));
    puts(Div("86", "10", result, remainder));
    puts(remainder);
    puts(Mod("-86", "10", result));
    puts(PowMod("7", "80", "86", result));

    // BigInt test
    puts(Sub("233333333333333333333333333333333333333333333333", "33", result));
    puts(Mul("2333333333333333333333333333333", "2333333333333333333", result));
    puts(Div("2333333333333333333333333333333", "2333333333333333332", result, remainder));
    puts(remainder);
    puts(Pow("8", "86", result));

    return 0;
}
Example #3
0
File: BSGS.cpp Project: chyyuu/ACM
int BabyStep(int A,int B,int C){
	map<int,int> Hash;
	LL buf=1%C,D=buf,K;
	int i,d=0,tmp;
	for(i=0;i<=100;buf=buf*A%C,++i)if(buf==B)return i;
	while((tmp=GCD(A,C))!=1){
		if(B%tmp)return -1;
		++d;
		C/=tmp;
		B/=tmp;
		D=D*A/tmp%C;
	}
	Hash.clear();
	int M=(int)ceil(sqrt((double)C));
	for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)if(Hash.find((int)buf)==Hash.end())Hash[(int)buf]=i;
	for(i=0,K=PowMod((LL)A,M,C);i<=M;D=D*K%C,++i){
		tmp=inval((int)D,B,C);
		if(tmp>0&&Hash.find(tmp)!=Hash.end())return i*M+Hash[tmp]+d;
	}
	return -1;
}
Example #4
0
// TODO: Add the ability to set a maximum number of iterations
inline BigInt FindFactor
( const BigInt& n,
  Int a,
  const PollardRhoCtrl& ctrl )
{
    if( a == 0 || a == -2 )
        Output("WARNING: Problematic choice of Pollard rho shift");
    BigInt tmp, gcd;
    BigInt one(1);

    auto xAdvance =
      [&]( BigInt& x )
      {
        if( ctrl.numSteps == 1 )
        {
            // TODO: Determine if there is a penalty to x *= x
            /*
            tmp = x;
            tmp *= x;
            tmp += a;
            x = tmp;
            x %= n;
            */
            x *= x;
            x += a;
            x %= n;
        }
        else
        {
            PowMod( x, 2*ctrl.numSteps, n, x );
            x += a;
            x %= n;
        }
      };

    auto QAdvance =
      [&]( const BigInt& x, const BigInt& x2, BigInt& Q )
      {
        tmp = x2;
        tmp -= x;
        Q *= tmp;
        Q %= n;
      };

    Int gcdDelay = ctrl.gcdDelay;
    BigInt xi=ctrl.x0;
    BigInt x2i(xi);
    BigInt xiSave=xi, x2iSave=x2i;
    BigInt Qi(1);
    Int k=1, i=1; // it is okay for i to overflow since it is just for printing
    while( true )
    {
        // Advance xi once
        xAdvance( xi );

        // Advance x2i twice
        xAdvance( x2i );
        xAdvance( x2i );

        // Advance Qi
        QAdvance( xi, x2i, Qi );

        if( k >= gcdDelay )
        {
            GCD( Qi, n, gcd );
            if( gcd > one )
            {
                // NOTE: This was not suggested by Pollard's original paper
                if( gcd == n )
                {
                    if( gcdDelay == 1 )
                    {
                        RuntimeError("(x) converged before (x mod p) at i=",i);
                    }
                    else
                    {
                        if( ctrl.progress )
                            Output("Backtracking at i=",i);
                        i = Max( i-(gcdDelay+1), 0 );
                        gcdDelay = 1;
                        xi = xiSave;
                        x2i = x2iSave;
                    }
                }
                else
                {
                    if( ctrl.progress )
                        Output("Found factor ",gcd," at i=",i); 
                    return gcd;
                }
            }

            // NOTE: This was not suggested by Pollard's original paper
            k = 0;
            xiSave = xi;
            x2iSave = x2i;
            Qi = 1;
        }
        ++k;
        ++i;
    }
}
Example #5
0
/*
        Функция дешифрует сообщение, принимает пару m2[2]{r,e}
        Возвращает сообщение m
*/
long long eg_rec(long long P, long long key, long long *m2)
{
        return m2[1] * PowMod(m2[0], P - 1 - key, P);
}
Example #6
0
inline ZZmod<ID> operator^(ZZmod<ID> const & a, ZZ const & e)
{
    return PowMod(a.Representative(), e, ZZmod<ID>::Modulus());
}
Example #7
0
int main(int argc, const char * argv[])
{
	if (argc < 5) 
	{
        printf("Error: Too few arguments. <first_long_number_filename> [ + | - | * | / | % | ^ ] <second_long_number_filename> <result_long_number_filename>\n");
        return 0;
    }
    
    if (argc > 7) 
	{
        printf("Error: Too many arguments. <first_long_number_filename> [ + | - | * | / | % | ^ ] <second_long_number_filename> <result_long_number_filename> <module_long_number_filename> <-b>\n");
        return 0;
    }
    
    FILE* firstLongNumFile = fopen(argv[1], "r");
    if (!firstLongNumFile) 
	{
        printf("Error: Unable to open file: %s \n", argv[1]);
        return 0;
    }
	fclose(firstLongNumFile);

    const char* operation = argv[2];
    if ((strlen(operation) > 1 || operation[0] == '\0') || operation[0] != '+' && operation[0] != '-' && operation[0] != '*' && operation[0] != '/' && operation[0] != '%' && operation[0] != '^') 
	{
        printf("Error: Wrong operation: %s \n", operation);
        return 0;
    }
    
    FILE* secondLongNumFile = fopen(argv[3], "r");
    if (!secondLongNumFile) 
	{
        printf("Error: Unable to open file: %s \n", argv[3]);
        return 0;
    }
    fclose(secondLongNumFile);

	FILE* resultLongNumFile = fopen(argv[4], "r");
    if (!resultLongNumFile) 
	{
        printf("Error: Unable to open file: %s \n", argv[4]);
        return 0;
    }
    fclose(resultLongNumFile);

	/////////////////////////////////

	int bin = 0;

	if (argc == 5)
		if (argv[2][0] == '^')
		{
			printf("Error: Input module file\n");
			return 0;
		}

    if (argc == 6) 
	{
		if (argv[2][0] == '^')
		{
			FILE* moduleLongNumFile = fopen(argv[5], "r");
			if (!moduleLongNumFile) 
			{
				printf("Error: Unable to open file: %s \n", argv[5]);
				return 0;
			}
			fclose(moduleLongNumFile);
		}
		else
		{
			if (strcmp(argv[5], "-b")) 
			{
				printf("Error: Invalid flag: %s \n", argv[5]);
				return 0;
			}
			bin = 1;
		}
		
    }

	if (argc == 7) 
	{
		FILE* moduleLongNumFile = fopen(argv[5], "r");
		if (!moduleLongNumFile) 
		{
			printf("Error: Unable to open file: %s \n", argv[5]);
			return 0;
		}
		fclose(moduleLongNumFile);

        if (strcmp(argv[6], "-b")) 
		{
            printf("Error: Invalid flag: %s \n", argv[6]);
            return 0;
        }
		bin = 1;
    }

	////////////////////////////
    
	LongNumberClass a,b;

    //upload first large number------------------
	if(bin == 1)
		a.ReadBin(argv[1]);
	else
		a.ReadText(argv[1]);
    
    //upload second large number-------------------------------------------------------------------------------------
	if(bin == 1)
		b.ReadBin(argv[3]);
	else
		b.ReadText(argv[3]);
    
    //perform chosen operation----------------------------------------------------------------------------------------

    LongNumberClass result;
    
    switch (operation[0]) {
        case '+':
        {
            result = a + b;
            break;
        }
        case '-':
        {
            result = a - b;
            break;
        }
        case '*':
        {
            result = a * b;
            break;
        }
        case '/':
        {
            result = a / b;
            break;
        }
        case '%':
        {
            result = a % b;
            break;
        }
        case '^':
        {
			LongNumberClass c;
            if(bin == 1)
				c.ReadBin(argv[5]);
			else
				c.ReadText(argv[5]);
			
			result = PowMod(a, b, c);
            break;
        }
        default:
            break;
    }    
       
    //save result long number---------------
	if (bin == 1)
		result.WriteBin(argv[4]);
	else
		result.WriteText(argv[4]);

	return 0;
}
Example #8
0
unsigned int RSA32::Decrypt( const unsigned int p_message )
{
    return PowMod( p_message, m_d, m_n );
}
Example #9
0
inline BigInt FindFactor
( const BigInt& n,
        DynamicSieve<SieveUnsigned>& sieve,
  const PollardPMinusOneCtrl<SieveUnsigned>& ctrl )
{
    const double twoLog = Log( 2. );
    const double nLog = double( Log( BigFloat(n) ) );
    const BigInt zero(0), one(1);

    // Keep all of the generated primes
    sieve.SetStorage( true );

    SieveUnsigned smooth1 = ctrl.smooth1;
    SieveUnsigned smooth2 = ctrl.smooth2;
    SieveUnsigned smooth1Bound = Max( Pow(10ULL,9ULL), 8ULL*smooth1 );
    SieveUnsigned smooth2Bound = Max( Pow(10ULL,10ULL), 8ULL*smooth2 );

    // Ensure that we do not have a GCD of n appear too many times despite
    // separately checking the powers of two
    bool separateOdd=false;
    Int maxGCDFailures=10;
    Int numGCDFailures=0;

    BigInt smallPrime, gcd, tmp, diffPower;
    while( true )
    {
        // Ensure that we have sieved at least up until smooth1
        bool neededStage1Sieving = ( sieve.oddPrimes.back() < smooth1 );
        if( ctrl.progress && neededStage1Sieving )
            Output
            ("Updating sieve from ",sieve.oddPrimes.back()," to ",smooth1);
        sieve.Generate( smooth1 );
        if( ctrl.progress && neededStage1Sieving )
            Output("Done sieving for stage 1");

        // Uniformly select a in (Z/(n))*
        // (alternatively, we could set a=2)
        BigInt a = SampleUniform( zero, n );
        while( GCD( a, n ) != one )
        {
            a = SampleUniform( zero, n ); 
        }

        if( !separateOdd )
        {
            // Handle 2 separately
            unsigned smallPrimeExponent = unsigned(nLog/twoLog);
            for( Int i=0; i<smallPrimeExponent; ++i )
            {
                // a = a^2 (mod n)
                a *= a;
                a %= n;
            }
        }
        auto smooth1End = 
          std::upper_bound
          ( sieve.oddPrimes.begin(),
            sieve.oddPrimes.end(),
            smooth1 );
        for( auto iter=sieve.oddPrimes.begin(); iter<smooth1End; ++iter )
        {
            auto smallPrime = *iter;
            double smallPrimeLog = double(Log(double(smallPrime)));
            unsigned smallPrimeExponent = unsigned(nLog/smallPrimeLog);
            for( Int i=0; i<smallPrimeExponent; ++i )
            {
                // a = a^smallPrime (mod n)
                PowMod( a, smallPrime, n, a );
            }
        }

        // gcd := GCD( a-1, n )
        tmp = a; 
        tmp -= 1;
        GCD( tmp, n, gcd );
        if( gcd > one && gcd < n )
        {
            if( ctrl.progress )
                Output("Found stage-1 factor of ",gcd);
            return gcd;
        }

        if( separateOdd )
        { 
            unsigned twoExponent = unsigned(nLog/twoLog);
            for( Int i=0; i<twoExponent; ++i )
            {
                // a = a*a (mod n)
                a *= a;
                a %= n;

                //gcd = GCD( a-1, n );
                tmp = a;
                tmp -= 1;
                GCD( tmp, n, gcd );
                if( gcd > one && gcd < n )
                {
                    if( ctrl.progress )
                        Output("Found separate stage-1 factor of ",gcd);
                    return gcd;
                }
            }
        }

        if( gcd == n )
        {
            if( separateOdd )
            {
                ++numGCDFailures;
                if( numGCDFailures >= maxGCDFailures )
                    RuntimeError
                    ("Too many GCD failures despite separately checking "
                     "powers of two");
            }
            else
            {
                ++numGCDFailures;
                separateOdd = true;
                if( ctrl.progress )
                    Output("GCD was n; will separately check powers of two");
            }
            continue;
        }
        else // gcd == one
        {
            if( ctrl.progress )
                Output("Proceeding to stage-2");
        }
        
        // Run stage-2
        // ----------- 

        // Store all powers of a^{d_i}, where d_i is the difference between
        // primes p_{i+1} and p_i, where smooth1 < p_{i+1} <= smooth2
        bool neededStage2Sieving = ( sieve.oddPrimes.back() < smooth2 );
        if( ctrl.progress && neededStage2Sieving )
            Output
            ("Updating sieve from ",sieve.oddPrimes.back()," to ",smooth2);
        sieve.Generate( smooth2 );
        if( ctrl.progress && neededStage2Sieving )
            Output("Done sieving for stage 2");

        // NOTE: stage1End has potentially been invalidated due to reallocation
        auto stage2Beg =
          std::lower_bound
          ( sieve.oddPrimes.begin(),
            sieve.oddPrimes.end(),
            smooth1 );
        auto stage2End =
          std::upper_bound
          ( stage2Beg,
            sieve.oddPrimes.end(),
            smooth2 );
        std::map<SieveUnsigned,BigInt> diffPowers;
        for( auto iter=stage2Beg; iter<stage2End; ++iter )
        {
            SieveUnsigned diff = *iter - *(iter-1);
            auto search = diffPowers.find( diff );

            const size_t whichPrime = (iter-sieve.oddPrimes.begin())+1;
            Output("  ",whichPrime,": ",*iter," - ",*(iter-1)," = ",diff);
            if( search == diffPowers.end() )
            {
                PowMod( a, diff, n, diffPower );
                diffPowers.insert( std::make_pair(diff,diffPower) );
                Output("    Stored ",a,"^",diff,"=",diffPower);
            }
            else
                Output("    diff=",diff," was redundant");
        }

        // Test each stage two candidate
        for( auto iter=stage2Beg; iter<stage2End; ++iter )
        {
            SieveUnsigned diff = *iter - *(iter-1);
            a *= diffPowers[diff];
            a %= n;
            
            //gcd = GCD( a-1, n );
            tmp = a;
            tmp -= 1;
            GCD( tmp, n, gcd );
            if( gcd > one && gcd < n )
            {
                if( ctrl.progress )
                    Output("Found stage-2 factor of ",gcd);
                return gcd;
            }
        }

        if( gcd == n )
        {
            if( separateOdd )
            {
                if( ctrl.progress )
                    Output("GCD failure ",numGCDFailures);
                ++numGCDFailures;
                if( numGCDFailures >= maxGCDFailures )
                    RuntimeError
                    ("Too many GCD failures despite separately checking "
                     "powers of two");
            }
            else
            {
                ++numGCDFailures;
                separateOdd = true;
                if( ctrl.progress )
                    Output("GCD was n; will separately check powers of two");
            }
            continue;
        }
        else // gcd == one
        {
            if( smooth1 >= smooth1Bound )
            {
                RuntimeError
                ("Stage-1 smoothness bound of ",smooth1Bound," exceeded");
            }
            if( smooth2 >= smooth2Bound )
            {
                RuntimeError
                ("Stage-2 smoothness bound of ",smooth2Bound," exceeded");
            }
            smooth1 *= 2;
            smooth2 *= 2;
            if( ctrl.progress )
                Output
                ("Increased stage-1 smoothness to ",smooth1," and stage-2 "
                 "smoothness to ",smooth2);
        }
    }
}