Exemplo n.º 1
0
    def sign(
        self,
        private_key: bytearray,
        digest: bytearray,
        rand_k: bytearray = bytearray(b'')) -> bytearray:
        """
        Create a signature.

        Args:
            private_key: Private signature key (as a byte object).
            digest: Digest for which the signature is calculated.  This value
              must be obtained using the 'streebog' algorithm in accordance with
              GOST 34.11-2012.
            rand_k: Random (pseudo-random) number (as a byte object). By
              default, it is generated by the function itself.

        Returns:
            Signature for provided digest (as a byte object).

        Raises:
            GOSTSignatureError('GOSTSignatureError: invalid private key value'):
              If the private key value is incorrect.
            GOSTSignatureError('GOSTSignatureError: invalid digest value'): If
              the digest value is incorrect.
            GOSTSignatureError('GOSTSignatureError: invalid random value'): If
              the random value is incorrect.
        """
        if not check_value(private_key, self._size):
            raise GOSTSignatureError(
                'GOSTSignatureError: invalid private key value')
        if not check_value(digest, self._size):
            raise GOSTSignatureError(
                'GOSTSignatureError: invalid digest value')
        sign_e = self._set_e(digest)
        sign_r = 0
        sign_s = 0
        sign_k = 0
        if rand_k == bytearray(b''):
            rand_k = self._get_rand_k()
        if not isinstance(rand_k, (bytes, bytearray)):
            private_key = zero_fill(private_key)
            raise GOSTSignatureError(
                'GOSTSignatureError: invalid random value')
        if bytearray_to_int(rand_k) >= self._q:
            private_key = zero_fill(private_key)
            raise GOSTSignatureError(
                'GOSTSignatureError: invalid random value')
        while compare_to_zero(int_to_bytearray(sign_s, self._size)):
            while compare_to_zero(int_to_bytearray(sign_r, self._size)):
                sign_k = bytearray_to_int(rand_k)
                sign_c = self._mul_point(sign_k)
                sign_r = sign_c[0] % self._q
            sign_s = (sign_r * bytearray_to_int(private_key) +
                      sign_k * sign_e) % self._q
        result = int_to_bytearray(sign_r, self._size) + int_to_bytearray(
            sign_s, self._size)
        private_key = zero_fill(private_key)
        return result
Exemplo n.º 2
0
    def __init__(self, algorithm: str, key: bytearray) -> None:
        """
        Initialize the ciphering object.

        Args:
            algorithm: The string with the name of the ciphering algorithm.
            key: The encryption key.

        Raises:
            GOSTCipherError('GOSTCipherError: unsupported cipher algorithm'): In
              case of unsupported cipher algorithm (is not 'kuznechik' or
              'magma').
            GOSTCipherError('GOSTCipherError: invalid key value'): In case of
              invalid 'key' value (the key value is not a byte object
              ('bytearray' or 'bytes') or its length is not 256 bits).
        """
        if algorithm not in ('magma', 'kuznechik'):
            key = zero_fill(key)
            raise GOSTCipherError(
                'GOSTCipherError: unsupported cipher algorithm')
        if not check_value(key, _KEY_SIZE):
            key = zero_fill(key)
            raise GOSTCipherError('GOSTCipherError: invalid key value')
        if algorithm == 'kuznechik':
            self._cipher_obj: CipherObjType = GOST34122015Kuznechik(key)
        elif algorithm == 'magma':
            self._cipher_obj = GOST34122015Magma(key)
        self.oid = self._cipher_obj.oid
Exemplo n.º 3
0
    def __init__(self, rand_size: int, rand_k: bytearray, size_s: int) -> None:
        """
        Initialize the random object.

        Args:
            rand_size: Size of the generated random variable (in bytes).
            rand_k: Initial filling (seed).
            size_s: Size of the initial filling (in bytes).
        """
        self._size_s = size_s
        self._rand_u = bytearray(b'')
        if rand_k == bytearray(b''):
            self._rand_u = bytearray(
                os.urandom(self._size_s) + b'\x00' *
                (_SIZE_M - self._size_s - 1))
        else:
            if not check_value(rand_k, self._size_s):
                raise GOSTRandomError('GOSTRandomError: invalid seed value')
            self._rand_u = rand_k + bytearray(b'\x00' *
                                              (_SIZE_M - self._size_s - 1))
            self._rand_u = bytearray(self._rand_u)
        self._q = rand_size // _SIZE_H
        self._r = rand_size % _SIZE_H
        self._limit = 2**((_SIZE_M - self._size_s) * 8)
        self._hash_obj = GOST34112012('streebog512', data=bytearray(b''))
Exemplo n.º 4
0
    def verify(self, public_key: Any, digest: bytearray,
               signature: bytearray) -> bool:
        """
        Verify a signature.

        Args:
            public_key: Public signature key (as a byte object).
            digest: Digest for which to be checked signature (as a byte object).
            signature: Signature of the digest being checked (as a byte object).

        Returns:
            The result of the signature verification ('True' or 'False').

        Raises:
            GOSTSignatureError('GOSTSignatureError: invalid public key value'):
              If the public key value is incorrect.
            GOSTSignatureError('GOSTSignatureError: invalid signature value'):
              If the signature value is incorrect.
            GOSTSignatureError('GOSTSignatureError: invalid digest value'): If
              the digest value is incorrect.
        """
        if not check_value(public_key, self._size * 2):
            raise GOSTSignatureError(
                'GOSTSignatureError: invalid public key value')
        if not check_value(signature, self._size * 2):
            raise GOSTSignatureError(
                'GOSTSignatureError: invalid signature value')
        if not check_value(digest, self._size):
            raise GOSTSignatureError(
                'GOSTSignatureError: invalid digest value')
        public_key = (bytearray_to_int(public_key[:self._size]),
                      bytearray_to_int(public_key[self._size:]))
        sign_r, sign_s = self._get_r_s(signature)
        if not self._verify_step_1(sign_r, sign_s):
            return False
        sign_e = self._set_e(digest)
        sign_v = self._invert(sign_e, self._q)
        sign_z_1 = sign_s * sign_v % self._q
        sign_z_2 = self._q - sign_r * sign_v % self._q
        sign_p = self._mul_point(sign_z_1)
        sign_q = self._mul_point(sign_z_2, public_key[0], public_key[1])
        sign_c = self._add(sign_p[0], sign_q[0], sign_p[1], sign_q[1])
        sign_r_check = sign_c[0] % self._q
        return compare(int_to_bytearray(sign_r_check, self._size),
                       int_to_bytearray(sign_r, self._size))
Exemplo n.º 5
0
 def __init__(self, algorithm: str, key: bytearray) -> None:
     """Initialize the ciphering object."""
     if algorithm not in ('magma', 'kuznechik'):
         key = zero_fill(key)
         raise GOSTCipherError('unsupported cipher algorithm')
     if not check_value(key, _KEY_SIZE):
         key = zero_fill(key)
         raise GOSTCipherError('invalid key value')
     if algorithm == 'kuznechik':
         self._cipher_obj = GOST34122015Kuznechik(key)
     elif algorithm == 'magma':
         self._cipher_obj = GOST34122015Magma(key)
 def __init__(self, rand_size: int, rand_k: bytearray, size_s: int) -> None:
     """Initialize the random object."""
     self._size_s = size_s
     if rand_k == bytearray(b''):
         self._rand_u = os.urandom(self._size_s) + b'\x00' * (_SIZE_M - self._size_s - 1)
         self._rand_u = bytearray(self._rand_u)
     else:
         if not check_value(rand_k, self._size_s):
             raise GOSTRandomError('invalid seed value')
         self._rand_u = rand_k + bytearray(b'\x00' * (_SIZE_M - self._size_s - 1))
         self._rand_u = bytearray(self._rand_u)
     self._q = rand_size // _SIZE_H
     self._r = rand_size % _SIZE_H
     self._limit = 2 ** (_SIZE_M - self._size_s)
     self._hash_obj = GOST34112012('streebog512', data=b'')
Exemplo n.º 7
0
    def public_key_generate(self, private_key: Any) -> bytearray:
        """
        Generate a public key.

        Parameters
        - private_key: private signature key (as a byte object).

        Return: public key (as a byte object).

        Exception
        - GOSTSignatureError('invalid private key') - if the private key value
        is incorrect.
        """
        if not check_value(private_key, self._size):
            raise GOSTSignatureError('invalid private key')
        private_key = bytearray_to_int(private_key)
        public_key = self._mul_point(private_key)
        public_key_x = int_to_bytearray(public_key[0], self._size)
        public_key_y = int_to_bytearray(public_key[1], self._size)
        private_key = 0
        return public_key_x + public_key_y
Exemplo n.º 8
0
    def public_key_generate(self, private_key: Any) -> bytearray:
        """
        Generate a public key.

        Args:
            private_key: Private signature key (as a byte object).

        Returns:
            Public key (as a byte object).

        Raises:
            GOSTSignatureError('GOSTSignatureError: invalid private key'): If
              the private key value is incorrect.
        """
        if not check_value(private_key, self._size):
            raise GOSTSignatureError('GOSTSignatureError: invalid private key')
        private_key = bytearray_to_int(private_key)
        public_key = self._mul_point(private_key)
        public_key_x = int_to_bytearray(public_key[0], self._size)
        public_key_y = int_to_bytearray(public_key[1], self._size)
        private_key = 0
        return public_key_x + public_key_y
    def reset(self, rand_k: bytearray = bytearray(b'')):
        """
        Reset the counter and setting a new initial filling.

        Parameters
        - rand_k: new initial filling (seed).  If this argument is not passed
        to the function, the 'os.urandom' function is used to generate the
        initial filling.

        Exception
        - GOSTRandomError('invalid seed value'): in case of invalid size of
        initial filling.
        """
        if rand_k == bytearray(b''):
            self._rand_u = os.urandom(self._size_s) + b'\x00' * (_SIZE_M - self._size_s - 1)
            self._rand_u = bytearray(self._rand_u)
        else:
            if not check_value(rand_k, self._size_s):
                raise GOSTRandomError('invalid seed value')
            self._rand_u = rand_k + b'\x00' * (_SIZE_M - self._size_s - 1)
            self._rand_u = bytearray(self._rand_u)
        self._hash_obj.reset()
Exemplo n.º 10
0
    def reset(self, rand_k: bytearray = bytearray(b'')) -> None:
        """
        Reset the counter and setting a new initial filling.

        Args:
            rand_k: New initial filling (seed).  If this argument is not passed
              to the function, the 'os.urandom' function is used to generate
              the initial filling.

        Raises:
            GOSTRandomError('GOSTRandomError: invalid seed value'): In case of
              invalid value of initial filling.
        """
        if rand_k == bytearray(b''):
            self._rand_u = bytearray(
                os.urandom(self._size_s) +
                bytearray(b'\x00' * (_SIZE_M - self._size_s - 1)))
        else:
            if not check_value(rand_k, self._size_s):
                raise GOSTRandomError('GOSTRandomError: invalid seed value')
            self._rand_u = rand_k + b'\x00' * (_SIZE_M - self._size_s - 1)
            self._rand_u = bytearray(self._rand_u)
        self._hash_obj.reset()