Skip to content

Commit

Permalink
Merge branch 'master' into getproperty
Browse files Browse the repository at this point in the history
  • Loading branch information
inkydragon committed Nov 13, 2023
2 parents d11d980 + 068f85d commit 967a110
Show file tree
Hide file tree
Showing 13 changed files with 525 additions and 57 deletions.
28 changes: 28 additions & 0 deletions .ci/test_and_change_uuid.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@static if Base.VERSION >= v"1.6"
using TOML
using Test
else
using Pkg: TOML
using Test
end

# To generate the new UUID, we simply modify the first character of the original UUID
const original_uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
const new_uuid = "fa8e919c-243c-51af-8825-aaa63cd721ce"

# `@__DIR__` is the `.ci/` folder.
# Therefore, `dirname(@__DIR__)` is the repository root.
const project_filename = joinpath(dirname(@__DIR__), "Project.toml")

@testset "Test that the UUID is unchanged" begin
project_dict = TOML.parsefile(project_filename)
@test project_dict["uuid"] == original_uuid
end

write(
project_filename,
replace(
read(project_filename, String),
r"uuid = .*?\n" => "uuid = \"$(new_uuid)\"\n",
),
)
20 changes: 16 additions & 4 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ jobs:
version: ${{ matrix.julia-version }}
# Alter the UUID so that we test this package instead of loading
# the version that is already built into a Julia's system image.
- name: alter UUID
shell: bash
run: |
sed -i'' -e 's/ea8e919c-243c-51af-8825-aaa63cd721ce/ea8e919c-243c-51af-8825-aaa63cd721cf/' Project.toml
- run: julia --color=yes .ci/test_and_change_uuid.jl
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
Expand All @@ -52,3 +49,18 @@ jobs:
- uses: codecov/codecov-action@v1
with:
file: lcov.info
doctests:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
- uses: julia-actions/setup-julia@v1
with:
version: 'nightly'
- run: julia --color=yes .ci/test_and_change_uuid.jl
- run: julia --project=docs --color=yes -e 'using Pkg; Pkg.instantiate()'
- run: julia --project=docs --color=yes -e 'using Pkg; Pkg.develop(PackageSpec(path = pwd()))'
- name: Run doctests
run: julia --project=docs --color=yes -e 'import SHA; import Documenter; Documenter.doctest(SHA)'
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Manifest.toml
5 changes: 5 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"

[compat]
Documenter = "~0.27"
171 changes: 164 additions & 7 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
```@meta
EditURL = "https://github.com/JuliaCrypto/SHA.jl/blob/master/docs/src/index.md"
```

# SHA

```@meta
DocTestSetup = quote
using SHA
using InteractiveUtils
end
```


## SHA functions

Usage is very straightforward:
```jldoctest
Expand Down Expand Up @@ -38,10 +51,40 @@ julia> open("/tmp/test.txt") do f
0x08
```

Due to the colloquial usage of `sha256` to refer to `sha2_256`, convenience functions are provided, mapping `shaxxx()` function calls to `sha2_xxx()`. For SHA-3, no such colloquialisms exist and the user must use the full `sha3_xxx()` names.
### All SHA functions
Due to the colloquial usage of `sha256` to refer to `sha2_256`, convenience functions are provided, mapping `shaxxx()` function calls to `sha2_xxx()`.
For SHA-3, no such colloquialisms exist and the user must use the full `sha3_xxx()` names.

`shaxxx()` takes `AbstractString` and array-like objects (`NTuple` and `Array`) with elements of type `UInt8`.

**SHA-1**
```@docs
sha1
```

**SHA-2**
```@docs
sha224
sha256
sha384
sha512
sha2_224
sha2_256
sha2_384
sha2_512
```

**SHA-3**
```@docs
sha3_224
sha3_256
sha3_384
sha3_512
```


## Working with context

To create a hash from multiple items the `SHAX_XXX_CTX()` types can be used to create a stateful hash object that
is updated with `update!` and finalized with `digest!`

Expand Down Expand Up @@ -69,13 +112,7 @@ julia> digest!(ctx)
0xa3
0x57
0x92
0x5b
0xc5
0xe1
0x19
0xa0
0x1b
0x89
0x4f
0x59
Expand All @@ -88,3 +125,123 @@ julia> digest!(ctx)
```

Note that, at the time of this writing, the SHA3 code is not optimized, and as such is roughly an order of magnitude slower than SHA2.

```@docs
update!
digest!
```

### All SHA context types

**SHA-1**
```@docs
SHA1_CTX
```

**SHA-2**

Convenience types are also provided, where `SHAXXX_CTX` is a type alias for `SHA2_XXX_CTX`.
```@docs
SHA224_CTX
SHA256_CTX
SHA384_CTX
SHA512_CTX
SHA2_224_CTX
SHA2_256_CTX
SHA2_384_CTX
SHA2_512_CTX
```

**SHA-3**
```@docs
SHA3_224_CTX
SHA3_256_CTX
SHA3_384_CTX
SHA3_512_CTX
```


## HMAC functions

```jldoctest
julia> using SHA
julia> key = collect(codeunits("key_string"))
10-element Vector{UInt8}:
0x6b
0x65
0x79
0x5f
0x73
0x74
0x72
0x69
0x6e
0x67
julia> bytes2hex(hmac_sha3_256(key, "test-message"))
"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248"
```

To create a hash from multiple items, the `HMAC_CTX()` types can be used to create a stateful hash object that
is updated with `update!` and finalized with `digest!`.

```jldoctest
julia> using SHA
julia> key = collect(codeunits("key_string"))
10-element Vector{UInt8}:
0x6b
0x65
0x79
0x5f
0x73
0x74
0x72
0x69
0x6e
0x67
julia> ctx = HMAC_CTX(SHA3_256_CTX(), key);
julia> update!(ctx, b"test-")
0x0000000000000000000000000000008d
julia> update!(ctx, b"message")
0x00000000000000000000000000000094
julia> bytes2hex(digest!(ctx))
"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248"
```

### All HMAC functions

**HMAC context type**
```@docs
HMAC_CTX
```

**SHA-1**
```@docs
hmac_sha1
```

**SHA-2**
```@docs
hmac_sha224
hmac_sha256
hmac_sha384
hmac_sha512
hmac_sha2_224
hmac_sha2_256
hmac_sha2_384
hmac_sha2_512
```

**SHA-3**
```@docs
hmac_sha3_224
hmac_sha3_256
hmac_sha3_384
hmac_sha3_512
```
22 changes: 17 additions & 5 deletions src/SHA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,20 @@ export sha1, SHA1_CTX, update!, digest!
export sha224, sha256, sha384, sha512
export sha2_224, sha2_256, sha2_384, sha2_512
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 SHA3_224_CTX, SHA3_256_CTX, SHA3_384_CTX, SHA3_512_CTX
export SHAKE_128_CTX, SHAKE_256_CTX
export HMAC_CTX, hmac_sha1
export hmac_sha224, hmac_sha256, hmac_sha384, hmac_sha512
export hmac_sha2_224, hmac_sha2_256, hmac_sha2_384, hmac_sha2_512
export hmac_sha3_224, hmac_sha3_256, hmac_sha3_384, hmac_sha3_512

# data to be hashed:
"""
Union{AbstractVector{UInt8}, NTuple{N, UInt8} where N}
"""
const AbstractBytes = Union{AbstractVector{UInt8},NTuple{N,UInt8} where N}

include("constants.jl")
Expand All @@ -55,6 +60,7 @@ include("base_functions.jl")
include("sha1.jl")
include("sha2.jl")
include("sha3.jl")
include("shake.jl")
include("common.jl")
include("hmac.jl")

Expand All @@ -71,29 +77,29 @@ for (f, ctx) in [(:sha1, :SHA1_CTX),
(:sha3_224, :SHA3_224_CTX),
(:sha3_256, :SHA3_256_CTX),
(:sha3_384, :SHA3_384_CTX),
(:sha3_512, :SHA3_512_CTX),]
(:sha3_512, :SHA3_512_CTX)]
g = Symbol(:hmac_, f)

@eval begin
# Our basic function is to process arrays of bytes
"""
$($f)(data)
Hash data using the $($f) algorithm and return the resulting digest.
Hash data using the `$($f)` algorithm and return the resulting digest.
See also [`$($ctx)`](@ref).
"""
function $f(data::AbstractBytes)
ctx = $ctx()
update!(ctx, data)
return digest!(ctx)
end

"""
$($g)(key, data)
Hash data using the $($f) algorithm using the passed key
Hash data using the `$($f)` algorithm using the passed key.
See also [`HMAC_CTX`](@ref).
"""
end
function $g(key::Vector{UInt8}, data::AbstractBytes)
ctx = HMAC_CTX($ctx(), key)
update!(ctx, data)
Expand All @@ -109,7 +115,7 @@ for (f, ctx) in [(:sha1, :SHA1_CTX),
"""
$($f)(io::IO)
Hash data from io using $($f) algorithm from io.
Hash data from io using `$($f)` algorithm.
"""
function $f(io::IO, chunk_size=4*1024)
ctx = $ctx()
Expand All @@ -120,6 +126,12 @@ for (f, ctx) in [(:sha1, :SHA1_CTX),
end
return digest!(ctx)
end

"""
$($g)(key, io::IO)
Hash data from `io` with the passed key using `$($f)` algorithm.
"""
function $g(key::Vector{UInt8}, io::IO, chunk_size=4*1024)
ctx = HMAC_CTX($ctx(), key)
buff = Vector{UInt8}(undef, chunk_size)
Expand Down
Loading

0 comments on commit 967a110

Please sign in to comment.