Merge pull request #296 from gnh1201/cryptography

Add `WelsonJS.Cryptography` package (SEED, ARIA, HIGHT algoritm)
This commit is contained in:
Namhyeon Go 2025-07-26 23:21:48 +09:00 committed by GitHub
commit 453fc231d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1513 additions and 3 deletions

View File

@ -0,0 +1,76 @@
' Program.cs (WelsonJS.Cryptography.Test)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>WelsonJS.Cryptography.Test</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\WelsonJS.Cryptography\WelsonJS.Cryptography.vbproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,56 @@
' AriaAlgorithm.cs(WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,245 @@
' AriaCore.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,168 @@
' AriaEcbTransform.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,56 @@
' HightAlgorithm.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,201 @@
' HightCore.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,161 @@
' HightEcbTransform.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,56 @@
' SeedAlgorithm.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,256 @@
' SeedCore.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,167 @@
' SeedEcbTransform.cs (WelsonJS.Cryptography)
' SPDX-License-Identifier: MIT
' SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, 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

View File

@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>WelsonJS.Cryptography</RootNamespace>
<TargetFramework>netstandard2.0</TargetFramework>
<RepositoryUrl>https://github.com/gnh1201/welsonjs</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/gnh1201/welsonjs</PackageProjectUrl>
<Copyright>Catswords OSS</Copyright>
<Company>Catswords Research</Company>
<Authors>Namhyeon Go,Catswords OSS</Authors>
<Platforms>AnyCPU;x86</Platforms>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<AssemblyVersion>0.2.7.55</AssemblyVersion>
<FileVersion>0.2.7.55</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<RemoveIntegerChecks>True</RemoveIntegerChecks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<RemoveIntegerChecks>True</RemoveIntegerChecks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<RemoveIntegerChecks>True</RemoveIntegerChecks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<RemoveIntegerChecks>True</RemoveIntegerChecks>
</PropertyGroup>
</Project>

View File

@ -11,7 +11,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelsonJS.Launcher", "Welson
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentInterop", "EsentInterop\EsentInterop.csproj", "{E929E163-52A0-4AAC-917B-6D7FAF70C45E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentInterop", "EsentInterop\EsentInterop.csproj", "{E929E163-52A0-4AAC-917B-6D7FAF70C45E}"
EndProject 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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -59,8 +63,24 @@ Global
{783F2DB2-80D0-4F58-A55E-9593E44D5743}.Debug|x86.Build.0 = Debug|x86 {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.ActiveCfg = Release|Any CPU
{783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|Any CPU.Build.0 = 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.ActiveCfg = Release|x86
{783F2DB2-80D0-4F58-A55E-9593E44D5743}.Release|x86.Build.0 = Release|Any CPU {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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE