def process_challenge(self, bytes_s: bytes, bytes_B: bytes) -> Any: s = bytes_to_long(bytes_s) B = bytes_to_long(bytes_B) N = self.N g = self.g k = self.k hash_class = self.hash_class # SRP-6a safety check if (B % N) == 0: return None u = H(hash_class, self.A, B, width=len(long_to_bytes(N))) if u == 0: # SRP-6a safety check return None x = calculate_x(hash_class, s, self.Iu, self.p) v = pow(g, x, N) S = pow((B - k * v), (self.a + u * x), N) self.K = hash_class(long_to_bytes(S)).digest() M = calculate_M(hash_class, N, g, self.Iu, s, self.A, B, self.K) if not M: return None self.H_AMK = calculate_H_AMK(hash_class, self.A, M, self.K) return M
def generate_salt_and_verifier(Iu: str, p: str, len_s: int, hash_alg: int = SHA512, ng_type: int = NG_3072) -> Tuple[bytes, bytes]: hash_class = _hash_map[hash_alg] N, g = get_ng(ng_type) _s = long_to_bytes(get_random(len_s)) _v = long_to_bytes(pow(g, calculate_x(hash_class, _s, Iu, p), N)) return _s, _v
def calculate_M(hash_class: Callable, N: int, g: int, Iu: str, s: int, A: int, B: int, K: bytes) -> Any: _Iu = Iu.encode() h = hash_class() h.update(H_N_xor_g(hash_class, N, g)) h.update(hash_class(_Iu).digest()) h.update(long_to_bytes(s)) h.update(long_to_bytes(A)) h.update(long_to_bytes(B)) h.update(K) return h.digest()
def H_N_xor_g(hash_class: Callable, N: int, g: int) -> bytes: bin_N = long_to_bytes(N) bin_g = long_to_bytes(g) padding = len(bin_N) - len(bin_g) hN = hash_class(bin_N).digest() hg = hash_class(b''.join([b'\0' * padding, bin_g])).digest() return b''.join(long_to_bytes(hN[i] ^ hg[i]) for i in range(0, len(hN)))
def H(hash_class: Callable, *args: Any, **kwargs: Any) -> int: width = kwargs.get('width', None) h = hash_class() for s in args: if s is not None: data = long_to_bytes(s) if isinstance(s, int) else s if width is not None: h.update(bytes(width - len(data))) h.update(data) return int(h.hexdigest(), 16)
def sign(curve, private_key, digest): q = curve.q e = bytes_to_long(digest) % q if e == 0: e = 1 while True: k = bytes_to_long(urandom(MODE_SIZE)) % q if k == 0: continue r, _ = curve.scalar_multiply(k) r %= q if r == 0: continue d = private_key * r k *= e s = (d + k) % q if s == 0: continue return long_to_bytes(s, MODE_SIZE) + long_to_bytes(r, MODE_SIZE)
def setup0_request(self) -> Any: # Form SessionCmd0 request packet using client public key setup_req = proto.session_pb2.SessionData() setup_req.sec_ver = proto.session_pb2.SecScheme2 setup_req.sec2.msg = proto.sec2_pb2.S2Session_Command0 setup_req.sec2.sc0.client_username = str_to_bytes(self.username) self.srp6a_ctx = Srp6a(self.username, self.password) if self.srp6a_ctx is None: raise RuntimeError('Failed to initialize SRP6a instance!') client_pubkey = long_to_bytes(self.srp6a_ctx.A) setup_req.sec2.sc0.client_pubkey = client_pubkey self._print_verbose(f'Client Public Key:\t0x{client_pubkey.hex()}') return setup_req.SerializeToString().decode('latin-1')
def __init__(self, username: str, password: str, hash_alg: int = SHA512, ng_type: int = NG_3072): hash_class = _hash_map[hash_alg] N, g = get_ng(ng_type) k = H(hash_class, N, g, width=len(long_to_bytes(N))) self.Iu = username self.p = password self.a = get_random_of_length(32) self.A = pow(g, self.a, N) self.v: Optional[int] = None self.K: Optional[bytes] = None self.H_AMK = None self._authenticated = False self.hash_class = hash_class self.N = N self.g = g self.k = k
from lab4.elgamal import ElGamal from utils import bytes_to_long, long_to_bytes bit_length = 2048 # elgamal = ElGamal(bit_length)? elgamal = ElGamal() elgamal.save_config() # m = maurer_generator(512) m = b'Hello World' m_number = bytes_to_long(m) + elgamal.p + elgamal.p print(long_to_bytes(elgamal.decrypt(*elgamal.encrypt(m_number))))
def start_authentication(self) -> Tuple[str, bytes]: return (self.Iu, long_to_bytes(self.A))
def get_ephemeral_secret(self) -> Any: return long_to_bytes(self.a)
def calculate_H_AMK(hash_class: Callable, A: int, M: bytes, K: bytes) -> Any: h = hash_class() h.update(long_to_bytes(A)) h.update(M) h.update(K) return h.digest()
def a_xor_b(a: bytes, b: bytes) -> bytes: return b''.join(long_to_bytes(a[i] ^ b[i]) for i in range(0, len(b)))