File: miller_rabin.c

package info (click to toggle)
gobject-introspection 1.84.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 72,336 kB
  • sloc: ansic: 562,269; python: 23,692; xml: 16,240; yacc: 1,711; perl: 1,624; sh: 1,139; lex: 510; cpp: 487; makefile: 182; javascript: 15; lisp: 1
file content (67 lines) | stat: -rw-r--r-- 1,212 bytes parent folder | download | duplicates (24)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "miller_rabin.h"

static inline cmph_uint64 int_pow(cmph_uint64 a, cmph_uint64 d, cmph_uint64 n)
{
	cmph_uint64 a_pow = a;
	cmph_uint64 res = 1;
	while(d > 0)
	{
		if((d & 1) == 1)
			res =(((cmph_uint64)res) * a_pow) % n;
		a_pow = (((cmph_uint64)a_pow) * a_pow) % n;
		d /= 2;
	};
	return res;
};

static inline cmph_uint8 check_witness(cmph_uint64 a_exp_d, cmph_uint64 n, cmph_uint64 s)
{
	cmph_uint64 i;
	cmph_uint64 a_exp = a_exp_d;
	if(a_exp == 1 || a_exp == (n - 1))
		return 1;
	for(i = 1; i < s; i++)
	{
		a_exp = (((cmph_uint64)a_exp) * a_exp) % n;
		if(a_exp == (n - 1))
			return 1;
	};
	return 0;
};

cmph_uint8 check_primality(cmph_uint64 n)
{
	cmph_uint64 a, d, s, a_exp_d;
	if((n % 2) == 0)
		return 0;
	if((n % 3) == 0)
		return 0;
	if((n % 5) == 0)
		return 0;
	if((n % 7 ) == 0)
		return 0;
	//we decompoe the number n - 1 into 2^s*d
	s = 0;
	d = n - 1;
	do 
	{
		s++;
		d /= 2;
	}while((d % 2) == 0);

	a = 2;
	a_exp_d = int_pow(a, d, n);
	if(check_witness(a_exp_d, n, s) == 0)
		return 0;
	a = 7;
	a_exp_d = int_pow(a, d, n);
	if(check_witness(a_exp_d, n, s) == 0)
		return 0;
	a = 61;
	a_exp_d = int_pow(a, d, n);
	if(check_witness(a_exp_d, n, s) == 0)
		return 0;
	return 1;
};