diff --git a/com.unity.multiplayer.mlapi/Editor/NetworkingManagerEditor.cs b/com.unity.multiplayer.mlapi/Editor/NetworkingManagerEditor.cs index 43fd67d83f..d72e2706c4 100644 --- a/com.unity.multiplayer.mlapi/Editor/NetworkingManagerEditor.cs +++ b/com.unity.multiplayer.mlapi/Editor/NetworkingManagerEditor.cs @@ -44,9 +44,6 @@ public class NetworkingManagerEditor : Editor private SerializedProperty loadSceneTimeOutProperty; private SerializedProperty enableMessageBufferingProperty; private SerializedProperty messageBufferTimeoutProperty; - private SerializedProperty enableEncryptionProperty; - private SerializedProperty signKeyExchangeProperty; - private SerializedProperty serverBase64PfxCertificateProperty; private ReorderableList networkPrefabsList; private ReorderableList registeredScenesList; @@ -55,7 +52,7 @@ public class NetworkingManagerEditor : Editor private bool initialized; private readonly List transportTypes = new List(); - private string[] transportNames = new string[] { "Select transport..." }; + private string[] transportNames = { "Select transport..." }; private void ReloadTransports() { @@ -124,9 +121,6 @@ private void Init() loadSceneTimeOutProperty = networkConfigProperty.FindPropertyRelative("LoadSceneTimeOut"); enableMessageBufferingProperty = networkConfigProperty.FindPropertyRelative("EnableMessageBuffering"); messageBufferTimeoutProperty = networkConfigProperty.FindPropertyRelative("MessageBufferTimeout"); - enableEncryptionProperty = networkConfigProperty.FindPropertyRelative("EnableEncryption"); - signKeyExchangeProperty = networkConfigProperty.FindPropertyRelative("SignKeyExchange"); - serverBase64PfxCertificateProperty = networkConfigProperty.FindPropertyRelative("ServerBase64PfxCertificate"); ReloadTransports(); @@ -164,9 +158,6 @@ private void CheckNullProperties() loadSceneTimeOutProperty = networkConfigProperty.FindPropertyRelative("LoadSceneTimeOut"); enableMessageBufferingProperty = networkConfigProperty.FindPropertyRelative("EnableMessageBuffering"); messageBufferTimeoutProperty = networkConfigProperty.FindPropertyRelative("MessageBufferTimeout"); - enableEncryptionProperty = networkConfigProperty.FindPropertyRelative("EnableEncryption"); - signKeyExchangeProperty = networkConfigProperty.FindPropertyRelative("SignKeyExchange"); - serverBase64PfxCertificateProperty = networkConfigProperty.FindPropertyRelative("ServerBase64PfxCertificate"); } private void OnEnable() @@ -371,15 +362,6 @@ public override void OnInspectorGUI() EditorGUILayout.PropertyField(allowRuntimeSceneChangesProperty); } - EditorGUILayout.LabelField("Cryptography", EditorStyles.boldLabel); - EditorGUILayout.PropertyField(enableEncryptionProperty); - - using (new EditorGUI.DisabledScope(!networkingManager.NetworkConfig.EnableEncryption)) - { - EditorGUILayout.PropertyField(signKeyExchangeProperty); - EditorGUILayout.PropertyField(serverBase64PfxCertificateProperty); - } - serializedObject.ApplyModifiedProperties(); diff --git a/com.unity.multiplayer.mlapi/Runtime/Configuration/MLAPIConstants.cs b/com.unity.multiplayer.mlapi/Runtime/Configuration/MLAPIConstants.cs index 69902eace4..18142d9a44 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Configuration/MLAPIConstants.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Configuration/MLAPIConstants.cs @@ -7,9 +7,6 @@ internal static class MLAPIConstants { internal const string MLAPI_PROTOCOL_VERSION = "13.0.0"; - internal const byte MLAPI_CERTIFICATE_HAIL = 0; - internal const byte MLAPI_CERTIFICATE_HAIL_RESPONSE = 1; - internal const byte MLAPI_GREETINGS = 2; internal const byte MLAPI_CONNECTION_REQUEST = 3; internal const byte MLAPI_CONNECTION_APPROVED = 4; internal const byte MLAPI_ADD_OBJECT = 5; @@ -29,10 +26,11 @@ internal static class MLAPIConstants internal const byte MLAPI_CLIENT_RPC = 31; internal const byte INVALID = 32; - internal static readonly string[] MESSAGE_NAMES = { - "MLAPI_CERTIFICATE_HAIL", // 0 - "MLAPI_CERTIFICATE_HAIL_RESPONSE", - "MLAPI_GREETINGS", + internal static readonly string[] MESSAGE_NAMES = + { + "", // 0 + "", + "", "MLAPI_CONNECTION_REQUEST", "MLAPI_CONNECTION_APPROVED", "MLAPI_ADD_OBJECT", @@ -65,4 +63,4 @@ internal static class MLAPIConstants "INVALID" // 32 }; } -} +} \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConfig.cs b/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConfig.cs index 535f725365..0988328e83 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConfig.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConfig.cs @@ -4,10 +4,8 @@ using System.Linq; using MLAPI.Transports; using BitStream = MLAPI.Serialization.BitStream; -using System.Security.Cryptography.X509Certificates; using MLAPI.Hashing; using MLAPI.Serialization.Pooled; -using UnityEngine.Serialization; namespace MLAPI.Configuration { @@ -171,51 +169,6 @@ public class NetworkConfig /// Whether or not to enable network logs. /// public bool EnableNetworkLogs = true; - /// - /// Whether or not to enable the ECDHE key exchange to allow for encryption and authentication of messages - /// - [Tooltip("Whether or not to enable the ECDHE key exchange to allow for encryption and authentication of messages")] - public bool EnableEncryption = false; - /// - /// Whether or not to enable signed diffie hellman key exchange. - /// - [Tooltip("Whether or not to sign the diffie hellman key exchange to prevent MITM attacks on")] - public bool SignKeyExchange = false; - /// - /// Pfx file in base64 encoding containing private and public key - /// - [Tooltip("The certificate in base64 encoded PFX format")] - [TextArea] - public string ServerBase64PfxCertificate; - /// - /// Gets the currently in use certificate - /// - public X509Certificate2 ServerX509Certificate - { - get - { - return serverX509Certificate; - } - internal set - { - serverX509CertificateBytes = null; - serverX509Certificate = value; - } - } - private X509Certificate2 serverX509Certificate; - /// - /// Gets the cached binary representation of the server certificate that's used for handshaking - /// - public byte[] ServerX509CertificateBytes - { - get - { - if (serverX509CertificateBytes == null) - serverX509CertificateBytes = ServerX509Certificate.Export(X509ContentType.Cert); - return serverX509CertificateBytes; - } - } - private byte[] serverX509CertificateBytes = null; private void Sort() { @@ -248,8 +201,6 @@ public string ToBase64() writer.WriteInt32Packed(config.ClientConnectionBufferTimeout); writer.WriteBool(config.ConnectionApproval); writer.WriteInt32Packed(config.SecondsHistory); - writer.WriteBool(config.EnableEncryption); - writer.WriteBool(config.SignKeyExchange); writer.WriteInt32Packed(config.LoadSceneTimeOut); writer.WriteBool(config.EnableTimeResync); writer.WriteBool(config.EnsureNetworkedVarLengthSafety); @@ -297,8 +248,6 @@ public void FromBase64(string base64) config.ClientConnectionBufferTimeout = reader.ReadInt32Packed(); config.ConnectionApproval = reader.ReadBool(); config.SecondsHistory = reader.ReadInt32Packed(); - config.EnableEncryption = reader.ReadBool(); - config.SignKeyExchange = reader.ReadBool(); config.LoadSceneTimeOut = reader.ReadInt32Packed(); config.EnableTimeResync = reader.ReadBool(); config.EnsureNetworkedVarLengthSafety = reader.ReadBool(); @@ -358,8 +307,6 @@ public ulong GetConfig(bool cache = true) writer.WriteBool(UsePrefabSync); writer.WriteBool(EnableSceneManagement); writer.WriteBool(EnsureNetworkedVarLengthSafety); - writer.WriteBool(EnableEncryption); - writer.WriteBool(SignKeyExchange); writer.WriteBits((byte)RpcHashSize, 2); stream.PadStream(); diff --git a/com.unity.multiplayer.mlapi/Runtime/Connection/NetworkedClient.cs b/com.unity.multiplayer.mlapi/Runtime/Connection/NetworkedClient.cs index b11a81339e..2370af2a55 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Connection/NetworkedClient.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Connection/NetworkedClient.cs @@ -11,17 +11,15 @@ public class NetworkedClient /// The Id of the NetworkedClient /// public ulong ClientId; + /// /// The PlayerObject of the Client /// public NetworkedObject PlayerObject; + /// /// The NetworkedObject's owned by this Client /// public readonly List OwnedObjects = new List(); - /// - /// The encryption key used for this client - /// - public byte[] AesKey; } -} +} \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Connection/PendingClient.cs b/com.unity.multiplayer.mlapi/Runtime/Connection/PendingClient.cs index fe437afd52..766dd21513 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Connection/PendingClient.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Connection/PendingClient.cs @@ -1,8 +1,4 @@ -#if !DISABLE_CRYPTOGRAPHY -using MLAPI.Security; -#endif - -namespace MLAPI.Connection +namespace MLAPI.Connection { /// /// A class representing a client that is currently in the process of connecting @@ -13,14 +9,6 @@ public class PendingClient /// The ClientId of the client /// public ulong ClientId; - -#if !DISABLE_CRYPTOGRAPHY - internal EllipticDiffieHellman KeyExchange; -#endif - /// - /// The current AesKey - /// - public byte[] AesKey; /// /// The state of the connection process for the client @@ -32,10 +20,6 @@ public class PendingClient /// public enum State { - /// - /// Client is in the process of doing the hail handshake - /// - PendingHail, /// /// Client is in the process of doing the connection handshake /// diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedBehaviour.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedBehaviour.cs index 23e522bc46..541d00e0c0 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedBehaviour.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedBehaviour.cs @@ -12,7 +12,6 @@ using MLAPI.NetworkedVar; using MLAPI.Profiling; using MLAPI.Reflection; -using MLAPI.Security; using MLAPI.Serialization; using MLAPI.Serialization.Pooled; using MLAPI.Spawning; @@ -74,25 +73,21 @@ public BitSerializer __beginSendServerRpc(ServerRpcParams serverRpcParams, RpcDe if (IsHost) { - writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ServerRpc, Time.realtimeSinceStartup, transportChannel, 0, + writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ServerRpc, Time.realtimeSinceStartup, transportChannel, NetworkingManager.Singleton.ServerClientId, null, QueueHistoryFrame.QueueFrameType.Inbound, serverRpcParams.Send.UpdateStage); if (!isUsingBatching) { - writer.WriteBit(false); // Encrypted - writer.WriteBit(false); // Authenticated - writer.WriteBits(MLAPIConstants.MLAPI_SERVER_RPC, 6); // MessageType + writer.WriteByte(MLAPIConstants.MLAPI_SERVER_RPC); // MessageType } } else { - writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ServerRpc, Time.realtimeSinceStartup, transportChannel, 0, + writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ServerRpc, Time.realtimeSinceStartup, transportChannel, NetworkingManager.Singleton.ServerClientId, null, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateStage.PostLateUpdate); if (!isUsingBatching) { - writer.WriteBit(false); // Encrypted - writer.WriteBit(false); // Authenticated - writer.WriteBits(MLAPIConstants.MLAPI_SERVER_RPC, 6); // MessageType + writer.WriteByte(MLAPIConstants.MLAPI_SERVER_RPC); // MessageType } } @@ -157,7 +152,7 @@ public BitSerializer __beginSendClientRpc(ClientRpcParams clientRpcParams, RpcDe if (IsHost && ContainsServerClientId) { //Always write to the next frame's inbound queue - writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, transportChannel, 0, + writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, transportChannel, NetworkingManager.Singleton.ServerClientId, null, QueueHistoryFrame.QueueFrameType.Inbound, clientRpcParams.Send.UpdateStage); //Handle sending to the other clients, if so the above notes explain why this code is here (a temporary patch-fix) @@ -167,36 +162,30 @@ public BitSerializer __beginSendClientRpc(ClientRpcParams clientRpcParams, RpcDe rpcQueueContainer.SetLoopBackFrameItem(clientRpcParams.Send.UpdateStage); //Switch to the outbound queue - writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, Channel.ReliableRPC, 0, NetworkId, + writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, Channel.ReliableRPC, NetworkId, ClientIds, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateStage.PostLateUpdate); if (!isUsingBatching) { - writer.WriteBit(false); // Encrypted - writer.WriteBit(false); // Authenticated - writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType + writer.WriteByte(MLAPIConstants.MLAPI_CLIENT_RPC); // MessageType } } else { if (!isUsingBatching) { - writer.WriteBit(false); // Encrypted - writer.WriteBit(false); // Authenticated - writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType + writer.WriteByte(MLAPIConstants.MLAPI_CLIENT_RPC); // MessageType } } } else { - writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, transportChannel, 0, NetworkId, + writer = rpcQueueContainer.BeginAddQueueItemToFrame(RpcQueueContainer.QueueItemType.ClientRpc, Time.realtimeSinceStartup, transportChannel, NetworkId, ClientIds, QueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateStage.PostLateUpdate); if (!isUsingBatching) { - writer.WriteBit(false); // Encrypted - writer.WriteBit(false); // Authenticated - writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType + writer.WriteByte(MLAPIConstants.MLAPI_CLIENT_RPC); // MessageType } } @@ -708,9 +697,7 @@ private void NetworkedVarUpdate(ulong clientId) if (writtenAny) { - InternalMessageSender.Send(clientId, - MLAPIConstants.MLAPI_NETWORKED_VAR_DELTA, - channelsForNetworkedVarGroups[j], stream, SecuritySendFlags.None); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_NETWORKED_VAR_DELTA, channelsForNetworkedVarGroups[j], stream); } } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedObject.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedObject.cs index 87419d653f..e1d58680bd 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedObject.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkedObject.cs @@ -7,11 +7,9 @@ using MLAPI.Hashing; using MLAPI.Logging; using MLAPI.Messaging; -using MLAPI.Security; using MLAPI.Serialization.Pooled; using MLAPI.Spawning; using MLAPI.Transports; -using Unity.Profiling; using UnityEngine; namespace MLAPI @@ -283,7 +281,7 @@ public static void NetworkShow(List networkedObjects, ulong cli SpawnManager.WriteSpawnCallForObject(stream, clientId, networkedObjects[i], payload); } - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_ADD_OBJECTS, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_ADD_OBJECTS, Channel.Internal, stream); } } @@ -323,7 +321,7 @@ public void NetworkHide(ulong clientId) { writer.WriteUInt64Packed(NetworkId); - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_DESTROY_OBJECT, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_DESTROY_OBJECT, Channel.Internal, stream); } } } @@ -375,7 +373,7 @@ public static void NetworkHide(List networkedObjects, ulong cli } } - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_DESTROY_OBJECTS, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_DESTROY_OBJECTS, Channel.Internal, stream); } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkingManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkingManager.cs index 9b246c6918..4ae158ea3e 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkingManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkingManager.cs @@ -8,10 +8,7 @@ using MLAPI.Logging; using UnityEngine.SceneManagement; using System.IO; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using MLAPI.Configuration; -using MLAPI.Security; using MLAPI.Internal; using MLAPI.Profiling; using MLAPI.Serialization; @@ -56,7 +53,6 @@ public class NetworkingManager : MonoBehaviour, INetworkUpdateSystem static ProfilerMarker s_HandleIncomingData = new ProfilerMarker("HandleIncomingData"); static ProfilerMarker s_TransportDisconnect = new ProfilerMarker("TransportDisconnect"); - static ProfilerMarker s_MLAPIServerRPC = new ProfilerMarker("MLAPIServerRPC"); static ProfilerMarker s_MLAPIServerRPCQueued = new ProfilerMarker("MLAPIServerRPCQueued"); @@ -68,6 +64,7 @@ public class NetworkingManager : MonoBehaviour, INetworkUpdateSystem static ProfilerMarker s_MLAPIClientSTDRPC = new ProfilerMarker("MLAPIClientSTDRPC"); static ProfilerMarker s_MLAPIClientSTDRPCQueued = new ProfilerMarker("MLAPIClientSTDRPCQueued"); + static ProfilerMarker s_InvokeRPC = new ProfilerMarker("InvokeRPC"); #endif internal RpcQueueContainer rpcQueueContainer { get; private set; } @@ -240,7 +237,6 @@ internal void InvokeConnectionApproval(byte[] payload, ulong clientId, Connectio /// The current hostname we are connected to, used to validate certificate /// public string ConnectedHostname { get; private set; } - internal byte[] clientAesKey; internal static event Action OnSingletonReady; internal void InvokeOnIncomingCustomMessage(ulong clientId, Stream stream) @@ -257,9 +253,8 @@ internal void InvokeOnIncomingCustomMessage(ulong clientId, Stream stream) /// The clients to send to, sends to everyone if null /// The message stream containing the data /// The channel to send the data on - /// The security settings to apply to the message [Obsolete("Use CustomMessagingManager.SendUnnamedMessage instead")] - public void SendCustomMessage(List clientIds, BitStream stream, Channel channel = Channel.Internal, SecuritySendFlags security = SecuritySendFlags.None) + public void SendCustomMessage(List clientIds, BitStream stream, Channel channel = Channel.Internal) { if (!IsServer) { @@ -267,7 +262,7 @@ public void SendCustomMessage(List clientIds, BitStream stream, Channel c return; } - InternalMessageSender.Send(MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, clientIds, stream, security); + InternalMessageSender.Send(MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, clientIds, stream); } /// @@ -276,11 +271,10 @@ public void SendCustomMessage(List clientIds, BitStream stream, Channel c /// The client to send the message to /// The message stream containing the data /// The channel tos end the data on - /// The security settings to apply to the message [Obsolete("Use CustomMessagingManager.SendUnnamedMessage instead")] - public void SendCustomMessage(ulong clientId, BitStream stream, Channel channel = Channel.Internal, SecuritySendFlags security = SecuritySendFlags.None) + public void SendCustomMessage(ulong clientId, BitStream stream, Channel channel = Channel.Internal) { - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, stream, security); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, stream); } private void OnValidate() @@ -415,38 +409,6 @@ private void Init(bool server) this.RegisterNetworkUpdate(NetworkUpdateStage.EarlyUpdate); this.RegisterNetworkUpdate(NetworkUpdateStage.PreUpdate); - try - { - string pfx = null; - if (NetworkConfig.ServerBase64PfxCertificate != null) - { - pfx = NetworkConfig.ServerBase64PfxCertificate.Trim(); - } - - if (server && pfx != null && NetworkConfig.EnableEncryption && NetworkConfig.SignKeyExchange && !string.IsNullOrEmpty(pfx)) - { - try - { - byte[] decodedPfx = Convert.FromBase64String(pfx); - - NetworkConfig.ServerX509Certificate = new X509Certificate2(decodedPfx); - - if (!NetworkConfig.ServerX509Certificate.HasPrivateKey) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning("The imported PFX file did not have a private key"); - } - } - catch (FormatException ex) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Parsing PFX failed: " + ex.ToString()); - } - } - } - catch (CryptographicException ex) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Importing of certificate failed: " + ex.ToString()); - } - if (NetworkConfig.EnableSceneManagement) { NetworkConfig.RegisteredScenes.Sort(StringComparer.Ordinal); @@ -904,7 +866,7 @@ internal void SendConnectionRequest() writer.WriteByteArray(NetworkConfig.ConnectionData); } - InternalMessageSender.Send(ServerClientId, MLAPIConstants.MLAPI_CONNECTION_REQUEST, Channel.Internal, stream, SecuritySendFlags.Authenticated | SecuritySendFlags.Encrypted); + InternalMessageSender.Send(ServerClientId, MLAPIConstants.MLAPI_CONNECTION_REQUEST, Channel.Internal, stream); } } @@ -945,91 +907,19 @@ private void HandleRawTransportPoll(NetEventType eventType, ulong clientId, Chan if (IsServer) { if (NetworkLog.CurrentLogLevel <= LogLevel.Developer) NetworkLog.LogInfo("Client Connected"); -#if !DISABLE_CRYPTOGRAPHY - if (NetworkConfig.EnableEncryption) - { - // This client is required to complete the crypto-hail exchange. - using (PooledBitStream hailStream = PooledBitStream.Get()) - { - using (PooledBitWriter hailWriter = PooledBitWriter.Get(hailStream)) - { - if (NetworkConfig.SignKeyExchange) - { - // Write certificate - hailWriter.WriteByteArray(NetworkConfig.ServerX509CertificateBytes); - } - - // Write key exchange public part - EllipticDiffieHellman diffieHellman = new EllipticDiffieHellman(EllipticDiffieHellman.DEFAULT_CURVE, EllipticDiffieHellman.DEFAULT_GENERATOR, EllipticDiffieHellman.DEFAULT_ORDER); - byte[] diffieHellmanPublicPart = diffieHellman.GetPublicKey(); - hailWriter.WriteByteArray(diffieHellmanPublicPart); - PendingClients.Add(clientId, new PendingClient() - { - ClientId = clientId, - ConnectionState = PendingClient.State.PendingHail, - KeyExchange = diffieHellman - }); - - if (NetworkConfig.SignKeyExchange) - { - // Write public part signature (signed by certificate private) - X509Certificate2 certificate = NetworkConfig.ServerX509Certificate; - - if (!certificate.HasPrivateKey) - throw new CryptographicException("[MLAPI] No private key was found in server certificate. Unable to sign key exchange"); - - RSACryptoServiceProvider rsa = certificate.PrivateKey as RSACryptoServiceProvider; - DSACryptoServiceProvider dsa = certificate.PrivateKey as DSACryptoServiceProvider; - - if (rsa != null) - { - // RSA is 0 - hailWriter.WriteByte(0); - - using (SHA256Managed sha = new SHA256Managed()) - { - hailWriter.WriteByteArray(rsa.SignData(diffieHellmanPublicPart, sha)); - } - } - else if (dsa != null) - { - // DSA is 1 - hailWriter.WriteByte(1); - - using (SHA256Managed sha = new SHA256Managed()) - { - hailWriter.WriteByteArray(dsa.SignData(sha.ComputeHash(diffieHellmanPublicPart))); - } - } - else - { - throw new CryptographicException("[MLAPI] Only RSA and DSA certificates are supported. No valid RSA or DSA key was found"); - } - } - } - // Send the hail - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_CERTIFICATE_HAIL, Transport.MLAPI_INTERNAL_CHANNEL, hailStream, SecuritySendFlags.None); - } - } - else - { -#endif + PendingClients.Add(clientId, new PendingClient() { ClientId = clientId, ConnectionState = PendingClient.State.PendingConnection }); -#if !DISABLE_CRYPTOGRAPHY - } -#endif StartCoroutine(ApprovalTimeout(clientId)); } else { if (NetworkLog.CurrentLogLevel <= LogLevel.Developer) NetworkLog.LogInfo("Connected"); - if (!NetworkConfig.EnableEncryption) - SendConnectionRequest(); + SendConnectionRequest(); StartCoroutine(ApprovalTimeout(clientId)); } NetworkProfiler.EndEvent(); @@ -1083,7 +973,7 @@ internal void HandleIncomingData(ulong clientId, Channel channel, ArraySegment /// frame queue item to invoke +#pragma warning disable 618 internal static void InvokeRpc(RpcFrameQueueItem queueItem) { #if DEVELOPMENT_BUILD || UNITY_EDITOR @@ -1320,6 +1199,7 @@ internal static void InvokeRpc(RpcFrameQueueItem queueItem) __ntable[networkMethodId](networkBehaviour, new BitSerializer(queueItem.streamReader), rpcParams); } +#pragma warning restore 618 #if DEVELOPMENT_BUILD || UNITY_EDITOR s_InvokeRPC.End(); @@ -1456,7 +1336,7 @@ private void SyncTime() using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteSinglePacked(Time.realtimeSinceStartup); - InternalMessageSender.Send(MLAPIConstants.MLAPI_TIME_SYNC, Channel.SyncChannel, stream, SecuritySendFlags.None); + InternalMessageSender.Send(MLAPIConstants.MLAPI_TIME_SYNC, Channel.SyncChannel, stream); } } #if DEVELOPMENT_BUILD || UNITY_EDITOR @@ -1471,15 +1351,11 @@ internal void HandleApproval(ulong clientId, bool createPlayerObject, ulong? pla if (approved) { // Inform new client it got approved - byte[] aesKey = PendingClients.ContainsKey(clientId) ? PendingClients[clientId].AesKey : null; if (PendingClients.ContainsKey(clientId)) PendingClients.Remove(clientId); NetworkedClient client = new NetworkedClient() { ClientId = clientId, -#if !DISABLE_CRYPTOGRAPHY - AesKey = aesKey -#endif }; ConnectedClients.Add(clientId, client); ConnectedClientsList.Add(client); @@ -1591,7 +1467,7 @@ internal void HandleApproval(ulong clientId, bool createPlayerObject, ulong? pla } } - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_CONNECTION_APPROVED, Channel.Internal, stream, SecuritySendFlags.Encrypted | SecuritySendFlags.Authenticated); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_CONNECTION_APPROVED, Channel.Internal, stream); if (OnClientConnectedCallback != null) OnClientConnectedCallback.Invoke(clientId); @@ -1653,7 +1529,7 @@ internal void HandleApproval(ulong clientId, bool createPlayerObject, ulong? pla ConnectedClients[clientId].PlayerObject.WriteNetworkedVarData(stream, clientPair.Key); } - InternalMessageSender.Send(clientPair.Key, MLAPIConstants.MLAPI_ADD_OBJECT, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(clientPair.Key, MLAPIConstants.MLAPI_ADD_OBJECT, Channel.Internal, stream); } } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Logging/NetworkLog.cs b/com.unity.multiplayer.mlapi/Runtime/Logging/NetworkLog.cs index 7d479dd331..73c219f770 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Logging/NetworkLog.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Logging/NetworkLog.cs @@ -1,6 +1,5 @@ using MLAPI.Configuration; using MLAPI.Messaging; -using MLAPI.Security; using MLAPI.Serialization.Pooled; using MLAPI.Transports; using UnityEngine; @@ -76,7 +75,7 @@ private static void LogServer(string message, LogType logType) writer.WriteStringPacked(message); - InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_SERVER_LOG, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_SERVER_LOG, Channel.Internal, stream); } } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/CustomMessageManager.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/CustomMessageManager.cs index ae4ce25877..15574a9938 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/CustomMessageManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/CustomMessageManager.cs @@ -1,9 +1,7 @@ -using System; using System.Collections.Generic; using System.IO; using MLAPI.Configuration; using MLAPI.Logging; -using MLAPI.Security; using MLAPI.Serialization; using MLAPI.Serialization.Pooled; using MLAPI.Hashing; @@ -47,8 +45,7 @@ internal static void InvokeUnnamedMessage(ulong clientId, Stream stream) /// The clients to send to, sends to everyone if null /// The message stream containing the data /// The channel to send the data on - /// The security settings to apply to the message - public static void SendUnnamedMessage(List clientIds, BitStream stream, Channel channel = Channel.Internal, SecuritySendFlags security = SecuritySendFlags.None) + public static void SendUnnamedMessage(List clientIds, BitStream stream, Channel channel = Channel.Internal) { if (!NetworkingManager.Singleton.IsServer) { @@ -56,7 +53,7 @@ public static void SendUnnamedMessage(List clientIds, BitStream stream, C return; } - InternalMessageSender.Send(MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, clientIds, stream, security); + InternalMessageSender.Send(MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, clientIds, stream); } /// @@ -65,10 +62,9 @@ public static void SendUnnamedMessage(List clientIds, BitStream stream, C /// The client to send the message to /// The message stream containing the data /// The channel tos end the data on - /// The security settings to apply to the message - public static void SendUnnamedMessage(ulong clientId, BitStream stream, Channel channel = Channel.Internal, SecuritySendFlags security = SecuritySendFlags.None) + public static void SendUnnamedMessage(ulong clientId, BitStream stream, Channel channel = Channel.Internal) { - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, stream, security); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_UNNAMED_MESSAGE, channel, stream); } #endregion #region Named @@ -159,8 +155,7 @@ public static void UnregisterNamedMessageHandler(string name) /// The client to send the message to /// The message stream containing the data /// The channel to send the data on - /// The security settings to apply to the message - public static void SendNamedMessage(string name, ulong clientId, Stream stream, Channel channel = Channel.Internal, SecuritySendFlags security = SecuritySendFlags.None) + public static void SendNamedMessage(string name, ulong clientId, Stream stream, Channel channel = Channel.Internal) { ulong hash = 0; switch (NetworkingManager.Singleton.NetworkConfig.RpcHashSize) @@ -185,7 +180,7 @@ public static void SendNamedMessage(string name, ulong clientId, Stream stream, messageStream.CopyFrom(stream); - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_NAMED_MESSAGE, channel, messageStream, security); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_NAMED_MESSAGE, channel, messageStream); } } @@ -196,8 +191,7 @@ public static void SendNamedMessage(string name, ulong clientId, Stream stream, /// The clients to send to, sends to everyone if null /// The message stream containing the data /// The channel to send the data on - /// The security settings to apply to the message - public static void SendNamedMessage(string name, List clientIds, Stream stream, Channel channel = Channel.Internal, SecuritySendFlags security = SecuritySendFlags.None) + public static void SendNamedMessage(string name, List clientIds, Stream stream, Channel channel = Channel.Internal) { ulong hash = 0; switch (NetworkingManager.Singleton.NetworkConfig.RpcHashSize) @@ -228,7 +222,7 @@ public static void SendNamedMessage(string name, List clientIds, Stream s return; } - InternalMessageSender.Send(MLAPIConstants.MLAPI_NAMED_MESSAGE, channel, clientIds, messageStream, security); + InternalMessageSender.Send(MLAPIConstants.MLAPI_NAMED_MESSAGE, channel, clientIds, messageStream); } } #endregion diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs index 341b53ec57..1650020b2f 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs @@ -1,12 +1,6 @@ using System; using System.IO; -using MLAPI.Configuration; using MLAPI.Connection; -#if !DISABLE_CRYPTOGRAPHY -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -#endif -using MLAPI.Security; using MLAPI.Logging; using MLAPI.SceneManagement; using MLAPI.Serialization.Pooled; @@ -18,8 +12,6 @@ using MLAPI.Messaging.Buffering; using MLAPI.Profiling; using Unity.Profiling; -using MLAPI.Serialization; -using MLAPI.Transports; using BitStream = MLAPI.Serialization.BitStream; namespace MLAPI.Messaging @@ -33,177 +25,16 @@ internal static class InternalMessageHandler static ProfilerMarker s_HandleDestroyObject = new ProfilerMarker("InternalMessageHandler.HandleDestroyObject"); static ProfilerMarker s_HandleSwitchScene = new ProfilerMarker("InternalMessageHandler.HandleSwitchScene"); static ProfilerMarker s_HandleClientSwitchSceneCompleted = new ProfilerMarker("InternalMessageHandler.HandleClientSwitchSceneCompleted"); - static ProfilerMarker s_HandleChangeOwner = - new ProfilerMarker("InternalMessageHandler.HandleChangeOwner"); - static ProfilerMarker s_HandleAddObjects = - new ProfilerMarker("InternalMessageHandler.HandleAddObjects"); - static ProfilerMarker s_HandleDestroyObjects = - new ProfilerMarker("InternalMessageHandler.HandleDestroyObjects"); - static ProfilerMarker s_HandleTimeSync = - new ProfilerMarker("InternalMessageHandler.HandleTimeSync"); - static ProfilerMarker s_HandleNetworkedVarDelta = - new ProfilerMarker("InternalMessageHandler.HandleNetworkedVarDelta"); - static ProfilerMarker s_HandleNetworkedVarUpdate = - new ProfilerMarker("InternalMessageHandler.HandleNetworkedVarUpdate"); - static ProfilerMarker s_HandleUnnamedMessage = - new ProfilerMarker("InternalMessageHandler.HandleUnnamedMessage"); - static ProfilerMarker s_HandleNamedMessage = - new ProfilerMarker("InternalMessageHandler.HandleNamedMessage"); - static ProfilerMarker s_HandleNetworkLog = - new ProfilerMarker("InternalMessageHandler.HandleNetworkLog"); - -#endif - -#if !DISABLE_CRYPTOGRAPHY - // Runs on client - internal static void HandleHailRequest(ulong clientId, Stream stream) - { - X509Certificate2 certificate = null; - byte[] serverDiffieHellmanPublicPart = null; - using (PooledBitReader reader = PooledBitReader.Get(stream)) - { - if (NetworkingManager.Singleton.NetworkConfig.EnableEncryption) - { - // Read the certificate - if (NetworkingManager.Singleton.NetworkConfig.SignKeyExchange) - { - // Allocation justification: This runs on client and only once, at initial connection - certificate = new X509Certificate2(reader.ReadByteArray()); - if (CryptographyHelper.VerifyCertificate(certificate, NetworkingManager.Singleton.ConnectedHostname)) - { - // The certificate is not valid :( - // Man in the middle. - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning("Invalid certificate. Disconnecting"); - NetworkingManager.Singleton.StopClient(); - return; - } - else - { - NetworkingManager.Singleton.NetworkConfig.ServerX509Certificate = certificate; - } - } - - // Read the ECDH - // Allocation justification: This runs on client and only once, at initial connection - serverDiffieHellmanPublicPart = reader.ReadByteArray(); - - // Verify the key exchange - if (NetworkingManager.Singleton.NetworkConfig.SignKeyExchange) - { - int signatureType = reader.ReadByte(); - - byte[] serverDiffieHellmanPublicPartSignature = reader.ReadByteArray(); - - if (signatureType == 0) - { - RSACryptoServiceProvider rsa = certificate.PublicKey.Key as RSACryptoServiceProvider; - - if (rsa != null) - { - using (SHA256Managed sha = new SHA256Managed()) - { - if (!rsa.VerifyData(serverDiffieHellmanPublicPart, sha, serverDiffieHellmanPublicPartSignature)) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning("Invalid RSA signature. Disconnecting"); - NetworkingManager.Singleton.StopClient(); - return; - } - } - } - else - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning("No RSA key found in certificate. Disconnecting"); - NetworkingManager.Singleton.StopClient(); - return; - } - } - else if (signatureType == 1) - { - DSACryptoServiceProvider dsa = certificate.PublicKey.Key as DSACryptoServiceProvider; - - if (dsa != null) - { - using (SHA256Managed sha = new SHA256Managed()) - { - if (!dsa.VerifyData(sha.ComputeHash(serverDiffieHellmanPublicPart), serverDiffieHellmanPublicPartSignature)) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning("Invalid DSA signature. Disconnecting"); - NetworkingManager.Singleton.StopClient(); - return; - } - } - } - else - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning("No DSA key found in certificate. Disconnecting"); - NetworkingManager.Singleton.StopClient(); - return; - } - } - else - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogWarning("Invalid signature type. Disconnecting"); - NetworkingManager.Singleton.StopClient(); - return; - } - } - } - } - - using (PooledBitStream outStream = PooledBitStream.Get()) - { - using (PooledBitWriter writer = PooledBitWriter.Get(outStream)) - { - if (NetworkingManager.Singleton.NetworkConfig.EnableEncryption) - { - // Create a ECDH key - EllipticDiffieHellman diffieHellman = new EllipticDiffieHellman(EllipticDiffieHellman.DEFAULT_CURVE, EllipticDiffieHellman.DEFAULT_GENERATOR, EllipticDiffieHellman.DEFAULT_ORDER); - NetworkingManager.Singleton.clientAesKey = diffieHellman.GetSharedSecret(serverDiffieHellmanPublicPart); - byte[] diffieHellmanPublicKey = diffieHellman.GetPublicKey(); - writer.WriteByteArray(diffieHellmanPublicKey); - } - } - - // Send HailResponse - InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CERTIFICATE_HAIL_RESPONSE, Channel.Internal, outStream, SecuritySendFlags.None); - } - } - - // Ran on server - internal static void HandleHailResponse(ulong clientId, Stream stream) - { - if (!NetworkingManager.Singleton.PendingClients.ContainsKey(clientId) || NetworkingManager.Singleton.PendingClients[clientId].ConnectionState != PendingClient.State.PendingHail) return; - if (!NetworkingManager.Singleton.NetworkConfig.EnableEncryption) return; + static ProfilerMarker s_HandleChangeOwner = new ProfilerMarker("InternalMessageHandler.HandleChangeOwner"); + static ProfilerMarker s_HandleAddObjects = new ProfilerMarker("InternalMessageHandler.HandleAddObjects"); + static ProfilerMarker s_HandleDestroyObjects = new ProfilerMarker("InternalMessageHandler.HandleDestroyObjects"); + static ProfilerMarker s_HandleTimeSync = new ProfilerMarker("InternalMessageHandler.HandleTimeSync"); + static ProfilerMarker s_HandleNetworkedVarDelta = new ProfilerMarker("InternalMessageHandler.HandleNetworkedVarDelta"); + static ProfilerMarker s_HandleNetworkedVarUpdate = new ProfilerMarker("InternalMessageHandler.HandleNetworkedVarUpdate"); + static ProfilerMarker s_HandleUnnamedMessage = new ProfilerMarker("InternalMessageHandler.HandleUnnamedMessage"); + static ProfilerMarker s_HandleNamedMessage = new ProfilerMarker("InternalMessageHandler.HandleNamedMessage"); + static ProfilerMarker s_HandleNetworkLog = new ProfilerMarker("InternalMessageHandler.HandleNetworkLog"); - using (PooledBitReader reader = PooledBitReader.Get(stream)) - { - if (NetworkingManager.Singleton.PendingClients[clientId].KeyExchange != null) - { - byte[] diffieHellmanPublic = reader.ReadByteArray(); - NetworkingManager.Singleton.PendingClients[clientId].AesKey = NetworkingManager.Singleton.PendingClients[clientId].KeyExchange.GetSharedSecret(diffieHellmanPublic); - } - } - - NetworkingManager.Singleton.PendingClients[clientId].ConnectionState = PendingClient.State.PendingConnection; - NetworkingManager.Singleton.PendingClients[clientId].KeyExchange = null; // Give to GC - - // Send greetings, they have passed all the handshakes - using (PooledBitStream outStream = PooledBitStream.Get()) - { - using (PooledBitWriter writer = PooledBitWriter.Get(outStream)) - { - writer.WriteInt64Packed(DateTime.Now.Ticks); // This serves no purpose. - } - - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_GREETINGS, Channel.Internal, outStream, SecuritySendFlags.None); - } - } - - internal static void HandleGreetings(ulong clientId, Stream stream) - { - // Server greeted us, we can now initiate our request to connect. - NetworkingManager.Singleton.SendConnectionRequest(); - } #endif internal static void HandleConnectionRequest(ulong clientId, Stream stream) @@ -224,10 +55,7 @@ internal static void HandleConnectionRequest(ulong clientId, Stream stream) if (NetworkingManager.Singleton.NetworkConfig.ConnectionApproval) { byte[] connectionBuffer = reader.ReadByteArray(); - NetworkingManager.Singleton.InvokeConnectionApproval(connectionBuffer, clientId, (createPlayerObject, playerPrefabHash, approved, position, rotation) => - { - NetworkingManager.Singleton.HandleApproval(clientId, createPlayerObject, playerPrefabHash, approved, position, rotation); - }); + NetworkingManager.Singleton.InvokeConnectionApproval(connectionBuffer, clientId, (createPlayerObject, playerPrefabHash, approved, position, rotation) => { NetworkingManager.Singleton.HandleApproval(clientId, createPlayerObject, playerPrefabHash, approved, position, rotation); }); } else { @@ -527,11 +355,13 @@ internal static void HandleChangeOwner(ulong clientId, Stream stream) //We are current owner. SpawnManager.SpawnedObjects[networkId].InvokeBehaviourOnLostOwnership(); } + if (ownerClientId == NetworkingManager.Singleton.LocalClientId) { //We are new owner. SpawnManager.SpawnedObjects[networkId].InvokeBehaviourOnGainedOwnership(); } + SpawnManager.SpawnedObjects[networkId].OwnerClientId = ownerClientId; } #if DEVELOPMENT_BUILD || UNITY_EDITOR @@ -759,4 +589,4 @@ internal static void HandleNetworkLog(ulong clientId, Stream stream) #endif } } -} +} \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageSender.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageSender.cs index 9c8c0a9a2d..41ce9ce749 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageSender.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageSender.cs @@ -2,9 +2,7 @@ using System.Collections.Generic; using MLAPI.Configuration; using MLAPI.Internal; -using MLAPI.Logging; using MLAPI.Profiling; -using MLAPI.Security; using MLAPI.Transports; using BitStream = MLAPI.Serialization.BitStream; @@ -12,17 +10,15 @@ namespace MLAPI.Messaging { internal static class InternalMessageSender { - internal static void Send(ulong clientId, byte messageType, Channel channel, BitStream messageStream, SecuritySendFlags flags) + internal static void Send(ulong clientId, byte messageType, Channel channel, BitStream messageStream) { messageStream.PadStream(); - if (NetworkingManager.Singleton.IsServer && clientId == NetworkingManager.Singleton.ServerClientId) - return; + if (NetworkingManager.Singleton.IsServer && clientId == NetworkingManager.Singleton.ServerClientId) return; - using (BitStream stream = MessagePacker.WrapMessage(messageType, clientId, messageStream, flags)) + using (BitStream stream = MessagePacker.WrapMessage(messageType, messageStream)) { - NetworkProfiler.StartEvent(TickType.Send, (uint) stream.Length, channel, - MLAPIConstants.MESSAGE_NAMES[messageType]); + NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channel, MLAPIConstants.MESSAGE_NAMES[messageType]); NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(clientId, new ArraySegment(stream.GetBuffer(), 0, (int)stream.Length), channel); ProfilerStatManager.bytesSent.Record((int)stream.Length); @@ -32,113 +28,74 @@ internal static void Send(ulong clientId, byte messageType, Channel channel, Bit } } - internal static void Send(byte messageType, Channel channel, BitStream messageStream, SecuritySendFlags flags) + internal static void Send(byte messageType, Channel channel, BitStream messageStream) { - bool encrypted = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; - bool authenticated = ((flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; + messageStream.PadStream(); - if (authenticated || encrypted) + using (BitStream stream = MessagePacker.WrapMessage(messageType, messageStream)) { + NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channel, MLAPIConstants.MESSAGE_NAMES[messageType]); for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++) { - Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, messageType, channel, messageStream, flags); - } - } - else - { - messageStream.PadStream(); + if (NetworkingManager.Singleton.IsServer && NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == NetworkingManager.Singleton.ServerClientId) + continue; - using (BitStream stream = MessagePacker.WrapMessage(messageType, 0, messageStream, flags)) - { - NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channel, MLAPIConstants.MESSAGE_NAMES[messageType]); - for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++) - { - if (NetworkingManager.Singleton.IsServer && NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == NetworkingManager.Singleton.ServerClientId) - continue; - - NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, new ArraySegment(stream.GetBuffer(), 0, (int)stream.Length), channel); - ProfilerStatManager.bytesSent.Record((int)stream.Length); - PerformanceDataManager.Increment(ProfilerConstants.NumberBytesSent, (int)stream.Length); - } - NetworkProfiler.EndEvent(); + NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, new ArraySegment(stream.GetBuffer(), 0, (int)stream.Length), channel); + ProfilerStatManager.bytesSent.Record((int)stream.Length); + PerformanceDataManager.Increment(ProfilerConstants.NumberBytesSent, (int)stream.Length); } + + NetworkProfiler.EndEvent(); } } - internal static void Send(byte messageType, Channel channel, List clientIds, BitStream messageStream, SecuritySendFlags flags) + internal static void Send(byte messageType, Channel channel, List clientIds, BitStream messageStream) { if (clientIds == null) { - Send(messageType, channel, messageStream, flags); + Send(messageType, channel, messageStream); return; } - bool encrypted = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; - bool authenticated = ((flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; + messageStream.PadStream(); - if (authenticated || encrypted) + using (BitStream stream = MessagePacker.WrapMessage(messageType, messageStream)) { + NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channel, MLAPIConstants.MESSAGE_NAMES[messageType]); for (int i = 0; i < clientIds.Count; i++) { - Send(clientIds[i], messageType, channel, messageStream, flags); - } - } - else - { - messageStream.PadStream(); + if (NetworkingManager.Singleton.IsServer && clientIds[i] == NetworkingManager.Singleton.ServerClientId) + continue; - using (BitStream stream = MessagePacker.WrapMessage(messageType, 0, messageStream, flags)) - { - NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channel, MLAPIConstants.MESSAGE_NAMES[messageType]); - for (int i = 0; i < clientIds.Count; i++) - { - if (NetworkingManager.Singleton.IsServer && clientIds[i] == NetworkingManager.Singleton.ServerClientId) - continue; - - NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(clientIds[i], new ArraySegment(stream.GetBuffer(), 0, (int)stream.Length), channel); - ProfilerStatManager.bytesSent.Record((int)stream.Length); - PerformanceDataManager.Increment(ProfilerConstants.NumberBytesSent, (int)stream.Length); - } - NetworkProfiler.EndEvent(); + NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(clientIds[i], new ArraySegment(stream.GetBuffer(), 0, (int)stream.Length), channel); + ProfilerStatManager.bytesSent.Record((int)stream.Length); + PerformanceDataManager.Increment(ProfilerConstants.NumberBytesSent, (int)stream.Length); } + + NetworkProfiler.EndEvent(); } } - internal static void Send(byte messageType, Channel channel, ulong clientIdToIgnore, BitStream messageStream, SecuritySendFlags flags) + internal static void Send(byte messageType, Channel channel, ulong clientIdToIgnore, BitStream messageStream) { - bool encrypted = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; - bool authenticated = ((flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; + messageStream.PadStream(); - if (encrypted || authenticated) + using (BitStream stream = MessagePacker.WrapMessage(messageType, messageStream)) { + NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channel, MLAPIConstants.MESSAGE_NAMES[messageType]); for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++) { - if (NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == clientIdToIgnore) + if (NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == clientIdToIgnore || + (NetworkingManager.Singleton.IsServer && NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == NetworkingManager.Singleton.ServerClientId)) continue; - Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, messageType, channel, messageStream, flags); + NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, new ArraySegment(stream.GetBuffer(), 0, (int)stream.Length), channel); + ProfilerStatManager.bytesSent.Record((int)stream.Length); + PerformanceDataManager.Increment(ProfilerConstants.NumberBytesSent, (int)stream.Length); } - } - else - { - messageStream.PadStream(); - using (BitStream stream = MessagePacker.WrapMessage(messageType, 0, messageStream, flags)) - { - NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channel, MLAPIConstants.MESSAGE_NAMES[messageType]); - for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++) - { - if (NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == clientIdToIgnore || - (NetworkingManager.Singleton.IsServer && NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == NetworkingManager.Singleton.ServerClientId)) - continue; - - NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, new ArraySegment(stream.GetBuffer(), 0, (int)stream.Length), channel); - ProfilerStatManager.bytesSent.Record((int)stream.Length); - PerformanceDataManager.Increment(ProfilerConstants.NumberBytesSent, (int)stream.Length); - } - NetworkProfiler.EndEvent(); - } + NetworkProfiler.EndEvent(); } } } -} +} \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/MessagePacker.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/MessagePacker.cs index 55a6ffd3fb..6afe2ce47b 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/MessagePacker.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/MessagePacker.cs @@ -1,276 +1,41 @@ using MLAPI.Logging; using MLAPI.Serialization; -using System; using MLAPI.Configuration; using MLAPI.Serialization.Pooled; -#if !DISABLE_CRYPTOGRAPHY -using System.Security.Cryptography; -#endif -using MLAPI.Security; namespace MLAPI.Internal { internal static class MessagePacker { - private static readonly byte[] IV_BUFFER = new byte[16]; - private static readonly byte[] HMAC_BUFFER = new byte[32]; - private static readonly byte[] HMAC_PLACEHOLDER = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - // This method is responsible for unwrapping a message, that is extracting the messagebody. - // Could include decrypting and/or authentication. - internal static BitStream UnwrapMessage(BitStream inputStream, ulong clientId, out byte messageType, out SecuritySendFlags security) - { - using (PooledBitReader inputHeaderReader = PooledBitReader.Get(inputStream)) + internal static BitStream UnwrapMessage(BitStream inputStream, out byte messageType) + { + using (var inputHeaderReader = PooledBitReader.Get(inputStream)) { - try + if (inputStream.Length < 1) { - if (inputStream.Length < 1) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogError("The incoming message was too small"); - messageType = MLAPIConstants.INVALID; - security = SecuritySendFlags.None; - return null; - } - - bool isEncrypted = inputHeaderReader.ReadBit(); - bool isAuthenticated = inputHeaderReader.ReadBit(); - - if (isEncrypted && isAuthenticated) security = SecuritySendFlags.Encrypted | SecuritySendFlags.Authenticated; - else if (isEncrypted) security = SecuritySendFlags.Encrypted; - else if (isAuthenticated) security = SecuritySendFlags.Authenticated; - else security = SecuritySendFlags.None; - - -#if !DISABLE_CRYPTOGRAPHY - if (isEncrypted || isAuthenticated) - { - if (!NetworkingManager.Singleton.NetworkConfig.EnableEncryption) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Got a encrypted and/or authenticated message but key exchange (\"encryption\") was not enabled"); - messageType = MLAPIConstants.INVALID; - return null; - } - - // Skip last bits in first byte - inputHeaderReader.SkipPadBits(); - - if (isAuthenticated) - { - long hmacStartPos = inputStream.Position; - - int readHmacLength = inputStream.Read(HMAC_BUFFER, 0, HMAC_BUFFER.Length); - - if (readHmacLength != HMAC_BUFFER.Length) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("HMAC length was invalid"); - messageType = MLAPIConstants.INVALID; - return null; - } - - // Now we have read the HMAC, we need to set the hmac in the input to 0s to perform the HMAC. - inputStream.Position = hmacStartPos; - inputStream.Write(HMAC_PLACEHOLDER, 0, HMAC_PLACEHOLDER.Length); - - byte[] key = NetworkingManager.Singleton.IsServer ? CryptographyHelper.GetClientKey(clientId) : CryptographyHelper.GetServerKey(); - - if (key == null) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Failed to grab key"); - messageType = MLAPIConstants.INVALID; - return null; - } - - using (HMACSHA256 hmac = new HMACSHA256(key)) - { - byte[] computedHmac = hmac.ComputeHash(inputStream.GetBuffer(), 0, (int)inputStream.Length); - - - if (!CryptographyHelper.ConstTimeArrayEqual(computedHmac, HMAC_BUFFER)) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Received HMAC did not match the computed HMAC"); - messageType = MLAPIConstants.INVALID; - return null; - } - } - } - - if (isEncrypted) - { - int ivRead = inputStream.Read(IV_BUFFER, 0, IV_BUFFER.Length); - - if (ivRead != IV_BUFFER.Length) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogError("Invalid IV size"); - messageType = MLAPIConstants.INVALID; - return null; - } - - PooledBitStream outputStream = PooledBitStream.Get(); - - using (RijndaelManaged rijndael = new RijndaelManaged()) - { - rijndael.IV = IV_BUFFER; - rijndael.Padding = PaddingMode.PKCS7; - - byte[] key = NetworkingManager.Singleton.IsServer ? CryptographyHelper.GetClientKey(clientId) : CryptographyHelper.GetServerKey(); - - if (key == null) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Failed to grab key"); - messageType = MLAPIConstants.INVALID; - return null; - } - - rijndael.Key = key; - - using (CryptoStream cryptoStream = new CryptoStream(outputStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write)) - { - cryptoStream.Write(inputStream.GetBuffer(), (int)inputStream.Position, (int)(inputStream.Length - inputStream.Position)); - } - - outputStream.Position = 0; - - if (outputStream.Length == 0) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogError("The incoming message was too small"); - messageType = MLAPIConstants.INVALID; - return null; - } - - int msgType = outputStream.ReadByte(); - messageType = msgType == -1 ? MLAPIConstants.INVALID : (byte)msgType; - } - - return outputStream; - } - else - { - if (inputStream.Length - inputStream.Position <= 0) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogError("The incoming message was too small"); - messageType = MLAPIConstants.INVALID; - return null; - } - - int msgType = inputStream.ReadByte(); - messageType = msgType == -1 ? MLAPIConstants.INVALID : (byte)msgType; - return inputStream; - } - } - else - { -#endif - messageType = inputHeaderReader.ReadByteBits(6); - // The input stream is now ready to be read from. It's "safe" and has the correct position - return inputStream; -#if !DISABLE_CRYPTOGRAPHY - } -#endif - } - catch (Exception e) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogError("Error while unwrapping headers"); - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError(e.ToString()); - - security = SecuritySendFlags.None; + if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogError("The incoming message was too small"); messageType = MLAPIConstants.INVALID; return null; } + + messageType = inputHeaderReader.ReadByteDirect(); + // The input stream is now ready to be read from. It's "safe" and has the correct position + return inputStream; } } - internal static BitStream WrapMessage(byte messageType, ulong clientId, BitStream messageBody, SecuritySendFlags flags) + internal static BitStream WrapMessage(byte messageType, BitStream messageBody) { - try - { - bool encrypted = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; - bool authenticated = (flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; - - PooledBitStream outStream = PooledBitStream.Get(); - - using (PooledBitWriter outWriter = PooledBitWriter.Get(outStream)) - { - outWriter.WriteBit(encrypted); - outWriter.WriteBit(authenticated); - -#if !DISABLE_CRYPTOGRAPHY - if (authenticated || encrypted) - { - outWriter.WritePadBits(); - long hmacWritePos = outStream.Position; - - if (authenticated) outStream.Write(HMAC_PLACEHOLDER, 0, HMAC_PLACEHOLDER.Length); - - if (encrypted) - { - using (RijndaelManaged rijndael = new RijndaelManaged()) - { - rijndael.GenerateIV(); - rijndael.Padding = PaddingMode.PKCS7; - - byte[] key = NetworkingManager.Singleton.IsServer ? CryptographyHelper.GetClientKey(clientId) : CryptographyHelper.GetServerKey(); + var outStream = PooledBitStream.Get(); - if (key == null) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Failed to grab key"); - return null; - } - - rijndael.Key = key; - - outStream.Write(rijndael.IV); - - using (CryptoStream encryptionStream = new CryptoStream(outStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write)) - { - encryptionStream.WriteByte(messageType); - encryptionStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); - } - } - } - else - { - outStream.WriteByte(messageType); - outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); - } - - if (authenticated) - { - byte[] key = NetworkingManager.Singleton.IsServer ? CryptographyHelper.GetClientKey(clientId) : CryptographyHelper.GetServerKey(); - - if (key == null) - { - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Failed to grab key"); - return null; - } - - using (HMACSHA256 hmac = new HMACSHA256(key)) - { - byte[] computedHmac = hmac.ComputeHash(outStream.GetBuffer(), 0, (int)outStream.Length); - - outStream.Position = hmacWritePos; - outStream.Write(computedHmac, 0, computedHmac.Length); - } - } - } - else - { -#endif - outWriter.WriteBits(messageType, 6); - outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); -#if !DISABLE_CRYPTOGRAPHY - } -#endif - } - - return outStream; - } - catch (Exception e) + using (var outWriter = PooledBitWriter.Get(outStream)) { - if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) NetworkLog.LogError("Error while wrapping headers"); - if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError(e.ToString()); - - return null; + outWriter.WriteByte(messageType); + outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); } + + return outStream; } } -} +} \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcBatcher.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcBatcher.cs index 9da4e77164..b20a23aca9 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcBatcher.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcBatcher.cs @@ -126,17 +126,14 @@ public void QueueItem(in RpcFrameQueueItem queueItem) SendDict[clientId].IsEmpty = false; SendDict[clientId].Channel = queueItem.channel; - SendDict[clientId].Writer.WriteBit(false); // Encrypted - SendDict[clientId].Writer.WriteBit(false); // Authenticated - switch (queueItem.queueItemType) { - // 6 bits are used for the message type, which is an MLAPIConstants + // 8 bits are used for the message type, which is an MLAPIConstants case RpcQueueContainer.QueueItemType.ServerRpc: - SendDict[clientId].Writer.WriteBits(MLAPIConstants.MLAPI_SERVER_RPC, 6); // MessageType + SendDict[clientId].Writer.WriteByte(MLAPIConstants.MLAPI_SERVER_RPC); // MessageType break; case RpcQueueContainer.QueueItemType.ClientRpc: - SendDict[clientId].Writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType + SendDict[clientId].Writer.WriteByte(MLAPIConstants.MLAPI_CLIENT_RPC); // MessageType break; } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/QueueHistoryFrame.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/QueueHistoryFrame.cs index 6fc50c17c0..08ec00fc25 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/QueueHistoryFrame.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/QueueHistoryFrame.cs @@ -82,7 +82,6 @@ private RpcFrameQueueItem GetCurrentQueueItem() { //Write the packed version of the queueItem to our current queue history buffer m_CurrentQueueItem.queueItemType = (RpcQueueContainer.QueueItemType)queueReader.ReadUInt16(); - m_CurrentQueueItem.sendFlags = (Security.SecuritySendFlags)queueReader.ReadUInt16(); m_CurrentQueueItem.timeStamp = queueReader.ReadSingle(); m_CurrentQueueItem.networkId = queueReader.ReadUInt64(); diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcFrameQueueItem.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcFrameQueueItem.cs index 19fd3450f9..2a41e33b56 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcFrameQueueItem.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcFrameQueueItem.cs @@ -1,6 +1,5 @@ using System; using MLAPI.Transports; -using MLAPI.Security; using MLAPI.Serialization.Pooled; namespace MLAPI.Messaging @@ -16,7 +15,6 @@ internal struct RpcFrameQueueItem { public NetworkUpdateStage updateStage; public RpcQueueContainer.QueueItemType queueItemType; - public SecuritySendFlags sendFlags; public ulong networkId; //Sender's network Identifier public Channel channel; public ulong[] clientIds; //Server invoked Client RPCs only diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs index 4bbb342b13..2d1cdab565 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs @@ -286,7 +286,6 @@ internal void AddQueueItemToInboundFrame(QueueItemType qItemType, float timeStam //Write the packed version of the queueItem to our current queue history buffer queueHistoryItem.queueWriter.WriteUInt16((ushort)qItemType); - queueHistoryItem.queueWriter.WriteUInt16((ushort)0); queueHistoryItem.queueWriter.WriteSingle(timeStamp); queueHistoryItem.queueWriter.WriteUInt64(sourceNetworkId); @@ -347,11 +346,10 @@ public QueueHistoryFrame GetLoopBackHistoryFrame(QueueHistoryFrame.QueueFrameTyp /// type of rpc (client or server) /// when it was scheduled to be sent /// the channel to send it on - /// security flags /// who is sending the rpc /// who the rpc is being sent to /// - public PooledBitWriter BeginAddQueueItemToFrame(QueueItemType qItemType, float timeStamp, Channel channel, ushort sendflags, ulong sourceNetworkId, ulong[] targetNetworkIds, + public PooledBitWriter BeginAddQueueItemToFrame(QueueItemType qItemType, float timeStamp, Channel channel, ulong sourceNetworkId, ulong[] targetNetworkIds, QueueHistoryFrame.QueueFrameType queueFrameType, NetworkUpdateStage updateStage) { bool getNextFrame = NetworkingManager.Singleton.IsHost && queueFrameType == QueueHistoryFrame.QueueFrameType.Inbound; @@ -361,7 +359,6 @@ public PooledBitWriter BeginAddQueueItemToFrame(QueueItemType qItemType, float t //Write the packed version of the queueItem to our current queue history buffer queueHistoryItem.queueWriter.WriteUInt16((ushort)qItemType); - queueHistoryItem.queueWriter.WriteUInt16(sendflags); queueHistoryItem.queueWriter.WriteSingle(timeStamp); queueHistoryItem.queueWriter.WriteUInt64(sourceNetworkId); diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueProcessor.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueProcessor.cs index b87c518a86..b1044f3aa0 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueProcessor.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/RpcQueue/RpcQueueProcessor.cs @@ -9,7 +9,7 @@ namespace MLAPI.Messaging { /// /// RpcQueueProcessing - /// Handles processing of RPCQueues + /// Handles processing of RpcQueues /// Inbound to invocation /// Outbound to send /// @@ -128,7 +128,7 @@ public void InternalMessagesSendAndFlush() { foreach (ulong clientId in queueItem.clientIds) { - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_ADD_OBJECT, queueItem.channel, PoolStream, queueItem.sendFlags); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_ADD_OBJECT, queueItem.channel, PoolStream); } PerformanceDataManager.Increment(ProfilerConstants.NumberOfRPCsSent, queueItem.clientIds.Length); @@ -139,7 +139,7 @@ public void InternalMessagesSendAndFlush() { foreach (ulong clientId in queueItem.clientIds) { - InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_DESTROY_OBJECT, queueItem.channel, PoolStream, queueItem.sendFlags); + InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_DESTROY_OBJECT, queueItem.channel, PoolStream); } PerformanceDataManager.Increment(ProfilerConstants.NumberOfRPCsSent, queueItem.clientIds.Length); diff --git a/com.unity.multiplayer.mlapi/Runtime/Profiling/ProfilerConstants.cs b/com.unity.multiplayer.mlapi/Runtime/Profiling/ProfilerConstants.cs index 4eec90f044..2f4254893b 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Profiling/ProfilerConstants.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Profiling/ProfilerConstants.cs @@ -1,6 +1,7 @@ namespace MLAPI.Profiling { - public static class ProfilerConstants { + public static class ProfilerConstants + { public const string NumberOfConnections = nameof(NumberOfConnections); public const string ReceiveTickRate = nameof(ReceiveTickRate); @@ -17,4 +18,4 @@ public static class ProfilerConstants { public const string NumberOfRPCsInQueueSize = nameof(NumberOfRPCsInQueueSize); public const string NumberOfRPCsOutQueueSize = nameof(NumberOfRPCsOutQueueSize); } -} +} \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.multiplayer.mlapi/Runtime/SceneManagement/NetworkSceneManager.cs index f881e1960b..51292bb829 100644 --- a/com.unity.multiplayer.mlapi/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/SceneManagement/NetworkSceneManager.cs @@ -5,7 +5,6 @@ using MLAPI.Exceptions; using MLAPI.Logging; using MLAPI.Messaging; -using MLAPI.Security; using MLAPI.Serialization.Pooled; using MLAPI.Spawning; using UnityEngine; @@ -188,7 +187,7 @@ internal static void OnFirstSceneSwitchSync(uint sceneIndex, Guid switchSceneGui using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteByteArray(switchSceneGuid.ToByteArray()); - InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CLIENT_SWITCH_SCENE_COMPLETED, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CLIENT_SWITCH_SCENE_COMPLETED, Channel.Internal, stream); } } @@ -308,7 +307,7 @@ private static void OnSceneUnloadServer(Guid switchSceneGuid) } } - InternalMessageSender.Send(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId, MLAPIConstants.MLAPI_SWITCH_SCENE, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId, MLAPIConstants.MLAPI_SWITCH_SCENE, Channel.Internal, stream); } } } @@ -431,7 +430,7 @@ private static void OnSceneUnloadClient(Guid switchSceneGuid, Stream objectStrea using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteByteArray(switchSceneGuid.ToByteArray()); - InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CLIENT_SWITCH_SCENE_COMPLETED, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CLIENT_SWITCH_SCENE_COMPLETED, Channel.Internal, stream); } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Security.meta b/com.unity.multiplayer.mlapi/Runtime/Security.meta deleted file mode 100644 index c44e3f9a88..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 435c4695d380c43419e27f63d2afe8e9 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/BigInteger.cs b/com.unity.multiplayer.mlapi/Runtime/Security/BigInteger.cs deleted file mode 100644 index 250a3f9c97..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/BigInteger.cs +++ /dev/null @@ -1,2920 +0,0 @@ -/* - BigInteger Class Version 1.03 - - Copyright (c) 2002 Chew Keong TAN All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, and/or sell copies of the - Software, and to permit persons to whom the Software is furnished to do so, - provided that the above copyright notice(s) and this permission notice appear in - all copies of the Software and that both the above copyright notice(s) and this - permission notice appear in supporting documentation. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT - SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF - CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -#if !DISABLE_CRYPTOGRAPHY -using System; -using System.Security.Cryptography; - -namespace MLAPI.Security -{ - /// - /// This is a BigInteger class. Holds integer that is more than 64-bit (long). - /// - /// - /// This class contains overloaded arithmetic operators(+, -, *, /, %), bitwise operators(&, |) and other - /// operations that can be done with normal integer. It also contains implementation of various prime test. - /// This class also contains methods dealing with cryptography such as generating prime number, generating - /// a coprime number. - /// - - internal class BigInteger - { - // maximum length of the BigInteger in uint (4 bytes) - // change this to suit the required level of precision. - private const int MaxLength = 70; - - // primes smaller than 2000 to test the generated prime number - public static readonly int[] PrimesBelow2000 = - { - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, - 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, - 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, - 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, - 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, - 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, - 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, - 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, - 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, - 1069, - 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, - 1217, 1223, - 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, - 1367, 1373, - 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, - 1499, 1511, - 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, - 1637, 1657, - 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, - 1801, 1811, - 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, - 1979, 1987, - 1993, 1997, 1999 - }; - - private uint[] _data = null; // stores bytes from the Big Integer - public int DataLength; // number of actual chars used - - /// - /// Default constructor for BigInteger of value 0 - /// - public BigInteger() - { - _data = new uint[MaxLength]; - DataLength = 1; - } - - /// - /// Constructor (Default value provided by long) - /// - /// Turn the long value into BigInteger type - public BigInteger(long value) - { - _data = new uint[MaxLength]; - long tempVal = value; - - // copy bytes from long to BigInteger without any assumption of - // the length of the long datatype - DataLength = 0; - while (value != 0 && DataLength < MaxLength) - { - _data[DataLength] = (uint)(value & 0xFFFFFFFF); - value >>= 32; - DataLength++; - } - - if (tempVal > 0) // overflow check for +ve value - { - if (value != 0 || (_data[MaxLength - 1] & 0x80000000) != 0) - throw (new ArithmeticException("Positive overflow in constructor.")); - } - else if (tempVal < 0) // underflow check for -ve value - { - if (value != -1 || (_data[DataLength - 1] & 0x80000000) == 0) - throw (new ArithmeticException("Negative underflow in constructor.")); - } - - if (DataLength == 0) - DataLength = 1; - } - - /// - /// Constructor (Default value provided by ulong) - /// - /// Turn the unsigned long value into BigInteger type - public BigInteger(ulong value) - { - _data = new uint[MaxLength]; - - // copy bytes from ulong to BigInteger without any assumption of - // the length of the ulong datatype - DataLength = 0; - while (value != 0 && DataLength < MaxLength) - { - _data[DataLength] = (uint)(value & 0xFFFFFFFF); - value >>= 32; - DataLength++; - } - - if (value != 0 || (_data[MaxLength - 1] & 0x80000000) != 0) - throw (new ArithmeticException("Positive overflow in constructor.")); - - if (DataLength == 0) - DataLength = 1; - } - - /// - /// Constructor (Default value provided by BigInteger) - /// - /// - public BigInteger(BigInteger bi) - { - _data = new uint[MaxLength]; - - DataLength = bi.DataLength; - - for (int i = 0; i < DataLength; i++) - _data[i] = bi._data[i]; - } - - /// - /// Constructor (Default value provided by a string of digits of the specified base) - /// - /// - /// To initialize "a" with the default value of 1234 in base 10: - /// BigInteger a = new BigInteger("1234", 10) - /// To initialize "a" with the default value of -0x1D4F in base 16: - /// BigInteger a = new BigInteger("-1D4F", 16) - /// - /// - /// String value in the format of [sign][magnitude] - /// The base of value - public BigInteger(string value, int radix = 10) - { - BigInteger multiplier = new BigInteger(1); - BigInteger result = new BigInteger(); - value = (value.ToUpper()).Trim(); - int limit = 0; - - if (value[0] == '-') - limit = 1; - - for (int i = value.Length - 1; i >= limit; i--) - { - int posVal = value[i]; - - if (posVal >= '0' && posVal <= '9') - posVal -= '0'; - else if (posVal >= 'A' && posVal <= 'Z') - posVal = (posVal - 'A') + 10; - else - posVal = 9999999; // arbitrary large - - if (posVal >= radix) - throw (new ArithmeticException("Invalid string in constructor.")); - else - { - if (value[0] == '-') - posVal = -posVal; - - result = result + (multiplier * posVal); - - if ((i - 1) >= limit) - multiplier = multiplier * radix; - } - } - - if (value[0] == '-') // negative values - { - if ((result._data[MaxLength - 1] & 0x80000000) == 0) - throw (new ArithmeticException("Negative underflow in constructor.")); - } - else // positive values - { - if ((result._data[MaxLength - 1] & 0x80000000) != 0) - throw (new ArithmeticException("Positive overflow in constructor.")); - } - - _data = new uint[MaxLength]; - for (int i = 0; i < result.DataLength; i++) - _data[i] = result._data[i]; - - DataLength = result.DataLength; - } - - //*********************************************************************** - // Constructor (Default value provided by an array of bytes) - // - // The lowest index of the input byte array (i.e [0]) should contain the - // most significant byte of the number, and the highest index should - // contain the least significant byte. - // - // E.g. - // To initialize "a" with the default value of 0x1D4F in base 16 - // byte[] temp = { 0x1D, 0x4F }; - // BigInteger a = new BigInteger(temp) - // - // Note that this method of initialization does not allow the - // sign to be specified. - // - //*********************************************************************** - /*public BigInteger(byte[] inData) - { - dataLength = inData.Length >> 2; - - int leftOver = inData.Length & 0x3; - if (leftOver != 0) // length not multiples of 4 - dataLength++; - - if (dataLength > maxLength) - throw (new ArithmeticException("Byte overflow in constructor.")); - - data = new uint[maxLength]; - - for (int i = inData.Length - 1, j = 0; i >= 3; i -= 4, j++) - { - data[j] = ((uint)(inData[i - 3]) << 24) + ((uint)(inData[i - 2]) << 16) + - ((uint)(inData[i - 1] << 8)) + ((uint)(inData[i])); - } - - if (leftOver == 1) - data[dataLength - 1] = (uint)inData[0]; - else if (leftOver == 2) - data[dataLength - 1] = (uint)((inData[0] << 8) + inData[1]); - else if (leftOver == 3) - data[dataLength - 1] = (uint)((inData[0] << 16) + (inData[1] << 8) + inData[2]); - - while (dataLength > 1 && data[dataLength - 1] == 0) - dataLength--; - }*/ - - public BigInteger(byte[] inData) : this((System.Collections.Generic.IList)inData) - { - } - - /// - /// Constructor (Default value provided by an array of bytes of the specified length.) - /// - /// A list of byte values - /// Default -1 - /// Default 0 - public BigInteger(System.Collections.Generic.IList inData, int length = -1, int offset = 0) - { - var inLen = length == -1 ? inData.Count - offset : length; - - DataLength = inLen >> 2; - - int leftOver = inLen & 0x3; - if (leftOver != 0) // length not multiples of 4 - DataLength++; - - if (DataLength > MaxLength || inLen > inData.Count - offset) - throw (new ArithmeticException("Byte overflow in constructor.")); - - _data = new uint[MaxLength]; - - for (int i = inLen - 1, j = 0; i >= 3; i -= 4, j++) - { - _data[j] = (uint)((inData[offset + i - 3] << 24) + (inData[offset + i - 2] << 16) + - (inData[offset + i - 1] << 8) + inData[offset + i]); - } - - if (leftOver == 1) - _data[DataLength - 1] = inData[offset + 0]; - else if (leftOver == 2) - _data[DataLength - 1] = (uint)((inData[offset + 0] << 8) + inData[offset + 1]); - else if (leftOver == 3) - _data[DataLength - 1] = - (uint)((inData[offset + 0] << 16) + (inData[offset + 1] << 8) + inData[offset + 2]); - - if (DataLength == 0) - DataLength = 1; - - while (DataLength > 1 && _data[DataLength - 1] == 0) - DataLength--; - } - - /// - /// Constructor (Default value provided by an array of unsigned integers) - /// - /// Array of unsigned integer - public BigInteger(uint[] inData) - { - DataLength = inData.Length; - - if (DataLength > MaxLength) - throw (new ArithmeticException("Byte overflow in constructor.")); - - _data = new uint[MaxLength]; - - for (int i = DataLength - 1, j = 0; i >= 0; i--, j++) - _data[j] = inData[i]; - - while (DataLength > 1 && _data[DataLength - 1] == 0) - DataLength--; - } - - /// - /// Cast a type long value to type BigInteger value - /// - /// A long value - public static implicit operator BigInteger(long value) - { - return (new BigInteger(value)); - } - - /// - /// Cast a type ulong value to type BigInteger value - /// - /// An unsigned long value - public static implicit operator BigInteger(ulong value) - { - return (new BigInteger(value)); - } - - /// - /// Cast a type int value to type BigInteger value - /// - /// An int value - public static implicit operator BigInteger(int value) - { - return (new BigInteger(value)); - } - - /// - /// Cast a type uint value to type BigInteger value - /// - /// An unsigned int value - public static implicit operator BigInteger(uint value) - { - return (new BigInteger((ulong)value)); - } - - /// - /// Overloading of addition operator - /// - /// First BigInteger - /// Second BigInteger - /// Result of the addition of 2 BigIntegers - public static BigInteger operator +(BigInteger bi1, BigInteger bi2) - { - BigInteger result = new BigInteger() - { - DataLength = (bi1.DataLength > bi2.DataLength) ? bi1.DataLength : bi2.DataLength - }; - - long carry = 0; - for (int i = 0; i < result.DataLength; i++) - { - long sum = bi1._data[i] + (long)bi2._data[i] + carry; - carry = sum >> 32; - result._data[i] = (uint)(sum & 0xFFFFFFFF); - } - - if (carry != 0 && result.DataLength < MaxLength) - { - result._data[result.DataLength] = (uint)(carry); - result.DataLength++; - } - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - // overflow check - int lastPos = MaxLength - 1; - if ((bi1._data[lastPos] & 0x80000000) == (bi2._data[lastPos] & 0x80000000) && - (result._data[lastPos] & 0x80000000) != (bi1._data[lastPos] & 0x80000000)) - { - throw (new ArithmeticException()); - } - - return result; - } - - /// - /// Overloading of the unary ++ operator, which increments BigInteger by 1 - /// - /// A BigInteger - /// Incremented BigInteger - public static BigInteger operator ++(BigInteger bi1) - { - BigInteger result = new BigInteger(bi1); - - long val, carry = 1; - int index = 0; - - while (carry != 0 && index < MaxLength) - { - val = result._data[index]; - val++; - - result._data[index] = (uint)(val & 0xFFFFFFFF); - carry = val >> 32; - - index++; - } - - if (index > result.DataLength) - result.DataLength = index; - else - { - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - } - - // overflow check - int lastPos = MaxLength - 1; - - // overflow if initial value was +ve but ++ caused a sign - // change to negative. - - if ((bi1._data[lastPos] & 0x80000000) == 0 && - (result._data[lastPos] & 0x80000000) != (bi1._data[lastPos] & 0x80000000)) - { - throw (new ArithmeticException("Overflow in ++.")); - } - - return result; - } - - /// - /// Overloading of subtraction operator - /// - /// First BigInteger - /// Second BigInteger - /// Result of the subtraction of 2 BigIntegers - public static BigInteger operator -(BigInteger bi1, BigInteger bi2) - { - BigInteger result = new BigInteger() - { - DataLength = (bi1.DataLength > bi2.DataLength) ? bi1.DataLength : bi2.DataLength - }; - - long carryIn = 0; - for (int i = 0; i < result.DataLength; i++) - { - long diff; - - diff = bi1._data[i] - (long)bi2._data[i] - carryIn; - result._data[i] = (uint)(diff & 0xFFFFFFFF); - - if (diff < 0) - carryIn = 1; - else - carryIn = 0; - } - - // roll over to negative - if (carryIn != 0) - { - for (int i = result.DataLength; i < MaxLength; i++) - result._data[i] = 0xFFFFFFFF; - result.DataLength = MaxLength; - } - - // fixed in v1.03 to give correct datalength for a - (-b) - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - // overflow check - - int lastPos = MaxLength - 1; - if ((bi1._data[lastPos] & 0x80000000) != (bi2._data[lastPos] & 0x80000000) && - (result._data[lastPos] & 0x80000000) != (bi1._data[lastPos] & 0x80000000)) - { - throw (new ArithmeticException()); - } - - return result; - } - - /// - /// Overloading of the unary -- operator, decrements BigInteger by 1 - /// - /// A BigInteger - /// Decremented BigInteger - public static BigInteger operator --(BigInteger bi1) - { - BigInteger result = new BigInteger(bi1); - - long val; - bool carryIn = true; - int index = 0; - - while (carryIn && index < MaxLength) - { - val = result._data[index]; - val--; - - result._data[index] = (uint)(val & 0xFFFFFFFF); - - if (val >= 0) - carryIn = false; - - index++; - } - - if (index > result.DataLength) - result.DataLength = index; - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - // overflow check - int lastPos = MaxLength - 1; - - // overflow if initial value was -ve but -- caused a sign - // change to positive. - - if ((bi1._data[lastPos] & 0x80000000) != 0 && - (result._data[lastPos] & 0x80000000) != (bi1._data[lastPos] & 0x80000000)) - { - throw (new ArithmeticException("Underflow in --.")); - } - - return result; - } - - /// - /// Overloading of multiplication operator - /// - /// First BigInteger - /// Second BigInteger - /// Result of the multiplication of 2 BigIntegers - public static BigInteger operator *(BigInteger bi1, BigInteger bi2) - { - int lastPos = MaxLength - 1; - bool bi1Neg = false, bi2Neg = false; - - // take the absolute value of the inputs - try - { - if ((bi1._data[lastPos] & 0x80000000) != 0) // bi1 negative - { - bi1Neg = true; - bi1 = -bi1; - } - - if ((bi2._data[lastPos] & 0x80000000) != 0) // bi2 negative - { - bi2Neg = true; - bi2 = -bi2; - } - } - catch (Exception) - { - } - - BigInteger result = new BigInteger(); - - // multiply the absolute values - try - { - for (int i = 0; i < bi1.DataLength; i++) - { - if (bi1._data[i] == 0) continue; - - ulong mcarry = 0; - for (int j = 0, k = i; j < bi2.DataLength; j++, k++) - { - // k = i + j - ulong val = (bi1._data[i] * (ulong)bi2._data[j]) + - result._data[k] + mcarry; - - result._data[k] = (uint)(val & 0xFFFFFFFF); - mcarry = (val >> 32); - } - - if (mcarry != 0) - result._data[i + bi2.DataLength] = (uint)mcarry; - } - } - catch (Exception) - { - throw (new ArithmeticException("Multiplication overflow.")); - } - - result.DataLength = bi1.DataLength + bi2.DataLength; - if (result.DataLength > MaxLength) - result.DataLength = MaxLength; - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - // overflow check (result is -ve) - if ((result._data[lastPos] & 0x80000000) != 0) - { - if (bi1Neg != bi2Neg && result._data[lastPos] == 0x80000000) // different sign - { - // handle the special case where multiplication produces - // a max negative number in 2's complement. - - if (result.DataLength == 1) - return result; - else - { - bool isMaxNeg = true; - for (int i = 0; i < result.DataLength - 1 && isMaxNeg; i++) - { - if (result._data[i] != 0) - isMaxNeg = false; - } - - if (isMaxNeg) - return result; - } - } - - throw (new ArithmeticException("Multiplication overflow.")); - } - - // if input has different signs, then result is -ve - if (bi1Neg != bi2Neg) - return -result; - - return result; - } - - /// - /// Overloading of the unary << operator (left shift) - /// - /// - /// Shifting by a negative number is an undefined behaviour (UB). - /// - /// A BigInteger - /// Left shift by shiftVal bit - /// Left-shifted BigInteger - public static BigInteger operator <<(BigInteger bi1, int shiftVal) - { - BigInteger result = new BigInteger(bi1); - result.DataLength = ShiftLeft(result._data, shiftVal); - - return result; - } - - // least significant bits at lower part of buffer - private static int ShiftLeft(uint[] buffer, int shiftVal) - { - int shiftAmount = 32; - int bufLen = buffer.Length; - - while (bufLen > 1 && buffer[bufLen - 1] == 0) - bufLen--; - - for (int count = shiftVal; count > 0;) - { - if (count < shiftAmount) - shiftAmount = count; - - ulong carry = 0; - for (int i = 0; i < bufLen; i++) - { - ulong val = ((ulong)buffer[i]) << shiftAmount; - val |= carry; - - buffer[i] = (uint)(val & 0xFFFFFFFF); - carry = val >> 32; - } - - if (carry != 0) - { - if (bufLen + 1 <= buffer.Length) - { - buffer[bufLen] = (uint)carry; - bufLen++; - } - } - - count -= shiftAmount; - } - - return bufLen; - } - - /// - /// Overloading of the unary >> operator (right shift) - /// - /// - /// Shifting by a negative number is an undefined behaviour (UB). - /// - /// A BigInteger - /// Right shift by shiftVal bit - /// Right-shifted BigInteger - public static BigInteger operator >>(BigInteger bi1, int shiftVal) - { - BigInteger result = new BigInteger(bi1); - result.DataLength = ShiftRight(result._data, shiftVal); - - if ((bi1._data[MaxLength - 1] & 0x80000000) != 0) // negative - { - for (int i = MaxLength - 1; i >= result.DataLength; i--) - result._data[i] = 0xFFFFFFFF; - - uint mask = 0x80000000; - for (int i = 0; i < 32; i++) - { - if ((result._data[result.DataLength - 1] & mask) != 0) - break; - - result._data[result.DataLength - 1] |= mask; - mask >>= 1; - } - - result.DataLength = MaxLength; - } - - return result; - } - - private static int ShiftRight(uint[] buffer, int shiftVal) - { - int shiftAmount = 32; - int invShift = 0; - int bufLen = buffer.Length; - - while (bufLen > 1 && buffer[bufLen - 1] == 0) - bufLen--; - - for (int count = shiftVal; count > 0;) - { - if (count < shiftAmount) - { - shiftAmount = count; - invShift = 32 - shiftAmount; - } - - ulong carry = 0; - for (int i = bufLen - 1; i >= 0; i--) - { - ulong val = ((ulong)buffer[i]) >> shiftAmount; - val |= carry; - - carry = (((ulong)buffer[i]) << invShift) & 0xFFFFFFFF; - buffer[i] = (uint)(val); - } - - count -= shiftAmount; - } - - while (bufLen > 1 && buffer[bufLen - 1] == 0) - bufLen--; - - return bufLen; - } - - /// - /// Overloading of the bit-wise NOT operator (1's complement) - /// - /// A BigInteger - /// Complemented BigInteger - public static BigInteger operator ~(BigInteger bi1) - { - BigInteger result = new BigInteger(bi1); - - for (int i = 0; i < MaxLength; i++) - result._data[i] = ~(bi1._data[i]); - - result.DataLength = MaxLength; - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - return result; - } - - /// - /// Overloading of the NEGATE operator (2's complement) - /// - /// A BigInteger - /// Negated BigInteger or default BigInteger value if bi1 is 0 - public static BigInteger operator -(BigInteger bi1) - { - // handle neg of zero separately since it'll cause an overflow - // if we proceed. - - if (bi1.DataLength == 1 && bi1._data[0] == 0) - return (new BigInteger()); - - BigInteger result = new BigInteger(bi1); - - // 1's complement - for (int i = 0; i < MaxLength; i++) - result._data[i] = ~(bi1._data[i]); - - // add one to result of 1's complement - long val, carry = 1; - int index = 0; - - while (carry != 0 && index < MaxLength) - { - val = result._data[index]; - val++; - - result._data[index] = (uint)(val & 0xFFFFFFFF); - carry = val >> 32; - - index++; - } - - if ((bi1._data[MaxLength - 1] & 0x80000000) == (result._data[MaxLength - 1] & 0x80000000)) - throw (new ArithmeticException("Overflow in negation.\n")); - - result.DataLength = MaxLength; - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - return result; - } - - /// - /// Overloading of equality operator, allows comparing 2 BigIntegers with == operator - /// - /// First BigInteger - /// Second BigInteger - /// Boolean result of the comparison - public static bool operator ==(BigInteger bi1, BigInteger bi2) - { - return object.ReferenceEquals(bi1, bi2) || bi1.Equals(bi2); - } - - /// - /// Overloading of not equal operator, allows comparing 2 BigIntegers with != operator - /// - /// First BigInteger - /// Second BigInteger - /// Boolean result of the comparison - public static bool operator !=(BigInteger bi1, BigInteger bi2) - { - return !object.ReferenceEquals(bi1, bi2) && !(bi1.Equals(bi2)); - } - - /// - /// Overriding of Equals method, allows comparing BigInteger with an arbitary object - /// - /// Input object, to be casted into BigInteger type for comparison - /// Boolean result of the comparison - public override bool Equals(object o) - { - if (object.ReferenceEquals(null, o)) - { - return false; - } - - BigInteger bi = (BigInteger) o; - - - - if (this.DataLength != bi.DataLength) - return false; - - for (int i = 0; i < this.DataLength; i++) - { - if (this._data[i] != bi._data[i]) - return false; - } - - return true; - } - - public override int GetHashCode() - { - return this.ToString().GetHashCode(); - } - - /// - /// Overloading of greater than operator, allows comparing 2 BigIntegers with > operator - /// - /// First BigInteger - /// Second BigInteger - /// Boolean result of the comparison - public static bool operator >(BigInteger bi1, BigInteger bi2) - { - int pos = MaxLength - 1; - - // bi1 is negative, bi2 is positive - if ((bi1._data[pos] & 0x80000000) != 0 && (bi2._data[pos] & 0x80000000) == 0) - return false; - - // bi1 is positive, bi2 is negative - else if ((bi1._data[pos] & 0x80000000) == 0 && (bi2._data[pos] & 0x80000000) != 0) - return true; - - // same sign - int len = (bi1.DataLength > bi2.DataLength) ? bi1.DataLength : bi2.DataLength; - for (pos = len - 1; pos >= 0 && bi1._data[pos] == bi2._data[pos]; pos--) ; - - if (pos >= 0) - { - if (bi1._data[pos] > bi2._data[pos]) - return true; - return false; - } - - return false; - } - - /// - /// Overloading of greater than operator, allows comparing 2 BigIntegers with < operator - /// - /// First BigInteger - /// Second BigInteger - /// Boolean result of the comparison - public static bool operator <(BigInteger bi1, BigInteger bi2) - { - int pos = MaxLength - 1; - - // bi1 is negative, bi2 is positive - if ((bi1._data[pos] & 0x80000000) != 0 && (bi2._data[pos] & 0x80000000) == 0) - return true; - - // bi1 is positive, bi2 is negative - else if ((bi1._data[pos] & 0x80000000) == 0 && (bi2._data[pos] & 0x80000000) != 0) - return false; - - // same sign - int len = (bi1.DataLength > bi2.DataLength) ? bi1.DataLength : bi2.DataLength; - for (pos = len - 1; pos >= 0 && bi1._data[pos] == bi2._data[pos]; pos--) ; - - if (pos >= 0) - { - if (bi1._data[pos] < bi2._data[pos]) - return true; - return false; - } - - return false; - } - - /// - /// Overloading of greater than or equal to operator, allows comparing 2 BigIntegers with >= operator - /// - /// First BigInteger - /// Second BigInteger - /// Boolean result of the comparison - public static bool operator >=(BigInteger bi1, BigInteger bi2) - { - return (bi1 == bi2 || bi1 > bi2); - } - - /// - /// Overloading of less than or equal to operator, allows comparing 2 BigIntegers with <= operator - /// - /// First BigInteger - /// Second BigInteger - /// Boolean result of the comparison - public static bool operator <=(BigInteger bi1, BigInteger bi2) - { - return (bi1 == bi2 || bi1 < bi2); - } - - //*********************************************************************** - // Private function that supports the division of two numbers with - // a divisor that has more than 1 digit. - // - // Algorithm taken from [1] - //*********************************************************************** - private static void MultiByteDivide(BigInteger bi1, BigInteger bi2, - BigInteger outQuotient, BigInteger outRemainder) - { - uint[] result = new uint[MaxLength]; - - int remainderLen = bi1.DataLength + 1; - uint[] remainder = new uint[remainderLen]; - - uint mask = 0x80000000; - uint val = bi2._data[bi2.DataLength - 1]; - int shift = 0, resultPos = 0; - - while (mask != 0 && (val & mask) == 0) - { - shift++; - mask >>= 1; - } - - for (int i = 0; i < bi1.DataLength; i++) - remainder[i] = bi1._data[i]; - ShiftLeft(remainder, shift); - bi2 = bi2 << shift; - - int j = remainderLen - bi2.DataLength; - int pos = remainderLen - 1; - - ulong firstDivisorByte = bi2._data[bi2.DataLength - 1]; - ulong secondDivisorByte = bi2._data[bi2.DataLength - 2]; - - int divisorLen = bi2.DataLength + 1; - uint[] dividendPart = new uint[divisorLen]; - - while (j > 0) - { - ulong dividend = ((ulong)remainder[pos] << 32) + remainder[pos - 1]; - - ulong qHat = dividend / firstDivisorByte; - ulong rHat = dividend % firstDivisorByte; - - bool done = false; - while (!done) - { - done = true; - - if (qHat == 0x100000000 || - (qHat * secondDivisorByte) > ((rHat << 32) + remainder[pos - 2])) - { - qHat--; - rHat += firstDivisorByte; - - if (rHat < 0x100000000) - done = false; - } - } - - for (int h = 0; h < divisorLen; h++) - dividendPart[h] = remainder[pos - h]; - - BigInteger kk = new BigInteger(dividendPart); - BigInteger ss = bi2 * (long)qHat; - - while (ss > kk) - { - qHat--; - ss -= bi2; - } - - BigInteger yy = kk - ss; - - for (int h = 0; h < divisorLen; h++) - remainder[pos - h] = yy._data[bi2.DataLength - h]; - - result[resultPos++] = (uint)qHat; - - pos--; - j--; - } - - outQuotient.DataLength = resultPos; - int y = 0; - for (int x = outQuotient.DataLength - 1; x >= 0; x--, y++) - outQuotient._data[y] = result[x]; - for (; y < MaxLength; y++) - outQuotient._data[y] = 0; - - while (outQuotient.DataLength > 1 && outQuotient._data[outQuotient.DataLength - 1] == 0) - outQuotient.DataLength--; - - if (outQuotient.DataLength == 0) - outQuotient.DataLength = 1; - - outRemainder.DataLength = ShiftRight(remainder, shift); - - for (y = 0; y < outRemainder.DataLength; y++) - outRemainder._data[y] = remainder[y]; - for (; y < MaxLength; y++) - outRemainder._data[y] = 0; - } - - //*********************************************************************** - // Private function that supports the division of two numbers with - // a divisor that has only 1 digit. - //*********************************************************************** - private static void SingleByteDivide(BigInteger bi1, BigInteger bi2, - BigInteger outQuotient, BigInteger outRemainder) - { - uint[] result = new uint[MaxLength]; - int resultPos = 0; - - // copy dividend to reminder - for (int i = 0; i < MaxLength; i++) - outRemainder._data[i] = bi1._data[i]; - outRemainder.DataLength = bi1.DataLength; - - while (outRemainder.DataLength > 1 && outRemainder._data[outRemainder.DataLength - 1] == 0) - outRemainder.DataLength--; - - ulong divisor = bi2._data[0]; - int pos = outRemainder.DataLength - 1; - ulong dividend = outRemainder._data[pos]; - - if (dividend >= divisor) - { - ulong quotient = dividend / divisor; - result[resultPos++] = (uint)quotient; - - outRemainder._data[pos] = (uint)(dividend % divisor); - } - - pos--; - - while (pos >= 0) - { - dividend = ((ulong)outRemainder._data[pos + 1] << 32) + outRemainder._data[pos]; - ulong quotient = dividend / divisor; - result[resultPos++] = (uint)quotient; - - outRemainder._data[pos + 1] = 0; - outRemainder._data[pos--] = (uint)(dividend % divisor); - } - - outQuotient.DataLength = resultPos; - int j = 0; - for (int i = outQuotient.DataLength - 1; i >= 0; i--, j++) - outQuotient._data[j] = result[i]; - for (; j < MaxLength; j++) - outQuotient._data[j] = 0; - - while (outQuotient.DataLength > 1 && outQuotient._data[outQuotient.DataLength - 1] == 0) - outQuotient.DataLength--; - - if (outQuotient.DataLength == 0) - outQuotient.DataLength = 1; - - while (outRemainder.DataLength > 1 && outRemainder._data[outRemainder.DataLength - 1] == 0) - outRemainder.DataLength--; - } - - /// - /// Overloading of division operator - /// - /// The dataLength of the divisor's absolute value must be less than maxLength - /// Dividend - /// Divisor - /// Quotient of the division - public static BigInteger operator /(BigInteger bi1, BigInteger bi2) - { - BigInteger quotient = new BigInteger(); - BigInteger remainder = new BigInteger(); - - int lastPos = MaxLength - 1; - bool divisorNeg = false, dividendNeg = false; - - if ((bi1._data[lastPos] & 0x80000000) != 0) // bi1 negative - { - bi1 = -bi1; - dividendNeg = true; - } - - if ((bi2._data[lastPos] & 0x80000000) != 0) // bi2 negative - { - bi2 = -bi2; - divisorNeg = true; - } - - if (bi1 < bi2) - { - return quotient; - } - else - { - if (bi2.DataLength == 1) - SingleByteDivide(bi1, bi2, quotient, remainder); - else - MultiByteDivide(bi1, bi2, quotient, remainder); - - if (dividendNeg != divisorNeg) - return -quotient; - - return quotient; - } - } - - /// - /// Overloading of modulus operator - /// - /// The dataLength of the divisor's absolute value must be less than maxLength - /// Dividend - /// Divisor - /// Remainder of the division - public static BigInteger operator %(BigInteger bi1, BigInteger bi2) - { - BigInteger quotient = new BigInteger(); - BigInteger remainder = new BigInteger(bi1); - - int lastPos = MaxLength - 1; - bool dividendNeg = false; - - if ((bi1._data[lastPos] & 0x80000000) != 0) // bi1 negative - { - bi1 = -bi1; - dividendNeg = true; - } - - if ((bi2._data[lastPos] & 0x80000000) != 0) // bi2 negative - bi2 = -bi2; - - if (bi1 < bi2) - { - return remainder; - } - else - { - if (bi2.DataLength == 1) - SingleByteDivide(bi1, bi2, quotient, remainder); - else - MultiByteDivide(bi1, bi2, quotient, remainder); - - if (dividendNeg) - return -remainder; - - return remainder; - } - } - - /// - /// Overloading of bitwise AND operator - /// - /// First BigInteger - /// Second BigInteger - /// BigInteger result after performing & operation - public static BigInteger operator &(BigInteger bi1, BigInteger bi2) - { - BigInteger result = new BigInteger(); - - int len = (bi1.DataLength > bi2.DataLength) ? bi1.DataLength : bi2.DataLength; - - for (int i = 0; i < len; i++) - { - uint sum = bi1._data[i] & bi2._data[i]; - result._data[i] = sum; - } - - result.DataLength = MaxLength; - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - return result; - } - - /// - /// Overloading of bitwise OR operator - /// - /// First BigInteger - /// Second BigInteger - /// BigInteger result after performing | operation - public static BigInteger operator |(BigInteger bi1, BigInteger bi2) - { - BigInteger result = new BigInteger(); - - int len = (bi1.DataLength > bi2.DataLength) ? bi1.DataLength : bi2.DataLength; - - for (int i = 0; i < len; i++) - { - uint sum = bi1._data[i] | bi2._data[i]; - result._data[i] = sum; - } - - result.DataLength = MaxLength; - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - return result; - } - - /// - /// Overloading of bitwise XOR operator - /// - /// First BigInteger - /// Second BigInteger - /// BigInteger result after performing ^ operation - public static BigInteger operator ^(BigInteger bi1, BigInteger bi2) - { - BigInteger result = new BigInteger(); - - int len = (bi1.DataLength > bi2.DataLength) ? bi1.DataLength : bi2.DataLength; - - for (int i = 0; i < len; i++) - { - uint sum = bi1._data[i] ^ bi2._data[i]; - result._data[i] = sum; - } - - result.DataLength = MaxLength; - - while (result.DataLength > 1 && result._data[result.DataLength - 1] == 0) - result.DataLength--; - - return result; - } - - /// - /// Compare this and a BigInteger and find the maximum one - /// - /// BigInteger to be compared with this - /// The bigger value of this and bi - public BigInteger Max(BigInteger bi) - { - if (this > bi) - return (new BigInteger(this)); - else - return (new BigInteger(bi)); - } - - /// - /// Compare this and a BigInteger and find the minimum one - /// - /// BigInteger to be compared with this - /// The smaller value of this and bi - public BigInteger Min(BigInteger bi) - { - if (this < bi) - return (new BigInteger(this)); - else - return (new BigInteger(bi)); - } - - /// - /// Returns the absolute value - /// - /// Absolute value of this - public BigInteger Abs() - { - if ((this._data[MaxLength - 1] & 0x80000000) != 0) - return (-this); - else - return (new BigInteger(this)); - } - - /// - /// Returns a string representing the BigInteger in base 10 - /// - /// string representation of the BigInteger - public override string ToString() - { - return ToString(10); - } - - /// - /// Returns a string representing the BigInteger in [sign][magnitude] format in the specified radix - /// - /// If the value of BigInteger is -255 in base 10, then ToString(16) returns "-FF" - /// Base - /// string representation of the BigInteger in [sign][magnitude] format - public string ToString(int radix) - { - if (radix < 2 || radix > 36) - throw (new ArgumentException("Radix must be >= 2 and <= 36")); - - string charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - string result = ""; - - BigInteger a = this; - - bool negative = false; - if ((a._data[MaxLength - 1] & 0x80000000) != 0) - { - negative = true; - try - { - a = -a; - } - catch (Exception) - { - } - } - - BigInteger quotient = new BigInteger(); - BigInteger remainder = new BigInteger(); - BigInteger biRadix = new BigInteger(radix); - - if (a.DataLength == 1 && a._data[0] == 0) - result = "0"; - else - { - while (a.DataLength > 1 || (a.DataLength == 1 && a._data[0] != 0)) - { - SingleByteDivide(a, biRadix, quotient, remainder); - - if (remainder._data[0] < 10) - result = remainder._data[0] + result; - else - result = charSet[(int)remainder._data[0] - 10] + result; - - a = quotient; - } - - if (negative) - result = "-" + result; - } - - return result; - } - - /// - /// Returns a hex string showing the contains of the BigInteger - /// - /// - /// 1) If the value of BigInteger is 255 in base 10, then ToHexString() returns "FF" - /// 2) If the value of BigInteger is -255 in base 10, thenToHexString() returns ".....FFFFFFFFFF01", which is the 2's complement representation of -255. - /// - /// - public string ToHexString() - { - string result = _data[DataLength - 1].ToString("X"); - - for (int i = DataLength - 2; i >= 0; i--) - { - result += _data[i].ToString("X8"); - } - - return result; - } - - /// - /// Modulo Exponentiation - /// - /// Exponential - /// Modulo - /// BigInteger result of raising this to the power of exp and then modulo n - public BigInteger ModPow(BigInteger exp, BigInteger n) - { - if ((exp._data[MaxLength - 1] & 0x80000000) != 0) - throw (new ArithmeticException("Positive exponents only.")); - - BigInteger resultNum = 1; - BigInteger tempNum; - bool thisNegative = false; - - if ((this._data[MaxLength - 1] & 0x80000000) != 0) // negative this - { - tempNum = -this % n; - thisNegative = true; - } - else - tempNum = this % n; // ensures (tempNum * tempNum) < b^(2k) - - if ((n._data[MaxLength - 1] & 0x80000000) != 0) // negative n - n = -n; - - // calculate constant = b^(2k) / m - BigInteger constant = new BigInteger(); - - int i = n.DataLength << 1; - constant._data[i] = 0x00000001; - constant.DataLength = i + 1; - - constant = constant / n; - int totalBits = exp.BitCount(); - int count = 0; - - // perform squaring and multiply exponentiation - for (int pos = 0; pos < exp.DataLength; pos++) - { - uint mask = 0x01; - - for (int index = 0; index < 32; index++) - { - if ((exp._data[pos] & mask) != 0) - resultNum = BarrettReduction(resultNum * tempNum, n, constant); - - mask <<= 1; - - tempNum = BarrettReduction(tempNum * tempNum, n, constant); - - if (tempNum.DataLength == 1 && tempNum._data[0] == 1) - { - if (thisNegative && (exp._data[0] & 0x1) != 0) //odd exp - return -resultNum; - return resultNum; - } - - count++; - if (count == totalBits) - break; - } - } - - if (thisNegative && (exp._data[0] & 0x1) != 0) //odd exp - return -resultNum; - - return resultNum; - } - - /// - /// Fast calculation of modular reduction using Barrett's reduction - /// - /// - /// Requires x < b^(2k), where b is the base. In this case, base is 2^32 (uint). - /// - /// Reference [4] - /// - /// - /// - /// - /// - private BigInteger BarrettReduction(BigInteger x, BigInteger n, BigInteger constant) - { - int k = n.DataLength, - kPlusOne = k + 1, - kMinusOne = k - 1; - - BigInteger q1 = new BigInteger(); - - // q1 = x / b^(k-1) - for (int i = kMinusOne, j = 0; i < x.DataLength; i++, j++) - q1._data[j] = x._data[i]; - q1.DataLength = x.DataLength - kMinusOne; - if (q1.DataLength <= 0) - q1.DataLength = 1; - - BigInteger q2 = q1 * constant; - BigInteger q3 = new BigInteger(); - - // q3 = q2 / b^(k+1) - for (int i = kPlusOne, j = 0; i < q2.DataLength; i++, j++) - q3._data[j] = q2._data[i]; - q3.DataLength = q2.DataLength - kPlusOne; - if (q3.DataLength <= 0) - q3.DataLength = 1; - - // r1 = x mod b^(k+1) - // i.e. keep the lowest (k+1) words - BigInteger r1 = new BigInteger(); - int lengthToCopy = (x.DataLength > kPlusOne) ? kPlusOne : x.DataLength; - for (int i = 0; i < lengthToCopy; i++) - r1._data[i] = x._data[i]; - r1.DataLength = lengthToCopy; - - // r2 = (q3 * n) mod b^(k+1) - // partial multiplication of q3 and n - - BigInteger r2 = new BigInteger(); - for (int i = 0; i < q3.DataLength; i++) - { - if (q3._data[i] == 0) continue; - - ulong mcarry = 0; - int t = i; - for (int j = 0; j < n.DataLength && t < kPlusOne; j++, t++) - { - // t = i + j - ulong val = (q3._data[i] * (ulong)n._data[j]) + - r2._data[t] + mcarry; - - r2._data[t] = (uint)(val & 0xFFFFFFFF); - mcarry = (val >> 32); - } - - if (t < kPlusOne) - r2._data[t] = (uint)mcarry; - } - - r2.DataLength = kPlusOne; - while (r2.DataLength > 1 && r2._data[r2.DataLength - 1] == 0) - r2.DataLength--; - - r1 -= r2; - if ((r1._data[MaxLength - 1] & 0x80000000) != 0) // negative - { - BigInteger val = new BigInteger(); - val._data[kPlusOne] = 0x00000001; - val.DataLength = kPlusOne + 1; - r1 += val; - } - - while (r1 >= n) - r1 -= n; - - return r1; - } - - /// - /// Returns gcd(this, bi) - /// - /// - /// Greatest Common Divisor of this and bi - public BigInteger Gcd(BigInteger bi) - { - BigInteger x; - BigInteger y; - - if ((_data[MaxLength - 1] & 0x80000000) != 0) // negative - x = -this; - else - x = this; - - if ((bi._data[MaxLength - 1] & 0x80000000) != 0) // negative - y = -bi; - else - y = bi; - - BigInteger g = y; - - while (x.DataLength > 1 || (x.DataLength == 1 && x._data[0] != 0)) - { - g = x; - x = y % x; - y = g; - } - - return g; - } - - /// - /// Populates "this" with the specified amount of random bits - /// - /// - /// - public void GenRandomBits(int bits, Random rand) - { - int dwords = bits >> 5; - int remBits = bits & 0x1F; - - if (remBits != 0) - dwords++; - - if (dwords > MaxLength || bits <= 0) - throw (new ArithmeticException("Number of required bits is not valid.")); - - byte[] randBytes = new byte[dwords * 4]; - rand.NextBytes(randBytes); - - for (int i = 0; i < dwords; i++) - _data[i] = BitConverter.ToUInt32(randBytes, i * 4); - - for (int i = dwords; i < MaxLength; i++) - _data[i] = 0; - - if (remBits != 0) - { - uint mask; - - if (bits != 1) - { - mask = (uint)(0x01 << (remBits - 1)); - _data[dwords - 1] |= mask; - } - - mask = 0xFFFFFFFF >> (32 - remBits); - _data[dwords - 1] &= mask; - } - else - _data[dwords - 1] |= 0x80000000; - - DataLength = dwords; - - if (DataLength == 0) - DataLength = 1; - } - - /// - /// Populates "this" with the specified amount of random bits (secured version) - /// - /// - /// - public void GenRandomBits(int bits, RNGCryptoServiceProvider rng) - { - int dwords = bits >> 5; - int remBits = bits & 0x1F; - - if (remBits != 0) - dwords++; - - if (dwords > MaxLength || bits <= 0) - throw (new ArithmeticException("Number of required bits is not valid.")); - - byte[] randomBytes = new byte[dwords * 4]; - rng.GetBytes(randomBytes); - - for (int i = 0; i < dwords; i++) - _data[i] = BitConverter.ToUInt32(randomBytes, i * 4); - - for (int i = dwords; i < MaxLength; i++) - _data[i] = 0; - - if (remBits != 0) - { - uint mask; - - if (bits != 1) - { - mask = (uint)(0x01 << (remBits - 1)); - _data[dwords - 1] |= mask; - } - - mask = 0xFFFFFFFF >> (32 - remBits); - _data[dwords - 1] &= mask; - } - else - _data[dwords - 1] |= 0x80000000; - - DataLength = dwords; - - if (DataLength == 0) - DataLength = 1; - } - - /// - /// Returns the position of the most significant bit in the BigInteger - /// - /// - /// 1) The result is 1, if the value of BigInteger is 0...0000 0000 - /// 2) The result is 1, if the value of BigInteger is 0...0000 0001 - /// 3) The result is 2, if the value of BigInteger is 0...0000 0010 - /// 4) The result is 2, if the value of BigInteger is 0...0000 0011 - /// 5) The result is 5, if the value of BigInteger is 0...0001 0011 - /// - /// - public int BitCount() - { - while (DataLength > 1 && _data[DataLength - 1] == 0) - DataLength--; - - uint value = _data[DataLength - 1]; - uint mask = 0x80000000; - int bits = 32; - - while (bits > 0 && (value & mask) == 0) - { - bits--; - mask >>= 1; - } - - bits += ((DataLength - 1) << 5); - - return bits == 0 ? 1 : bits; - } - - /// - /// Probabilistic prime test based on Fermat's little theorem - /// - /// - /// for any a < p (p does not divide a) if - /// a^(p-1) mod p != 1 then p is not prime. - /// - /// Otherwise, p is probably prime (pseudoprime to the chosen base). - /// - /// This method is fast but fails for Carmichael numbers when the randomly chosen base is a factor of the number. - /// - /// Number of chosen bases - /// True if this is a pseudoprime to randomly chosen bases - public bool FermatLittleTest(int confidence) - { - BigInteger thisVal; - if ((this._data[MaxLength - 1] & 0x80000000) != 0) // negative - thisVal = -this; - else - thisVal = this; - - if (thisVal.DataLength == 1) - { - // test small numbers - if (thisVal._data[0] == 0 || thisVal._data[0] == 1) - return false; - else if (thisVal._data[0] == 2 || thisVal._data[0] == 3) - return true; - } - - if ((thisVal._data[0] & 0x1) == 0) // even numbers - return false; - - int bits = thisVal.BitCount(); - BigInteger a = new BigInteger(); - BigInteger pSub1 = thisVal - (new BigInteger(1)); - Random rand = new Random(); - - for (int round = 0; round < confidence; round++) - { - bool done = false; - - while (!done) // generate a < n - { - int testBits = 0; - - // make sure "a" has at least 2 bits - while (testBits < 2) - testBits = (int)(rand.NextDouble() * bits); - - a.GenRandomBits(testBits, rand); - - int byteLen = a.DataLength; - - // make sure "a" is not 0 - if (byteLen > 1 || (byteLen == 1 && a._data[0] != 1)) - done = true; - } - - // check whether a factor exists (fix for version 1.03) - BigInteger gcdTest = a.Gcd(thisVal); - if (gcdTest.DataLength == 1 && gcdTest._data[0] != 1) - return false; - - // calculate a^(p-1) mod p - BigInteger expResult = a.ModPow(pSub1, thisVal); - - int resultLen = expResult.DataLength; - - // is NOT prime is a^(p-1) mod p != 1 - - if (resultLen > 1 || (resultLen == 1 && expResult._data[0] != 1)) - return false; - } - - return true; - } - - /// - /// Probabilistic prime test based on Rabin-Miller's - /// - /// - /// for any p > 0 with p - 1 = 2^s * t - /// - /// p is probably prime (strong pseudoprime) if for any a < p, - /// 1) a^t mod p = 1 or - /// 2) a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 - /// - /// Otherwise, p is composite. - /// - /// Number of chosen bases - /// True if this is a strong pseudoprime to randomly chosen bases - public bool RabinMillerTest(int confidence) - { - BigInteger thisVal; - if ((this._data[MaxLength - 1] & 0x80000000) != 0) // negative - thisVal = -this; - else - thisVal = this; - - if (thisVal.DataLength == 1) - { - // test small numbers - if (thisVal._data[0] == 0 || thisVal._data[0] == 1) - return false; - else if (thisVal._data[0] == 2 || thisVal._data[0] == 3) - return true; - } - - if ((thisVal._data[0] & 0x1) == 0) // even numbers - return false; - - // calculate values of s and t - BigInteger pSub1 = thisVal - (new BigInteger(1)); - int s = 0; - - for (int index = 0; index < pSub1.DataLength; index++) - { - uint mask = 0x01; - - for (int i = 0; i < 32; i++) - { - if ((pSub1._data[index] & mask) != 0) - { - index = pSub1.DataLength; // to break the outer loop - break; - } - - mask <<= 1; - s++; - } - } - - BigInteger t = pSub1 >> s; - - int bits = thisVal.BitCount(); - BigInteger a = new BigInteger(); - Random rand = new Random(); - - for (int round = 0; round < confidence; round++) - { - bool done = false; - - while (!done) // generate a < n - { - int testBits = 0; - - // make sure "a" has at least 2 bits - while (testBits < 2) - testBits = (int)(rand.NextDouble() * bits); - - a.GenRandomBits(testBits, rand); - - int byteLen = a.DataLength; - - // make sure "a" is not 0 - if (byteLen > 1 || (byteLen == 1 && a._data[0] != 1)) - done = true; - } - - // check whether a factor exists (fix for version 1.03) - BigInteger gcdTest = a.Gcd(thisVal); - if (gcdTest.DataLength == 1 && gcdTest._data[0] != 1) - return false; - - BigInteger b = a.ModPow(t, thisVal); - - bool result = false; - - if (b.DataLength == 1 && b._data[0] == 1) // a^t mod p = 1 - result = true; - - for (int j = 0; result == false && j < s; j++) - { - if (b == pSub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 - { - result = true; - break; - } - - b = (b * b) % thisVal; - } - - if (result == false) - return false; - } - - return true; - } - - /// - /// Probabilistic prime test based on Solovay-Strassen (Euler Criterion) - /// - /// - /// p is probably prime if for any a < p (a is not multiple of p), - /// a^((p-1)/2) mod p = J(a, p) - /// - /// where J is the Jacobi symbol. - /// - /// Otherwise, p is composite. - /// - /// Number of chosen bases - /// True if this is a Euler pseudoprime to randomly chosen bases - public bool SolovayStrassenTest(int confidence) - { - BigInteger thisVal; - if ((this._data[MaxLength - 1] & 0x80000000) != 0) // negative - thisVal = -this; - else - thisVal = this; - - if (thisVal.DataLength == 1) - { - // test small numbers - if (thisVal._data[0] == 0 || thisVal._data[0] == 1) - return false; - else if (thisVal._data[0] == 2 || thisVal._data[0] == 3) - return true; - } - - if ((thisVal._data[0] & 0x1) == 0) // even numbers - return false; - - int bits = thisVal.BitCount(); - BigInteger a = new BigInteger(); - BigInteger pSub1 = thisVal - 1; - BigInteger pSub1Shift = pSub1 >> 1; - - Random rand = new Random(); - - for (int round = 0; round < confidence; round++) - { - bool done = false; - - while (!done) // generate a < n - { - int testBits = 0; - - // make sure "a" has at least 2 bits - while (testBits < 2) - testBits = (int)(rand.NextDouble() * bits); - - a.GenRandomBits(testBits, rand); - - int byteLen = a.DataLength; - - // make sure "a" is not 0 - if (byteLen > 1 || (byteLen == 1 && a._data[0] != 1)) - done = true; - } - - // check whether a factor exists (fix for version 1.03) - BigInteger gcdTest = a.Gcd(thisVal); - if (gcdTest.DataLength == 1 && gcdTest._data[0] != 1) - return false; - - // calculate a^((p-1)/2) mod p - - BigInteger expResult = a.ModPow(pSub1Shift, thisVal); - if (expResult == pSub1) - expResult = -1; - - // calculate Jacobi symbol - BigInteger jacob = Jacobi(a, thisVal); - - // if they are different then it is not prime - if (expResult != jacob) - return false; - } - - return true; - } - - /// - /// Implementation of the Lucas Strong Pseudo Prime test - /// - /// - /// Let n be an odd number with gcd(n,D) = 1, and n - J(D, n) = 2^s * d - /// with d odd and s >= 0. - /// - /// If Ud mod n = 0 or V2^r*d mod n = 0 for some 0 <= r < s, then n - /// is a strong Lucas pseudoprime with parameters (P, Q). We select - /// P and Q based on Selfridge. - /// - /// True if number is a strong Lucus pseudo prime - public bool LucasStrongTest() - { - BigInteger thisVal; - if ((this._data[MaxLength - 1] & 0x80000000) != 0) // negative - thisVal = -this; - else - thisVal = this; - - if (thisVal.DataLength == 1) - { - // test small numbers - if (thisVal._data[0] == 0 || thisVal._data[0] == 1) - return false; - else if (thisVal._data[0] == 2 || thisVal._data[0] == 3) - return true; - } - - if ((thisVal._data[0] & 0x1) == 0) // even numbers - return false; - - return LucasStrongTestHelper(thisVal); - } - - private bool LucasStrongTestHelper(BigInteger thisVal) - { - // Do the test (selects D based on Selfridge) - // Let D be the first element of the sequence - // 5, -7, 9, -11, 13, ... for which J(D,n) = -1 - // Let P = 1, Q = (1-D) / 4 - - long d = 5, sign = -1, dCount = 0; - bool done = false; - - while (!done) - { - int jresult = BigInteger.Jacobi(d, thisVal); - - if (jresult == -1) - done = true; // J(D, this) = 1 - else - { - if (jresult == 0 && Math.Abs(d) < thisVal) // divisor found - return false; - - if (dCount == 20) - { - // check for square - BigInteger root = thisVal.Sqrt(); - if (root * root == thisVal) - return false; - } - - d = (Math.Abs(d) + 2) * sign; - sign = -sign; - } - - dCount++; - } - - long q = (1 - d) >> 2; - - BigInteger pAdd1 = thisVal + 1; - int s = 0; - - for (int index = 0; index < pAdd1.DataLength; index++) - { - uint mask = 0x01; - - for (int i = 0; i < 32; i++) - { - if ((pAdd1._data[index] & mask) != 0) - { - index = pAdd1.DataLength; // to break the outer loop - break; - } - - mask <<= 1; - s++; - } - } - - BigInteger t = pAdd1 >> s; - - // calculate constant = b^(2k) / m - // for Barrett Reduction - BigInteger constant = new BigInteger(); - - int nLen = thisVal.DataLength << 1; - constant._data[nLen] = 0x00000001; - constant.DataLength = nLen + 1; - - constant = constant / thisVal; - - BigInteger[] lucas = LucasSequenceHelper(1, q, t, thisVal, constant, 0); - bool isPrime = false; - - if ((lucas[0].DataLength == 1 && lucas[0]._data[0] == 0) || - (lucas[1].DataLength == 1 && lucas[1]._data[0] == 0)) - { - // u(t) = 0 or V(t) = 0 - isPrime = true; - } - - for (int i = 1; i < s; i++) - { - if (!isPrime) - { - // doubling of index - lucas[1] = thisVal.BarrettReduction(lucas[1] * lucas[1], thisVal, constant); - lucas[1] = (lucas[1] - (lucas[2] << 1)) % thisVal; - - if ((lucas[1].DataLength == 1 && lucas[1]._data[0] == 0)) - isPrime = true; - } - - lucas[2] = thisVal.BarrettReduction(lucas[2] * lucas[2], thisVal, constant); //Q^k - } - - if (isPrime) // additional checks for composite numbers - { - // If n is prime and gcd(n, Q) == 1, then - // Q^((n+1)/2) = Q * Q^((n-1)/2) is congruent to (Q * J(Q, n)) mod n - - BigInteger g = thisVal.Gcd(q); - if (g.DataLength == 1 && g._data[0] == 1) // gcd(this, Q) == 1 - { - if ((lucas[2]._data[MaxLength - 1] & 0x80000000) != 0) - lucas[2] += thisVal; - - BigInteger temp = (q * BigInteger.Jacobi(q, thisVal)) % thisVal; - if ((temp._data[MaxLength - 1] & 0x80000000) != 0) - temp += thisVal; - - if (lucas[2] != temp) - isPrime = false; - } - } - - return isPrime; - } - - /// - /// Determines whether a number is probably prime using the Rabin-Miller's test - /// - /// - /// Before applying the test, the number is tested for divisibility by primes < 2000 - /// - /// Number of chosen bases - /// True if this is probably prime - public bool IsProbablePrime(int confidence) - { - BigInteger thisVal; - if ((this._data[MaxLength - 1] & 0x80000000) != 0) // negative - thisVal = -this; - else - thisVal = this; - - // test for divisibility by primes < 2000 - for (int p = 0; p < PrimesBelow2000.Length; p++) - { - BigInteger divisor = PrimesBelow2000[p]; - - if (divisor >= thisVal) - break; - - BigInteger resultNum = thisVal % divisor; - if (resultNum.IntValue() == 0) - return false; - } - - if (thisVal.RabinMillerTest(confidence)) - return true; - else - return false; - } - - /// - /// Determines whether this BigInteger is probably prime using a combination of base 2 strong pseudoprime test and Lucas strong pseudoprime test - /// - /// - /// The sequence of the primality test is as follows, - /// - /// 1) Trial divisions are carried out using prime numbers below 2000. - /// if any of the primes divides this BigInteger, then it is not prime. - /// - /// 2) Perform base 2 strong pseudoprime test. If this BigInteger is a - /// base 2 strong pseudoprime, proceed on to the next step. - /// - /// 3) Perform strong Lucas pseudoprime test. - /// - /// For a detailed discussion of this primality test, see [6]. - /// - /// True if this is probably prime - public bool IsProbablePrime() - { - BigInteger thisVal; - if ((this._data[MaxLength - 1] & 0x80000000) != 0) // negative - thisVal = -this; - else - thisVal = this; - - if (thisVal.DataLength == 1) - { - // test small numbers - if (thisVal._data[0] == 0 || thisVal._data[0] == 1) - return false; - else if (thisVal._data[0] == 2 || thisVal._data[0] == 3) - return true; - } - - if ((thisVal._data[0] & 0x1) == 0) // even numbers - return false; - - // test for divisibility by primes < 2000 - for (int p = 0; p < PrimesBelow2000.Length; p++) - { - BigInteger divisor = PrimesBelow2000[p]; - - if (divisor >= thisVal) - break; - - BigInteger resultNum = thisVal % divisor; - if (resultNum.IntValue() == 0) - return false; - } - - // Perform BASE 2 Rabin-Miller Test - - // calculate values of s and t - BigInteger pSub1 = thisVal - (new BigInteger(1)); - int s = 0; - - for (int index = 0; index < pSub1.DataLength; index++) - { - uint mask = 0x01; - - for (int i = 0; i < 32; i++) - { - if ((pSub1._data[index] & mask) != 0) - { - index = pSub1.DataLength; // to break the outer loop - break; - } - - mask <<= 1; - s++; - } - } - - BigInteger t = pSub1 >> s; - - int bits = thisVal.BitCount(); - BigInteger a = 2; - - // b = a^t mod p - BigInteger b = a.ModPow(t, thisVal); - bool result = false; - - if (b.DataLength == 1 && b._data[0] == 1) // a^t mod p = 1 - result = true; - - for (int j = 0; result == false && j < s; j++) - { - if (b == pSub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 - { - result = true; - break; - } - - b = (b * b) % thisVal; - } - - // if number is strong pseudoprime to base 2, then do a strong lucas test - if (result) - result = LucasStrongTestHelper(thisVal); - - return result; - } - - /// - /// Returns the lowest 4 bytes of the BigInteger as an int - /// - /// Lowest 4 bytes as integer - public int IntValue() - { - return (int)_data[0]; - } - - /// - /// Returns the lowest 8 bytes of the BigInteger as a long - /// - /// Lowest 8 bytes as long - public long LongValue() - { - long val = 0; - - val = _data[0]; - try - { - // exception if maxLength = 1 - val |= (long)_data[1] << 32; - } - catch (Exception) - { - if ((_data[0] & 0x80000000) != 0) // negative - val = (int)_data[0]; - } - - return val; - } - - /// - /// Computes the Jacobi Symbol for 2 BigInteger a and b - /// - /// - /// Algorithm adapted from [3] and [4] with some optimizations - /// - /// Any BigInteger - /// Odd BigInteger - /// Jacobi Symbol - public static int Jacobi(BigInteger a, BigInteger b) - { - // Jacobi defined only for odd integers - if ((b._data[0] & 0x1) == 0) - throw (new ArgumentException("Jacobi defined only for odd integers.")); - - if (a >= b) a %= b; - if (a.DataLength == 1 && a._data[0] == 0) return 0; // a == 0 - if (a.DataLength == 1 && a._data[0] == 1) return 1; // a == 1 - - if (a < 0) - { - if ((((b - 1)._data[0]) & 0x2) == 0) //if( (((b-1) >> 1).data[0] & 0x1) == 0) - return Jacobi(-a, b); - else - return -Jacobi(-a, b); - } - - int e = 0; - for (int index = 0; index < a.DataLength; index++) - { - uint mask = 0x01; - - for (int i = 0; i < 32; i++) - { - if ((a._data[index] & mask) != 0) - { - index = a.DataLength; // to break the outer loop - break; - } - - mask <<= 1; - e++; - } - } - - BigInteger a1 = a >> e; - - int s = 1; - if ((e & 0x1) != 0 && ((b._data[0] & 0x7) == 3 || (b._data[0] & 0x7) == 5)) - s = -1; - - if ((b._data[0] & 0x3) == 3 && (a1._data[0] & 0x3) == 3) - s = -s; - - if (a1.DataLength == 1 && a1._data[0] == 1) - return s; - else - return (s * Jacobi(b % a1, a1)); - } - - /// - /// Generates a positive BigInteger that is probably prime - /// - /// Number of bit - /// Number of chosen bases - /// Random object - /// A probably prime number - public static BigInteger GenPseudoPrime(int bits, int confidence, Random rand) - { - BigInteger result = new BigInteger(); - bool done = false; - - while (!done) - { - result.GenRandomBits(bits, rand); - result._data[0] |= 0x01; // make it odd - - // prime test - done = result.IsProbablePrime(confidence); - } - - return result; - } - - /// - /// Generates a positive BigInteger that is probably prime (secured version) - /// - /// Number of bit - /// Number of chosen bases - /// RNGCryptoServiceProvider object - /// A probably prime number - public static BigInteger GenPseudoPrime(int bits, int confidence, RNGCryptoServiceProvider rand) - { - BigInteger result = new BigInteger(); - bool done = false; - - while (!done) - { - result.GenRandomBits(bits, rand); - result._data[0] |= 0x01; // make it odd - - // prime test - done = result.IsProbablePrime(confidence); - } - - return result; - } - - /// - /// Generates a random number with the specified number of bits such that gcd(number, this) = 1 - /// - /// - /// The number of bits must be greater than 0 and less than 2209 - /// - /// Number of bit - /// Random object - /// Relatively prime number of this - public BigInteger GenCoPrime(int bits, Random rand) - { - bool done = false; - BigInteger result = new BigInteger(); - - while (!done) - { - result.GenRandomBits(bits, rand); - - // gcd test - BigInteger g = result.Gcd(this); - if (g.DataLength == 1 && g._data[0] == 1) - done = true; - } - - return result; - } - - /// - /// Generates a random number with the specified number of bits such that gcd(number, this) = 1 (secured) - /// - /// Number of bit - /// Random object - /// Relatively prime number of this - public BigInteger GenCoPrime(int bits, RNGCryptoServiceProvider rand) - { - bool done = false; - BigInteger result = new BigInteger(); - - while (!done) - { - result.GenRandomBits(bits, rand); - - // gcd test - BigInteger g = result.Gcd(this); - if (g.DataLength == 1 && g._data[0] == 1) - done = true; - } - - return result; - } - - /// - /// Returns the modulo inverse of this - /// - /// - /// Throws ArithmeticException if the inverse does not exist. (i.e. gcd(this, modulus) != 1) - /// - /// - /// Modulo inverse of this - public BigInteger ModInverse(BigInteger modulus) - { - BigInteger[] p = { 0, 1 }; - BigInteger[] q = new BigInteger[2]; // quotients - BigInteger[] r = { 0, 0 }; // remainders - - int step = 0; - - BigInteger a = modulus; - BigInteger b = this; - - while (b.DataLength > 1 || (b.DataLength == 1 && b._data[0] != 0)) - { - BigInteger quotient = new BigInteger(); - BigInteger remainder = new BigInteger(); - - if (step > 1) - { - BigInteger pval = (p[0] - (p[1] * q[0])) % modulus; - p[0] = p[1]; - p[1] = pval; - } - - if (b.DataLength == 1) - SingleByteDivide(a, b, quotient, remainder); - else - MultiByteDivide(a, b, quotient, remainder); - - q[0] = q[1]; - r[0] = r[1]; - q[1] = quotient; - r[1] = remainder; - - a = b; - b = remainder; - - step++; - } - - if (r[0].DataLength > 1 || (r[0].DataLength == 1 && r[0]._data[0] != 1)) - throw (new ArithmeticException("No inverse!")); - - BigInteger result = ((p[0] - (p[1] * q[0])) % modulus); - - if ((result._data[MaxLength - 1] & 0x80000000) != 0) - result += modulus; // get the least positive modulus - - return result; - } - - /// - /// Returns the value of the BigInteger as a byte array - /// - /// - /// The lowest index contains the MSB - /// - /// Byte array containing value of the BigInteger - public byte[] GetBytes() - { - int numBits = BitCount(); - - int numBytes = numBits >> 3; - if ((numBits & 0x7) != 0) - numBytes++; - - byte[] result = new byte[numBytes]; - - int pos = 0; - uint tempVal, val = _data[DataLength - 1]; - - if ((tempVal = (val >> 24 & 0xFF)) != 0) - result[pos++] = (byte)tempVal; - - if ((tempVal = (val >> 16 & 0xFF)) != 0) - result[pos++] = (byte)tempVal; - else if (pos > 0) - pos++; - - if ((tempVal = (val >> 8 & 0xFF)) != 0) - result[pos++] = (byte)tempVal; - else if (pos > 0) - pos++; - - if ((tempVal = (val & 0xFF)) != 0) - result[pos++] = (byte)tempVal; - else if (pos > 0) - pos++; - - for (int i = DataLength - 2; i >= 0; i--, pos += 4) - { - val = _data[i]; - result[pos + 3] = (byte)(val & 0xFF); - val >>= 8; - result[pos + 2] = (byte)(val & 0xFF); - val >>= 8; - result[pos + 1] = (byte)(val & 0xFF); - val >>= 8; - result[pos] = (byte)(val & 0xFF); - } - - return result; - } - - public uint[] GetInternalState() - { - uint[] result = new UInt32[_data.Length]; - _data.CopyTo(result, 0); - return result; - } - - /// - /// Sets the value of the specified bit to 1 - /// - /// - /// The Least Significant Bit position is 0 - /// - /// The position of bit to be changed - public void SetBit(uint bitNum) - { - uint bytePos = bitNum >> 5; // divide by 32 - byte bitPos = (byte)(bitNum & 0x1F); // get the lowest 5 bits - - uint mask = (uint)1 << bitPos; - this._data[bytePos] |= mask; - - if (bytePos >= this.DataLength) - this.DataLength = (int)bytePos + 1; - } - - /// - /// Sets the value of the specified bit to 0 - /// - /// - /// The Least Significant Bit position is 0 - /// - /// The position of bit to be changed - public void UnsetBit(uint bitNum) - { - uint bytePos = bitNum >> 5; - - if (bytePos < this.DataLength) - { - byte bitPos = (byte)(bitNum & 0x1F); - - uint mask = (uint)1 << bitPos; - uint mask2 = 0xFFFFFFFF ^ mask; - - this._data[bytePos] &= mask2; - - if (this.DataLength > 1 && this._data[this.DataLength - 1] == 0) - this.DataLength--; - } - } - - /// - /// Returns a value that is equivalent to the integer square root of this - /// - /// - /// The integer square root of "this" is defined as the largest integer n, such that (n * n) <= this. - /// Square root of negative integer is an undefined behaviour (UB). - /// - /// Integer square root of this - public BigInteger Sqrt() - { - uint numBits = (uint)this.BitCount(); - - if ((numBits & 0x1) != 0) // odd number of bits - numBits = (numBits >> 1) + 1; - else - numBits = (numBits >> 1); - - uint bytePos = numBits >> 5; - byte bitPos = (byte)(numBits & 0x1F); - - uint mask; - - BigInteger result = new BigInteger(); - if (bitPos == 0) - mask = 0x80000000; - else - { - mask = (uint)1 << bitPos; - bytePos++; - } - - result.DataLength = (int)bytePos; - - for (int i = (int)bytePos - 1; i >= 0; i--) - { - while (mask != 0) - { - // guess - result._data[i] ^= mask; - - // undo the guess if its square is larger than this - if ((result * result) > this) - result._data[i] ^= mask; - - mask >>= 1; - } - - mask = 0x80000000; - } - - return result; - } - - /// - /// Returns the k_th number in the Lucas Sequence reduced modulo n - /// - /// - /// Uses index doubling to speed up the process. For example, to calculate V(k), - /// we maintain two numbers in the sequence V(n) and V(n+1). - /// - /// To obtain V(2n), we use the identity - /// V(2n) = (V(n) * V(n)) - (2 * Q^n) - /// To obtain V(2n+1), we first write it as - /// V(2n+1) = V((n+1) + n) - /// and use the identity - /// V(m+n) = V(m) * V(n) - Q * V(m-n) - /// Hence, - /// V((n+1) + n) = V(n+1) * V(n) - Q^n * V((n+1) - n) - /// = V(n+1) * V(n) - Q^n * V(1) - /// = V(n+1) * V(n) - Q^n * P - /// - /// We use k in its binary expansion and perform index doubling for each - /// bit position. For each bit position that is set, we perform an - /// index doubling followed by an index addition. This means that for V(n), - /// we need to update it to V(2n+1). For V(n+1), we need to update it to - /// V((2n+1)+1) = V(2*(n+1)) - /// - /// This function returns - /// [0] = U(k) - /// [1] = V(k) - /// [2] = Q^n - /// - /// Where U(0) = 0 % n, U(1) = 1 % n - /// V(0) = 2 % n, V(1) = P % n - /// - /// - /// - /// - /// - /// - public static BigInteger[] LucasSequence(BigInteger p, BigInteger q, - BigInteger k, BigInteger n) - { - if (k.DataLength == 1 && k._data[0] == 0) - { - BigInteger[] result = new BigInteger[3]; - - result[0] = 0; - result[1] = 2 % n; - result[2] = 1 % n; - return result; - } - - // calculate constant = b^(2k) / m - // for Barrett Reduction - BigInteger constant = new BigInteger(); - - int nLen = n.DataLength << 1; - constant._data[nLen] = 0x00000001; - constant.DataLength = nLen + 1; - - constant = constant / n; - - // calculate values of s and t - int s = 0; - - for (int index = 0; index < k.DataLength; index++) - { - uint mask = 0x01; - - for (int i = 0; i < 32; i++) - { - if ((k._data[index] & mask) != 0) - { - index = k.DataLength; // to break the outer loop - break; - } - - mask <<= 1; - s++; - } - } - - BigInteger t = k >> s; - - return LucasSequenceHelper(p, q, t, n, constant, s); - } - - //*********************************************************************** - // Performs the calculation of the kth term in the Lucas Sequence. - // For details of the algorithm, see reference [9]. - // - // k must be odd. i.e LSB == 1 - //*********************************************************************** - private static BigInteger[] LucasSequenceHelper(BigInteger p, BigInteger q, - BigInteger k, BigInteger n, - BigInteger constant, int s) - { - BigInteger[] result = new BigInteger[3]; - - if ((k._data[0] & 0x00000001) == 0) - throw (new ArgumentException("Argument k must be odd.")); - - int numbits = k.BitCount(); - uint mask = (uint)0x1 << ((numbits & 0x1F) - 1); - - // v = v0, v1 = v1, u1 = u1, Q_k = Q^0 - - BigInteger v = 2 % n, - qK = 1 % n, - v1 = p % n, - u1 = qK; - bool flag = true; - - for (int i = k.DataLength - 1; i >= 0; i--) // iterate on the binary expansion of k - { - while (mask != 0) - { - if (i == 0 && mask == 0x00000001) // last bit - break; - - if ((k._data[i] & mask) != 0) // bit is set - { - // index doubling with addition - - u1 = (u1 * v1) % n; - - v = ((v * v1) - (p * qK)) % n; - v1 = n.BarrettReduction(v1 * v1, n, constant); - v1 = (v1 - ((qK * q) << 1)) % n; - - if (flag) - flag = false; - else - qK = n.BarrettReduction(qK * qK, n, constant); - - qK = (qK * q) % n; - } - else - { - // index doubling - u1 = ((u1 * v) - qK) % n; - - v1 = ((v * v1) - (p * qK)) % n; - v = n.BarrettReduction(v * v, n, constant); - v = (v - (qK << 1)) % n; - - if (flag) - { - qK = q % n; - flag = false; - } - else - qK = n.BarrettReduction(qK * qK, n, constant); - } - - mask >>= 1; - } - - mask = 0x80000000; - } - - // at this point u1 = u(n+1) and v = v(n) - // since the last bit always 1, we need to transform u1 to u(2n+1) and v to v(2n+1) - - u1 = ((u1 * v) - qK) % n; - v = ((v * v1) - (p * qK)) % n; - if (flag) - flag = false; - else - qK = n.BarrettReduction(qK * qK, n, constant); - - qK = (qK * q) % n; - - for (int i = 0; i < s; i++) - { - // index doubling - u1 = (u1 * v) % n; - v = ((v * v) - (qK << 1)) % n; - - if (flag) - { - qK = q % n; - flag = false; - } - else - qK = n.BarrettReduction(qK * qK, n, constant); - } - - result[0] = u1; - result[1] = v; - result[2] = qK; - - return result; - } - } -} -#endif \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/BigInteger.cs.meta b/com.unity.multiplayer.mlapi/Runtime/Security/BigInteger.cs.meta deleted file mode 100644 index 41225e7b9b..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/BigInteger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4c3aecf52f4cabc44888e828122a7292 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/CryptographyHelper.cs b/com.unity.multiplayer.mlapi/Runtime/Security/CryptographyHelper.cs deleted file mode 100644 index 3759fa2b7d..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/CryptographyHelper.cs +++ /dev/null @@ -1,97 +0,0 @@ -#if !DISABLE_CRYPTOGRAPHY -using System.Security.Cryptography.X509Certificates; - -namespace MLAPI.Security -{ - /// - /// Helper class for encryption purposes - /// - public static class CryptographyHelper - { - /// - /// The delegate to invoke to validate the certificates - /// - public static VerifyCertificateDelegate OnValidateCertificateCallback = null; - - /// - /// The delegate type used to validate certificates - /// - /// The certificate to validate - /// The hostname the certificate is claiming to be - public delegate bool VerifyCertificateDelegate(X509Certificate2 certificate, string hostname); - - /// - /// - /// - /// The certificate to validate - /// The hostname the certificate is claiming to be - /// Whether or not the certificate is considered valid - public static bool VerifyCertificate(X509Certificate2 certificate, string hostname) - { - if (OnValidateCertificateCallback != null) return OnValidateCertificateCallback(certificate, hostname); - return certificate.Verify() && (hostname == certificate.GetNameInfo(X509NameType.DnsName, false) || hostname == "127.0.0.1"); - } - - /// - /// Gets the aes key for any given clientId - /// - /// The clientId of the client whose aes key we want - /// The aes key in binary - public static byte[] GetClientKey(ulong clientId) - { - if (NetworkingManager.Singleton.IsServer) - { - if (NetworkingManager.Singleton.ConnectedClients.ContainsKey(clientId)) - { - return NetworkingManager.Singleton.ConnectedClients[clientId].AesKey; - } - else if (NetworkingManager.Singleton.PendingClients.ContainsKey(clientId)) - { - return NetworkingManager.Singleton.PendingClients[clientId].AesKey; - } - else - { - return null; - } - } - else - { - return null; - } - } - - /// - /// Gets the aes key for the server - /// - /// The servers aes key - public static byte[] GetServerKey() - { - if (NetworkingManager.Singleton.IsServer) - { - return null; - } - else - { - return NetworkingManager.Singleton.clientAesKey; - } - } - - internal static bool ConstTimeArrayEqual(byte[] a, byte[] b) - { - if (a.Length != b.Length) - return false; - - int i = a.Length; - int cmp = 0; - - while (i != 0) - { - --i; - cmp |= (a[i] ^ b[i]); - } - - return cmp == 0; - } - } -} -#endif diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/CryptographyHelper.cs.meta b/com.unity.multiplayer.mlapi/Runtime/Security/CryptographyHelper.cs.meta deleted file mode 100644 index 0e83f96784..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/CryptographyHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 86973a207e04f17478633d8cdaec305f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/DiffieHellman.cs b/com.unity.multiplayer.mlapi/Runtime/Security/DiffieHellman.cs deleted file mode 100644 index bc700cbcaa..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/DiffieHellman.cs +++ /dev/null @@ -1,158 +0,0 @@ -#if !DISABLE_CRYPTOGRAPHY -using System; -using System.Security.Cryptography; -using System.Text; -using UnityEngine; - -namespace MLAPI.Security -{ - internal class EllipticDiffieHellman - { - protected static readonly RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider(); - - public static BigInteger DEFAULT_PRIME - { - get - { - if (defaultPrime == null) - { - try - { - defaultPrime = (new BigInteger("1") << 255) - 19; - } - catch (Exception) - { - Debug.LogError("[MLAPI] CryptoLib failed to parse BigInt. If you are using .NET 2.0 Subset, switch to .NET 2.0 or .NET 4.5"); - } - } - - return defaultPrime; - } - } - - private static BigInteger defaultPrime; - - public static BigInteger DEFAULT_ORDER - { - get - { - if (defaultOrder == null) - { - try - { - defaultOrder = (new BigInteger(1) << 252) + - new BigInteger("27742317777372353535851937790883648493"); - } - catch (Exception) - { - Debug.LogError("[MLAPI] CryptoLib failed to parse BigInt. If you are using .NET 2.0 Subset, switch to .NET 2.0 or .NET 4.5"); - } - } - - return defaultOrder; - } - } - - private static BigInteger defaultOrder; - - public static EllipticCurve DEFAULT_CURVE - { - get - { - if (defaultCurve == null) - { - try - { - defaultCurve = new EllipticCurve(486662, 1, DEFAULT_PRIME, EllipticCurve.CurveType.Montgomery); - } - catch (Exception) - { - Debug.LogError("[MLAPI] CryptoLib failed to parse BigInt. If you are using .NET 2.0 Subset, switch to .NET 2.0 or .NET 4.5"); - } - } - - return defaultCurve; - } - } - - private static EllipticCurve defaultCurve; - - public static CurvePoint DEFAULT_GENERATOR - { - get - { - if (defaultGenerator == null) - { - try - { - defaultGenerator = new CurvePoint(9, new BigInteger("14781619447589544791020593568409986887264606134616475288964881837755586237401")); - } - catch (Exception) - { - Debug.LogError("[MLAPI] CryptoLib failed to parse BigInt. If you are using .NET 2.0 Subset, switch to .NET 2.0 or .NET 4.5"); - } - } - - return defaultGenerator; - } - } - - private static CurvePoint defaultGenerator; - - protected readonly EllipticCurve curve; - public readonly BigInteger priv; - protected readonly CurvePoint generator, pub; - - public EllipticDiffieHellman(EllipticCurve curve, CurvePoint generator, BigInteger order, byte[] priv = null) - { - this.curve = curve; - this.generator = generator; - - // Generate private key - if (priv == null) - { - this.priv = new BigInteger(); - this.priv.GenRandomBits(order.DataLength, rand); - } - else this.priv = new BigInteger(priv); - - // Generate public key - pub = curve.Multiply(generator, this.priv); - } - - public byte[] GetPublicKey() - { - byte[] p1 = pub.X.GetBytes(); - byte[] p2 = pub.Y.GetBytes(); - - byte[] ser = new byte[4 + p1.Length + p2.Length]; - ser[0] = (byte)(p1.Length & 255); - ser[1] = (byte)((p1.Length >> 8) & 255); - ser[2] = (byte)((p1.Length >> 16) & 255); - ser[3] = (byte)((p1.Length >> 24) & 255); - Array.Copy(p1, 0, ser, 4, p1.Length); - Array.Copy(p2, 0, ser, 4 + p1.Length, p2.Length); - - return ser; - } - - public byte[] GetPrivateKey() => priv.GetBytes(); - - public byte[] GetSharedSecret(byte[] pK) - { - byte[] p1 = new byte[pK[0] | (pK[1] << 8) | (pK[2] << 16) | (pK[3] << 24)]; // Reconstruct x-axis size - byte[] p2 = new byte[pK.Length - p1.Length - 4]; - Array.Copy(pK, 4, p1, 0, p1.Length); - Array.Copy(pK, 4 + p1.Length, p2, 0, p2.Length); - - CurvePoint remotePublic = new CurvePoint(new BigInteger(p1), new BigInteger(p2)); - - byte[] secret = curve.Multiply(remotePublic, priv).X.GetBytes(); // Use the x-coordinate as the shared secret - - // PBKDF2-HMAC-SHA1 (Common shared secret generation method) - return new Rfc2898DeriveBytes(secret, Encoding.UTF8.GetBytes("P1sN0R4inb0wPl5P1sPls"), 1000).GetBytes(32); - } - } -} - -#endif \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/DiffieHellman.cs.meta b/com.unity.multiplayer.mlapi/Runtime/Security/DiffieHellman.cs.meta deleted file mode 100644 index 526b54d440..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/DiffieHellman.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 117d772186026314aab3f981fa627b19 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/EllipticCurve.cs b/com.unity.multiplayer.mlapi/Runtime/Security/EllipticCurve.cs deleted file mode 100644 index 312c43ee6b..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/EllipticCurve.cs +++ /dev/null @@ -1,201 +0,0 @@ -#if !DISABLE_CRYPTOGRAPHY -using MLAPI.Serialization; -using System; -using System.Collections.Generic; - -namespace MLAPI.Security -{ - internal class CurvePoint - { - public static readonly CurvePoint POINT_AT_INFINITY = new CurvePoint(); - public BigInteger X { get; private set; } - public BigInteger Y { get; private set; } - private readonly bool pai = false; - - public CurvePoint(BigInteger x, BigInteger y) - { - X = x; - Y = y; - } - - private CurvePoint() - { - pai = true; - } // Accessing corrdinates causes undocumented behaviour - - public override string ToString() - { - return pai ? "(POINT_AT_INFINITY)" : "(" + X + ", " + Y + ")"; - } - } - - internal class EllipticCurve - { - public enum CurveType { Weierstrass, Montgomery } - - protected readonly BigInteger a, b, modulo; - protected readonly CurveType type; - - public EllipticCurve(BigInteger a, BigInteger b, BigInteger modulo, CurveType type = CurveType.Weierstrass) - { - if ( - (type == CurveType.Weierstrass && (4 * a * a * a) + (27 * b * b) == 0) || // Unfavourable Weierstrass curves - (type == CurveType.Montgomery && b * (a * a - 4) == 0) // Unfavourable Montgomery curves - ) throw new Exception("Unfavourable curve"); - this.a = a; - this.b = b; - this.modulo = modulo; - this.type = type; - } - - public CurvePoint Add(CurvePoint p1, CurvePoint p2) - { -#if SAFE_MATH - CheckOnCurve(p1); - CheckOnCurve(p2); -#endif - - // Special cases - if (p1 == CurvePoint.POINT_AT_INFINITY && p2 == CurvePoint.POINT_AT_INFINITY) return CurvePoint.POINT_AT_INFINITY; - else if (p1 == CurvePoint.POINT_AT_INFINITY) return p2; - else if (p2 == CurvePoint.POINT_AT_INFINITY) return p1; - else if (p1.X == p2.X && p1.Y == Inverse(p2).Y) return CurvePoint.POINT_AT_INFINITY; - - BigInteger x3 = 0, y3 = 0; - if (type == CurveType.Weierstrass) - { - BigInteger slope = p1.X == p2.X && p1.Y == p2.Y ? Mod((3 * p1.X * p1.X + a) * MulInverse(2 * p1.Y)) : Mod(Mod(p2.Y - p1.Y) * MulInverse(p2.X - p1.X)); - x3 = Mod((slope * slope) - p1.X - p2.X); - y3 = Mod(-((slope * x3) + p1.Y - (slope * p1.X))); - } - else if (type == CurveType.Montgomery) - { - if ((p1.X == p2.X && p1.Y == p2.Y)) - { - BigInteger q = 3 * p1.X; - BigInteger w = q * p1.X; - - BigInteger e = 2 * a; - BigInteger r = e * p1.X; - - BigInteger t = 2 * b; - BigInteger y = t * p1.Y; - - BigInteger u = MulInverse(y); - - BigInteger o = w + e + 1; - BigInteger p = o * u; - } - BigInteger co = p1.X == p2.X && p1.Y == p2.Y ? Mod((3 * p1.X * p1.X + 2 * a * p1.X + 1) * MulInverse(2 * b * p1.Y)) : Mod(Mod(p2.Y - p1.Y) * MulInverse(p2.X - p1.X)); // Compute a commonly used coefficient - x3 = Mod(b * co * co - a - p1.X - p2.X); - y3 = Mod(((2 * p1.X + p2.X + a) * co) - (b * co * co * co) - p1.Y); - } - - return new CurvePoint(x3, y3); - } - - public CurvePoint Multiply(CurvePoint p, BigInteger scalar) - { - if (scalar <= 0) throw new Exception("Cannot multiply by a scalar which is <= 0"); - if (p == CurvePoint.POINT_AT_INFINITY) return CurvePoint.POINT_AT_INFINITY; - - CurvePoint p1 = new CurvePoint(p.X, p.Y); - uint[] u = scalar.GetInternalState(); - long high_bit = -1; - for (int i = u.Length - 1; i >= 0; --i) - if (u[i] != 0) - { - for (int j = 31; j >= 0; --j) - if ((u[i] & (1 << j)) != 0) - { - high_bit = j + i * 32; - goto Next; - } - } - Next: - - // Double-and-add method - while (high_bit >= 0) - { - p1 = Add(p1, p1); // Double - if ((u.BitAt(high_bit))) - p1 = Add(p1, p); // Add - --high_bit; - } - - return p1; - } - - protected BigInteger MulInverse(BigInteger eq) => MulInverse(eq, modulo); - - public static BigInteger MulInverse(BigInteger eq, BigInteger modulo) - { - eq = Mod(eq, modulo); - Stack collect = new Stack(); - BigInteger v = modulo; // Copy modulo - BigInteger m; - while ((m = v % eq) != 0) - { - collect.Push(-v / eq/*-(m.l_div)*/); - v = eq; - eq = m; - } - if (collect.Count == 0) return 1; - v = 1; - m = collect.Pop(); - while (collect.Count > 0) - { - eq = m; - m = v + (m * collect.Pop()); - v = eq; - } - return Mod(m, modulo); - } - - public CurvePoint Inverse(CurvePoint p) => Inverse(p, modulo); - - protected static CurvePoint Inverse(CurvePoint p, BigInteger modulo) => new CurvePoint(p.X, Mod(-p.Y, modulo)); - - public bool IsOnCurve(CurvePoint p) - { - try { CheckOnCurve(p); } - catch { return false; } - return true; - } - - protected void CheckOnCurve(CurvePoint p) - { - if ( - p != CurvePoint.POINT_AT_INFINITY && // The point at infinity is asserted to be on the curve - (type == CurveType.Weierstrass && Mod(p.Y * p.Y) != Mod((p.X * p.X * p.X) + (p.X * a) + b)) || // Weierstrass formula - (type == CurveType.Montgomery && Mod(b * p.Y * p.Y) != Mod((p.X * p.X * p.X) + (p.X * p.X * a) + p.X)) // Montgomery formula - ) throw new Exception("Point is not on curve"); - } - - protected BigInteger Mod(BigInteger b) => Mod(b, modulo); - - private static BigInteger Mod(BigInteger x, BigInteger m) - { - BigInteger r = x.Abs() > m ? x % m : x; - return r < 0 ? r + m : r; - } - - protected static BigInteger ModPow(BigInteger x, BigInteger power, BigInteger prime) - { - BigInteger result = 1; - bool setBit = false; - while (power > 0) - { - x %= prime; - setBit = (power & 1) == 1; - power >>= 1; - if (setBit) result *= x; - x *= x; - } - - return result; - } - } -} - -#endif \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/EllipticCurve.cs.meta b/com.unity.multiplayer.mlapi/Runtime/Security/EllipticCurve.cs.meta deleted file mode 100644 index 9868bda110..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/EllipticCurve.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c3c46415fa53cb64b9bf9c2866a418c2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/SecuritySendFlags.cs b/com.unity.multiplayer.mlapi/Runtime/Security/SecuritySendFlags.cs deleted file mode 100644 index b430a3302f..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/SecuritySendFlags.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace MLAPI.Security -{ - /// - /// The security operations of a payload - /// - [Flags] - public enum SecuritySendFlags - { - /// - /// No security operations are applied - /// - None = 0x0, - /// - /// The payload is encrypted - /// - Encrypted = 0x1, - /// - /// The payload is authenticated - /// - Authenticated = 0x2 - } -} \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/Security/SecuritySendFlags.cs.meta b/com.unity.multiplayer.mlapi/Runtime/Security/SecuritySendFlags.cs.meta deleted file mode 100644 index 912afb32b7..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/Security/SecuritySendFlags.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6032c0f7a13ffda49bffe34894f4976d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Runtime/Spawning/SpawnManager.cs b/com.unity.multiplayer.mlapi/Runtime/Spawning/SpawnManager.cs index f136c01142..c90e2f840e 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Spawning/SpawnManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Spawning/SpawnManager.cs @@ -8,7 +8,6 @@ using MLAPI.Logging; using MLAPI.Messaging; using MLAPI.SceneManagement; -using MLAPI.Security; using MLAPI.Serialization.Pooled; using MLAPI.Transports; using UnityEngine; @@ -195,7 +194,7 @@ internal static void RemoveOwnership(NetworkedObject netObject) writer.WriteUInt64Packed(netObject.NetworkId); writer.WriteUInt64Packed(netObject.OwnerClientId); - InternalMessageSender.Send(MLAPIConstants.MLAPI_CHANGE_OWNER, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(MLAPIConstants.MLAPI_CHANGE_OWNER, Channel.Internal, stream); } } } @@ -231,7 +230,7 @@ internal static void ChangeOwnership(NetworkedObject netObject, ulong clientId) writer.WriteUInt64Packed(netObject.NetworkId); writer.WriteUInt64Packed(clientId); - InternalMessageSender.Send(MLAPIConstants.MLAPI_CHANGE_OWNER, Channel.Internal, stream, SecuritySendFlags.None); + InternalMessageSender.Send(MLAPIConstants.MLAPI_CHANGE_OWNER, Channel.Internal, stream); } } } @@ -424,7 +423,6 @@ internal static void SendSpawnCallForObject(ulong clientId, NetworkedObject netO networkId = 0, itemStream = stream, channel = Channel.Internal, - sendFlags = SecuritySendFlags.None, clientIds = new[] {clientId} }; rpcQueueContainer.AddToInternalMLAPISendQueue(queueItem); @@ -698,7 +696,6 @@ internal static void OnDestroyObject(ulong networkId, bool destroyGameObject) networkId = networkId, itemStream = stream, channel = Channel.Internal, - sendFlags = SecuritySendFlags.None, clientIds = NetworkingManager.Singleton.ConnectedClientsList.Select(c => c.ClientId).ToArray() }; rpcQueueContainer.AddToInternalMLAPISendQueue(queueItem); diff --git a/com.unity.multiplayer.mlapi/Runtime/Transports/Tests/Editor/TransportTest.cs b/com.unity.multiplayer.mlapi/Runtime/Transports/Tests/Editor/TransportTest.cs index 9ac2627614..cddf27d311 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Transports/Tests/Editor/TransportTest.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Transports/Tests/Editor/TransportTest.cs @@ -71,4 +71,3 @@ public void UNetCustomChannelRegistrationTest() nm.Shutdown(); } } - diff --git a/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/RelayTransport.cs b/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/RelayTransport.cs index ac0be3baf2..fdc4e64def 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/RelayTransport.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/RelayTransport.cs @@ -1,3 +1,4 @@ +#pragma warning disable 618 #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; using System.Collections.Generic; @@ -287,9 +288,9 @@ public static NetworkEventType Receive(out int hostId, out int connectionId, out return BaseReceive(@event, hostId, ref connectionId, ref channelId, buffer, bufferSize, ref receivedSize, ref error); } - private static NetworkEventType BaseReceive(NetworkEventType @event, int hostId, ref int connectionId, ref int channelId, byte[] buffer, int bufferSize, ref int receivedSize, ref byte error) + private static NetworkEventType BaseReceive(NetworkEventType netEvent, int hostId, ref int connectionId, ref int channelId, byte[] buffer, int bufferSize, ref int receivedSize, ref byte error) { - switch (@event) + switch (netEvent) { case NetworkEventType.DataEvent: { @@ -423,7 +424,7 @@ private static NetworkEventType BaseReceive(NetworkEventType @event, int hostId, } } - return @event; + return netEvent; } } @@ -434,3 +435,4 @@ public InvalidConfigException(string issue) : base(issue) { } } } #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member +#pragma warning restore 618 diff --git a/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/UnetTransport.cs b/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/UnetTransport.cs index fd04f19e77..085fdf4b6a 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/UnetTransport.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Transports/UNET/UnetTransport.cs @@ -1,7 +1,7 @@ +#pragma warning disable 618 #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; using System.Collections.Generic; -using System.Diagnostics; using MLAPI.Exceptions; using MLAPI.Logging; using MLAPI.Profiling; @@ -468,3 +468,4 @@ public IReadOnlyDictionary GetTransportProfilerData() } } #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member +#pragma warning restore 618 diff --git a/com.unity.multiplayer.mlapi/Runtime/csc.rsp b/com.unity.multiplayer.mlapi/Runtime/csc.rsp deleted file mode 100644 index f57fbb5769..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/csc.rsp +++ /dev/null @@ -1,2 +0,0 @@ --nowarn:CS0618 --define:DISABLE_CRYPTOGRAPHY \ No newline at end of file diff --git a/com.unity.multiplayer.mlapi/Runtime/csc.rsp.meta b/com.unity.multiplayer.mlapi/Runtime/csc.rsp.meta deleted file mode 100644 index 0564cd6be9..0000000000 --- a/com.unity.multiplayer.mlapi/Runtime/csc.rsp.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 0792ffa3ad8dceb4bbf6784a856658f9 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Editor/RpcBatcherTests.cs b/com.unity.multiplayer.mlapi/Tests/Editor/RpcBatcherTests.cs index 2e1c0b07ef..aec67f1d49 100644 --- a/com.unity.multiplayer.mlapi/Tests/Editor/RpcBatcherTests.cs +++ b/com.unity.multiplayer.mlapi/Tests/Editor/RpcBatcherTests.cs @@ -57,9 +57,7 @@ public void SendWithThreshold() // todo: revisit // The following line is sub-optimal // The stream returned by SendItems() includes: - // - 1 bit for authentication flag - // - 1 bit for encryption flag - // - 6 bits for the MLAPI message types. + // - 8 bits for the MLAPI message types. // ReceiveItems expects those to have been stripped by the receive code. // In order to replicate this behaviour, we'll read 8 bits before calling ReceiveItems() recvStream.ReadByte(); @@ -117,9 +115,7 @@ public void SendWithoutThreshold() // todo: revisit // The following line is sub-optimal // The stream returned by SendItems() includes: - // - 1 bit for authentication flag - // - 1 bit for encryption flag - // - 6 bits for the MLAPI message types. + // - 8 bits for the MLAPI message types. // ReceiveItems expects those to have been stripped by the receive code. // In order to replicate this behaviour, we'll read 8 bits before calling ReceiveItems() recvStream.ReadByte(); @@ -130,4 +126,4 @@ public void SendWithoutThreshold() Assert.AreEqual(k_QueueItemCount, recvItemCounter); } } -} +} \ No newline at end of file diff --git a/testproject/Assets/Scripts/Raygun.cs b/testproject/Assets/Scripts/Raygun.cs index 1e06202d60..30fe34207b 100644 --- a/testproject/Assets/Scripts/Raygun.cs +++ b/testproject/Assets/Scripts/Raygun.cs @@ -1,8 +1,6 @@ -using UnityEngine; -using System.Collections; using System.Collections.Generic; +using UnityEngine; using MLAPI; -using UnityEditor; public class Raygun : NetworkedBehaviour { @@ -11,10 +9,6 @@ public class Raygun : NetworkedBehaviour private GameObject m_CurrentTarget; private LineRenderer m_LineRenderer; - private void Start() - { - } - private void Awake() { m_LineRenderer = GetComponent(); @@ -27,7 +21,7 @@ private void FixedUpdate() { var forward = transform.forward * m_Range; - m_LineRenderer.SetVertexCount(2); + m_LineRenderer.positionCount = 2; m_LineRenderer.SetPosition(0, transform.position); m_LineRenderer.SetPosition(1, transform.position + forward); @@ -36,7 +30,6 @@ private void FixedUpdate() m_CurrentTarget = FindTarget(); transform.position = m_CurrentTarget.transform.position + forward; } - } private GameObject FindTarget() @@ -47,4 +40,4 @@ private GameObject FindTarget() return list.Count == 0 ? null : list[Random.Range(0, list.Count)]; } -} +} \ No newline at end of file