From a22173e3de076b800349097999b2fd94ec093b9b Mon Sep 17 00:00:00 2001 From: Guido Kraemer Date: Sun, 17 Sep 2017 07:13:52 +0200 Subject: [PATCH] hashing tuples (#34) * hashing tuples * remove type specification for data and update! for 0.4 compat * Added documentations * Fix wrong use of reinterpret * Fix depwarns under 0.7 and bump REQUIRE and CI to 0.6. * Remove isdefined for precompile * Add syntax highlighting to readme * update parameterized syntax * Remove extra spaces * Fix depwarns on 0.7 * hashing tuples * remove type specification for data and update! for 0.4 compat * Added documentations * added NTuples to update! * remove unnecessary type check --- README.md | 2 ++ src/SHA.jl | 2 +- src/common.jl | 3 ++- test/runtests.jl | 51 ++++++++++++++++++++++++++++++++++-------------- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5111b22ef2cc8..85bf4f5fb1e43 100644 --- a/README.md +++ b/README.md @@ -47,4 +47,6 @@ Note the lack of a newline at the end of `/tmp/text.txt`. Julia automatically i 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`. + 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. Pull requests are welcome. diff --git a/src/SHA.jl b/src/SHA.jl index 3edfb3c94a29b..085ebeaa41c1c 100644 --- a/src/SHA.jl +++ b/src/SHA.jl @@ -38,7 +38,7 @@ for (f, ctx) in [(:sha1, :SHA1_CTX), (:sha3_512, :SHA3_512_CTX),] @eval begin # Our basic function is to process arrays of bytes - function $f(data::Array{UInt8,1}) + function $f(data::T) where T<:Union{Array{UInt8,1},NTuple{N,UInt8} where N} ctx = $ctx() update!(ctx, data) return digest!(ctx) diff --git a/src/common.jl b/src/common.jl index 4b089eb477b95..e7ffdf00f1112 100644 --- a/src/common.jl +++ b/src/common.jl @@ -2,7 +2,8 @@ # update! takes in variable-length data, buffering it into blocklen()-sized pieces, # calling transform!() when necessary to update the internal hash state. -function update!(context::T, data::Array{UInt8,1}) where {T<:Union{SHA1_CTX,SHA2_CTX,SHA3_CTX}} +function update!(context::T, data::U) where {T<:Union{SHA1_CTX,SHA2_CTX,SHA3_CTX}, + U<:Union{Array{UInt8,1},NTuple{N,UInt8} where N}} # We need to do all our arithmetic in the proper bitwidth UIntXXX = typeof(context.bytecount) diff --git a/test/runtests.jl b/test/runtests.jl index 0e2d4edeeca72..dab41f2425a5f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,15 +3,17 @@ using Compat # Define some data we will run our tests on lorem = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." -so_many_as = repmat([0x61], 1000000) +so_many_as_array = repmat([0x61], 1000000) +so_many_as_tuple = ntuple((i) -> 0x61, 1000000) file = ".sha" # Subject to change fIO = open(file, "w") write(fIO, '\0') close(fIO) -data = Any["", "test", lorem, file, so_many_as] +data = Any["", "test", lorem, file, so_many_as_array, so_many_as_tuple] # Descriptions of the data, the SHA functions we'll run on the data, etc... -data_desc = ["the empty string", "the string \"test\"", "lorem ipsum", "0 file", "one million a's"] +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, sha3_224 => SHA.SHA3_224_CTX, sha3_256 => SHA.SHA3_256_CTX, sha3_384 => SHA.SHA3_384_CTX, sha3_512 => SHA.SHA3_512_CTX) @@ -32,12 +34,14 @@ sha1 => [ "19afa2a4a37462c7b940a6c4c61363d49c3a35f4", "5ba93c9db0cff93f52b521d7420e43f6eda2784f", "34aa973cd4c4daa4f61eeb2bdbad27316534016f", +"34aa973cd4c4daa4f61eeb2bdbad27316534016f" ], sha2_224 => [ "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809", "6a0644abcf1e2cecbec2814443dab5f24b7ad8ebb66c75667ab67959", "fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073", +"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67", "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" ], sha2_256 => [ @@ -45,6 +49,7 @@ sha2_256 => [ "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18", "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", +"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" ], sha2_384 => [ @@ -52,6 +57,7 @@ sha2_384 => [ "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9", "63980fd0425cd2c3d8a400ee0f2671ef135db03b947ec1af21b6e28f19c16ca272036469541f4d8e336ac6d1da50580f", "bec021b4f368e3069134e012c2b4307083d3a9bdd206e24e5f0d86e13d6636655933ec2b413465966817a9c208a11717", +"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985", "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985" ], sha2_512 => [ @@ -59,6 +65,7 @@ sha2_512 => [ "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff", "f41d92bc9fc1157a0d1387e67f3d0893b70f7039d3d46d8115b5079d45ad601159398c79c281681e2da09bf7d9f8c23b41d1a0a3c5b528a7f2735933a4353194", "b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee", +"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b", "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" ], sha3_224 => [ @@ -66,6 +73,7 @@ sha3_224 => [ "3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b", "ea5395370949ad8c7d2ca3e7c045ef3306fe3a3f4740de452ef87a28", "bdd5167212d2dc69665f5a8875ab87f23d5ce7849132f56371a19096", +"d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c", "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c" ], sha3_256 => [ @@ -73,21 +81,24 @@ sha3_256 => [ "36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80", "8c8142d2ca964ab307ace567ddd5764f17ebb76eb8ff25543ab54c14fe2ab139", "5d53469f20fef4f8eab52b88044ede69c77a6a68a60728609fc4a65ff531e7d0", -"5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1" +"5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1", +"5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1", ], sha3_384 => [ "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", "e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7ff0f1b41eecb9db3ff219007c4e097260d58621bd", "eb9fbba3eb916a4efe384b3125f5d03ceb9c5c1b94431ac30fa86c54408b92701ca5d2628cd7113aa5541177ec3ccd1d", "127677f8b66725bbcb7c3eae9698351ca41e0eb6d66c784bd28dcdb3b5fb12d0c8e840342db03ad1ae180b92e3504933", -"eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340" +"eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340", +"eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340", ], sha3_512 => [ "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14", "3a4318353396a12dfd20442cfce1d8ad4d7e732e85cc56b01b4cf9057a41c8827c0a03c70812e76ace68d776759225c213b4f581aac0dba5dd43b785b1a33fe5", "7127aab211f82a18d06cf7578ff49d5089017944139aa60d8bee057811a15fb55a53887600a3eceba004de51105139f32506fe5b53e1913bfa6b32e716fe97da", -"3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87" +"3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87", +"3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87", ] ) @@ -140,8 +151,8 @@ print("Testing on one million a's (chunked properly)") nerrors_old = nerrors for sha_idx in 1:length(sha_funcs) ctx = sha_types[sha_funcs[sha_idx]]() - SHA.update!(ctx, so_many_as[1:2*SHA.blocklen(typeof(ctx))]) - SHA.update!(ctx, so_many_as[2*SHA.blocklen(typeof(ctx))+1:end]) + SHA.update!(ctx, so_many_as_array[1:2*SHA.blocklen(typeof(ctx))]) + SHA.update!(ctx, so_many_as_array[2*SHA.blocklen(typeof(ctx))+1:end]) hash = bytes2hex(SHA.digest!(ctx)) if hash != answers[sha_funcs[sha_idx]][end] print("\n") @@ -173,13 +184,13 @@ for sha_idx in 1:length(sha_funcs) idx2 = round(Int, 2.6*SHA.blocklen(typeof(ctx))) # Feed data in according to our dastardly blocking scheme - SHA.update!(ctx, so_many_as[0 + 1:1*idx0]) - SHA.update!(ctx, so_many_as[1*idx0 + 1:2*idx0]) - SHA.update!(ctx, so_many_as[2*idx0 + 1:3*idx0]) - SHA.update!(ctx, so_many_as[3*idx0 + 1:4*idx0]) - SHA.update!(ctx, so_many_as[4*idx0 + 1:idx1]) - SHA.update!(ctx, so_many_as[idx1 + 1:idx2]) - SHA.update!(ctx, so_many_as[idx2 + 1:end]) + SHA.update!(ctx, so_many_as_array[0 + 1:1*idx0]) + SHA.update!(ctx, so_many_as_array[1*idx0 + 1:2*idx0]) + SHA.update!(ctx, so_many_as_array[2*idx0 + 1:3*idx0]) + SHA.update!(ctx, so_many_as_array[3*idx0 + 1:4*idx0]) + SHA.update!(ctx, so_many_as_array[4*idx0 + 1:idx1]) + SHA.update!(ctx, so_many_as_array[idx1 + 1:idx2]) + SHA.update!(ctx, so_many_as_array[idx2 + 1:end]) # Ensure the hash is the appropriate one hash = bytes2hex(SHA.digest!(ctx)) @@ -227,6 +238,16 @@ for idx in 1:length(ctxs) println("Done! [$(nerrors - nerrors_old) errors]") end +# test error if eltype of input is not UInt8 +for f in sha_funcs + try + f(UInt32[0x23467, 0x324775]) + warn("Non-UInt8 Arrays should fail") + nerrors += 1 + end +end + + # Clean up the I/O mess rm(file)