mirror of https://github.com/icsharpcode/ILSpy.git
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
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")); |
|
} |
|
} |
|
}
|
|
|