Skip to content

Commit

Permalink
Merge pull request #98 from fork4jl/sha512-t
Browse files Browse the repository at this point in the history
SHA-512: impl SHA-512/224, SHA-512/256
  • Loading branch information
inkydragon committed Jan 16, 2024
2 parents 969f867 + a658829 commit 4ab324c
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 5 deletions.
4 changes: 4 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ sha2_224
sha2_256
sha2_384
sha2_512
sha2_512_224
sha2_512_256
```

**SHA-3**
Expand Down Expand Up @@ -150,6 +152,8 @@ SHA2_224_CTX
SHA2_256_CTX
SHA2_384_CTX
SHA2_512_CTX
SHA2_512_224_CTX
SHA2_512_256_CTX
```

**SHA-3**
Expand Down
4 changes: 4 additions & 0 deletions src/SHA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ module SHA
export sha1, SHA1_CTX, update!, digest!
export sha224, sha256, sha384, sha512
export sha2_224, sha2_256, sha2_384, sha2_512
export sha2_512_224, sha2_512_256
export sha3_224, sha3_256, sha3_384, sha3_512
export shake128, shake256
export SHA224_CTX, SHA256_CTX, SHA384_CTX, SHA512_CTX
export SHA2_224_CTX, SHA2_256_CTX, SHA2_384_CTX, SHA2_512_CTX
export SHA2_512_224_CTX, SHA2_512_256_CTX
export SHA3_224_CTX, SHA3_256_CTX, SHA3_384_CTX, SHA3_512_CTX
export SHAKE_128_CTX, SHAKE_256_CTX
export HMAC_CTX, hmac_sha1
Expand Down Expand Up @@ -74,6 +76,8 @@ for (f, ctx) in [(:sha1, :SHA1_CTX),
(:sha2_256, :SHA2_256_CTX),
(:sha2_384, :SHA2_384_CTX),
(:sha2_512, :SHA2_512_CTX),
(:sha2_512_224, :SHA2_512_224_CTX),
(:sha2_512_256, :SHA2_512_256_CTX),
(:sha3_224, :SHA3_224_CTX),
(:sha3_256, :SHA3_256_CTX),
(:sha3_384, :SHA3_384_CTX),
Expand Down
23 changes: 22 additions & 1 deletion src/constants.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# SHA initial hash values and constants
"""SHA initial hash values and constants
Reference:
- SHA-1, SHA2: FIPS 180-4: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
"""

# Hash constant words K for SHA1
const K1 = UInt32[
Expand Down Expand Up @@ -104,6 +108,23 @@ const SHA2_512_initial_hash_value = UInt64[
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
]

# Initial hash value H for SHA-512/224
const SHA2_512_224_initial_hash_value = UInt64[
0x8C3D37C819544DA2, 0x73E1996689DCD4D6,
0x1DFAB7AE32FF9C82, 0x679DD514582F9FCF,
0x0F6D2B697BD44DA8, 0x77E36F7304C48942,
0x3F9D85A86A1D36C8, 0x1112E6AD91D692A1
]

# Initial hash value H for SHA-512/256
const SHA2_512_256_initial_hash_value = UInt64[
0x22312194FC2BF72C, 0x9F555FA3C84C64C2,
0x2393B86B6F53B151, 0x963877195940EABD,
0x96283EE2A88EFFE3, 0xBE5E1E2553863992,
0x2B0199FC2C85B8AA, 0x0EB72DDC81C52CA2
]


# Round constants for SHA3 rounds
const SHA3_ROUND_CONSTS = UInt64[
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
Expand Down
5 changes: 3 additions & 2 deletions src/sha2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ macro R_end(T)
end

@generated function transform!(context::Union{SHA2_224_CTX, SHA2_256_CTX,
SHA2_384_CTX, SHA2_512_CTX})
SHA2_384_CTX, SHA2_512_CTX,
SHA2_512_224_CTX, SHA512_256_CTX})
if context <: Union{SHA2_224_CTX,SHA2_256_CTX}
T = 256
elseif context <: Union{SHA2_384_CTX,SHA2_512_CTX}
elseif context <: Union{SHA2_384_CTX,SHA2_512_CTX,SHA2_512_224_CTX,SHA512_256_CTX}
T = 512
end

Expand Down
44 changes: 42 additions & 2 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ mutable struct SHA2_512_CTX <: SHA2_CTX
used::Bool
end

mutable struct SHA2_512_224_CTX <: SHA2_CTX
state::Vector{UInt64}
bytecount::UInt128
buffer::Vector{UInt8}
used::Bool
end

mutable struct SHA2_512_256_CTX <: SHA2_CTX
state::Vector{UInt64}
bytecount::UInt128
buffer::Vector{UInt8}
used::Bool
end

function Base.getproperty(ctx::SHA2_CTX, fieldname::Symbol)
if fieldname === :state
return getfield(ctx, :state)::Union{Vector{UInt32},Vector{UInt64}}
Expand All @@ -64,7 +78,8 @@ const SHA224_CTX = SHA2_224_CTX
const SHA256_CTX = SHA2_256_CTX
const SHA384_CTX = SHA2_384_CTX
const SHA512_CTX = SHA2_512_CTX

const SHA512_224_CTX = SHA2_512_224_CTX
const SHA512_256_CTX = SHA2_512_256_CTX

# SHA3 224/256/384/512-bit context structures
mutable struct SHA3_224_CTX <: SHA3_CTX
Expand Down Expand Up @@ -123,6 +138,8 @@ digestlen(::Type{SHA3_256_CTX}) = 32
digestlen(::Type{SHA2_384_CTX}) = 48
digestlen(::Type{SHA3_384_CTX}) = 48
digestlen(::Type{SHA2_512_CTX}) = 64
digestlen(::Type{SHA2_512_224_CTX}) = 28
digestlen(::Type{SHA2_512_256_CTX}) = 32
digestlen(::Type{SHA3_512_CTX}) = 64

# SHA1 and SHA2 have differing element types for the internal state objects
Expand All @@ -131,6 +148,8 @@ state_type(::Type{SHA2_224_CTX}) = UInt32
state_type(::Type{SHA2_256_CTX}) = UInt32
state_type(::Type{SHA2_384_CTX}) = UInt64
state_type(::Type{SHA2_512_CTX}) = UInt64
state_type(::Type{SHA2_512_224_CTX}) = UInt64
state_type(::Type{SHA2_512_256_CTX}) = UInt64
state_type(::Type{T}) where {T<:SHA3_CTX} = UInt64

# blocklen is the number of bytes of data processed by the transform!() function at once
Expand All @@ -139,7 +158,8 @@ blocklen(::Type{SHA2_224_CTX}) = UInt64(64)
blocklen(::Type{SHA2_256_CTX}) = UInt64(64)
blocklen(::Type{SHA2_384_CTX}) = UInt64(128)
blocklen(::Type{SHA2_512_CTX}) = UInt64(128)

blocklen(::Type{SHA2_512_224_CTX}) = UInt64(128)
blocklen(::Type{SHA2_512_256_CTX}) = UInt64(128)
blocklen(::Type{SHA3_224_CTX}) = UInt64(25*8 - 2*digestlen(SHA3_224_CTX))
blocklen(::Type{SHA3_256_CTX}) = UInt64(25*8 - 2*digestlen(SHA3_256_CTX))
blocklen(::Type{SHA3_384_CTX}) = UInt64(25*8 - 2*digestlen(SHA3_384_CTX))
Expand Down Expand Up @@ -175,6 +195,24 @@ SHA2_384_CTX() = SHA2_384_CTX(copy(SHA2_384_initial_hash_value), 0, zeros(UInt8,
Construct an empty SHA2_512 context.
"""
SHA2_512_CTX() = SHA2_512_CTX(copy(SHA2_512_initial_hash_value), 0, zeros(UInt8, blocklen(SHA2_512_CTX)), false)
"""
SHA2_512_224_CTX()
Construct an empty SHA2_512/224 context and set the initial hash value.
For the source of the initial value,
refer to [FIPS 180-4, 5.3.6.1 SHA-512/224](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf)
"""
SHA2_512_224_CTX() = SHA2_512_224_CTX(copy(SHA2_512_224_initial_hash_value), 0, zeros(UInt8, blocklen(SHA2_512_224_CTX)), false)
"""
SHA2_512_256_CTX()
Construct an empty SHA2_512/256 context and set the initial hash value.
For the source of the initial value,
refer to [FIPS 180-4, 5.3.6.2 SHA-512/256](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf)
"""
SHA2_512_256_CTX() = SHA2_512_256_CTX(copy(SHA2_512_256_initial_hash_value), 0, zeros(UInt8, blocklen(SHA2_512_256_CTX)), false)

"""
SHA3_224_CTX()
Expand Down Expand Up @@ -229,6 +267,8 @@ show(io::IO, ::SHA2_224_CTX) = print(io, "SHA2 224-bit hash state")
show(io::IO, ::SHA2_256_CTX) = print(io, "SHA2 256-bit hash state")
show(io::IO, ::SHA2_384_CTX) = print(io, "SHA2 384-bit hash state")
show(io::IO, ::SHA2_512_CTX) = print(io, "SHA2 512-bit hash state")
show(io::IO, ::SHA2_512_224_CTX) = print(io, "SHA2 512/224-bit hash state")
show(io::IO, ::SHA2_512_256_CTX) = print(io, "SHA2 512/256-bit hash state")
show(io::IO, ::SHA3_224_CTX) = print(io, "SHA3 224-bit hash state")
show(io::IO, ::SHA3_256_CTX) = print(io, "SHA3 256-bit hash state")
show(io::IO, ::SHA3_384_CTX) = print(io, "SHA3 384-bit hash state")
Expand Down
21 changes: 21 additions & 0 deletions test/constants.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ data_desc = ["the empty string", "the string \"test\"", "lorem ipsum",
"0 file", "one million a's Array", "one million a's Tuple"]
sha_types = Dict(sha1 => SHA.SHA1_CTX,
sha2_224 => SHA.SHA2_224_CTX, sha2_256 => SHA.SHA2_256_CTX, sha2_384 => SHA.SHA2_384_CTX, sha2_512 => SHA.SHA2_512_CTX,
sha2_512_224 => SHA.SHA2_512_224_CTX, sha2_512_256 => SHA.SHA2_512_256_CTX,
sha3_224 => SHA.SHA3_224_CTX, sha3_256 => SHA.SHA3_256_CTX, sha3_384 => SHA.SHA3_384_CTX, sha3_512 => SHA.SHA3_512_CTX)
sha_funcs = [sha1,
sha2_224, sha2_256, sha2_384, sha2_512,
sha2_512_224, sha2_512_256,
sha3_224, sha3_256, sha3_384, sha3_512]
ctxs = [SHA1_CTX,
SHA2_224_CTX, SHA2_256_CTX, SHA2_384_CTX, SHA2_512_CTX,
SHA2_512_224_CTX, SHA2_512_256_CTX,
SHA3_224_CTX, SHA3_256_CTX, SHA3_384_CTX, SHA3_512_CTX]
shws = ["SHA1 hash state",
"SHA2 224-bit hash state", "SHA2 256-bit hash state", "SHA2 384-bit hash state", "SHA2 512-bit hash state",
"SHA2 512/224-bit hash state", "SHA2 512/256-bit hash state",
"SHA3 224-bit hash state", "SHA3 256-bit hash state", "SHA3 384-bit hash state", "SHA3 512-bit hash state"]

answers = Dict(
Expand Down Expand Up @@ -62,6 +66,23 @@ answers = Dict(
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b",
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
],
sha2_512_224 => [
"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4",
"06001bf08dfb17d2b54925116823be230e98b5c6c278303bc4909a8c",
"3a312b004a593b706790a4a5b25309eb7c83efb85a4d1f0a8440e09e",
"283bb59af7081ed08197227d8f65b9591ffe1155be43e9550e57f941",
"37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287",
"37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287"
],
sha2_512_256 => [
"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a",
"3d37fe58435e0d87323dee4a2c1b339ef954de63716ee79f5747f94d974f913f",
"9423e3863ebb6f22b9464aeb873a39d757ef6b6a87c4bc55642f69052741fc43",
"10baad1713566ac2333467bddb0597dec9066120dd72ac2dcb8394221dcbe43d",
"9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21",
"9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21"
],

sha3_224 => [
"6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7",
"3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b",
Expand Down
13 changes: 13 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ end
end
end

@testset "SHA-512/t" begin
# https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512_224.pdf
@test sha2_512_224("abc") |> bytes2hex ==
"4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa"
@test sha2_512_224("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") |> bytes2hex ==
"23fec5bb94d60b23308192640b0c453335d664734fe40e7268674af9"
# https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512_256.pdf
@test sha2_512_256("abc") |> bytes2hex ==
"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"
@test sha2_512_256("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") |> bytes2hex ==
"3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a"
end

@testset "SHA3" begin
@test sha3_512("0" ^ 70) |> bytes2hex ==
"1ec3e5ebb442c09e7ab7a1ee18edfa1a9ec771ad243e3e3d65cad1730416109a0890e29f9314babd7ab018a246b2f9639af29ee09aec2352a2f94dc12a2f6109"
Expand Down

0 comments on commit 4ab324c

Please sign in to comment.