@@ -7,7 +7,8 @@ export legendre, jacobi, sqrt_mod_prime, find_quadratic_non_residue, is_quadrati
7
7
8
8
export n2b, b2n
9
9
10
- export random_prime, safe_prime, tower_two_prime, get_first_primes, twin_primes
10
+ export random_prime, safe_prime, tower_two_prime, get_first_primes, twin_primes,
11
+ is_generator, get_safe_prime_generator
11
12
12
13
export factor_with_ed, wiener
13
14
@@ -359,6 +360,55 @@ function surd(n::BigInt, k::Int64)
359
360
end
360
361
361
362
363
+ """
364
+ is_generator(g::Integer, q::Integer, factors::Array) -> Bool
365
+
366
+ Returns true if `g` is a generator of `Z_q` where `q` is prime and
367
+ `factors` is the prime factorization of `q - 1 = p1^e1 * p2^e2 ... * pk^ek`.
368
+
369
+ ```
370
+ q = 2^7 * 5 + 1
371
+ is_generator(2, q, [2, 5]) -> false
372
+ is_generator(3, q, [2, 5]) -> true
373
+ ```
374
+ """
375
+ function is_generator (g:: Integer , q:: Integer , factors:: Array ):: Bool
376
+ if q % 2 == 0 && ! isprime (q)
377
+ throw (" Argument q should be an odd prime." )
378
+ end
379
+ n = q - 1
380
+ for factor in factors
381
+ if powermod (g, div (n,factor), q) == 1
382
+ return false
383
+ end
384
+ end
385
+ return true
386
+ end
387
+
388
+
389
+ """
390
+ get_safe_prime_generator(q::BigInt) -> BigInt
391
+
392
+ Returns a generator of `Z_q`, where `q = 2 * p + 1` with `q, p` primes.
393
+ """
394
+ function get_safe_prime_generator (q:: BigInt ):: BigInt
395
+ if q % 2 == 0 && ! isprime (q)
396
+ throw (" Argument q should be an odd prime." )
397
+ end
398
+
399
+ p = div (q - 1 , 2 )
400
+ factors = [2 , p]
401
+
402
+ @label sample_generator
403
+ g = rand (1 : q - 1 )
404
+
405
+ if ! is_generator (g, q, factors)
406
+ @goto sample_generator
407
+ end
408
+
409
+ return g
410
+ end
411
+
362
412
363
413
364
414
# ###############################################################
0 commit comments