Implement HIGHT algorithm with official test vector (TEST PASSED) #293

Implement HIGHT algorithm with official test vector (TEST PASSED) #293
This commit is contained in:
Namhyeon Go 2025-07-25 00:06:40 +09:00
parent 2a8c4d196c
commit 3498f27619
3 changed files with 160 additions and 93 deletions

View File

@ -33,7 +33,7 @@ Module Program
' HIGHT algorithm ' HIGHT algorithm
Console.WriteLine("Start HIGHT encryption and decryption test") Console.WriteLine("Start HIGHT encryption and decryption test")
Dim hightCipher As New WelsonJS.Cryptography.HightAlgorithm() Dim hightCipher As New WelsonJS.Cryptography.HightAlgorithm()
hightCipher.Key = {&H0, &H11, &H22, &H33, &H44, &H55, &H66, &H77, &H88, &H99, &HAA, &HBB, &HCC, &HDD, &HEE, &HFF} 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.IV = {&H0F, &H1E, &H2D, &H3C, &H4B, &H5A, &H69, &H78, &H87, &H96, &HA5, &HB4, &HC3, &HD2, &HE1, &HF0}
hightCipher.Mode = CipherMode.ECB hightCipher.Mode = CipherMode.ECB
hightCipher.Padding = PaddingMode.PKCS7 hightCipher.Padding = PaddingMode.PKCS7
@ -45,7 +45,7 @@ Module Program
Public Sub RunTest(cipher As SymmetricAlgorithm) 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, &HFE} ' SEED test vector ' Dim inputBytes As Byte() = {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0, &HFE} ' SEED test vector
' Dim inputBytes As Byte() = {&H11, &H11, &H11, &H11, &HAA, &HAA, &HAA, &HAA, &H11, &H11, &H11, &H11, &HBB, &HBB, &HBB, &HBB} ' ARIA test vector ' Dim inputBytes As Byte() = {&H11, &H11, &H11, &H11, &HAA, &HAA, &HAA, &HAA, &H11, &H11, &H11, &H11, &HBB, &HBB, &HBB, &HBB} ' ARIA test vector
Dim inputBytes As Byte() = {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0} ' HIGHT test vector Dim inputBytes As Byte() = {&H80, &H0, &H0, &H0, &H0, &H0, &H0, &H0} ' HIGHT test vector
Console.WriteLine("Key (HEX):") Console.WriteLine("Key (HEX):")
PrintHex(cipher.Key) PrintHex(cipher.Key)

View File

@ -1,6 +1,11 @@
Public Class HightCore ' 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 ReadOnly roundKey(135) As Byte
Private Shared ReadOnly Delta As Byte() = { Private Shared ReadOnly DELTA As Byte() = {
&H5A, &H6D, &H36, &H1B, &HD, &H6, &H3, &H41, &H5A, &H6D, &H36, &H1B, &HD, &H6, &H3, &H41,
&H60, &H30, &H18, &H4C, &H66, &H33, &H59, &H2C, &H60, &H30, &H18, &H4C, &H66, &H33, &H59, &H2C,
&H56, &H2B, &H15, &H4A, &H65, &H72, &H39, &H1C, &H56, &H2B, &H15, &H4A, &H65, &H72, &H39, &H1C,
@ -19,121 +24,178 @@
&H74, &H3A, &H5D, &H2E, &H57, &H6B, &H35, &H5A &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()) Public Sub New(userKey As Byte())
If userKey.Length <> 16 Then Throw New ArgumentException("Key must be 16 bytes") If userKey.Length <> 16 Then Throw New ArgumentException("Key must be 16 bytes")
KeySchedule(userKey) KeySchedule(userKey)
End Sub End Sub
Private Sub KeySchedule(userKey As Byte())
' Whitening keys
For i As Integer = 0 To 3
roundKey(i) = userKey(i + 12)
roundKey(i + 4) = userKey(i)
Next
' Round keys (SK008 to SK135)
For i As Integer = 0 To 7
For j As Integer = 0 To 7
Dim idx = 16 * i + j
roundKey(8 + idx) = CByte((userKey((j - i) And 7) + Delta(idx)) And &HFF)
roundKey(8 + idx + 8) = CByte((userKey(8 + ((j - i) And 7)) + Delta(idx + 8)) And &HFF)
Next
Next
End Sub
Private Function RotL(x As Byte, n As Integer) As Byte
Return CByte(((x << n) Or (x >> (8 - n))) And &HFF)
End Function
Private Function F0(x As Byte) As Byte Private Function F0(x As Byte) As Byte
Return CByte(RotL(x, 1) Xor RotL(x, 2) Xor RotL(x, 7)) Return F0_TABLE(x)
End Function End Function
Private Function F1(x As Byte) As Byte Private Function F1(x As Byte) As Byte
Return CByte(RotL(x, 3) Xor RotL(x, 4) Xor RotL(x, 6)) Return F1_TABLE(x)
End Function End Function
Public Sub EncryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) Private Function Mod8(x As Integer) As Integer
Dim X(7) As Byte Return ((x Mod 8) + 8) Mod 8
' Initial whitening End Function
X(0) = CByte((input(inOffset + 0) + roundKey(0)) And &HFF)
X(1) = input(inOffset + 1)
X(2) = CByte(input(inOffset + 2) Xor roundKey(1))
X(3) = input(inOffset + 3)
X(4) = CByte((input(inOffset + 4) + roundKey(2)) And &HFF)
X(5) = input(inOffset + 5)
X(6) = CByte(input(inOffset + 6) Xor roundKey(3))
X(7) = input(inOffset + 7)
For r As Integer = 0 To 31 Private Sub KeySchedule(key As Byte())
Dim T0 = CByte(F0(X(1)) Xor roundKey(8 + 4 * r + 0)) If key.Length <> 16 Then Throw New ArgumentException("Key must be 16 bytes")
Dim T1 = CByte(F1(X(3)) Xor roundKey(8 + 4 * r + 1))
Dim T2 = CByte(F0(X(5)) Xor roundKey(8 + 4 * r + 2))
Dim T3 = CByte(F1(X(7)) Xor roundKey(8 + 4 * r + 3))
Dim tmp(7) As Byte ' 1. Set the whitening key (WK0 ~ WK7): Use MK[8..15]
tmp(0) = X(1) For i As Integer = 0 To 7
tmp(1) = CByte((X(2) + T0) And &HFF) roundKey(i) = key(8 + i)
tmp(2) = X(3)
tmp(3) = CByte((X(0) + T1) And &HFF)
tmp(4) = X(5)
tmp(5) = CByte((X(6) + T2) And &HFF)
tmp(6) = X(7)
tmp(7) = CByte((X(4) + T3) And &HFF)
Array.Copy(tmp, X, 8)
Next Next
' Final whitening ' 2. Set the round key (key length is 128)
output(outOffset + 0) = CByte((X(0) + roundKey(4)) And &HFF) For i As Integer = 0 To 7
output(outOffset + 1) = X(1) For j As Integer = 0 To 7
output(outOffset + 2) = CByte(X(2) Xor roundKey(5)) Dim idx = 16 * i + j
output(outOffset + 3) = X(3) roundKey(8 + idx) = CByte((key(8 + Mod8(j - i)) + DELTA(idx)) And &HFF)
output(outOffset + 4) = CByte((X(4) + roundKey(6)) And &HFF) roundKey(8 + idx + 8) = CByte((key(Mod8(j - i)) + DELTA(idx + 8)) And &HFF)
output(outOffset + 5) = X(5) Next
output(outOffset + 6) = CByte(X(6) Xor roundKey(7)) Next
output(outOffset + 7) = X(7) 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 End Sub
Public Sub DecryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer) Public Sub DecryptBlock(input() As Byte, inOffset As Integer, output() As Byte, outOffset As Integer)
Dim X(7) As Byte Dim XX(7) As Byte
' Final whitening undo
X(0) = CByte((input(inOffset + 0) - roundKey(4)) And &HFF)
X(1) = input(inOffset + 1)
X(2) = CByte(input(inOffset + 2) Xor roundKey(5))
X(3) = input(inOffset + 3)
X(4) = CByte((input(inOffset + 4) - roundKey(6)) And &HFF)
X(5) = input(inOffset + 5)
X(6) = CByte(input(inOffset + 6) Xor roundKey(7))
X(7) = input(inOffset + 7)
For r As Integer = 31 To 0 Step -1 ' Initial Round
Dim T3 = CByte(F1(X(6)) Xor roundKey(8 + 4 * r + 3)) XX(2) = input(inOffset + 1)
Dim T2 = CByte(F0(X(4)) Xor roundKey(8 + 4 * r + 2)) XX(4) = input(inOffset + 3)
Dim T1 = CByte(F1(X(2)) Xor roundKey(8 + 4 * r + 1)) XX(6) = input(inOffset + 5)
Dim T0 = CByte(F0(X(0)) Xor roundKey(8 + 4 * r + 0)) XX(0) = input(inOffset + 7)
Dim tmp(7) As Byte XX(1) = CByte((input(inOffset + 0) - roundKey(4)) And &HFF)
tmp(0) = CByte((X(3) - T1) And &HFF) XX(3) = CByte(input(inOffset + 2) Xor roundKey(5))
tmp(1) = X(0) XX(5) = CByte((input(inOffset + 4) - roundKey(6)) And &HFF)
tmp(2) = CByte((X(1) - T0) And &HFF) XX(7) = CByte(input(inOffset + 6) Xor roundKey(7))
tmp(3) = X(2)
tmp(4) = CByte((X(7) - T3) And &HFF)
tmp(5) = X(4)
tmp(6) = CByte((X(5) - T2) And &HFF)
tmp(7) = X(6)
Array.Copy(tmp, X, 8) ' 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 Next
' Initial whitening undo ' Final output
output(outOffset + 0) = CByte((X(0) - roundKey(0)) And &HFF) output(outOffset + 1) = XX(1)
output(outOffset + 1) = X(1) output(outOffset + 3) = XX(3)
output(outOffset + 2) = CByte(X(2) Xor roundKey(1)) output(outOffset + 5) = XX(5)
output(outOffset + 3) = X(3) output(outOffset + 7) = XX(7)
output(outOffset + 4) = CByte((X(4) - roundKey(2)) And &HFF)
output(outOffset + 5) = X(5) output(outOffset + 0) = CByte((XX(0) - roundKey(0)) And &HFF)
output(outOffset + 6) = CByte(X(6) Xor roundKey(3)) output(outOffset + 2) = CByte(XX(2) Xor roundKey(1))
output(outOffset + 7) = X(7) output(outOffset + 4) = CByte((XX(4) - roundKey(2)) And &HFF)
output(outOffset + 6) = CByte(XX(6) Xor roundKey(3))
End Sub End Sub
End Class End Class

View File

@ -1,4 +1,9 @@
Imports System.Security.Cryptography ' 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 Public Class HightEcbTransform
Implements ICryptoTransform Implements ICryptoTransform