diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/Program.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/Program.vb new file mode 100644 index 0000000..a2797f2 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/Program.vb @@ -0,0 +1,76 @@ +' Program.cs (WelsonJS.Cryptography.Test) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Imports System.IO +Imports System.Security.Cryptography +Imports System.Text + +Module Program + Sub Main(args As String()) + + ' SEED algorithm + Console.WriteLine("Start SEED encryption and decryption test") + Dim seedCipher As New WelsonJS.Cryptography.SeedAlgorithm() + seedCipher.Key = {&H9F, &H38, &H79, &HB9, &H64, &HCB, &H88, &H49, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0} + ' seedCipher.IV = {&H26, &H8D, &H66, &HA7, &H35, &HA8, &H1A, &H81, &H6F, &HBA, &HD9, &HFA, &H36, &H16, &H25, &H1} + seedCipher.Mode = CipherMode.ECB + seedCipher.Padding = PaddingMode.PKCS7 + RunTest(seedCipher) + Console.WriteLine() + + ' ARIA algorithm + Console.WriteLine("Start ARIA encryption and decryption test") + Dim ariaCipher As New WelsonJS.Cryptography.AriaAlgorithm() + ariaCipher.Key = {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0} + ' ariaChiper.IV = {&H0F, &H1E, &H2D, &H3C, &H4B, &H5A, &H69, &H78, &H87, &H96, &HA5, &HB4, &HC3, &HD2, &HE1, &HF0} + ariaCipher.Mode = CipherMode.ECB + ariaCipher.Padding = PaddingMode.PKCS7 + RunTest(ariaCipher) + Console.WriteLine() + + ' HIGHT algorithm + Console.WriteLine("Start HIGHT encryption and decryption test") + Dim hightCipher As New WelsonJS.Cryptography.HightAlgorithm() + hightCipher.Key = {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0} + ' hightCipher.IV = {&H0F, &H1E, &H2D, &H3C, &H4B, &H5A, &H69, &H78, &H87, &H96, &HA5, &HB4, &HC3, &HD2, &HE1, &HF0} + hightCipher.Mode = CipherMode.ECB + hightCipher.Padding = PaddingMode.PKCS7 + RunTest(hightCipher) + Console.WriteLine() + + End Sub + + Public Sub RunTest(cipher As SymmetricAlgorithm) + ' Dim inputBytes As Byte() = {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0} ' SEED test vector + Dim inputBytes As Byte() = {&H80, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0} ' ARIA test vector + ' Dim inputBytes As Byte() = {&H80, &H0, &H0, &H0, &H0, &H0, &H0, &H0} ' HIGHT test vector + Console.WriteLine("Key (HEX):") + PrintHex(cipher.Key) + + Console.WriteLine("Original bytes (HEX):") + PrintHex(inputBytes) + + Dim encryptor As ICryptoTransform = cipher.CreateEncryptor() + Dim encrypted As Byte() = ApplyTransform(encryptor, inputBytes) + Console.WriteLine("Encrypted (HEX):") + PrintHex(encrypted) + + Dim decryptor As ICryptoTransform = cipher.CreateDecryptor() + Dim decrypted As Byte() = ApplyTransform(decryptor, encrypted) + Console.WriteLine("Decrypted (HEX):") + PrintHex(decrypted) + End Sub + + Private Function ApplyTransform(transformer As ICryptoTransform, input As Byte()) As Byte() + Return transformer.TransformFinalBlock(input, 0, input.Length) + End Function + + Private Sub PrintHex(data As Byte()) + For Each b As Byte In data + Console.Write("{0:X2} ", b) + Next + Console.WriteLine() + End Sub +End Module \ No newline at end of file diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/WelsonJS.Cryptography.Test.vbproj b/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/WelsonJS.Cryptography.Test.vbproj new file mode 100644 index 0000000..f926372 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography.Test/WelsonJS.Cryptography.Test.vbproj @@ -0,0 +1,14 @@ + + + + Exe + WelsonJS.Cryptography.Test + net8.0 + AnyCPU;x86 + + + + + + + diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaAlgorithm.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaAlgorithm.vb new file mode 100644 index 0000000..003c07a --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaAlgorithm.vb @@ -0,0 +1,56 @@ +' AriaAlgorithm.cs(WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Imports System.Security.Cryptography + +Public Class AriaAlgorithm + Inherits SymmetricAlgorithm + + Public Sub New() + LegalBlockSizesValue = New KeySizes() {New KeySizes(128, 128, 0)} + LegalKeySizesValue = New KeySizes() {New KeySizes(128, 256, 64)} + + Me.BlockSize = 128 + Me.KeySize = 128 + Me.FeedbackSize = 128 + + Me.Mode = CipherMode.ECB + Me.Padding = PaddingMode.PKCS7 + + Me.Key = New Byte(15) {} + Me.IV = New Byte(15) {} + End Sub + + Public Overrides Sub GenerateKey() + Using rng As New RNGCryptoServiceProvider() + rng.GetBytes(Me.Key) + End Using + End Sub + + Public Overrides Sub GenerateIV() + Using rng As New RNGCryptoServiceProvider() + rng.GetBytes(Me.IV) + End Using + End Sub + + Public Overrides Function CreateEncryptor(rgbKey As Byte(), rgbIV As Byte()) As ICryptoTransform + Return CreateTransform(rgbKey, rgbIV, True) + End Function + + Public Overrides Function CreateDecryptor(rgbKey As Byte(), rgbIV As Byte()) As ICryptoTransform + Return CreateTransform(rgbKey, rgbIV, False) + End Function + + Private Function CreateTransform(key As Byte(), iv As Byte(), encrypt As Boolean) As ICryptoTransform + Select Case Me.Mode + Case CipherMode.ECB + Return New AriaEcbTransform(key, encrypt, Me.Padding) + Case Else + Throw New NotSupportedException("This mode not supported yet") + End Select + End Function + + ' TODO: CCM, GCM, CMAC +End Class \ No newline at end of file diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaCore.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaCore.vb new file mode 100644 index 0000000..448104c --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaCore.vb @@ -0,0 +1,245 @@ +' AriaCore.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs + +Public Class AriaCore + Private S(3, 255) As Byte + Private KRK(2, 15) As Byte + Private roundKeyEnc(271) As Byte + Private roundKeyDec(271) As Byte + Private R As Integer + + Private ReadOnly KeyBits As Integer + + Public Sub New(key As Byte()) + If key.Length Mod 8 <> 0 Or key.Length < 16 Or key.Length > 32 Then + Throw New ArgumentException($"ARIA key must be 16, 24, or 32 bytes. Your key length is {key.Length} bytes") + End If + + InitConstants() + + KeyBits = key.Length * 8 + roundKeyEnc = New Byte(271) {} + roundKeyDec = New Byte(271) {} + R = EncKeySetup(key, roundKeyEnc) + DecKeySetup(key, roundKeyDec) + End Sub + + Public Sub EncryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) + Dim block(15) As Byte + Array.Copy(input, inOffset, block, 0, 16) + Dim encrypted(15) As Byte + Crypt(block, R, roundKeyEnc, encrypted) + Array.Copy(encrypted, 0, output, outOffset, 16) + End Sub + + Public Sub DecryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) + Dim block(15) As Byte + Array.Copy(input, inOffset, block, 0, 16) + Dim decrypted(15) As Byte + Crypt(block, R, roundKeyDec, decrypted) + Array.Copy(decrypted, 0, output, outOffset, 16) + End Sub + + Public Sub InitConstants() + KRK = New Byte(,) { + { + &H51, &H7C, &HC1, &HB7, &H27, &H22, &HA, &H94, &HFE, &H13, &HAB, &HE8, &HFA, &H9A, &H6E, &HE0 + }, + { + &H6D, &HB1, &H4A, &HCC, &H9E, &H21, &HC8, &H20, &HFF, &H28, &HB1, &HD5, &HEF, &H5D, &HE2, &HB0 + }, + { + &HDB, &H92, &H37, &H1D, &H21, &H26, &HE9, &H70, &H3, &H24, &H97, &H75, &H4, &HE8, &HC9, &HE + } + } + + S = New Byte(,) { + { + &H63, &H7C, &H77, &H7B, &HF2, &H6B, &H6F, &HC5, &H30, &H1, &H67, &H2B, &HFE, &HD7, &HAB, &H76, + &HCA, &H82, &HC9, &H7D, &HFA, &H59, &H47, &HF0, &HAD, &HD4, &HA2, &HAF, &H9C, &HA4, &H72, &HC0, + &HB7, &HFD, &H93, &H26, &H36, &H3F, &HF7, &HCC, &H34, &HA5, &HE5, &HF1, &H71, &HD8, &H31, &H15, + &H4, &HC7, &H23, &HC3, &H18, &H96, &H5, &H9A, &H7, &H12, &H80, &HE2, &HEB, &H27, &HB2, &H75, + &H9, &H83, &H2C, &H1A, &H1B, &H6E, &H5A, &HA0, &H52, &H3B, &HD6, &HB3, &H29, &HE3, &H2F, &H84, + &H53, &HD1, &H0, &HED, &H20, &HFC, &HB1, &H5B, &H6A, &HCB, &HBE, &H39, &H4A, &H4C, &H58, &HCF, + &HD0, &HEF, &HAA, &HFB, &H43, &H4D, &H33, &H85, &H45, &HF9, &H2, &H7F, &H50, &H3C, &H9F, &HA8, + &H51, &HA3, &H40, &H8F, &H92, &H9D, &H38, &HF5, &HBC, &HB6, &HDA, &H21, &H10, &HFF, &HF3, &HD2, + &HCD, &HC, &H13, &HEC, &H5F, &H97, &H44, &H17, &HC4, &HA7, &H7E, &H3D, &H64, &H5D, &H19, &H73, + &H60, &H81, &H4F, &HDC, &H22, &H2A, &H90, &H88, &H46, &HEE, &HB8, &H14, &HDE, &H5E, &HB, &HDB, + &HE0, &H32, &H3A, &HA, &H49, &H6, &H24, &H5C, &HC2, &HD3, &HAC, &H62, &H91, &H95, &HE4, &H79, + &HE7, &HC8, &H37, &H6D, &H8D, &HD5, &H4E, &HA9, &H6C, &H56, &HF4, &HEA, &H65, &H7A, &HAE, &H8, + &HBA, &H78, &H25, &H2E, &H1C, &HA6, &HB4, &HC6, &HE8, &HDD, &H74, &H1F, &H4B, &HBD, &H8B, &H8A, + &H70, &H3E, &HB5, &H66, &H48, &H3, &HF6, &HE, &H61, &H35, &H57, &HB9, &H86, &HC1, &H1D, &H9E, + &HE1, &HF8, &H98, &H11, &H69, &HD9, &H8E, &H94, &H9B, &H1E, &H87, &HE9, &HCE, &H55, &H28, &HDF, + &H8C, &HA1, &H89, &HD, &HBF, &HE6, &H42, &H68, &H41, &H99, &H2D, &HF, &HB0, &H54, &HBB, &H16 + }, + { + &HE2, &H4E, &H54, &HFC, &H94, &HC2, &H4A, &HCC, &H62, &HD, &H6A, &H46, &H3C, &H4D, &H8B, &HD1, + &H5E, &HFA, &H64, &HCB, &HB4, &H97, &HBE, &H2B, &HBC, &H77, &H2E, &H3, &HD3, &H19, &H59, &HC1, + &H1D, &H6, &H41, &H6B, &H55, &HF0, &H99, &H69, &HEA, &H9C, &H18, &HAE, &H63, &HDF, &HE7, &HBB, + &H0, &H73, &H66, &HFB, &H96, &H4C, &H85, &HE4, &H3A, &H9, &H45, &HAA, &HF, &HEE, &H10, &HEB, + &H2D, &H7F, &HF4, &H29, &HAC, &HCF, &HAD, &H91, &H8D, &H78, &HC8, &H95, &HF9, &H2F, &HCE, &HCD, + &H8, &H7A, &H88, &H38, &H5C, &H83, &H2A, &H28, &H47, &HDB, &HB8, &HC7, &H93, &HA4, &H12, &H53, + &HFF, &H87, &HE, &H31, &H36, &H21, &H58, &H48, &H1, &H8E, &H37, &H74, &H32, &HCA, &HE9, &HB1, + &HB7, &HAB, &HC, &HD7, &HC4, &H56, &H42, &H26, &H7, &H98, &H60, &HD9, &HB6, &HB9, &H11, &H40, + &HEC, &H20, &H8C, &HBD, &HA0, &HC9, &H84, &H4, &H49, &H23, &HF1, &H4F, &H50, &H1F, &H13, &HDC, + &HD8, &HC0, &H9E, &H57, &HE3, &HC3, &H7B, &H65, &H3B, &H2, &H8F, &H3E, &HE8, &H25, &H92, &HE5, + &H15, &HDD, &HFD, &H17, &HA9, &HBF, &HD4, &H9A, &H7E, &HC5, &H39, &H67, &HFE, &H76, &H9D, &H43, + &HA7, &HE1, &HD0, &HF5, &H68, &HF2, &H1B, &H34, &H70, &H5, &HA3, &H8A, &HD5, &H79, &H86, &HA8, + &H30, &HC6, &H51, &H4B, &H1E, &HA6, &H27, &HF6, &H35, &HD2, &H6E, &H24, &H16, &H82, &H5F, &HDA, + &HE6, &H75, &HA2, &HEF, &H2C, &HB2, &H1C, &H9F, &H5D, &H6F, &H80, &HA, &H72, &H44, &H9B, &H6C, + &H90, &HB, &H5B, &H33, &H7D, &H5A, &H52, &HF3, &H61, &HA1, &HF7, &HB0, &HD6, &H3F, &H7C, &H6D, + &HED, &H14, &HE0, &HA5, &H3D, &H22, &HB3, &HF8, &H89, &HDE, &H71, &H1A, &HAF, &HBA, &HB5, &H81 + }, + { + &H52, &H9, &H6A, &HD5, &H30, &H36, &HA5, &H38, &HBF, &H40, &HA3, &H9E, &H81, &HF3, &HD7, &HFB, + &H7C, &HE3, &H39, &H82, &H9B, &H2F, &HFF, &H87, &H34, &H8E, &H43, &H44, &HC4, &HDE, &HE9, &HCB, + &H54, &H7B, &H94, &H32, &HA6, &HC2, &H23, &H3D, &HEE, &H4C, &H95, &HB, &H42, &HFA, &HC3, &H4E, + &H8, &H2E, &HA1, &H66, &H28, &HD9, &H24, &HB2, &H76, &H5B, &HA2, &H49, &H6D, &H8B, &HD1, &H25, + &H72, &HF8, &HF6, &H64, &H86, &H68, &H98, &H16, &HD4, &HA4, &H5C, &HCC, &H5D, &H65, &HB6, &H92, + &H6C, &H70, &H48, &H50, &HFD, &HED, &HB9, &HDA, &H5E, &H15, &H46, &H57, &HA7, &H8D, &H9D, &H84, + &H90, &HD8, &HAB, &H0, &H8C, &HBC, &HD3, &HA, &HF7, &HE4, &H58, &H5, &HB8, &HB3, &H45, &H6, + &HD0, &H2C, &H1E, &H8F, &HCA, &H3F, &HF, &H2, &HC1, &HAF, &HBD, &H3, &H1, &H13, &H8A, &H6B, + &H3A, &H91, &H11, &H41, &H4F, &H67, &HDC, &HEA, &H97, &HF2, &HCF, &HCE, &HF0, &HB4, &HE6, &H73, + &H96, &HAC, &H74, &H22, &HE7, &HAD, &H35, &H85, &HE2, &HF9, &H37, &HE8, &H1C, &H75, &HDF, &H6E, + &H47, &HF1, &H1A, &H71, &H1D, &H29, &HC5, &H89, &H6F, &HB7, &H62, &HE, &HAA, &H18, &HBE, &H1B, + &HFC, &H56, &H3E, &H4B, &HC6, &HD2, &H79, &H20, &H9A, &HDB, &HC0, &HFE, &H78, &HCD, &H5A, &HF4, + &H1F, &HDD, &HA8, &H33, &H88, &H7, &HC7, &H31, &HB1, &H12, &H10, &H59, &H27, &H80, &HEC, &H5F, + &H60, &H51, &H7F, &HA9, &H19, &HB5, &H4A, &HD, &H2D, &HE5, &H7A, &H9F, &H93, &HC9, &H9C, &HEF, + &HA0, &HE0, &H3B, &H4D, &HAE, &H2A, &HF5, &HB0, &HC8, &HEB, &HBB, &H3C, &H83, &H53, &H99, &H61, + &H17, &H2B, &H4, &H7E, &HBA, &H77, &HD6, &H26, &HE1, &H69, &H14, &H63, &H55, &H21, &HC, &H7D + }, + { + &H30, &H68, &H99, &H1B, &H87, &HB9, &H21, &H78, &H50, &H39, &HDB, &HE1, &H72, &H9, &H62, &H3C, + &H3E, &H7E, &H5E, &H8E, &HF1, &HA0, &HCC, &HA3, &H2A, &H1D, &HFB, &HB6, &HD6, &H20, &HC4, &H8D, + &H81, &H65, &HF5, &H89, &HCB, &H9D, &H77, &HC6, &H57, &H43, &H56, &H17, &HD4, &H40, &H1A, &H4D, + &HC0, &H63, &H6C, &HE3, &HB7, &HC8, &H64, &H6A, &H53, &HAA, &H38, &H98, &HC, &HF4, &H9B, &HED, + &H7F, &H22, &H76, &HAF, &HDD, &H3A, &HB, &H58, &H67, &H88, &H6, &HC3, &H35, &HD, &H1, &H8B, + &H8C, &HC2, &HE6, &H5F, &H2, &H24, &H75, &H93, &H66, &H1E, &HE5, &HE2, &H54, &HD8, &H10, &HCE, + &H7A, &HE8, &H8, &H2C, &H12, &H97, &H32, &HAB, &HB4, &H27, &HA, &H23, &HDF, &HEF, &HCA, &HD9, + &HB8, &HFA, &HDC, &H31, &H6B, &HD1, &HAD, &H19, &H49, &HBD, &H51, &H96, &HEE, &HE4, &HA8, &H41, + &HDA, &HFF, &HCD, &H55, &H86, &H36, &HBE, &H61, &H52, &HF8, &HBB, &HE, &H82, &H48, &H69, &H9A, + &HE0, &H47, &H9E, &H5C, &H4, &H4B, &H34, &H15, &H79, &H26, &HA7, &HDE, &H29, &HAE, &H92, &HD7, + &H84, &HE9, &HD2, &HBA, &H5D, &HF3, &HC5, &HB0, &HBF, &HA4, &H3B, &H71, &H44, &H46, &H2B, &HFC, + &HEB, &H6F, &HD5, &HF6, &H14, &HFE, &H7C, &H70, &H5A, &H7D, &HFD, &H2F, &H18, &H83, &H16, &HA5, + &H91, &H1F, &H5, &H95, &H74, &HA9, &HC1, &H5B, &H4A, &H85, &H6D, &H13, &H7, &H4F, &H4E, &H45, + &HB2, &HF, &HC9, &H1C, &HA6, &HBC, &HEC, &H73, &H90, &H7B, &HCF, &H59, &H8F, &HA1, &HF9, &H2D, + &HF2, &HB1, &H0, &H94, &H37, &H9F, &HD0, &H2E, &H9C, &H6E, &H28, &H3F, &H80, &HF0, &H3D, &HD3, + &H25, &H8A, &HB5, &HE7, &H42, &HB3, &HC7, &HEA, &HF7, &H4C, &H11, &H33, &H3, &HA2, &HAC, &H60 + } + } + End Sub + + Public Sub DL(ByRef input() As Byte, ByRef output() As Byte) + Dim T As Byte + T = input(3) Xor input(4) Xor input(9) Xor input(14) + output(0) = input(6) Xor input(8) Xor input(13) Xor T + output(5) = input(1) Xor input(10) Xor input(15) Xor T + output(11) = input(2) Xor input(7) Xor input(12) Xor T + output(14) = input(0) Xor input(5) Xor input(11) Xor T + T = input(2) Xor input(5) Xor input(8) Xor input(15) + output(1) = input(7) Xor input(9) Xor input(12) Xor T + output(4) = input(0) Xor input(11) Xor input(14) Xor T + output(10) = input(3) Xor input(6) Xor input(13) Xor T + output(15) = input(1) Xor input(4) Xor input(10) Xor T + T = input(1) Xor input(6) Xor input(11) Xor input(12) + output(2) = input(4) Xor input(10) Xor input(15) Xor T + output(7) = input(3) Xor input(8) Xor input(13) Xor T + output(9) = input(0) Xor input(5) Xor input(14) Xor T + output(12) = input(2) Xor input(7) Xor input(9) Xor T + T = input(0) Xor input(7) Xor input(10) Xor input(13) + output(3) = input(5) Xor input(11) Xor input(14) Xor T + output(6) = input(2) Xor input(9) Xor input(12) Xor T + output(8) = input(1) Xor input(4) Xor input(15) Xor T + output(13) = input(3) Xor input(6) Xor input(8) Xor T + End Sub + + Public Sub RotXOR(ByRef s() As Byte, n As Integer, ByRef t() As Byte, Optional offset As Integer = 0) + Dim i As Integer, q As Integer = n \ 8 : n = n Mod 8 + For i = 0 To 15 + t((q + i) Mod 16 + offset) = t((q + i) Mod 16 + offset) Xor (s(i) >> n) + If n <> 0 Then + t((q + i + 1) Mod 16 + offset) = t((q + i + 1) Mod 16 + offset) Xor (s(i) << (8 - n)) + End If + Next + End Sub + + Public Function EncKeySetup(ByRef w0() As Byte, ByRef e() As Byte) As Integer + Dim i As Integer + Dim R As Integer = (KeyBits + 256) \ 32, q As Integer + Dim t(15), w1(15), w2(15), w3(15) As Byte + q = (KeyBits - 128) \ 64 + For i = 0 To 15 : t(i) = S(i Mod 4, KRK(q, i) Xor w0(i)) : Next + DL(t, w1) + If R = 14 Then For i = 0 To 7 : w1(i) = w1(i) Xor w0(16 + i) : Next + If R = 16 Then For i = 0 To 15 : w1(i) = w1(i) Xor w0(16 + i) : Next + q = If(q = 2, 0, q + 1) + For i = 0 To 15 : t(i) = S((2 + i) Mod 4, KRK(q, i) Xor w1(i)) : Next + DL(t, w2) + For i = 0 To 15 : w2(i) = w2(i) Xor w0(i) : Next + q = If(q = 2, 0, q + 1) + For i = 0 To 15 : t(i) = S(i Mod 4, KRK(q, i) Xor w2(i)) : Next + DL(t, w3) + For i = 0 To 15 : w3(i) = w3(i) Xor w1(i) : Next + For i = 0 To 16 * (R + 1) - 1 : e(i) = 0 : Next + RotXOR(w0, 0, e) : RotXOR(w1, 19, e) + RotXOR(w1, 0, e, 16) : RotXOR(w2, 19, e, 16) + RotXOR(w2, 0, e, 32) : RotXOR(w3, 19, e, 32) + RotXOR(w3, 0, e, 48) : RotXOR(w0, 19, e, 48) + RotXOR(w0, 0, e, 64) : RotXOR(w1, 31, e, 64) + RotXOR(w1, 0, e, 80) : RotXOR(w2, 31, e, 80) + RotXOR(w2, 0, e, 96) : RotXOR(w3, 31, e, 96) + RotXOR(w3, 0, e, 112) : RotXOR(w0, 31, e, 112) + RotXOR(w0, 0, e, 128) : RotXOR(w1, 67, e, 128) + RotXOR(w1, 0, e, 144) : RotXOR(w2, 67, e, 144) + RotXOR(w2, 0, e, 160) : RotXOR(w3, 67, e, 160) + RotXOR(w3, 0, e, 176) : RotXOR(w0, 67, e, 176) + RotXOR(w0, 0, e, 192) : RotXOR(w1, 97, e, 192) + If R > 12 Then + RotXOR(w1, 0, e, 208) : RotXOR(w2, 97, e, 208) + RotXOR(w2, 0, e, 224) : RotXOR(w3, 97, e, 224) + End If + If R > 14 Then + RotXOR(w3, 0, e, 240) : RotXOR(w0, 97, e, 240) + RotXOR(w0, 0, e, 256) : RotXOR(w1, 109, e, 256) + End If + Return R + End Function + + Public Sub DecKeySetup(ByRef w0() As Byte, ByRef d() As Byte) + Dim r As Integer = EncKeySetup(w0, d) + Dim t(15) As Byte, i, j As Integer + For j = 0 To 15 + t(j) = d(j) + d(j) = d(16 * r + j) + d(16 * r + j) = t(j) + Next + For i = 1 To r \ 2 + Dim input1(15), input2(15), output1(15), output2(15) As Byte + Array.Copy(d, i * 16, input1, 0, 16) + DL(input1, output1) + Array.Copy(d, (r - i) * 16, input2, 0, 16) + DL(input2, output2) + Array.Copy(output2, 0, d, i * 16, 16) + Array.Copy(output1, 0, d, (r - i) * 16, 16) + Next + End Sub + + Public Sub Crypt(ByRef p() As Byte, R As Integer, ByRef e() As Byte, ByRef c() As Byte) + Dim i, j As Integer + Dim t(15) As Byte + Dim eOffset As Integer = 0 + For j = 0 To 15 : c(j) = p(j) : Next + For i = 0 To (R \ 2) - 1 + For j = 0 To 15 : t(j) = S(j Mod 4, e(eOffset + j) Xor c(j)) : Next + DL(t, c) + eOffset += 16 + For j = 0 To 15 : t(j) = S((2 + j) Mod 4, e(eOffset + j) Xor c(j)) : Next + DL(t, c) + eOffset += 16 + Next + DL(c, t) + For j = 0 To 15 : c(j) = e(eOffset + j) Xor t(j) : Next + End Sub +End Class diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaEcbTransform.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaEcbTransform.vb new file mode 100644 index 0000000..bd8af41 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/AriaEcbTransform.vb @@ -0,0 +1,168 @@ +' AriaEcbTransform.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Imports System.Security.Cryptography + +Public Class AriaEcbTransform + Implements ICryptoTransform + + Private ReadOnly rnd As New Random() + Private ReadOnly core As AriaCore + Private ReadOnly encrypt As Boolean + Private ReadOnly paddingMode As PaddingMode + + Public Sub New(key As Byte(), encryptMode As Boolean, Optional mode As PaddingMode = PaddingMode.PKCS7) + core = New AriaCore(key) + encrypt = encryptMode + paddingMode = mode + End Sub + + Public ReadOnly Property InputBlockSize As Integer Implements ICryptoTransform.InputBlockSize + Get + Return 16 + End Get + End Property + + Public ReadOnly Property OutputBlockSize As Integer Implements ICryptoTransform.OutputBlockSize + Get + Return 16 + End Get + End Property + + Public ReadOnly Property CanTransformMultipleBlocks As Boolean Implements ICryptoTransform.CanTransformMultipleBlocks + Get + Return True + End Get + End Property + + Public ReadOnly Property CanReuseTransform As Boolean Implements ICryptoTransform.CanReuseTransform + Get + Return True + End Get + End Property + + Public Function TransformBlock(input() As Byte, inputOffset As Integer, inputCount As Integer, + output() As Byte, outputOffset As Integer) As Integer Implements ICryptoTransform.TransformBlock + If inputCount <= 0 Then Return 0 + + Dim blockSize = InputBlockSize + Dim remaining = inputCount + Dim inPtr = inputOffset + Dim outPtr = outputOffset + + While remaining >= blockSize + If encrypt Then + core.EncryptBlock(input, inPtr, output, outPtr) + Else + core.DecryptBlock(input, inPtr, output, outPtr) + End If + inPtr += blockSize + outPtr += blockSize + remaining -= blockSize + End While + + Return inputCount - remaining + End Function + + Public Function TransformFinalBlock(input() As Byte, inputOffset As Integer, inputCount As Integer) As Byte() Implements ICryptoTransform.TransformFinalBlock + Dim blockSize = InputBlockSize + Dim buffer() As Byte + + If paddingMode = PaddingMode.None Then + buffer = New Byte(inputCount - 1) {} + TransformBlock(input, inputOffset, inputCount, buffer, 0) + Return buffer + End If + + If encrypt Then + Dim paddedLength As Integer + Select Case paddingMode + Case PaddingMode.None + If (inputCount Mod blockSize) <> 0 Then + Throw New CryptographicException("Input data is not a multiple of block size and PaddingMode is None.") + End If + paddedLength = inputCount + + Case PaddingMode.Zeros + paddedLength = ((inputCount + blockSize - 1) \ blockSize) * blockSize + + Case PaddingMode.PKCS7, PaddingMode.ANSIX923, PaddingMode.ISO10126 + Dim padLen = blockSize - (inputCount Mod blockSize) + If padLen = 0 Then padLen = blockSize + paddedLength = inputCount + padLen + + Case Else + Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) + End Select + + buffer = New Byte(paddedLength - 1) {} + Array.Copy(input, inputOffset, buffer, 0, inputCount) + + Dim padVal As Byte = CByte(paddedLength - inputCount) + Select Case paddingMode + Case PaddingMode.PKCS7 + For i = inputCount To paddedLength - 1 + buffer(i) = padVal + Next + Case PaddingMode.ANSIX923 + For i = inputCount To paddedLength - 2 + buffer(i) = 0 + Next + buffer(paddedLength - 1) = padVal + Case PaddingMode.ISO10126 + For i = inputCount To paddedLength - 2 + buffer(i) = CByte(rnd.Next(0, 256)) + Next + buffer(paddedLength - 1) = padVal + End Select + + For i = 0 To buffer.Length - 1 Step blockSize + core.EncryptBlock(buffer, i, buffer, i) + Next + Return buffer + + Else + If (inputCount Mod blockSize) <> 0 Then + Throw New CryptographicException("Encrypted data is not a multiple of block size.") + End If + + buffer = New Byte(inputCount - 1) {} + TransformBlock(input, inputOffset, inputCount, buffer, 0) + + Dim padVal As Integer = buffer(buffer.Length - 1) + If padVal <= 0 OrElse padVal > blockSize Then + ' Throw New CryptographicException("Invalid padding.") + Return buffer + End If + + Select Case paddingMode + Case PaddingMode.PKCS7 + For i = buffer.Length - padVal To buffer.Length - 1 + If buffer(i) <> padVal Then + Throw New CryptographicException("Invalid PKCS7 padding value.") + End If + Next + Case PaddingMode.ANSIX923 + For i = buffer.Length - padVal To buffer.Length - 2 + If buffer(i) <> 0 Then + Throw New CryptographicException("Invalid ANSIX923 padding value.") + End If + Next + Case PaddingMode.ISO10126 + ' no need to check random bytes, only length byte matters + Case Else + Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) + End Select + + Dim result(buffer.Length - padVal - 1) As Byte + Array.Copy(buffer, 0, result, 0, result.Length) + Return result + End If + End Function + + Public Sub Dispose() Implements IDisposable.Dispose + ' No resources to dispose + End Sub +End Class diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/HightAlgorithm.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/HightAlgorithm.vb new file mode 100644 index 0000000..73dcefa --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/HightAlgorithm.vb @@ -0,0 +1,56 @@ +' HightAlgorithm.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Imports System.Security.Cryptography + +Public Class HightAlgorithm + Inherits SymmetricAlgorithm + + Public Sub New() + LegalBlockSizesValue = New KeySizes() {New KeySizes(64, 64, 0)} + LegalKeySizesValue = New KeySizes() {New KeySizes(128, 128, 0)} + + Me.BlockSize = 64 + Me.KeySize = 128 + Me.FeedbackSize = 64 + + Me.Mode = CipherMode.ECB + Me.Padding = PaddingMode.PKCS7 + + Me.Key = New Byte(15) {} + Me.IV = New Byte(7) {} + End Sub + + Public Overrides Sub GenerateKey() + Using rng As New RNGCryptoServiceProvider() + rng.GetBytes(Me.Key) + End Using + End Sub + + Public Overrides Sub GenerateIV() + Using rng As New RNGCryptoServiceProvider() + rng.GetBytes(Me.IV) + End Using + End Sub + + Public Overrides Function CreateEncryptor(rgbKey As Byte(), rgbIV As Byte()) As ICryptoTransform + Return CreateTransform(rgbKey, rgbIV, True) + End Function + + Public Overrides Function CreateDecryptor(rgbKey As Byte(), rgbIV As Byte()) As ICryptoTransform + Return CreateTransform(rgbKey, rgbIV, False) + End Function + + Private Function CreateTransform(key As Byte(), iv As Byte(), encrypt As Boolean) As ICryptoTransform + Select Case Me.Mode + Case CipherMode.ECB + Return New HightEcbTransform(key, encrypt, Me.Padding) + Case Else + Throw New NotSupportedException("This mode not supported yet") + End Select + End Function + + ' TODO: CCM, GCM, CMAC +End Class \ No newline at end of file diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/HightCore.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/HightCore.vb new file mode 100644 index 0000000..01fec35 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/HightCore.vb @@ -0,0 +1,201 @@ +' HightCore.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Public Class HightCore + Private ReadOnly roundKey(135) As Byte + Private Shared ReadOnly DELTA As Byte() = { + &H5A, &H6D, &H36, &H1B, &HD, &H6, &H3, &H41, + &H60, &H30, &H18, &H4C, &H66, &H33, &H59, &H2C, + &H56, &H2B, &H15, &H4A, &H65, &H72, &H39, &H1C, + &H4E, &H67, &H73, &H79, &H3C, &H5E, &H6F, &H37, + &H5B, &H2D, &H16, &HB, &H5, &H42, &H21, &H50, + &H28, &H54, &H2A, &H55, &H6A, &H75, &H7A, &H7D, + &H3E, &H5F, &H2F, &H17, &H4B, &H25, &H52, &H29, + &H14, &HA, &H45, &H62, &H31, &H58, &H6C, &H76, + &H3B, &H1D, &HE, &H47, &H63, &H71, &H78, &H7C, + &H7E, &H7F, &H3F, &H1F, &HF, &H7, &H43, &H61, + &H70, &H38, &H5C, &H6E, &H77, &H7B, &H3D, &H1E, + &H4F, &H27, &H53, &H69, &H34, &H1A, &H4D, &H26, + &H13, &H49, &H24, &H12, &H9, &H4, &H2, &H1, + &H40, &H20, &H10, &H8, &H44, &H22, &H11, &H48, + &H64, &H32, &H19, &HC, &H46, &H23, &H51, &H68, + &H74, &H3A, &H5D, &H2E, &H57, &H6B, &H35, &H5A + } + + Private Shared ReadOnly F0_TABLE As Byte() = { + &H0, &H86, &HD, &H8B, &H1A, &H9C, &H17, &H91, &H34, &HB2, &H39, &HBF, &H2E, &HA8, &H23, &HA5, + &H68, &HEE, &H65, &HE3, &H72, &HF4, &H7F, &HF9, &H5C, &HDA, &H51, &HD7, &H46, &HC0, &H4B, &HCD, + &HD0, &H56, &HDD, &H5B, &HCA, &H4C, &HC7, &H41, &HE4, &H62, &HE9, &H6F, &HFE, &H78, &HF3, &H75, + &HB8, &H3E, &HB5, &H33, &HA2, &H24, &HAF, &H29, &H8C, &HA, &H81, &H7, &H96, &H10, &H9B, &H1D, + &HA1, &H27, &HAC, &H2A, &HBB, &H3D, &HB6, &H30, &H95, &H13, &H98, &H1E, &H8F, &H9, &H82, &H4, + &HC9, &H4F, &HC4, &H42, &HD3, &H55, &HDE, &H58, &HFD, &H7B, &HF0, &H76, &HE7, &H61, &HEA, &H6C, + &H71, &HF7, &H7C, &HFA, &H6B, &HED, &H66, &HE0, &H45, &HC3, &H48, &HCE, &H5F, &HD9, &H52, &HD4, + &H19, &H9F, &H14, &H92, &H3, &H85, &HE, &H88, &H2D, &HAB, &H20, &HA6, &H37, &HB1, &H3A, &HBC, + &H43, &HC5, &H4E, &HC8, &H59, &HDF, &H54, &HD2, &H77, &HF1, &H7A, &HFC, &H6D, &HEB, &H60, &HE6, + &H2B, &HAD, &H26, &HA0, &H31, &HB7, &H3C, &HBA, &H1F, &H99, &H12, &H94, &H5, &H83, &H8, &H8E, + &H93, &H15, &H9E, &H18, &H89, &HF, &H84, &H2, &HA7, &H21, &HAA, &H2C, &HBD, &H3B, &HB0, &H36, + &HFB, &H7D, &HF6, &H70, &HE1, &H67, &HEC, &H6A, &HCF, &H49, &HC2, &H44, &HD5, &H53, &HD8, &H5E, + &HE2, &H64, &HEF, &H69, &HF8, &H7E, &HF5, &H73, &HD6, &H50, &HDB, &H5D, &HCC, &H4A, &HC1, &H47, + &H8A, &HC, &H87, &H1, &H90, &H16, &H9D, &H1B, &HBE, &H38, &HB3, &H35, &HA4, &H22, &HA9, &H2F, + &H32, &HB4, &H3F, &HB9, &H28, &HAE, &H25, &HA3, &H6, &H80, &HB, &H8D, &H1C, &H9A, &H11, &H97, + &H5A, &HDC, &H57, &HD1, &H40, &HC6, &H4D, &HCB, &H6E, &HE8, &H63, &HE5, &H74, &HF2, &H79, &HFF + } + + Private Shared ReadOnly F1_TABLE As Byte() = { + &H0, &H58, &HB0, &HE8, &H61, &H39, &HD1, &H89, &HC2, &H9A, &H72, &H2A, &HA3, &HFB, &H13, &H4B, + &H85, &HDD, &H35, &H6D, &HE4, &HBC, &H54, &HC, &H47, &H1F, &HF7, &HAF, &H26, &H7E, &H96, &HCE, + &HB, &H53, &HBB, &HE3, &H6A, &H32, &HDA, &H82, &HC9, &H91, &H79, &H21, &HA8, &HF0, &H18, &H40, + &H8E, &HD6, &H3E, &H66, &HEF, &HB7, &H5F, &H7, &H4C, &H14, &HFC, &HA4, &H2D, &H75, &H9D, &HC5, + &H16, &H4E, &HA6, &HFE, &H77, &H2F, &HC7, &H9F, &HD4, &H8C, &H64, &H3C, &HB5, &HED, &H5D, &H5D, + &H93, &HCB, &H23, &H7B, &HF2, &HAA, &H42, &H1A, &H51, &H9, &HE1, &HB9, &H30, &H68, &H80, &HD8, + &H1D, &H45, &HAD, &HF5, &H7C, &H24, &HCC, &H94, &HDF, &H87, &H6F, &H37, &HBE, &HE6, &HE, &H56, + &H98, &HC0, &H28, &H70, &HF9, &HA1, &H49, &H11, &H5A, &H2, &HEA, &HB2, &H3B, &H63, &H8B, &HD3, + &H2C, &H74, &H9C, &HC4, &H4D, &H15, &HFD, &HA5, &HEE, &HB6, &H5E, &H6, &H8F, &HD7, &H3F, &H67, + &HA9, &HF1, &H19, &H41, &HC8, &H90, &H78, &H20, &H6B, &H33, &HDB, &H83, &HA, &H52, &HBA, &HE2, + &H27, &H7F, &H97, &HCF, &H46, &H1E, &HF6, &HAE, &HE5, &HBD, &H55, &HD, &H84, &HDC, &H34, &H6C, + &HA2, &HFA, &H12, &H4A, &HC3, &H9B, &H73, &H2B, &H60, &H38, &HD0, &H88, &H1, &H59, &HB1, &HE9, + &H3A, &H62, &H8A, &HD2, &H5B, &H3, &HEB, &HB3, &HF8, &HA0, &H48, &H10, &H99, &HC1, &H29, &H71, + &HBF, &HE7, &HF, &H57, &HDE, &H86, &H6E, &H36, &H7D, &H25, &HCD, &H95, &H1C, &H44, &HAC, &HF4, + &H31, &H69, &H81, &HD9, &H50, &H8, &HE0, &HB8, &HF3, &HAB, &H43, &H1B, &H92, &HCA, &H22, &H7A, + &HB4, &HEC, &H4, &H5C, &HD5, &H8D, &H65, &H3D, &H76, &H2E, &HC6, &H9E, &H17, &H4F, &HA7, &HFF + } + + Public Sub New(userKey As Byte()) + If userKey.Length <> 16 Then Throw New ArgumentException("Key must be 16 bytes") + KeySchedule(userKey) + End Sub + + Private Function F0(x As Byte) As Byte + Return F0_TABLE(x) + End Function + + Private Function F1(x As Byte) As Byte + Return F1_TABLE(x) + End Function + + Private Function Mod8(x As Integer) As Integer + Return ((x Mod 8) + 8) Mod 8 + End Function + + Private Sub KeySchedule(key As Byte()) + If key.Length <> 16 Then Throw New ArgumentException("Key must be 16 bytes") + + ' 1. Set the whitening key (WK0 ~ WK7): Use MK[8..15] + For i As Integer = 0 To 7 + roundKey(i) = key(8 + i) + Next + + ' 2. Set the round key (key length is 128) + For i As Integer = 0 To 7 + For j As Integer = 0 To 7 + Dim idx = 16 * i + j + roundKey(8 + idx) = CByte((key(8 + Mod8(j - i)) + DELTA(idx)) And &HFF) + roundKey(8 + idx + 8) = CByte((key(Mod8(j - i)) + DELTA(idx + 8)) And &HFF) + Next + Next + End Sub + + Public Sub EncryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) + Dim XX(7) As Byte + + ' First Round + XX(1) = input(inOffset + 1) + XX(3) = input(inOffset + 3) + XX(5) = input(inOffset + 5) + XX(7) = input(inOffset + 7) + + XX(0) = CByte((input(inOffset + 0) + roundKey(0)) And &HFF) + XX(2) = CByte(input(inOffset + 2) Xor roundKey(1)) + XX(4) = CByte((input(inOffset + 4) + roundKey(2)) And &HFF) + XX(6) = CByte(input(inOffset + 6) Xor roundKey(3)) + + Dim HIGHT_ENC As Action(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer) = + Sub(k, i0, i1, i2, i3, i4, i5, i6, i7) + XX(i0) = CByte((XX(i0) Xor (F0(XX(i1)) + roundKey(4 * k + 3))) And &HFF) + XX(i2) = CByte((XX(i2) + (F1(XX(i3)) Xor roundKey(4 * k + 2))) And &HFF) + XX(i4) = CByte((XX(i4) Xor (F0(XX(i5)) + roundKey(4 * k + 1))) And &HFF) + XX(i6) = CByte((XX(i6) + (F1(XX(i7)) Xor roundKey(4 * k + 0))) And &HFF) + End Sub + + Dim encRounds As Integer()() = { + New Integer() {7, 6, 5, 4, 3, 2, 1, 0}, + New Integer() {6, 5, 4, 3, 2, 1, 0, 7}, + New Integer() {5, 4, 3, 2, 1, 0, 7, 6}, + New Integer() {4, 3, 2, 1, 0, 7, 6, 5}, + New Integer() {3, 2, 1, 0, 7, 6, 5, 4}, + New Integer() {2, 1, 0, 7, 6, 5, 4, 3}, + New Integer() {1, 0, 7, 6, 5, 4, 3, 2}, + New Integer() {0, 7, 6, 5, 4, 3, 2, 1} + } + + For round As Integer = 2 To 33 + Dim seq As Integer() = encRounds((round - 2) Mod 8) + HIGHT_ENC(round, seq(0), seq(1), seq(2), seq(3), seq(4), seq(5), seq(6), seq(7)) + Next + + output(outOffset + 1) = XX(2) + output(outOffset + 3) = XX(4) + output(outOffset + 5) = XX(6) + output(outOffset + 7) = XX(0) + + output(outOffset + 0) = CByte((XX(1) + roundKey(4)) And &HFF) + output(outOffset + 2) = CByte(XX(3) Xor roundKey(5)) + output(outOffset + 4) = CByte((XX(5) + roundKey(6)) And &HFF) + output(outOffset + 6) = CByte(XX(7) Xor roundKey(7)) + End Sub + + Public Sub DecryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) + Dim XX(7) As Byte + + ' Initial Round + XX(2) = input(inOffset + 1) + XX(4) = input(inOffset + 3) + XX(6) = input(inOffset + 5) + XX(0) = input(inOffset + 7) + + XX(1) = CByte((input(inOffset + 0) - roundKey(4)) And &HFF) + XX(3) = CByte(input(inOffset + 2) Xor roundKey(5)) + XX(5) = CByte((input(inOffset + 4) - roundKey(6)) And &HFF) + XX(7) = CByte(input(inOffset + 6) Xor roundKey(7)) + + ' HIGHT_DEC as Action + Dim HIGHT_DEC As Action(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer) = + Sub(k, i0, i1, i2, i3, i4, i5, i6, i7) + XX(i1) = CByte((XX(i1) - (F1(XX(i2)) Xor roundKey(4 * k + 2))) And &HFF) + XX(i3) = CByte((XX(i3) Xor (F0(XX(i4)) + roundKey(4 * k + 1))) And &HFF) + XX(i5) = CByte((XX(i5) - (F1(XX(i6)) Xor roundKey(4 * k + 0))) And &HFF) + XX(i7) = CByte((XX(i7) Xor (F0(XX(i0)) + roundKey(4 * k + 3))) And &HFF) + End Sub + + ' Round pattern (same as encryption, reused) + Dim decRounds As Integer()() = { + New Integer() {7, 6, 5, 4, 3, 2, 1, 0}, + New Integer() {0, 7, 6, 5, 4, 3, 2, 1}, + New Integer() {1, 0, 7, 6, 5, 4, 3, 2}, + New Integer() {2, 1, 0, 7, 6, 5, 4, 3}, + New Integer() {3, 2, 1, 0, 7, 6, 5, 4}, + New Integer() {4, 3, 2, 1, 0, 7, 6, 5}, + New Integer() {5, 4, 3, 2, 1, 0, 7, 6}, + New Integer() {6, 5, 4, 3, 2, 1, 0, 7} + } + + ' Apply decryption rounds + For round As Integer = 33 To 2 Step -1 + Dim seq As Integer() = decRounds((33 - round) Mod 8) + HIGHT_DEC(round, seq(0), seq(1), seq(2), seq(3), seq(4), seq(5), seq(6), seq(7)) + Next + + ' Final output + output(outOffset + 1) = XX(1) + output(outOffset + 3) = XX(3) + output(outOffset + 5) = XX(5) + output(outOffset + 7) = XX(7) + + output(outOffset + 0) = CByte((XX(0) - roundKey(0)) And &HFF) + output(outOffset + 2) = CByte(XX(2) Xor roundKey(1)) + output(outOffset + 4) = CByte((XX(4) - roundKey(2)) And &HFF) + output(outOffset + 6) = CByte(XX(6) Xor roundKey(3)) + End Sub +End Class diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/HightEcbTransform.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/HightEcbTransform.vb new file mode 100644 index 0000000..68adea9 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/HightEcbTransform.vb @@ -0,0 +1,161 @@ +' HightEcbTransform.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Imports System.Security.Cryptography + +Public Class HightEcbTransform + Implements ICryptoTransform + + Private ReadOnly rnd As New Random() + Private ReadOnly core As HightCore + Private ReadOnly encrypt As Boolean + Private ReadOnly paddingMode As PaddingMode + + Public Sub New(key As Byte(), encryptMode As Boolean, Optional mode As PaddingMode = PaddingMode.PKCS7) + core = New HightCore(key) + encrypt = encryptMode + paddingMode = mode + End Sub + + Public ReadOnly Property InputBlockSize As Integer Implements ICryptoTransform.InputBlockSize + Get + Return 8 + End Get + End Property + + Public ReadOnly Property OutputBlockSize As Integer Implements ICryptoTransform.OutputBlockSize + Get + Return 8 + End Get + End Property + + Public ReadOnly Property CanTransformMultipleBlocks As Boolean Implements ICryptoTransform.CanTransformMultipleBlocks + Get + Return True + End Get + End Property + + Public ReadOnly Property CanReuseTransform As Boolean Implements ICryptoTransform.CanReuseTransform + Get + Return True + End Get + End Property + + Public Function TransformBlock(input() As Byte, inputOffset As Integer, inputCount As Integer, + output() As Byte, outputOffset As Integer) As Integer Implements ICryptoTransform.TransformBlock + If inputCount <= 0 Then Return 0 + + Dim blockSize = InputBlockSize + Dim remaining = inputCount + Dim inPtr = inputOffset + Dim outPtr = outputOffset + + While remaining >= blockSize + If encrypt Then + core.EncryptBlock(input, inPtr, output, outPtr) + Else + core.DecryptBlock(input, inPtr, output, outPtr) + End If + inPtr += blockSize + outPtr += blockSize + remaining -= blockSize + End While + + Return inputCount - remaining + End Function + + Public Function TransformFinalBlock(input() As Byte, inputOffset As Integer, inputCount As Integer) As Byte() Implements ICryptoTransform.TransformFinalBlock + Dim blockSize = InputBlockSize + Dim buffer() As Byte + + If paddingMode = PaddingMode.None Then + buffer = New Byte(inputCount - 1) {} + TransformBlock(input, inputOffset, inputCount, buffer, 0) + Return buffer + End If + + If encrypt Then + Dim paddedLength As Integer + Select Case paddingMode + Case PaddingMode.Zeros + paddedLength = ((inputCount + blockSize - 1) \ blockSize) * blockSize + + Case PaddingMode.PKCS7, PaddingMode.ANSIX923, PaddingMode.ISO10126 + Dim padLen = blockSize - (inputCount Mod blockSize) + If padLen = 0 Then padLen = blockSize + paddedLength = inputCount + padLen + + Case Else + Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) + End Select + + buffer = New Byte(paddedLength - 1) {} + Array.Copy(input, inputOffset, buffer, 0, inputCount) + + Dim padVal As Byte = CByte(paddedLength - inputCount) + Select Case paddingMode + Case PaddingMode.PKCS7 + For i = inputCount To paddedLength - 1 + buffer(i) = padVal + Next + Case PaddingMode.ANSIX923 + For i = inputCount To paddedLength - 2 + buffer(i) = 0 + Next + buffer(paddedLength - 1) = padVal + Case PaddingMode.ISO10126 + For i = inputCount To paddedLength - 2 + buffer(i) = CByte(rnd.Next(0, 256)) + Next + buffer(paddedLength - 1) = padVal + End Select + + For i = 0 To buffer.Length - 1 Step blockSize + core.EncryptBlock(buffer, i, buffer, i) + Next + Return buffer + + Else + If (inputCount Mod blockSize) <> 0 Then + Throw New CryptographicException("Encrypted data is not a multiple of block size.") + End If + + buffer = New Byte(inputCount - 1) {} + TransformBlock(input, inputOffset, inputCount, buffer, 0) + + Dim padVal As Integer = buffer(buffer.Length - 1) + If padVal <= 0 OrElse padVal > blockSize Then + Throw New CryptographicException("Invalid padding.") + End If + + Select Case paddingMode + Case PaddingMode.PKCS7 + For i = buffer.Length - padVal To buffer.Length - 1 + If buffer(i) <> padVal Then + Throw New CryptographicException("Invalid PKCS7 padding value.") + End If + Next + Case PaddingMode.ANSIX923 + For i = buffer.Length - padVal To buffer.Length - 2 + If buffer(i) <> 0 Then + Throw New CryptographicException("Invalid ANSIX923 padding value.") + End If + Next + Case PaddingMode.ISO10126 + ' no need to check random bytes, only length byte matters + Case Else + Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) + End Select + + Dim result(buffer.Length - padVal - 1) As Byte + Array.Copy(buffer, 0, result, 0, result.Length) + Return result + End If + End Function + + Public Sub Dispose() Implements IDisposable.Dispose + ' No resources to dispose + End Sub +End Class diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedAlgorithm.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedAlgorithm.vb new file mode 100644 index 0000000..085ac70 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedAlgorithm.vb @@ -0,0 +1,56 @@ +' SeedAlgorithm.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Imports System.Security.Cryptography + +Public Class SeedAlgorithm + Inherits SymmetricAlgorithm + + Public Sub New() + LegalBlockSizesValue = New KeySizes() {New KeySizes(128, 128, 0)} + LegalKeySizesValue = New KeySizes() {New KeySizes(128, 128, 0)} + + Me.BlockSize = 128 + Me.KeySize = 128 + Me.FeedbackSize = 128 + + Me.Mode = CipherMode.ECB + Me.Padding = PaddingMode.PKCS7 + + Me.Key = New Byte(15) {} + Me.IV = New Byte(15) {} + End Sub + + Public Overrides Sub GenerateKey() + Using rng As New RNGCryptoServiceProvider() + rng.GetBytes(Me.Key) + End Using + End Sub + + Public Overrides Sub GenerateIV() + Using rng As New RNGCryptoServiceProvider() + rng.GetBytes(Me.IV) + End Using + End Sub + + Public Overrides Function CreateEncryptor(rgbKey As Byte(), rgbIV As Byte()) As ICryptoTransform + Return CreateTransform(rgbKey, rgbIV, True) + End Function + + Public Overrides Function CreateDecryptor(rgbKey As Byte(), rgbIV As Byte()) As ICryptoTransform + Return CreateTransform(rgbKey, rgbIV, False) + End Function + + Private Function CreateTransform(key As Byte(), iv As Byte(), encrypt As Boolean) As ICryptoTransform + Select Case Me.Mode + Case CipherMode.ECB + Return New SeedEcbTransform(key, encrypt, Me.Padding) + Case Else + Throw New NotSupportedException("This mode not supported yet") + End Select + End Function + + ' TODO: CCM, GCM, CMAC +End Class \ No newline at end of file diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedCore.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedCore.vb new file mode 100644 index 0000000..b92cd76 --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedCore.vb @@ -0,0 +1,256 @@ +' SeedCore.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs +' +Public Class SeedCore + Private ReadOnly roundKey(31) As UInteger + + Private Shared ReadOnly SS0() As UInteger = { + &H2989A1A8UI, &H5858184UI, &H16C6D2D4UI, &H13C3D3D0UI, &H14445054UI, &H1D0D111CUI, &H2C8CA0ACUI, &H25052124UI, + &H1D4D515CUI, &H3434340UI, &H18081018UI, &H1E0E121CUI, &H11415150UI, &H3CCCF0FCUI, &HACAC2C8UI, &H23436360UI, + &H28082028UI, &H4444044UI, &H20002020UI, &H1D8D919CUI, &H20C0E0E0UI, &H22C2E2E0UI, &H8C8C0C8UI, &H17071314UI, + &H2585A1A4UI, &HF8F838CUI, &H3030300UI, &H3B4B7378UI, &H3B8BB3B8UI, &H13031310UI, &H12C2D2D0UI, &H2ECEE2ECUI, + &H30407070UI, &HC8C808CUI, &H3F0F333CUI, &H2888A0A8UI, &H32023230UI, &H1DCDD1DCUI, &H36C6F2F4UI, &H34447074UI, + &H2CCCE0ECUI, &H15859194UI, &HB0B0308UI, &H17475354UI, &H1C4C505CUI, &H1B4B5358UI, &H3D8DB1BCUI, &H1010100UI, + &H24042024UI, &H1C0C101CUI, &H33437370UI, &H18889098UI, &H10001010UI, &HCCCC0CCUI, &H32C2F2F0UI, &H19C9D1D8UI, + &H2C0C202CUI, &H27C7E3E4UI, &H32427270UI, &H3838380UI, &H1B8B9398UI, &H11C1D1D0UI, &H6868284UI, &H9C9C1C8UI, + &H20406060UI, &H10405050UI, &H2383A3A0UI, &H2BCBE3E8UI, &HD0D010CUI, &H3686B2B4UI, &H1E8E929CUI, &HF4F434CUI, + &H3787B3B4UI, &H1A4A5258UI, &H6C6C2C4UI, &H38487078UI, &H2686A2A4UI, &H12021210UI, &H2F8FA3ACUI, &H15C5D1D4UI, + &H21416160UI, &H3C3C3C0UI, &H3484B0B4UI, &H1414140UI, &H12425250UI, &H3D4D717CUI, &HD8D818CUI, &H8080008UI, + &H1F0F131CUI, &H19899198UI, &H0UI, &H19091118UI, &H4040004UI, &H13435350UI, &H37C7F3F4UI, &H21C1E1E0UI, + &H3DCDF1FCUI, &H36467274UI, &H2F0F232CUI, &H27072324UI, &H3080B0B0UI, &HB8B8388UI, &HE0E020CUI, &H2B8BA3A8UI, + &H2282A2A0UI, &H2E4E626CUI, &H13839390UI, &HD4D414CUI, &H29496168UI, &H3C4C707CUI, &H9090108UI, &HA0A0208UI, + &H3F8FB3BCUI, &H2FCFE3ECUI, &H33C3F3F0UI, &H5C5C1C4UI, &H7878384UI, &H14041014UI, &H3ECEF2FCUI, &H24446064UI, + &H1ECED2DCUI, &H2E0E222CUI, &HB4B4348UI, &H1A0A1218UI, &H6060204UI, &H21012120UI, &H2B4B6368UI, &H26466264UI, + &H2020200UI, &H35C5F1F4UI, &H12829290UI, &HA8A8288UI, &HC0C000CUI, &H3383B3B0UI, &H3E4E727CUI, &H10C0D0D0UI, + &H3A4A7278UI, &H7474344UI, &H16869294UI, &H25C5E1E4UI, &H26062224UI, &H808080UI, &H2D8DA1ACUI, &H1FCFD3DCUI, + &H2181A1A0UI, &H30003030UI, &H37073334UI, &H2E8EA2ACUI, &H36063234UI, &H15051114UI, &H22022220UI, &H38083038UI, + &H34C4F0F4UI, &H2787A3A4UI, &H5454144UI, &HC4C404CUI, &H1818180UI, &H29C9E1E8UI, &H4848084UI, &H17879394UI, + &H35053134UI, &HBCBC3C8UI, &HECEC2CCUI, &H3C0C303CUI, &H31417170UI, &H11011110UI, &H7C7C3C4UI, &H9898188UI, + &H35457174UI, &H3BCBF3F8UI, &H1ACAD2D8UI, &H38C8F0F8UI, &H14849094UI, &H19495158UI, &H2828280UI, &H4C4C0C4UI, + &H3FCFF3FCUI, &H9494148UI, &H39093138UI, &H27476364UI, &HC0C0C0UI, &HFCFC3CCUI, &H17C7D3D4UI, &H3888B0B8UI, + &HF0F030CUI, &HE8E828CUI, &H2424240UI, &H23032320UI, &H11819190UI, &H2C4C606CUI, &H1BCBD3D8UI, &H2484A0A4UI, + &H34043034UI, &H31C1F1F0UI, &H8484048UI, &H2C2C2C0UI, &H2F4F636CUI, &H3D0D313CUI, &H2D0D212CUI, &H404040UI, + &H3E8EB2BCUI, &H3E0E323CUI, &H3C8CB0BCUI, &H1C1C1C0UI, &H2A8AA2A8UI, &H3A8AB2B8UI, &HE4E424CUI, &H15455154UI, + &H3B0B3338UI, &H1CCCD0DCUI, &H28486068UI, &H3F4F737CUI, &H1C8C909CUI, &H18C8D0D8UI, &HA4A4248UI, &H16465254UI, + &H37477374UI, &H2080A0A0UI, &H2DCDE1ECUI, &H6464244UI, &H3585B1B4UI, &H2B0B2328UI, &H25456164UI, &H3ACAF2F8UI, + &H23C3E3E0UI, &H3989B1B8UI, &H3181B1B0UI, &H1F8F939CUI, &H1E4E525CUI, &H39C9F1F8UI, &H26C6E2E4UI, &H3282B2B0UI, + &H31013130UI, &H2ACAE2E8UI, &H2D4D616CUI, &H1F4F535CUI, &H24C4E0E4UI, &H30C0F0F0UI, &HDCDC1CCUI, &H8888088UI, + &H16061214UI, &H3A0A3238UI, &H18485058UI, &H14C4D0D4UI, &H22426260UI, &H29092128UI, &H7070304UI, &H33033330UI, + &H28C8E0E8UI, &H1B0B1318UI, &H5050104UI, &H39497178UI, &H10809090UI, &H2A4A6268UI, &H2A0A2228UI, &H1A8A9298UI + } + + Private Shared ReadOnly SS1() As UInteger = { + &H38380830UI, &HE828C8E0UI, &H2C2D0D21UI, &HA42686A2UI, &HCC0FCFC3UI, &HDC1ECED2UI, &HB03383B3UI, &HB83888B0UI, + &HAC2F8FA3UI, &H60204060UI, &H54154551UI, &HC407C7C3UI, &H44044440UI, &H6C2F4F63UI, &H682B4B63UI, &H581B4B53UI, + &HC003C3C3UI, &H60224262UI, &H30330333UI, &HB43585B1UI, &H28290921UI, &HA02080A0UI, &HE022C2E2UI, &HA42787A3UI, + &HD013C3D3UI, &H90118191UI, &H10110111UI, &H4060602UI, &H1C1C0C10UI, &HBC3C8CB0UI, &H34360632UI, &H480B4B43UI, + &HEC2FCFE3UI, &H88088880UI, &H6C2C4C60UI, &HA82888A0UI, &H14170713UI, &HC404C4C0UI, &H14160612UI, &HF434C4F0UI, + &HC002C2C2UI, &H44054541UI, &HE021C1E1UI, &HD416C6D2UI, &H3C3F0F33UI, &H3C3D0D31UI, &H8C0E8E82UI, &H98188890UI, + &H28280820UI, &H4C0E4E42UI, &HF436C6F2UI, &H3C3E0E32UI, &HA42585A1UI, &HF839C9F1UI, &HC0D0D01UI, &HDC1FCFD3UI, + &HD818C8D0UI, &H282B0B23UI, &H64264662UI, &H783A4A72UI, &H24270723UI, &H2C2F0F23UI, &HF031C1F1UI, &H70324272UI, + &H40024242UI, &HD414C4D0UI, &H40014141UI, &HC000C0C0UI, &H70334373UI, &H64274763UI, &HAC2C8CA0UI, &H880B8B83UI, + &HF437C7F3UI, &HAC2D8DA1UI, &H80008080UI, &H1C1F0F13UI, &HC80ACAC2UI, &H2C2C0C20UI, &HA82A8AA2UI, &H34340430UI, + &HD012C2D2UI, &H80B0B03UI, &HEC2ECEE2UI, &HE829C9E1UI, &H5C1D4D51UI, &H94148490UI, &H18180810UI, &HF838C8F0UI, + &H54174753UI, &HAC2E8EA2UI, &H8080800UI, &HC405C5C1UI, &H10130313UI, &HCC0DCDC1UI, &H84068682UI, &HB83989B1UI, + &HFC3FCFF3UI, &H7C3D4D71UI, &HC001C1C1UI, &H30310131UI, &HF435C5F1UI, &H880A8A82UI, &H682A4A62UI, &HB03181B1UI, + &HD011C1D1UI, &H20200020UI, &HD417C7D3UI, &H20202UI, &H20220222UI, &H4040400UI, &H68284860UI, &H70314171UI, + &H4070703UI, &HD81BCBD3UI, &H9C1D8D91UI, &H98198991UI, &H60214161UI, &HBC3E8EB2UI, &HE426C6E2UI, &H58194951UI, + &HDC1DCDD1UI, &H50114151UI, &H90108090UI, &HDC1CCCD0UI, &H981A8A92UI, &HA02383A3UI, &HA82B8BA3UI, &HD010C0D0UI, + &H80018181UI, &HC0F0F03UI, &H44074743UI, &H181A0A12UI, &HE023C3E3UI, &HEC2CCCE0UI, &H8C0D8D81UI, &HBC3F8FB3UI, + &H94168692UI, &H783B4B73UI, &H5C1C4C50UI, &HA02282A2UI, &HA02181A1UI, &H60234363UI, &H20230323UI, &H4C0D4D41UI, + &HC808C8C0UI, &H9C1E8E92UI, &H9C1C8C90UI, &H383A0A32UI, &HC0C0C00UI, &H2C2E0E22UI, &HB83A8AB2UI, &H6C2E4E62UI, + &H9C1F8F93UI, &H581A4A52UI, &HF032C2F2UI, &H90128292UI, &HF033C3F3UI, &H48094941UI, &H78384870UI, &HCC0CCCC0UI, + &H14150511UI, &HF83BCBF3UI, &H70304070UI, &H74354571UI, &H7C3F4F73UI, &H34350531UI, &H10100010UI, &H30303UI, + &H64244460UI, &H6C2D4D61UI, &HC406C6C2UI, &H74344470UI, &HD415C5D1UI, &HB43484B0UI, &HE82ACAE2UI, &H8090901UI, + &H74364672UI, &H18190911UI, &HFC3ECEF2UI, &H40004040UI, &H10120212UI, &HE020C0E0UI, &HBC3D8DB1UI, &H4050501UI, + &HF83ACAF2UI, &H10101UI, &HF030C0F0UI, &H282A0A22UI, &H5C1E4E52UI, &HA82989A1UI, &H54164652UI, &H40034343UI, + &H84058581UI, &H14140410UI, &H88098981UI, &H981B8B93UI, &HB03080B0UI, &HE425C5E1UI, &H48084840UI, &H78394971UI, + &H94178793UI, &HFC3CCCF0UI, &H1C1E0E12UI, &H80028282UI, &H20210121UI, &H8C0C8C80UI, &H181B0B13UI, &H5C1F4F53UI, + &H74374773UI, &H54144450UI, &HB03282B2UI, &H1C1D0D11UI, &H24250521UI, &H4C0F4F43UI, &H0UI, &H44064642UI, + &HEC2DCDE1UI, &H58184850UI, &H50124252UI, &HE82BCBE3UI, &H7C3E4E72UI, &HD81ACAD2UI, &HC809C9C1UI, &HFC3DCDF1UI, + &H30300030UI, &H94158591UI, &H64254561UI, &H3C3C0C30UI, &HB43686B2UI, &HE424C4E0UI, &HB83B8BB3UI, &H7C3C4C70UI, + &HC0E0E02UI, &H50104050UI, &H38390931UI, &H24260622UI, &H30320232UI, &H84048480UI, &H68294961UI, &H90138393UI, + &H34370733UI, &HE427C7E3UI, &H24240420UI, &HA42484A0UI, &HC80BCBC3UI, &H50134353UI, &H80A0A02UI, &H84078783UI, + &HD819C9D1UI, &H4C0C4C40UI, &H80038383UI, &H8C0F8F83UI, &HCC0ECEC2UI, &H383B0B33UI, &H480A4A42UI, &HB43787B3UI + } + Private Shared ReadOnly SS2() As UInteger = { + &HA1A82989UI, &H81840585UI, &HD2D416C6UI, &HD3D013C3UI, &H50541444UI, &H111C1D0DUI, &HA0AC2C8CUI, &H21242505UI, + &H515C1D4DUI, &H43400343UI, &H10181808UI, &H121C1E0EUI, &H51501141UI, &HF0FC3CCCUI, &HC2C80ACAUI, &H63602343UI, + &H20282808UI, &H40440444UI, &H20202000UI, &H919C1D8DUI, &HE0E020C0UI, &HE2E022C2UI, &HC0C808C8UI, &H13141707UI, + &HA1A42585UI, &H838C0F8FUI, &H3000303UI, &H73783B4BUI, &HB3B83B8BUI, &H13101303UI, &HD2D012C2UI, &HE2EC2ECEUI, + &H70703040UI, &H808C0C8CUI, &H333C3F0FUI, &HA0A82888UI, &H32303202UI, &HD1DC1DCDUI, &HF2F436C6UI, &H70743444UI, + &HE0EC2CCCUI, &H91941585UI, &H3080B0BUI, &H53541747UI, &H505C1C4CUI, &H53581B4BUI, &HB1BC3D8DUI, &H1000101UI, + &H20242404UI, &H101C1C0CUI, &H73703343UI, &H90981888UI, &H10101000UI, &HC0CC0CCCUI, &HF2F032C2UI, &HD1D819C9UI, + &H202C2C0CUI, &HE3E427C7UI, &H72703242UI, &H83800383UI, &H93981B8BUI, &HD1D011C1UI, &H82840686UI, &HC1C809C9UI, + &H60602040UI, &H50501040UI, &HA3A02383UI, &HE3E82BCBUI, &H10C0D0DUI, &HB2B43686UI, &H929C1E8EUI, &H434C0F4FUI, + &HB3B43787UI, &H52581A4AUI, &HC2C406C6UI, &H70783848UI, &HA2A42686UI, &H12101202UI, &HA3AC2F8FUI, &HD1D415C5UI, + &H61602141UI, &HC3C003C3UI, &HB0B43484UI, &H41400141UI, &H52501242UI, &H717C3D4DUI, &H818C0D8DUI, &H80808UI, + &H131C1F0FUI, &H91981989UI, &H0UI, &H11181909UI, &H40404UI, &H53501343UI, &HF3F437C7UI, &HE1E021C1UI, + &HF1FC3DCDUI, &H72743646UI, &H232C2F0FUI, &H23242707UI, &HB0B03080UI, &H83880B8BUI, &H20C0E0EUI, &HA3A82B8BUI, + &HA2A02282UI, &H626C2E4EUI, &H93901383UI, &H414C0D4DUI, &H61682949UI, &H707C3C4CUI, &H1080909UI, &H2080A0AUI, + &HB3BC3F8FUI, &HE3EC2FCFUI, &HF3F033C3UI, &HC1C405C5UI, &H83840787UI, &H10141404UI, &HF2FC3ECEUI, &H60642444UI, + &HD2DC1ECEUI, &H222C2E0EUI, &H43480B4BUI, &H12181A0AUI, &H2040606UI, &H21202101UI, &H63682B4BUI, &H62642646UI, + &H2000202UI, &HF1F435C5UI, &H92901282UI, &H82880A8AUI, &HC0C0CUI, &HB3B03383UI, &H727C3E4EUI, &HD0D010C0UI, + &H72783A4AUI, &H43440747UI, &H92941686UI, &HE1E425C5UI, &H22242606UI, &H80800080UI, &HA1AC2D8DUI, &HD3DC1FCFUI, + &HA1A02181UI, &H30303000UI, &H33343707UI, &HA2AC2E8EUI, &H32343606UI, &H11141505UI, &H22202202UI, &H30383808UI, + &HF0F434C4UI, &HA3A42787UI, &H41440545UI, &H404C0C4CUI, &H81800181UI, &HE1E829C9UI, &H80840484UI, &H93941787UI, + &H31343505UI, &HC3C80BCBUI, &HC2CC0ECEUI, &H303C3C0CUI, &H71703141UI, &H11101101UI, &HC3C407C7UI, &H81880989UI, + &H71743545UI, &HF3F83BCBUI, &HD2D81ACAUI, &HF0F838C8UI, &H90941484UI, &H51581949UI, &H82800282UI, &HC0C404C4UI, + &HF3FC3FCFUI, &H41480949UI, &H31383909UI, &H63642747UI, &HC0C000C0UI, &HC3CC0FCFUI, &HD3D417C7UI, &HB0B83888UI, + &H30C0F0FUI, &H828C0E8EUI, &H42400242UI, &H23202303UI, &H91901181UI, &H606C2C4CUI, &HD3D81BCBUI, &HA0A42484UI, + &H30343404UI, &HF1F031C1UI, &H40480848UI, &HC2C002C2UI, &H636C2F4FUI, &H313C3D0DUI, &H212C2D0DUI, &H40400040UI, + &HB2BC3E8EUI, &H323C3E0EUI, &HB0BC3C8CUI, &HC1C001C1UI, &HA2A82A8AUI, &HB2B83A8AUI, &H424C0E4EUI, &H51541545UI, + &H33383B0BUI, &HD0DC1CCCUI, &H60682848UI, &H737C3F4FUI, &H909C1C8CUI, &HD0D818C8UI, &H42480A4AUI, &H52541646UI, + &H73743747UI, &HA0A02080UI, &HE1EC2DCDUI, &H42440646UI, &HB1B43585UI, &H23282B0BUI, &H61642545UI, &HF2F83ACAUI, + &HE3E023C3UI, &HB1B83989UI, &HB1B03181UI, &H939C1F8FUI, &H525C1E4EUI, &HF1F839C9UI, &HE2E426C6UI, &HB2B03282UI, + &H31303101UI, &HE2E82ACAUI, &H616C2D4DUI, &H535C1F4FUI, &HE0E424C4UI, &HF0F030C0UI, &HC1CC0DCDUI, &H80880888UI, + &H12141606UI, &H32383A0AUI, &H50581848UI, &HD0D414C4UI, &H62602242UI, &H21282909UI, &H3040707UI, &H33303303UI, + &HE0E828C8UI, &H13181B0BUI, &H1040505UI, &H71783949UI, &H90901080UI, &H62682A4AUI, &H22282A0AUI, &H92981A8AUI + } + Private Shared ReadOnly SS3() As UInteger = { + &H8303838UI, &HC8E0E828UI, &HD212C2DUI, &H86A2A426UI, &HCFC3CC0FUI, &HCED2DC1EUI, &H83B3B033UI, &H88B0B838UI, + &H8FA3AC2FUI, &H40606020UI, &H45515415UI, &HC7C3C407UI, &H44404404UI, &H4F636C2FUI, &H4B63682BUI, &H4B53581BUI, + &HC3C3C003UI, &H42626022UI, &H3333033UI, &H85B1B435UI, &H9212829UI, &H80A0A020UI, &HC2E2E022UI, &H87A3A427UI, + &HC3D3D013UI, &H81919011UI, &H1111011UI, &H6020406UI, &HC101C1CUI, &H8CB0BC3CUI, &H6323436UI, &H4B43480BUI, + &HCFE3EC2FUI, &H88808808UI, &H4C606C2CUI, &H88A0A828UI, &H7131417UI, &HC4C0C404UI, &H6121416UI, &HC4F0F434UI, + &HC2C2C002UI, &H45414405UI, &HC1E1E021UI, &HC6D2D416UI, &HF333C3FUI, &HD313C3DUI, &H8E828C0EUI, &H88909818UI, + &H8202828UI, &H4E424C0EUI, &HC6F2F436UI, &HE323C3EUI, &H85A1A425UI, &HC9F1F839UI, &HD010C0DUI, &HCFD3DC1FUI, + &HC8D0D818UI, &HB23282BUI, &H46626426UI, &H4A72783AUI, &H7232427UI, &HF232C2FUI, &HC1F1F031UI, &H42727032UI, + &H42424002UI, &HC4D0D414UI, &H41414001UI, &HC0C0C000UI, &H43737033UI, &H47636427UI, &H8CA0AC2CUI, &H8B83880BUI, + &HC7F3F437UI, &H8DA1AC2DUI, &H80808000UI, &HF131C1FUI, &HCAC2C80AUI, &HC202C2CUI, &H8AA2A82AUI, &H4303434UI, + &HC2D2D012UI, &HB03080BUI, &HCEE2EC2EUI, &HC9E1E829UI, &H4D515C1DUI, &H84909414UI, &H8101818UI, &HC8F0F838UI, + &H47535417UI, &H8EA2AC2EUI, &H8000808UI, &HC5C1C405UI, &H3131013UI, &HCDC1CC0DUI, &H86828406UI, &H89B1B839UI, + &HCFF3FC3FUI, &H4D717C3DUI, &HC1C1C001UI, &H1313031UI, &HC5F1F435UI, &H8A82880AUI, &H4A62682AUI, &H81B1B031UI, + &HC1D1D011UI, &H202020UI, &HC7D3D417UI, &H2020002UI, &H2222022UI, &H4000404UI, &H48606828UI, &H41717031UI, + &H7030407UI, &HCBD3D81BUI, &H8D919C1DUI, &H89919819UI, &H41616021UI, &H8EB2BC3EUI, &HC6E2E426UI, &H49515819UI, + &HCDD1DC1DUI, &H41515011UI, &H80909010UI, &HCCD0DC1CUI, &H8A92981AUI, &H83A3A023UI, &H8BA3A82BUI, &HC0D0D010UI, + &H81818001UI, &HF030C0FUI, &H47434407UI, &HA12181AUI, &HC3E3E023UI, &HCCE0EC2CUI, &H8D818C0DUI, &H8FB3BC3FUI, + &H86929416UI, &H4B73783BUI, &H4C505C1CUI, &H82A2A022UI, &H81A1A021UI, &H43636023UI, &H3232023UI, &H4D414C0DUI, + &HC8C0C808UI, &H8E929C1EUI, &H8C909C1CUI, &HA32383AUI, &HC000C0CUI, &HE222C2EUI, &H8AB2B83AUI, &H4E626C2EUI, + &H8F939C1FUI, &H4A52581AUI, &HC2F2F032UI, &H82929012UI, &HC3F3F033UI, &H49414809UI, &H48707838UI, &HCCC0CC0CUI, + &H5111415UI, &HCBF3F83BUI, &H40707030UI, &H45717435UI, &H4F737C3FUI, &H5313435UI, &H101010UI, &H3030003UI, + &H44606424UI, &H4D616C2DUI, &HC6C2C406UI, &H44707434UI, &HC5D1D415UI, &H84B0B434UI, &HCAE2E82AUI, &H9010809UI, + &H46727436UI, &H9111819UI, &HCEF2FC3EUI, &H40404000UI, &H2121012UI, &HC0E0E020UI, &H8DB1BC3DUI, &H5010405UI, + &HCAF2F83AUI, &H1010001UI, &HC0F0F030UI, &HA22282AUI, &H4E525C1EUI, &H89A1A829UI, &H46525416UI, &H43434003UI, + &H85818405UI, &H4101414UI, &H89818809UI, &H8B93981BUI, &H80B0B030UI, &HC5E1E425UI, &H48404808UI, &H49717839UI, + &H87939417UI, &HCCF0FC3CUI, &HE121C1EUI, &H82828002UI, &H1212021UI, &H8C808C0CUI, &HB13181BUI, &H4F535C1FUI, + &H47737437UI, &H44505414UI, &H82B2B032UI, &HD111C1DUI, &H5212425UI, &H4F434C0FUI, &H0UI, &H46424406UI, + &HCDE1EC2DUI, &H48505818UI, &H42525012UI, &HCBE3E82BUI, &H4E727C3EUI, &HCAD2D81AUI, &HC9C1C809UI, &HCDF1FC3DUI, + &H303030UI, &H85919415UI, &H45616425UI, &HC303C3CUI, &H86B2B436UI, &HC4E0E424UI, &H8BB3B83BUI, &H4C707C3CUI, + &HE020C0EUI, &H40505010UI, &H9313839UI, &H6222426UI, &H2323032UI, &H84808404UI, &H49616829UI, &H83939013UI, + &H7333437UI, &HC7E3E427UI, &H4202424UI, &H84A0A424UI, &HCBC3C80BUI, &H43535013UI, &HA02080AUI, &H87838407UI, + &HC9D1D819UI, &H4C404C0CUI, &H83838003UI, &H8F838C0FUI, &HCEC2CC0EUI, &HB33383BUI, &H4A42480AUI, &H87B3B437UI + } + + Private Shared ReadOnly KC() As UInteger = { + &H9E3779B9UI, &H3C6EF373UI, &H78DDE6E6UI, &HF1BBCDCCUI, + &HE3779B99UI, &HC6EF3733UI, &H8DDE6E67UI, &H1BBCDCCFUI, + &H3779B99EUI, &H6EF3733CUI, &HDDE6E678UI, &HBBCDCCF1UI, + &H779B99E3UI, &HEF3733C6UI, &HDE6E678DUI, &HBCDCCF1BUI + } + + Public Sub New(key As Byte()) + If key.Length <> 16 Then Throw New ArgumentException("SEED key must be 16 bytes.") + KeySchedule(key) + End Sub + + Private Shared Function GetByte(n As UInteger, index As Integer) As Byte + Return CByte((n >> (index * 8)) And &HFF) + End Function + + Private Shared Function ToUInt32BE(data() As Byte, offset As Integer) As UInteger + Return (CUInt(data(offset)) << 24) Or (CUInt(data(offset + 1)) << 16) Or (CUInt(data(offset + 2)) << 8) Or CUInt(data(offset + 3)) + End Function + + Private Shared Sub WriteUInt32BE(value As UInteger, output() As Byte, offset As Integer) + output(offset) = CByte((value >> 24) And &HFF) + output(offset + 1) = CByte((value >> 16) And &HFF) + output(offset + 2) = CByte((value >> 8) And &HFF) + output(offset + 3) = CByte(value And &HFF) + End Sub + + Private Shared Function RoundFunction(T0 As UInteger, T1 As UInteger) As Tuple(Of UInteger, UInteger) + T1 = T1 Xor T0 + T1 = SS0(GetByte(T1, 0)) Xor SS1(GetByte(T1, 1)) Xor SS2(GetByte(T1, 2)) Xor SS3(GetByte(T1, 3)) + T0 = (T0 + T1) And &HFFFFFFFFUI + T0 = SS0(GetByte(T0, 0)) Xor SS1(GetByte(T0, 1)) Xor SS2(GetByte(T0, 2)) Xor SS3(GetByte(T0, 3)) + T1 = (T1 + T0) And &HFFFFFFFFUI + T1 = SS0(GetByte(T1, 0)) Xor SS1(GetByte(T1, 1)) Xor SS2(GetByte(T1, 2)) Xor SS3(GetByte(T1, 3)) + T0 = (T0 + T1) And &HFFFFFFFFUI + Return Tuple.Create(T0, T1) + End Function + + Private Sub KeySchedule(userKey As Byte()) + Dim A As UInteger = ToUInt32BE(userKey, 0) + Dim B As UInteger = ToUInt32BE(userKey, 4) + Dim C As UInteger = ToUInt32BE(userKey, 8) + Dim D As UInteger = ToUInt32BE(userKey, 12) + + For i As Integer = 0 To 15 + Dim T0 As UInteger = (A + C - KC(i)) And &HFFFFFFFFUI + Dim T1 As UInteger = (B - D + KC(i)) And &HFFFFFFFFUI + roundKey(2 * i) = SS0(GetByte(T0, 0)) Xor SS1(GetByte(T0, 1)) Xor SS2(GetByte(T0, 2)) Xor SS3(GetByte(T0, 3)) + roundKey(2 * i + 1) = SS0(GetByte(T1, 0)) Xor SS1(GetByte(T1, 1)) Xor SS2(GetByte(T1, 2)) Xor SS3(GetByte(T1, 3)) + + If i Mod 2 = 0 Then + Dim AB As ULong = (CLng(A) << 32) Or B + AB = ((AB >> 8) Or (AB << 56)) And &HFFFFFFFFFFFFFFFFUL + A = CUInt(AB >> 32) + B = CUInt(AB And &HFFFFFFFFUL) + Else + Dim CD As ULong = (CLng(C) << 32) Or D + CD = ((CD << 8) Or (CD >> 56)) And &HFFFFFFFFFFFFFFFFUL + C = CUInt(CD >> 32) + D = CUInt(CD And &HFFFFFFFFUL) + End If + Next + End Sub + + Public Sub EncryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) + Dim L0 = ToUInt32BE(input, inOffset) + Dim L1 = ToUInt32BE(input, inOffset + 4) + Dim R0 = ToUInt32BE(input, inOffset + 8) + Dim R1 = ToUInt32BE(input, inOffset + 12) + + For i As Integer = 0 To 15 + Dim t = RoundFunction(R0 Xor roundKey(2 * i), R1 Xor roundKey(2 * i + 1)) + Dim T0 = t.Item1 + Dim T1 = t.Item2 + + Dim temp0 = L0 Xor T0 + Dim temp1 = L1 Xor T1 + L0 = R0 : L1 = R1 + R0 = temp0 : R1 = temp1 + Next + + WriteUInt32BE(R0, output, outOffset) + WriteUInt32BE(R1, output, outOffset + 4) + WriteUInt32BE(L0, output, outOffset + 8) + WriteUInt32BE(L1, output, outOffset + 12) + End Sub + + Public Sub DecryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) + Dim L0 = ToUInt32BE(input, inOffset) + Dim L1 = ToUInt32BE(input, inOffset + 4) + Dim R0 = ToUInt32BE(input, inOffset + 8) + Dim R1 = ToUInt32BE(input, inOffset + 12) + + For i As Integer = 0 To 15 + Dim t = RoundFunction(R0 Xor roundKey(30 - 2 * i), R1 Xor roundKey(31 - 2 * i)) + Dim T0 = t.Item1 + Dim T1 = t.Item2 + + Dim temp0 = L0 Xor T0 + Dim temp1 = L1 Xor T1 + L0 = R0 : L1 = R1 + R0 = temp0 : R1 = temp1 + Next + + WriteUInt32BE(R0, output, outOffset) + WriteUInt32BE(R1, output, outOffset + 4) + WriteUInt32BE(L0, output, outOffset + 8) + WriteUInt32BE(L1, output, outOffset + 12) + End Sub +End Class \ No newline at end of file diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedEcbTransform.vb b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedEcbTransform.vb new file mode 100644 index 0000000..0f1797e --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/SeedEcbTransform.vb @@ -0,0 +1,167 @@ +' SeedEcbTransform.cs (WelsonJS.Cryptography) +' SPDX-License-Identifier: MIT +' SPDX-FileCopyrightText: 2025 Namhyeon Go , Catswords OSS And WelsonJS Contributors +' https://github.com/gnh1201/welsonjs + +Imports System.Security.Cryptography + +Public Class SeedEcbTransform + Implements ICryptoTransform + + Private ReadOnly rnd As New Random() + Private ReadOnly core As SeedCore + Private ReadOnly encrypt As Boolean + Private ReadOnly paddingMode As PaddingMode + + Public Sub New(key As Byte(), encryptMode As Boolean, Optional mode As PaddingMode = PaddingMode.PKCS7) + core = New SeedCore(key) + encrypt = encryptMode + paddingMode = mode + End Sub + + Public ReadOnly Property InputBlockSize As Integer Implements ICryptoTransform.InputBlockSize + Get + Return 16 + End Get + End Property + + Public ReadOnly Property OutputBlockSize As Integer Implements ICryptoTransform.OutputBlockSize + Get + Return 16 + End Get + End Property + + Public ReadOnly Property CanTransformMultipleBlocks As Boolean Implements ICryptoTransform.CanTransformMultipleBlocks + Get + Return True + End Get + End Property + + Public ReadOnly Property CanReuseTransform As Boolean Implements ICryptoTransform.CanReuseTransform + Get + Return True + End Get + End Property + + Public Function TransformBlock(input() As Byte, inputOffset As Integer, inputCount As Integer, + output() As Byte, outputOffset As Integer) As Integer Implements ICryptoTransform.TransformBlock + If inputCount <= 0 Then Return 0 + + Dim blockSize = InputBlockSize + Dim remaining = inputCount + Dim inPtr = inputOffset + Dim outPtr = outputOffset + + While remaining >= blockSize + If encrypt Then + core.EncryptBlock(input, inPtr, output, outPtr) + Else + core.DecryptBlock(input, inPtr, output, outPtr) + End If + inPtr += blockSize + outPtr += blockSize + remaining -= blockSize + End While + + Return inputCount - remaining + End Function + + Public Function TransformFinalBlock(input() As Byte, inputOffset As Integer, inputCount As Integer) As Byte() Implements ICryptoTransform.TransformFinalBlock + Dim blockSize = InputBlockSize + Dim buffer() As Byte + + If paddingMode = PaddingMode.None Then + buffer = New Byte(inputCount - 1) {} + TransformBlock(input, inputOffset, inputCount, buffer, 0) + Return buffer + End If + + If encrypt Then + Dim paddedLength As Integer + Select Case paddingMode + Case PaddingMode.None + If (inputCount Mod blockSize) <> 0 Then + Throw New CryptographicException("Input data is not a multiple of block size and PaddingMode is None.") + End If + paddedLength = inputCount + + Case PaddingMode.Zeros + paddedLength = ((inputCount + blockSize - 1) \ blockSize) * blockSize + + Case PaddingMode.PKCS7, PaddingMode.ANSIX923, PaddingMode.ISO10126 + Dim padLen = blockSize - (inputCount Mod blockSize) + If padLen = 0 Then padLen = blockSize + paddedLength = inputCount + padLen + + Case Else + Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) + End Select + + buffer = New Byte(paddedLength - 1) {} + Array.Copy(input, inputOffset, buffer, 0, inputCount) + + Dim padVal As Byte = CByte(paddedLength - inputCount) + Select Case paddingMode + Case PaddingMode.PKCS7 + For i = inputCount To paddedLength - 1 + buffer(i) = padVal + Next + Case PaddingMode.ANSIX923 + For i = inputCount To paddedLength - 2 + buffer(i) = 0 + Next + buffer(paddedLength - 1) = padVal + Case PaddingMode.ISO10126 + For i = inputCount To paddedLength - 2 + buffer(i) = CByte(rnd.Next(0, 256)) + Next + buffer(paddedLength - 1) = padVal + End Select + + For i = 0 To buffer.Length - 1 Step blockSize + core.EncryptBlock(buffer, i, buffer, i) + Next + Return buffer + + Else + If (inputCount Mod blockSize) <> 0 Then + Throw New CryptographicException("Encrypted data is not a multiple of block size.") + End If + + buffer = New Byte(inputCount - 1) {} + TransformBlock(input, inputOffset, inputCount, buffer, 0) + + Dim padVal As Integer = buffer(buffer.Length - 1) + If padVal <= 0 OrElse padVal > blockSize Then + Throw New CryptographicException("Invalid padding.") + End If + + Select Case paddingMode + Case PaddingMode.PKCS7 + For i = buffer.Length - padVal To buffer.Length - 1 + If buffer(i) <> padVal Then + Throw New CryptographicException("Invalid PKCS7 padding value.") + End If + Next + Case PaddingMode.ANSIX923 + For i = buffer.Length - padVal To buffer.Length - 2 + If buffer(i) <> 0 Then + Throw New CryptographicException("Invalid ANSIX923 padding value.") + End If + Next + Case PaddingMode.ISO10126 + ' no need to check random bytes, only length byte matters + Case Else + Throw New NotSupportedException("Unsupported padding mode: " & paddingMode.ToString()) + End Select + + Dim result(buffer.Length - padVal - 1) As Byte + Array.Copy(buffer, 0, result, 0, result.Length) + Return result + End If + End Function + + Public Sub Dispose() Implements IDisposable.Dispose + ' No resources to dispose + End Sub +End Class diff --git a/WelsonJS.Toolkit/WelsonJS.Cryptography/WelsonJS.Cryptography.vbproj b/WelsonJS.Toolkit/WelsonJS.Cryptography/WelsonJS.Cryptography.vbproj new file mode 100644 index 0000000..71bb12b --- /dev/null +++ b/WelsonJS.Toolkit/WelsonJS.Cryptography/WelsonJS.Cryptography.vbproj @@ -0,0 +1,34 @@ + + + + WelsonJS.Cryptography + netstandard2.0 + https://github.com/gnh1201/welsonjs + git + https://github.com/gnh1201/welsonjs + Catswords OSS + Catswords Research + Namhyeon Go,Catswords OSS + AnyCPU;x86 + MIT + 0.2.7.55 + 0.2.7.55 + + + + True + + + + True + + + + True + + + + True + + + diff --git a/WelsonJS.Toolkit/WelsonJS.Toolkit.sln b/WelsonJS.Toolkit/WelsonJS.Toolkit.sln index b079305..38c0f9a 100644 --- a/WelsonJS.Toolkit/WelsonJS.Toolkit.sln +++ b/WelsonJS.Toolkit/WelsonJS.Toolkit.sln @@ -11,7 +11,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelsonJS.Launcher", "Welson EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentInterop", "EsentInterop\EsentInterop.csproj", "{E929E163-52A0-4AAC-917B-6D7FAF70C45E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelsonJS.Esent", "WelsonJS.Esent\WelsonJS.Esent.csproj", "{783F2DB2-80D0-4F58-A55E-9593E44D5743}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WelsonJS.Esent", "WelsonJS.Esent\WelsonJS.Esent.csproj", "{783F2DB2-80D0-4F58-A55E-9593E44D5743}" +EndProject +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "WelsonJS.Cryptography", "WelsonJS.Cryptography\WelsonJS.Cryptography.vbproj", "{577A0EA3-0E02-4099-8ECA-4E8DC7339C69}" +EndProject +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "WelsonJS.Cryptography.Test", "WelsonJS.Cryptography.Test\WelsonJS.Cryptography.Test.vbproj", "{C65EC34B-71C7-47CF-912E-D304283EB412}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -59,8 +63,24 @@ Global {783F2DB2-80D0-4F58-A55E-9593E44D5743}.Debug|x86.Build.0 = Debug|x86 {783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|Any CPU.ActiveCfg = Release|Any CPU {783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|Any CPU.Build.0 = Release|Any CPU - {783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|x86.ActiveCfg = Release|Any CPU - {783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|x86.Build.0 = Release|Any CPU + {783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|x86.ActiveCfg = Release|x86 + {783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|x86.Build.0 = Release|x86 + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Debug|x86.ActiveCfg = Debug|x86 + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Debug|x86.Build.0 = Debug|x86 + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Release|Any CPU.Build.0 = Release|Any CPU + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Release|x86.ActiveCfg = Release|x86 + {577A0EA3-0E02-4099-8ECA-4E8DC7339C69}.Release|x86.Build.0 = Release|x86 + {C65EC34B-71C7-47CF-912E-D304283EB412}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C65EC34B-71C7-47CF-912E-D304283EB412}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C65EC34B-71C7-47CF-912E-D304283EB412}.Debug|x86.ActiveCfg = Debug|x86 + {C65EC34B-71C7-47CF-912E-D304283EB412}.Debug|x86.Build.0 = Debug|x86 + {C65EC34B-71C7-47CF-912E-D304283EB412}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C65EC34B-71C7-47CF-912E-D304283EB412}.Release|Any CPU.Build.0 = Release|Any CPU + {C65EC34B-71C7-47CF-912E-D304283EB412}.Release|x86.ActiveCfg = Release|x86 + {C65EC34B-71C7-47CF-912E-D304283EB412}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE