// GetRandomGenerator returns a random generator of a group of quadratic residues QR_N.
GetRandomGenerator returns a random generator of a group of quadratic residues QR_N.
// GetRandomGenerator returns a random generator of a group of quadratic residues QR_N .
func (group *QRSpecialRSA) GetRandomGenerator() (*big.Int, error) {
	if group.P == nil {
		return nil,
			fmt.Errorf("GetRandomGenerator not available for QRSpecialRSA with only public parameters")
	}
	for {
		a := common.GetRandomZnInvertibleElement(group.N)
		a.Exp(a, big.NewInt(2), group.N) 
		check1 := group.Exp(a, group.P1)
		if check1.Cmp(big.NewInt(1)) == 0 {
			continue
		}
		check2 := group.Exp(a, group.Q1)
		if check2.Cmp(big.NewInt(1)) == 0 {
			continue
		}
		return a, nil
	}
}
func ( group * QRSpecialRSA ) GetRandomGenerator ( ) ( * big . Int , error ) { if group . P == nil { return nil , fmt . Errorf ( " " ) } for { a := common . GetRandomZnInvertibleElement ( group . N ) a . Exp ( a , big . NewInt ( 2 ) , group . N ) check1 := group . Exp ( a , group . P1 ) if check1 . Cmp ( big . NewInt ( 1 ) ) == 0 { continue } check2 := group . Exp ( a , group . Q1 ) if check2 . Cmp ( big . NewInt ( 1 ) ) == 0 { continue } return a , nil } }
GetRandomGenerator returns a random generator of a group of quadratic residues QR_N.
GetRandomGenerator returns a random generator of a group of quadratic residues QR_N .
// We know Z_n* and Z_p* x Z_q* are isomorphic (Chinese Remainder Theorem). // Let's take x from Z_n* and its counterpart from (x mod p, x mod q) from Z_p* x Z_q*. // Because of the isomorphism, if we compute x^2 mod n, the counterpart of this // element in Z_p* x Z_q* is (x^2 mod p, x^2 mod q). // Thus QR_n = QR_p x QR_q. // The order of QR_p is (p-1)/2 = p1 and the order of QR_q is (q-1)/2 = q1. // Because p1 and q1 are primes, QR_p and QR_q are cyclic. Thus, also QR_n is cyclic // (because the product of two cyclic groups is cyclic iff the two orders are coprime) // and of order p1 * q1. // Thus the possible orders of elements in QR_n are: p1, q1, p1 * q1. // We need to find an element of order p1 * q1 (we rule out elements of order p1 and q1). // make it quadratic residue // check if the order is p1 // check if the order is q1