def random(self, size: object) -> object: """ Generate a random element. Parameters: size (int/RingElement): The maximum ordinality/element (non-inclusive). Returns: RingElement: Random element of the algebra. """ from samson.math.general import random_int if type(size) is int: return self[random_int(size)] else: return self[random_int(size.ordinality())]
def test_complex_order(self): # Build complex algebras and test their order for algebra in [ZZ, F23, P, P_q]: max_elem = algebra[107] for _ in range(20): try: AQ = max(algebra[2], algebra.random(max_elem)) PX = (algebra / AQ)[y] PQ = max(PX[2], PX.random(PX(y**5))) RX = PX / PQ except NotInvertibleException: continue smaller_orders = [] for _ in range(10): rand_elem = RX.zero() while rand_elem == RX.zero(): rand_elem = RX[random_int(50)] # Assert order is a multiple of the number of element self.assertEqual(rand_elem * RX.order, RX.zero()) # Assert order is the minimum multiple (i.e. 1) factors = factor(RX.order) has_smaller_order = any([ rand_elem * reduce(int.__mul__, list(set(factors) - set([fac])), 1) == RX.zero() for fac in factors if not (fac == RX.order or fac == 1) ]) smaller_orders.append(has_smaller_order) self.assertFalse(bool(smaller_orders) and all(smaller_orders))
def simulate_until_event(p: float, runs: int, visual: bool=False) -> float: """ Simulates an event with probability `p` for `runs` runs and returns the average number of attempts until it occured. Parameters: p (float): Probability event will occur. runs (int): Number of runs. visual (bool): Whether or not to display a progress bar. Returns: float: Average number of attempts. """ space, cutoff = __float_to_discrete_probability(p) total = 0 r_iter = range(runs) if visual: r_iter = tqdm(r_iter) for _ in r_iter: curr = 0 while True: curr += 1 if random_int(space) < cutoff: break total += curr return total / runs
def encrypt(self, plaintext: bytes) -> int: """ Encrypts `plaintext`. Parameters: plaintext (bytes): Plaintext. Returns: int: Ciphertext. """ m = Bytes.wrap(plaintext).to_int() assert m < self.n r = random_int(self.n) while gcd(r, self.n) != 1: r = random_int(self.n) n_sqr = self.n ** 2 return pow(self.g, m, n_sqr) * pow(r, self.n, n_sqr)
def random(self, size: int = None) -> object: """ Generate a random element. Parameters: size (int): The ring-specific 'size' of the element. Returns: TwistedEdwardsCurve: Random element of the algebra. """ return self.B * random_int(size or self.q)
def __init__(self, d: int = None, pub: WeierstrassPoint = None, G: WeierstrassPoint = P256.G): """ Parameters: d (int): Secret key. G (WeierstrassPoint): Generator point on an elliptical curve. """ Primitive.__init__(self) self.d = d or random_int(G.ring.cardinality()) self.G = G self.pub = pub if not pub: self.recompute_pub()
def simulate_event(p: float, attempts: int) -> int: """ Simulates an event with probability `p` for `attempts` attempts and returns the number of times it occured. Parameters: p (float): Probability event will occur. attempts (int): Number of attempts. Returns: int: Number of occurences. """ space, cutoff = __float_to_discrete_probability(p) total = 0 for _ in range(attempts): total += random_int(space) < cutoff return total
from samson.math.algebra.all import FF, ZZ, QQ, P256 from samson.math.symbols import Symbol, oo from samson.math.general import random_int, find_prime, factor from samson.utilities.exceptions import NotInvertibleException from functools import reduce import unittest x = Symbol('x') y = Symbol('y') F = FF(2, 8) F23 = F / F[23] FX2 = F[x] / (x**2) Z_star = ZZ.mul_group() Zp_star = (ZZ / ZZ(find_prime(128))).mul_group() Zn_star = (ZZ / ZZ(random_int(2**32))).mul_group() Z_2 = ZZ / ZZ(2) P = Z_2[x] P_q = P / (x**8 + x**4 + x**3 + x + 1) R = ZZ[x] / (x**167 - 1) P256C = P256[x, y] ALGEBRAS = [ZZ, QQ, F, F23, P, Z_star, Z_2, P_q, P256, P256C] class AlgebraTestCase(unittest.TestCase): def test_random(self): for algebra in ALGEBRAS: try: max_elem = algebra[11] except NotImplementedError: