Skip to content

Commit

Permalink
Refactor Crc64 type (#769)
Browse files Browse the repository at this point in the history
Context: dotnet/android#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`.
  • Loading branch information
radekdoulik authored Jan 4, 2021
1 parent 876442f commit 7d197f1
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Originally ported from: https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c
*
* Copyright (c) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
* 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
{
/// <summary>
/// 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
/// </summary>
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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
}
Expand Down Expand Up @@ -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.");
}
Expand Down Expand Up @@ -644,10 +642,10 @@ static IEnumerable<MethodDefinition> 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);
Expand Down

0 comments on commit 7d197f1

Please sign in to comment.