예제 #1
0
    def __add__(self, b):
        assert self.curve == b.curve

        a_pt = ossl.point_new_from_ints(self.curve.os_group, self.x, self.y, self.infinity)
        b_pt = ossl.point_new_from_ints(b.curve.os_group, b.x, b.y, b.infinity)
        ossl.lc.EC_POINT_add(self.curve.os_group, a_pt, a_pt, b_pt, None)

        x, y, inf = ossl.point_get_xy_ints(self.curve.os_group, a_pt)

        ossl.lc.EC_POINT_free(a_pt)
        ossl.lc.EC_POINT_free(b_pt)

        return ECPointAffine(self.curve, x, y, inf)
예제 #2
0
    def __add__(self, b):
        assert self.curve == b.curve

        a_pt = ossl.point_new_from_ints(self.curve.os_group, self.x, self.y,
                                        self.infinity)
        b_pt = ossl.point_new_from_ints(b.curve.os_group, b.x, b.y, b.infinity)
        ossl.lc.EC_POINT_add(self.curve.os_group, a_pt, a_pt, b_pt, None)

        x, y, inf = ossl.point_get_xy_ints(self.curve.os_group, a_pt)

        ossl.lc.EC_POINT_free(a_pt)
        ossl.lc.EC_POINT_free(b_pt)

        return ECPointAffine(self.curve, x, y, inf)
예제 #3
0
    def is_on_curve(self, p):
        """ Checks whether a point is on the curve.

        Args:
            p (ECPointAffine): Point to be checked

        Returns:
            bool: True if p is on the curve, False otherwise.
        """
        ec_pt = ossl.point_new_from_ints(self.os_group, p.x, p.y)
        on_curve = ossl.lc.EC_POINT_is_on_curve(self.os_group, ec_pt, None)
        ossl.lc.EC_POINT_free(ec_pt)

        return bool(on_curve)
예제 #4
0
    def is_on_curve(self, p):
        """ Checks whether a point is on the curve.

        Args:
            p (ECPointAffine): Point to be checked

        Returns:
            bool: True if p is on the curve, False otherwise.
        """
        ec_pt = ossl.point_new_from_ints(self.os_group, p.x, p.y)
        on_curve = ossl.lc.EC_POINT_is_on_curve(self.os_group, ec_pt, None)
        ossl.lc.EC_POINT_free(ec_pt)

        return bool(on_curve)
예제 #5
0
    def recover_public_key(self, message, signature, recovery_id=None):
        """ Recovers possibilities for the public key associated with the
            private key used to sign message and generate signature.

            Since there are multiple possibilities (two for curves with
            co-factor = 1), each possibility that successfully verifies the
            signature is returned.
        Args:
           message (bytes): The message that was signed.
           signature (ECPointAffine): The point representing the signature.
           recovery_id (int) (Optional): If provided, limits the valid x and y
              point to only that described by the recovery_id.

        Returns:
           list(ECPointAffine): List of points representing valid public
              keys that verify signature.
        """
        r = signature.x
        s = signature.y

        ctx = c_void_p(ossl.lc.BN_CTX_new())
        ossl.lc.BN_CTX_start(ctx)

        order_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        x_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        i_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        in_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        p_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        r_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        s_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        rinv_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        z_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        ossl.lc.EC_GROUP_get_order(self.os_group, order_bn, ctx)

        ossl.int_to_bn(self.p, p_bn)
        ossl.int_to_bn(r, r_bn)
        ossl.int_to_bn(s, s_bn)
        ossl.lc.BN_mod_inverse(rinv_bn, r_bn, order_bn, ctx)

        if recovery_id is not None:
            i_list = [recovery_id >> 1]
            k_list = [recovery_id & 0x1]
        else:
            i_list = range(2)
            k_list = range(2)

        rv = []
        num_bytes = math.ceil(self.nlen / 8)

        z = int.from_bytes(self.hash_function(message).digest()[:num_bytes], 'big')
        ossl.int_to_bn(z, z_bn)

        zG = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        sR = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        temp = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        pub_key = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        Rn = c_void_p(ossl.lc.EC_POINT_new(self.os_group))

        for i in i_list:
            ossl.int_to_bn(i, i_bn)
            ossl.lc.BN_mod_mul(in_bn, i_bn, order_bn, p_bn, ctx)
            ossl.lc.BN_mod_add(x_bn, r_bn, in_bn, p_bn, ctx)
            x = ossl.bn_to_int(x_bn)
            ys = self.y_from_x(x)

            for k in k_list:
                y = ys[k]
                if y & 0x1 != k:
                    y = ys[k ^ 1]

                R = ossl.point_new_from_ints(self.os_group, r, y)
                ossl.lc.EC_POINT_mul(self.os_group,
                                     Rn,
                                     None,
                                     R,
                                     order_bn,
                                     ctx)
                if not ossl.lc.EC_POINT_is_at_infinity(self.os_group, Rn):
                    continue

                ossl.lc.EC_POINT_mul(self.os_group,
                                     zG,
                                     z_bn,
                                     None,
                                     None,
                                     ctx)
                ossl.lc.EC_POINT_invert(self.os_group, zG, ctx)
                ossl.lc.EC_POINT_mul(self.os_group,
                                     sR,
                                     None,
                                     R,
                                     s_bn,
                                     ctx)
                ossl.lc.EC_POINT_add(self.os_group, temp, sR, zG, ctx)
                ossl.lc.EC_POINT_mul(self.os_group,
                                     pub_key,
                                     None,
                                     temp,
                                     rinv_bn,
                                     ctx)

                ossl.lc.EC_POINT_free(R)

                # Convert to ECPointAffine
                pub_x, pub_y, inf = ossl.point_get_xy_ints(self.os_group, pub_key)
                rv.append((ECPointAffine(self, pub_x, pub_y, inf), 2 * i + k))

        ossl.lc.EC_POINT_free(zG)
        ossl.lc.EC_POINT_free(sR)
        ossl.lc.EC_POINT_free(temp)
        ossl.lc.EC_POINT_free(pub_key)
        ossl.lc.EC_POINT_free(Rn)

        ossl.lc.BN_CTX_end(ctx)
        ossl.lc.BN_CTX_free(ctx)

        return rv
예제 #6
0
    def recover_public_key(self, message, signature, recovery_id=None):
        """ Recovers possibilities for the public key associated with the
        private key used to sign message and generate signature.

        Since there are multiple possibilities (two for curves with
        co-factor = 1), each possibility that successfully verifies the
        signature is returned.

        Args:
           message (bytes): The message that was signed.
           signature (ECPointAffine): The point representing the signature.
           recovery_id (int) (Optional): If provided, limits the valid x and y
              point to only that described by the recovery_id.

        Returns:
           list(ECPointAffine): List of points representing valid public
           keys that verify signature.
        """
        r = signature.x
        s = signature.y

        ctx = c_void_p(ossl.lc.BN_CTX_new())
        ossl.lc.BN_CTX_start(ctx)

        order_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        x_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        i_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        in_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        p_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        r_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        s_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        rinv_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        z_bn = c_void_p(ossl.lc.BN_CTX_get(ctx))
        ossl.lc.EC_GROUP_get_order(self.os_group, order_bn, ctx)

        ossl.int_to_bn(self.p, p_bn)
        ossl.int_to_bn(r, r_bn)
        ossl.int_to_bn(s, s_bn)
        ossl.lc.BN_mod_inverse(rinv_bn, r_bn, order_bn, ctx)

        if recovery_id is not None:
            i_list = [recovery_id >> 1]
            k_list = [recovery_id & 0x1]
        else:
            i_list = range(2)
            k_list = range(2)

        rv = []
        num_bytes = math.ceil(self.nlen / 8)

        z = int.from_bytes(
            self.hash_function(message).digest()[:num_bytes], 'big')
        ossl.int_to_bn(z, z_bn)

        zG = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        sR = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        temp = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        pub_key = c_void_p(ossl.lc.EC_POINT_new(self.os_group))
        Rn = c_void_p(ossl.lc.EC_POINT_new(self.os_group))

        for i in i_list:
            ossl.int_to_bn(i, i_bn)
            ossl.lc.BN_mod_mul(in_bn, i_bn, order_bn, p_bn, ctx)
            ossl.lc.BN_mod_add(x_bn, r_bn, in_bn, p_bn, ctx)
            x = ossl.bn_to_int(x_bn)
            ys = self.y_from_x(x)

            for k in k_list:
                y = ys[k]
                if y & 0x1 != k:
                    y = ys[k ^ 1]

                R = ossl.point_new_from_ints(self.os_group, r, y)
                ossl.lc.EC_POINT_mul(self.os_group, Rn, None, R, order_bn, ctx)
                if not ossl.lc.EC_POINT_is_at_infinity(self.os_group, Rn):
                    continue

                ossl.lc.EC_POINT_mul(self.os_group, zG, z_bn, None, None, ctx)
                ossl.lc.EC_POINT_invert(self.os_group, zG, ctx)
                ossl.lc.EC_POINT_mul(self.os_group, sR, None, R, s_bn, ctx)
                ossl.lc.EC_POINT_add(self.os_group, temp, sR, zG, ctx)
                ossl.lc.EC_POINT_mul(self.os_group, pub_key, None, temp,
                                     rinv_bn, ctx)

                ossl.lc.EC_POINT_free(R)

                # Convert to ECPointAffine
                pub_x, pub_y, inf = ossl.point_get_xy_ints(
                    self.os_group, pub_key)
                rv.append((ECPointAffine(self, pub_x, pub_y, inf), 2 * i + k))

        ossl.lc.EC_POINT_free(zG)
        ossl.lc.EC_POINT_free(sR)
        ossl.lc.EC_POINT_free(temp)
        ossl.lc.EC_POINT_free(pub_key)
        ossl.lc.EC_POINT_free(Rn)

        ossl.lc.BN_CTX_end(ctx)
        ossl.lc.BN_CTX_free(ctx)

        return rv