From a464f747a83e2da332f34f7e6e4ba949f4f0d2d8 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 29 Dec 2020 22:39:35 +0100 Subject: [PATCH] Refactor Crc64 type Context: https://github.com/xamarin/xamarin-android/issues/5451 Split the code to static helper class, which can be used from `Java.Interop.Tools.TypeNameMappings.JavaNativeTypeManager.GetPackageName`. This way the linker can strip the whole `System.Security.Cryptography.Primitives` assembly out in simple XA apps. The `Crc64` is still needed in XA, so we still keep it based on `System.Security.Cryptography.HashAlgorithm`. --- .../Crc64.Table.cs | 4 +- .../Crc64.cs | 32 +------ .../Crc64Helper.cs | 91 +++++++++++++++++++ .../JavaNativeTypeManager.cs | 10 +- 4 files changed, 99 insertions(+), 38 deletions(-) create mode 100644 src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64Helper.cs diff --git a/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.Table.cs b/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.Table.cs index 785c953c9..c82097ed5 100644 --- a/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.Table.cs +++ b/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.Table.cs @@ -1,8 +1,8 @@ namespace Java.Interop.Tools.JavaCallableWrappers { - partial class Crc64 + partial class Crc64Helper { - static readonly ulong[,] Table = { + static readonly ulong[,] table = { { 0x0000000000000000, 0x7ad870c830358979, 0xf5b0e190606b12f2, 0x8f689158505e9b8b, 0xc038e5739841b68f, 0xbae095bba8743ff6, 0x358804e3f82aa47d, 0x4f50742bc81f2d04, diff --git a/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.cs b/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.cs index e639c93c1..f3dabdc2f 100644 --- a/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.cs +++ b/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.cs @@ -53,37 +53,9 @@ public override void Initialize () length = 0; } - unsafe protected override void HashCore (byte [] array, int ibStart, int cbSize) + protected override unsafe void HashCore (byte [] array, int ibStart, int cbSize) { - int len = cbSize; - int idx = ibStart; - - fixed (ulong* tptr = Table) { - fixed (byte* aptr = array) { - while (len >= 8) { - crc ^= *((ulong*)(aptr + idx)); - crc = - tptr [7 * 256 + (crc & 0xff)] ^ - tptr [6 * 256 + ((crc >> 8) & 0xff)] ^ - tptr [5 * 256 + ((crc >> 16) & 0xff)] ^ - tptr [4 * 256 + ((crc >> 24) & 0xff)] ^ - tptr [3 * 256 + ((crc >> 32) & 0xff)] ^ - tptr [2 * 256 + ((crc >> 40) & 0xff)] ^ - tptr [1 * 256 + ((crc >> 48) & 0xff)] ^ - tptr [0 * 256 + (crc >> 56)]; - idx += 8; - len -= 8; - } - - while (len > 0) { - crc = tptr [0 * 256 + ((crc ^ aptr[idx]) & 0xff)] ^ (crc >> 8); - idx++; - len--; - } - } - } - - length += (ulong) cbSize; + Crc64Helper.HashCore (array, ibStart, cbSize, ref crc, ref length); } protected override byte [] HashFinal () => BitConverter.GetBytes (crc ^ length); diff --git a/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64Helper.cs b/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64Helper.cs new file mode 100644 index 000000000..82ab2a90b --- /dev/null +++ b/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64Helper.cs @@ -0,0 +1,91 @@ +/* + * Originally ported from: https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c + * + * Copyright (c) 2012, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ + +using System; +using System.Security.Cryptography; + +namespace Java.Interop.Tools.JavaCallableWrappers +{ + /// + /// CRC64 variant: crc-64-jones 64-bit + /// * Poly: 0xad93d23594c935a9 + /// + /// Changes beyond initial implementation: + /// * Starting Value: ulong.MaxValue + /// * XOR length in HashFinal() + /// * Using spliced table for faster processing + /// + internal static partial class Crc64Helper + { + + internal static byte [] Compute (byte [] array) + { + ulong crc = ulong.MaxValue; + ulong length = 0; + + HashCore (array, 0, array.Length, ref crc, ref length); + + return BitConverter.GetBytes (crc ^ length); + } + + internal static unsafe void HashCore (byte [] array, int ibStart, int cbSize, ref ulong crc, ref ulong length) + { + int len = cbSize; + int idx = ibStart; + + fixed (ulong* tptr = table) { + fixed (byte* aptr = array) { + while (len >= 8) { + crc ^= *((ulong*) (aptr + idx)); + crc = + tptr [7 * 256 + (crc & 0xff)] ^ + tptr [6 * 256 + ((crc >> 8) & 0xff)] ^ + tptr [5 * 256 + ((crc >> 16) & 0xff)] ^ + tptr [4 * 256 + ((crc >> 24) & 0xff)] ^ + tptr [3 * 256 + ((crc >> 32) & 0xff)] ^ + tptr [2 * 256 + ((crc >> 40) & 0xff)] ^ + tptr [1 * 256 + ((crc >> 48) & 0xff)] ^ + tptr [0 * 256 + (crc >> 56)]; + idx += 8; + len -= 8; + } + + while (len > 0) { + crc = tptr [0 * 256 + ((crc ^ aptr [idx]) & 0xff)] ^ (crc >> 8); + idx++; + len--; + } + } + } + + length += (ulong) cbSize; + } + } +} diff --git a/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs b/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs index 71fa30309..5ec2e9007 100644 --- a/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs +++ b/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs @@ -205,8 +205,7 @@ public static string GetPackageName (Type type) case PackageNamingPolicy.LowercaseWithAssemblyName: return "assembly_" + (assemblyName.Replace ('.', '_') + "." + type.Namespace).ToLowerInvariant (); case PackageNamingPolicy.LowercaseCrc64: - using (var crc = new Crc64 ()) - return CRC_PREFIX + ToHash (type.Namespace + ":" + assemblyName, crc); + return CRC_PREFIX + ToCrc64 (type.Namespace + ":" + assemblyName); default: throw new NotSupportedException ($"PackageNamingPolicy.{PackageNamingPolicy} is no longer supported."); } @@ -574,8 +573,7 @@ public static string GetPackageName (TypeDefinition type, TypeDefinitionCache? c case PackageNamingPolicy.LowercaseWithAssemblyName: return "assembly_" + (type.GetPartialAssemblyName (cache).Replace ('.', '_') + "." + type.Namespace).ToLowerInvariant (); case PackageNamingPolicy.LowercaseCrc64: - using (var crc = new Crc64 ()) - return CRC_PREFIX + ToHash (type.Namespace + ":" + type.GetPartialAssemblyName (cache), crc); + return CRC_PREFIX + ToCrc64 (type.Namespace + ":" + type.GetPartialAssemblyName (cache)); default: throw new NotSupportedException ($"PackageNamingPolicy.{PackageNamingPolicy} is no longer supported."); } @@ -644,10 +642,10 @@ static IEnumerable GetBaseConstructors (TypeDefinition type, T } #endif // HAVE_CECIL - static string ToHash (string value, HashAlgorithm algorithm) + static string ToCrc64 (string value) { var data = Encoding.UTF8.GetBytes (value); - var hash = algorithm.ComputeHash (data); + var hash = Crc64Helper.Compute (data); var buf = new StringBuilder (hash.Length * 2); foreach (var b in hash) buf.AppendFormat ("{0:x2}", b);