Esempio n. 1
0
    def __init__(
        self,
        curvemodel,
        prime,
        formula,
        style,
        exponent,
        tuned,
        multievaluation,
        uninitialized,
        verbose,
    ):
        self.curvemodel = curvemodel
        self.prime = prime
        self.style = style
        self._exponent = exponent
        self.tuned = tuned
        self.uninitialized = uninitialized
        self.multievaluation = multievaluation
        self.params = attrdict(parameters['csidh'][prime])
        self.params.update(self.params[style])
        self.p_bytes = (self.params.p_bits + 8 - (self.params.p_bits % 8)) // 8

        if self.curvemodel == 'montgomery':
            self.isogeny = MontgomeryIsogeny(formula,
                                             uninitialized=self.uninitialized)
            self.curve = MontgomeryCurve(prime)
            self.field = self.curve.field
        else:
            self.curve = None
            raise NotImplemented

        self.formula = self.isogeny(self.curve, self.tuned,
                                    self.multievaluation)

        if self.style == 'df':
            self.gae = Gae_df(prime, self.tuned, self.curve, self.formula)
        elif self.style == 'wd1':
            self.gae = Gae_wd1(prime, self.tuned, self.curve, self.formula)
        elif self.style == 'wd2':
            self.gae = Gae_wd2(prime, self.tuned, self.curve, self.formula)
        else:
            self.gae = NotImplemented
Esempio n. 2
0
    def __init__(
        self,
        curvemodel,
        prime,
        formula,
        tuned,
        multievaluation,
        uninitialized,
        verbose
    ):

        self.params = attrdict(parameters['bsidh'][prime])
        self.p_bytes = (self.params.p_bits + (self.params.p_bits % 8)) // 8
        self.prime = prime
        self.tuned = tuned
        self.uninitialized = uninitialized
        self.multievaluation = multievaluation
        self.verbose = verbose

        random = SystemRandom()

        if curvemodel == 'montgomery':
            self.isogeny = MontgomeryIsogeny(formula, uninitialized = self.uninitialized)
            self.curve = MontgomeryCurve(prime)
            self.field = self.curve.field
            self.basefield = self.curve.field.basefield
        else:
            self.curve = None
            raise NotImplemented

        self.formula = self.isogeny(self.curve, self.tuned, self.multievaluation)

        if self.formula is not None and self.curve is not None:
            self.strategy = Strategy(prime, self.tuned, self.curve, self.formula)
        else:
            self.strategy = None
            raise NotImplemented
Esempio n. 3
0
class BSIDH(object):
    """

    BSIDH

    Here is one group action test with random keys:

    >>> bsidh_hvelu = BSIDH('montgomery', 'b2', 'hvelu', True, False, False, False)
    >>> sk_a, sk_b = bsidh_hvelu.secret_key_a(), bsidh_hvelu.secret_key_b()
    >>> pk_a, pk_b = bsidh_hvelu.public_key_a(sk_a), bsidh_hvelu.public_key_b(sk_b)
    >>> ss_a, ss_b = bsidh_hvelu.dh_a(sk_a, pk_b), bsidh_hvelu.dh_b(sk_b, pk_a)
    >>> ss_a == ss_b
    True

    >>> from sibc.bsidh import BSIDH, default_parameters
    >>> b = BSIDH(**default_parameters)
    >>> sk_a, sk_b = b.secret_key_a(), b.secret_key_b()
    >>> pk_a, pk_b = b.public_key_a(sk_a), b.public_key_b(sk_b)
    >>> ss_a, ss_b = b.dh_a(sk_a, pk_b), b.dh_b(sk_b, pk_a)
    >>> ss_a == ss_b
    True

    >>> from sibc.bsidh import BSIDH, default_parameters
    >>> b = BSIDH(**default_parameters)
    >>> sk_a, pk_a = b.keygen_a()
    >>> sk_b, pk_b = b.keygen_b()
    >>> ss_a, ss_b = b.dh_a(sk_a, pk_b), b.dh_b(sk_b, pk_a)
    >>> ss_a == ss_b
    True
    
    Other tests which were previously here are now in the test directory.

    """

    def __init__(
        self,
        curvemodel,
        prime,
        formula,
        tuned,
        multievaluation,
        uninitialized,
        verbose
    ):

        self.params = attrdict(parameters['bsidh'][prime])
        self.p_bytes = (self.params.p_bits + (self.params.p_bits % 8)) // 8
        self.prime = prime
        self.tuned = tuned
        self.uninitialized = uninitialized
        self.multievaluation = multievaluation
        self.verbose = verbose

        random = SystemRandom()

        if curvemodel == 'montgomery':
            self.isogeny = MontgomeryIsogeny(formula, uninitialized = self.uninitialized)
            self.curve = MontgomeryCurve(prime)
            self.field = self.curve.field
            self.basefield = self.curve.field.basefield
        else:
            self.curve = None
            raise NotImplemented

        self.formula = self.isogeny(self.curve, self.tuned, self.multievaluation)

        if self.formula is not None and self.curve is not None:
            self.strategy = Strategy(prime, self.tuned, self.curve, self.formula)
        else:
            self.strategy = None
            raise NotImplemented

    def secret_key_a(self):
        k = self.strategy.random_scalar_A()
        return k.to_bytes(length=self.p_bytes, byteorder='little')

    def secret_key_b(self):
        k = self.strategy.random_scalar_B()
        return k.to_bytes(length=self.p_bytes, byteorder='little')

    def public_key_a(self, sk):
        sk = int.from_bytes(sk, byteorder='little')
        x, y, z = self.strategy.strategy_at_6_A(sk)
        pk = x.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        x.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return pk

    def public_key_b(self, sk):
        sk = int.from_bytes(sk, byteorder='little')
        x, y, z = self.strategy.strategy_at_6_B(sk)
        pk = x.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        x.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return pk

    def dh_a(self, sk, pk):
        sk = int.from_bytes(sk, byteorder='little')
        # --- P
        P_re = int.from_bytes(pk[0:self.p_bytes], byteorder='little')
        P_im = int.from_bytes(pk[self.p_bytes:(2*self.p_bytes)], byteorder='little')
        # --- Q
        Q_re = int.from_bytes(pk[(2*self.p_bytes):(3*self.p_bytes)], byteorder='little')
        Q_im = int.from_bytes(pk[(3*self.p_bytes):(4*self.p_bytes)], byteorder='little')
        # --- Q
        PQ_re = int.from_bytes(pk[(4*self.p_bytes):(5*self.p_bytes)], byteorder='little')
        PQ_im = int.from_bytes(pk[(5*self.p_bytes):(6*self.p_bytes)], byteorder='little')

        pk = (self.field([P_re, P_im]), self.field([Q_re, Q_im]), self.field([PQ_re, PQ_im]))
        ss = self.strategy.strategy_A(sk, pk)
        ss = self.curve.coeff(ss)
        x = ss.re.x.to_bytes(length=self.p_bytes, byteorder='little')
        y = ss.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return x + y

    def dh_b(self, sk, pk):
        sk = int.from_bytes(sk, byteorder='little')
        # --- P
        P_re = int.from_bytes(pk[0:self.p_bytes], byteorder='little')
        P_im = int.from_bytes(pk[self.p_bytes:(2*self.p_bytes)], byteorder='little')
        # --- Q
        Q_re = int.from_bytes(pk[(2*self.p_bytes):(3*self.p_bytes)], byteorder='little')
        Q_im = int.from_bytes(pk[(3*self.p_bytes):(4*self.p_bytes)], byteorder='little')
        # --- Q
        PQ_re = int.from_bytes(pk[(4*self.p_bytes):(5*self.p_bytes)], byteorder='little')
        PQ_im = int.from_bytes(pk[(5*self.p_bytes):(6*self.p_bytes)], byteorder='little')

        pk = (self.field([P_re, P_im]), self.field([Q_re, Q_im]), self.field([PQ_re, PQ_im]))
        ss = self.strategy.strategy_B(sk, pk)
        ss = self.curve.coeff(ss)
        x = ss.re.x.to_bytes(length=self.p_bytes, byteorder='little')
        y = ss.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return x + y

    def derive_a(self, sk, pk):
        sk = int.from_bytes(sk, byteorder='little')
        # --- P
        P_re = int.from_bytes(pk[0:self.p_bytes], byteorder='little')
        P_im = int.from_bytes(pk[self.p_bytes:(2*self.p_bytes)], byteorder='little')
        # --- Q
        Q_re = int.from_bytes(pk[(2*self.p_bytes):(3*self.p_bytes)], byteorder='little')
        Q_im = int.from_bytes(pk[(3*self.p_bytes):(4*self.p_bytes)], byteorder='little')
        # --- Q
        PQ_re = int.from_bytes(pk[(4*self.p_bytes):(5*self.p_bytes)], byteorder='little')
        PQ_im = int.from_bytes(pk[(5*self.p_bytes):(6*self.p_bytes)], byteorder='little')

        pk = (self.field([P_re, P_im]), self.field([Q_re, Q_im]), self.field([PQ_re, PQ_im]))
        ss = self.strategy.strategy_A(sk, pk)
        ss = self.curve.coeff(ss)
        x = ss.re.x.to_bytes(length=self.p_bytes, byteorder='little')
        y = ss.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return x + y

    def derive_b(self, sk, pk):
        sk = int.from_bytes(sk, byteorder='little')
        # --- P
        P_re = int.from_bytes(pk[0:self.p_bytes], byteorder='little')
        P_im = int.from_bytes(pk[self.p_bytes:(2*self.p_bytes)], byteorder='little')
        # --- Q
        Q_re = int.from_bytes(pk[(2*self.p_bytes):(3*self.p_bytes)], byteorder='little')
        Q_im = int.from_bytes(pk[(3*self.p_bytes):(4*self.p_bytes)], byteorder='little')
        # --- Q
        PQ_re = int.from_bytes(pk[(4*self.p_bytes):(5*self.p_bytes)], byteorder='little')
        PQ_im = int.from_bytes(pk[(5*self.p_bytes):(6*self.p_bytes)], byteorder='little')

        pk = (self.field([P_re, P_im]), self.field([Q_re, Q_im]), self.field([PQ_re, PQ_im]))
        ss = self.strategy.strategy_B(sk, pk)
        ss = self.curve.coeff(ss)
        x = ss.re.x.to_bytes(length=self.p_bytes, byteorder='little')
        y = ss.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return x + y

    def keygen_a(self):
        sk = self.strategy.random_scalar_A()
        x, y, z = self.strategy.strategy_at_6_A(sk)
        sk = sk.to_bytes(length=self.p_bytes, byteorder='little')
        pk = x.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        x.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return sk, pk

    def keygen_b(self):
        sk = self.strategy.random_scalar_B()
        x, y, z = self.strategy.strategy_at_6_B(sk)
        sk = sk.to_bytes(length=self.p_bytes, byteorder='little')
        pk = x.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        x.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        y.im.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.re.x.to_bytes(length=self.p_bytes, byteorder='little') +\
        z.im.x.to_bytes(length=self.p_bytes, byteorder='little')
        return sk, pk
Esempio n. 4
0
class CSIDH(object):
    """

    CSIDH

    Here is one group action test with random keys:

    >>> csidh_tvelu_wd1 = CSIDH('montgomery', 'p512', 'tvelu', 'wd1', 10, False, False, False, False)
    >>> sk_a, sk_b = csidh_tvelu_wd1.secret_key(), csidh_tvelu_wd1.secret_key()
    >>> pk_a, pk_b = csidh_tvelu_wd1.public_key(sk_a), csidh_tvelu_wd1.public_key(sk_b)
    >>> csidh_tvelu_wd1.dh(sk_a, pk_b) == csidh_tvelu_wd1.dh(sk_b, pk_a)
    True

    >>> from sibc.csidh import CSIDH, default_parameters
    >>> c = CSIDH(**default_parameters)
    >>> # alice generates a key
    >>> alice_secret_key = c.secret_key()
    >>> alice_public_key = c.public_key(alice_secret_key)
    >>> # bob generates a key
    >>> bob_secret_key = c.secret_key()
    >>> bob_public_key = c.public_key(bob_secret_key)
    >>> # if either alice or bob use their secret key with the other's respective
    >>> # public key, the resulting shared secrets are the same
    >>> shared_secret_alice = c.dh(alice_secret_key, bob_public_key)
    >>> shared_secret_bob = c.dh(bob_secret_key, alice_public_key)
    >>> # Alice and bob produce an identical shared secret
    >>> shared_secret_alice == shared_secret_bob
    True

    >>> from sibc.csidh import CSIDH, default_parameters
    >>> c = CSIDH(**default_parameters)
    >>> # alice generates a key
    >>> alice_secret_key, alice_public_key = c.keygen()
    >>> # bob generates a key
    >>> bob_secret_key, bob_public_key = c.keygen()
    >>> # if either alice or bob use their secret key with the other's respective
    >>> # public key, the resulting shared secrets are the same
    >>> shared_secret_alice = c.dh(alice_secret_key, bob_public_key)
    >>> shared_secret_bob = c.dh(bob_secret_key, alice_public_key)
    >>> # Alice and bob produce an identical shared secret
    >>> shared_secret_alice == shared_secret_bob
    True

    Other tests which were previously here are now in the test directory.

    """

    def __init__(
        self,
        curvemodel,
        prime,
        formula,
        style,
        exponent,
        tuned,
        multievaluation,
        uninitialized,
        verbose,
    ):
        self.curvemodel = curvemodel
        self.prime = prime
        self.style = style
        self._exponent = exponent
        self.tuned = tuned
        self.uninitialized = uninitialized
        self.multievaluation = multievaluation
        self.params = attrdict(parameters['csidh'][prime])
        self.params.update(self.params[style])
        self.p_bytes = (self.params.p_bits + (self.params.p_bits % 8)) // 8

        if self.curvemodel == 'montgomery':
            self.isogeny = MontgomeryIsogeny(formula, uninitialized = self.uninitialized)
            self.curve = MontgomeryCurve(prime)
            self.field = self.curve.field
        else:
            self.curve = None
            raise NotImplemented

        self.formula = self.isogeny(self.curve, self.tuned, self.multievaluation)

        if self.style == 'df':
            self.gae = Gae_df(prime, self.tuned, self.curve, self.formula)
        elif self.style == 'wd1':
            self.gae = Gae_wd1(prime, self.tuned, self.curve, self.formula)
        elif self.style == 'wd2':
            self.gae = Gae_wd2(prime, self.tuned, self.curve, self.formula)
        else:
            self.gae = NotImplemented

    def dh(self, sk, pk):
        sk = unpack('<{}b'.format(len(sk)), sk)
        pk = int.from_bytes(pk, 'little')
        pk = self.curve.affine_to_projective(pk)
        ss = self.curve.coeff(self.gae.GAE_at_A(sk, pk)).x.to_bytes(
            length=self.p_bytes, byteorder='little'
        )
        return ss

    def derive(self, sk, pk):
        sk = unpack('<{}b'.format(len(sk)), sk)
        pk = int.from_bytes(pk, 'little')
        pk = self.curve.affine_to_projective(pk)
        ss = self.curve.coeff(self.gae.GAE_at_A(sk, pk)).x.to_bytes(
            length=self.p_bytes, byteorder='little'
        )
        return ss

    def secret_key(self):
        k = self.gae.random_exponents()
        return pack('<{}b'.format(len(k)), *k)

    def public_key(self, sk):
        sk = unpack('<{}b'.format(len(sk)), sk)
        xy = self.gae.GAE_at_0(sk)
        pk = self.curve.coeff(xy)
        # this implies a y of 4 on the receiver side
        return pk.x.to_bytes(length=self.p_bytes, byteorder='little')

    def keygen(self):
        sk = self.gae.random_exponents()
        xy = self.gae.GAE_at_0(sk)
        pk = self.curve.coeff(xy)
        # this implies a y of 4 on the receiver side
        return pack('<{}b'.format(len(sk)), *sk), pk.x.to_bytes(length=self.p_bytes, byteorder='little')