.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

111 lines
4.0 KiB

// Copyright (c) 2026 Siegfried Pammer
//
// 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, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// 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. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Util
{
[TestFixture]
public class Sha1ForNonSecretPurposesTests
{
static string OneShotHash(byte[] input)
{
byte[] output = new byte[20];
Sha1ForNonSecretPurposes.HashData(input, output);
return ToHex(output);
}
static string IncrementalHash(byte[] input)
{
var sha1 = default(Sha1ForNonSecretPurposes);
sha1.Start();
sha1.Append(input);
byte[] output = new byte[20];
sha1.Finish(output);
return ToHex(output);
}
static string ToHex(byte[] bytes)
{
return string.Concat(bytes.Select(b => b.ToString("x2")));
}
// FIPS 180 test vectors
[TestCase("", "da39a3ee5e6b4b0d3255bfef95601890afd80709")]
[TestCase("abc", "a9993e364706816aba3e25717850c26c9cd0d89d")]
[TestCase("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "84983e441c3bd26ebaae4aa1f95129e5e54670f1")]
public void KnownVectors(string input, string expectedHex)
{
byte[] bytes = Encoding.ASCII.GetBytes(input);
Assert.That(OneShotHash(bytes), Is.EqualTo(expectedHex));
Assert.That(IncrementalHash(bytes), Is.EqualTo(expectedHex));
}
[Test]
public void MatchesPlatformSha1AroundBlockBoundaries()
{
// Cover all interesting positions relative to the 64-byte block size and the
// 8-byte length suffix: 0, 1, 55, 56, 57, 63, 64, 65, 119, 120, 127, 128, ...
using var platformSha1 = System.Security.Cryptography.SHA1.Create();
for (int length = 0; length <= 130; length++)
{
byte[] input = new byte[length];
for (int i = 0; i < length; i++)
{
input[i] = unchecked((byte)(i * 131 + 7));
}
string expected = ToHex(platformSha1.ComputeHash(input));
Assert.That(OneShotHash(input), Is.EqualTo(expected), $"one-shot, length {length}");
Assert.That(IncrementalHash(input), Is.EqualTo(expected), $"incremental, length {length}");
}
}
[Test]
public void StartResetsTheIncrementalState()
{
var sha1 = default(Sha1ForNonSecretPurposes);
sha1.Start();
sha1.Append(Encoding.ASCII.GetBytes("garbage that must not leak into the second hash"));
byte[] output = new byte[20];
sha1.Finish(output);
sha1.Start();
sha1.Append(Encoding.ASCII.GetBytes("abc"));
sha1.Finish(output);
Assert.That(ToHex(output), Is.EqualTo("a9993e364706816aba3e25717850c26c9cd0d89d"));
}
[Test]
public void EcmaStandardPublicKeyYieldsKnownToken()
{
// The strong-name public key token is defined as the last 8 bytes of the
// SHA-1 of the public key, in reversed order. The ECMA standard public key
// must produce the well-known token b77a5c561934e089 (mscorlib et al.).
byte[] ecmaKey = new byte[16];
ecmaKey[8] = 0x04;
byte[] hash = new byte[20];
Sha1ForNonSecretPurposes.HashData(ecmaKey, hash);
string token = ToHex(hash.Skip(12).Reverse().ToArray());
Assert.That(token, Is.EqualTo("b77a5c561934e089"));
}
}
}