private byte[] computeAuthKey(TLPhoneCallAccepted call) { BigInteger p = new BigInteger(1, secretP); BigInteger i_authKey = new BigInteger(1, call.GB); i_authKey = i_authKey.ModPow(new BigInteger(1, a_or_b), p); byte[] authKey = i_authKey.ToByteArray(); if (authKey.Length > 256) { byte[] correctedAuth = new byte[256]; Buffer.BlockCopy(authKey, authKey.Length - 256, correctedAuth, 0, 256); authKey = correctedAuth; } else if (authKey.Length < 256) { byte[] correctedAuth = new byte[256]; Buffer.BlockCopy(authKey, 0, correctedAuth, 256 - authKey.Length, authKey.Length); for (int a = 0; a < 256 - authKey.Length; a++) { authKey[a] = 0; } authKey = correctedAuth; } return(authKey); }
private void ProcessAcceptedCall(TLPhoneCallAccepted phoneCallAccepted) { DispatchStateChanged(PhoneCallState.STATE_EXCHANGING_KEYS); if (!TLUtils.CheckGaAndGb(phoneCallAccepted.GB.Data, _secretP.Data)) { CallFailed(); return; } _authKey = MTProtoService.GetAuthKey(_aOrB, phoneCallAccepted.GB.ToBytes(), _secretP.ToBytes()); var keyHash = Utils.ComputeSHA1(_authKey); var keyFingerprint = new TLLong(BitConverter.ToInt64(keyHash, 12)); var peer = new TLInputPhoneCall { Id = phoneCallAccepted.Id, AccessHash = phoneCallAccepted.AccessHash }; var protocol = new TLPhoneCallProtocol { Flags = new TLInt(0), UdpP2P = true, UdpReflector = true, MinLayer = new TLInt(CALL_MIN_LAYER), MaxLayer = new TLInt(CALL_MAX_LAYER) }; _mtProtoService.ConfirmCallAsync(peer, TLString.FromBigEndianData(_ga), keyFingerprint, protocol, result => { _call = result; InitiateActualEncryptedCall(); }, error => { CallFailed(); }); }