예제 #1
0
    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())]
예제 #2
0
    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))
예제 #3
0
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
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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()
예제 #7
0
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
예제 #8
0
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: