digest/0000755000176200001440000000000014151623322011530 5ustar liggesusersdigest/NAMESPACE0000644000176200001440000000206213572200266012753 0ustar liggesusers## package has a dynamic library useDynLib(digest, digest_impl=digest, vdigest_impl=vdigest, digest2int_impl=digest2int, AESinit, AESencryptECB, AESdecryptECB, spookydigest_impl, .registration=TRUE) importFrom(utils, packageVersion) ## and exported functions export(AES, digest, digest2int, getVDigest, sha1, sha1_attr_digest, sha1_digest, hmac, makeRaw) S3method(print, AES) S3method(sha1, anova) S3method(sha1, array) S3method(sha1, call) S3method(sha1, character) S3method(sha1, complex) S3method(sha1, data.frame) S3method(sha1, Date) S3method(sha1, default) S3method(sha1, integer) S3method(sha1, factor) S3method(sha1, formula) S3method(sha1, "function") S3method(sha1, logical) S3method(sha1, list) S3method(sha1, matrix) S3method(sha1, name) S3method(sha1, NULL) S3method(sha1, numeric) S3method(sha1, pairlist) S3method(sha1, POSIXct) S3method(sha1, POSIXlt) S3method(sha1, raw) S3method(sha1, "(") S3method(makeRaw, default) S3method(makeRaw, digest) S3method(makeRaw, character) S3method(makeRaw, raw) digest/demo/0000755000176200001440000000000013540654254012465 5ustar liggesusersdigest/demo/vectorised.R0000644000176200001440000000162613540654254014764 0ustar liggesuserslibrary(digest) #vectorisation md5 <- getVDigest() digest2 <- base::Vectorize(digest) x <- rep(letters, 1e3) rbenchmark::benchmark( vdigest = md5(x, serialize = FALSE), Vectorize = digest2(x, serialize = FALSE), vapply = vapply(x, digest, character(1), serialize = FALSE), replications = 5 )[,1:4] all(md5(x, serialize=FALSE) == digest2(x, serialize=FALSE)) all(md5(x, serialize=FALSE) == vapply(x, digest, character(1), serialize = FALSE)) #repeated calls stretch_key <- function(d, n) { md5 <- getVDigest() for (i in seq_len(n)) d <- md5(d, serialize = FALSE) d } stretch_key2 <- function(d, n) { for (i in seq_len(n)) d <- digest(d, serialize = FALSE) d } rbenchmark::benchmark( vdigest = stretch_key('abc123', 65e3), plaindigest = stretch_key2('abc123', 65e3), replications = 10 )[,1:4] stretch_key('abc123', 65e3) == stretch_key2('abc123', 65e3) digest/demo/00Index0000644000176200001440000000011613540654254013615 0ustar liggesusersvectorised Timing comparison of approaches for vectorised digest digest/ChangeLog0000644000176200001440000011677514151531046013324 0ustar liggesusers2021-11-30 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.29 * src/digest.c (digest): Accomodate Windows UCRT build * man/AES.Rd: Remove one URL that upsets the URL checker * README.md: Update one URL that upsets the URL checker 2021-11-20 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * vignettes/sha1.md: Renamed from .Rmd, corrected code block syntax 2021-11-19 Dirk Eddelbuettel * DESCRIPTION (VignetteBuilder): Converted to simplermarkdown engine * vignettes/sha1.Rmd: Idem * vignettes/water.css: Added 2021-11-05 Dirk Eddelbuettel * README.md: Remove Travis badge * .travis.yml: Remove Travis YAML config 2021-09-23 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.28 2021-09-22 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * vignettes/sha1.Rmd (date): Remove knitr date calculation in YAML header which GitHub does not like and mistakes for Jekyll code * docs/mkdmt-src/src/vignette.md (date): Idem * README.md: Add total download badge, label other as monthly 2021-09-22 András Svraka * R/vdigest.R (non_streaming_digest): Ensure UTF-8 encoded file paths on Windows * inst/tinytest/test_encoding.R: Expand test coverage for path name encodings on Windows 2021-03-28 Dirk Eddelbuettel * docs/mkdmt-src/: Moved mkdocs-material input 2021-03-26 Dirk Eddelbuettel * README.md: Add 'last commit' badge 2021-03-23 Dirk Eddelbuettel * DESCRIPTION (URL): Add link to repo 2021-03-22 Dirk Eddelbuettel * docs-src/mkdocs.yml (theme): Add (draft, incomplete) vignette * docs-src/src/vignette.md (title): Idem 2021-03-22 Floris Vanderhaeghe * man/digest.Rd: Reworded to also highlight file mode 2021-01-16 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * src/SpookyV2.cpp: Disallow unaligned reads which have been seen to trigger SAN issues as reported by Winston in #167 2020-12-23 Dirk Eddelbuettel * .github/workflows/ci.yaml: Add CI runner using r-ci * README.md: Add new CI badge 2020-10-20 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.27 2020-10-19 Dirk Eddelbuettel * src/blake3_dispatch.c: Comment-out include of intrinsics to also comment-out erroring on insufficient architectures such as Solaris 2020-10-17 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.26 * docs/: Added package website * docs-src/: Added package website inputs * .travis.yml (dist): Change to focal 2020-10-15 Dirk Eddelbuettel * README.md: Update URLs * man/digest.Rd: Ditto * man/hmac.Rd: Ditto 2020-10-14 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * inst/tinytest/test_blake3.R: Skip file-based blake3 tests on Windows * vignettes/sha1.Rmd: Switch to minidown and 'framework: water' * DESCRIPTION (Suggests): Add minidown 2020-10-07 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2020-10-06 Winston Chang * R/digest.R: Speedup via explicit alternative values for match.arg() and a direct call to serialize() * R/vdigest.R: Idem * R/init.R: Idem (for serialize()) * inst/tinytest/test_digest.R: New test ensuring all variants hit 2020-09-21 Dirk Eddelbuettel * .travis.yml: Updated to 'bionic', R 4.0, and BSPM 2020-08-03 Dirk Eddelbuettel * DESCRIPTION (Depends): Roll Depends: on to R (>= 3.3.0) due to use of startsWith(), with thanks to Florian Pein 2020-05-20 Dirk Eddelbuettel * .travis.yml: Switch to bionic and R 4.0.0 2020-05-19 Dirk Schumacher * src/digest.c: Support file operation * inst/tinytest/test_blake3.R: Update test 2020-05-19 Dirk Eddelbuettel * DESCRIPTION (Version): Roll minor version and date 2020-05-19 Dirk Schumacher * src/blake3.c: Add blake3 implementation * src/blake3.h: Idem * src/blake3_dispatch.c: Idem * src/blake3_impl.h: Idem * src/blake3_portable.c: Idem * src/digest.c: Support blake3 call * R/digest.R: Idem * inst/tinytest/test_blake3.R: Add tests * man/digest.Rd: Add documentation 2020-03-05 Harris McGehee * man/sha1.Rd: Correct typo 2020-02-26 Dirk Eddelbuettel * README.md: Add Debian badge 2020-02-22 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.25 2020-02-15 Kendon Bell * R/digest.R: Complete call to spookyhash 2020-02-12 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.24 2019-12-12 Thierry Onkelinx * DESCRIPTION (Version, Date): Roll minor version * R/sha1.R: ignore the "srcref" attribute if set * inst/tinytest/test_new_matrix_behaviour.R: update unit test * inst/tinytest/test_sha1.R: update unit test * man/sha1.Rd: update documentation 2019-12-09 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * src/init.c: Do not register a .Call method for PMurHash 2019-12-05 Will Landau * R/init.R (.onLoad): Cache nosharing state in base::serialize (.hasNoSharing): Return cached value * R/digest.R (digest): Use cached value accessor * R/vdigest.R (non_streaming_digest): Use cached value accessor 2019-12-04 Dirk Eddelbuettel * R/init.R (.onLoad): Cache isWindows state (.isWindows): Return cached value * R/digest.R (digest): Use cached value accessor 2019-11-23 Dirk Eddelbuettel * inst/tinytest/test_new_matrix_behaviour.R: Split off tests affected by new matrix/array behavior in R-devel (i.e. future R 4.0.0) 2019-11-22 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.23 * inst/tinytest/test_sha1.R: Uncomment several tests which failed under r-devel on Linux at CRAN 2019-11-13 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2019-11-11 Bill Denney * R/sha1.R: Increase efficiency of num2hex() 2019-11-07 Bill Denney * NAMESPACE: add sha1_digest() and sha1_attr_digest() functions * R/sha1.R: Idem * man/sha1.Rd: Idem * Also, renamed sha1.rd to sha1.Rd 2019-11-03 Bill Denney * R/sha1.R: Add support for the "(" class used in some formulae * NAMESPACE: Idem * man/sha1.Rd: Idem; also corrected typo for old version behavior * inst.tinytest/test_sha1.R: Add tests for the "(" class 2019-10-27 Thierry Onkelinx * DESCRIPTION (Version, Date): Roll minor version * R/sha1.R: consider object attributes when calculating the hash * man/sha1.Rd: update documentation * R/init.R: add "sha1PackageVersion" option * inst.tinytest/test_sha1.R: add units tests for new functionality * NAMESPACE: import utils::packageVersion 2019-10-26 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * R/digest.R (digest): Call enc2utf8() only on Windows; add internal one-liner function to test for being on Windows 2019-10-23 Dirk Eddelbuettel * inst/tinytest/test_encoding.R: Skip test unless on Windows 2019-10-21 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.22 2019-10-20 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * inst/tinytest/test_misc.R: File split off test_digest.R 2019-10-19 Dirk Eddelbuettel * DESCRIPTION: Add Ion and Bill to Authors * README.md: Idem 2019-10-13 Jim Hester * src/digest.c: Add support for UTF-8 file paths on Windows * R/digest.R: Idem * inst/tinytest/test_encoding.R: Add tests for UTF-8 file paths. 2019-10-13 Bill Denney * R/sha1.R: Add sha1.formula() * NAMESPACE: Idem * man/sha1.rd: Idem * inst/tinytest/test_sha1.R: Add tests for sha1.formula() 2019-10-12 Bill Denney * R/sha1.R: Fix issue with num2hex() and input of Inf * inst/tinytest/test_sha1.R: Add Inf to the tests 2019-10-05 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * man/digest.Rd: Change three URL references to https * man/hmac.Rd: Ditto * R/utils.R: Move back functions used by digest() + makeVDigest() * R/AES.R: Added copyright header * R/digest.R: Idem * R/hmac.R: Idem * R/sha1.R: Idem * R/vdigest.R: Idem 2019-10-02 Ion Suruceanu * R/AES.R: Add support for CFB cipher mode * man/AES.Rd: Add documentation * inst/tinytest/test_aes.R: Add tests 2019-09-20 Matthew de Queljoe * R/digest.R: refactor digest function * R/vdigest.R: remove helper functions from file * R/utils.R: new file to hold helper functions 2019-09-19 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.21 2019-09-18 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * DESCRIPTION (Author): Add Matthew * README.md (Author): Ditto * demo/vectorised.R: Add demo (based on Matthew's PR) * R/vdigest.R: Added a handful of #nocov tags * man/vdigest.Rd: Break up two long lines 2019-09-17 Matthew de Queljoe * src/digest.c: Add vectorised digest function * R/vdigest.R: Add vectorised digest function factory * man/vdigest.Rd: Add documentation * NAMESPACE: Export new function getVDigest * inst/tinytest/test_digest.R: Add tests 2019-07-04 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.20 2019-06-29 Dirk Eddelbuettel * README.md: Add installation and continues testing sections * .travis.yml (install): Use r-cran-tinytest from PPA 2019-06-23 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * inst/tinytest/test_num2hex.R: Quieter with sapply * test/tinytest/test_aes.R: renamed from testAES.R * test/tinytest/test_crc32.R: renamed from testCRC32.R * test/tinytest/test_digest.R: renamed from testDigest.R * test/tinytest/test_digest2int.R: from testDigest2Int.R * test/tinytest/test_hmac.R: renamed from testHMAC.R * test/tinytest/test_num2hex.R: renamed from testNum2Hex.R * test/tinytest/test_raw.R: renamed from testRaw.R * test/tinytest/test_sha1.R: renamed from testSHA1.R 2019-06-10 Dirk Eddelbuettel * inst/tinytest/testCRC32.R: Use expcect_* functions * inst/tinytest/testDigest2Int.R: Idem * inst/tinytest/testNum2Hex.R: Idem * inst/tinytest/testRaw.R: Idem 2019-05-26 Dirk Eddelbuettel * tests/tinytest.R: New test driver using tinytest * DESCRIPTION (Suggests): Added tinytest * .travis.yml (install): Install tinytest * inst/tinytest/testRaw.R: Converted from tests/raw.R * inst/tinytest/testCRC32.R: Converted from tests/crc32.R * inst/tinytest/testDigest2Int.R: From tests/digest2int.R * inst/tinytest/testNum2Hex.R: From tests/num2hexTest.R * inst/tinytest/testSHA1.R: Converted from tests/sha1Test.R * inst/tinytest/testHMAC.R: Converted from tests/hmacTest.R * inst/tinytest/testAES.R: Converted from tests/aesTest.R * inst/tinytest/testDigest.R: From tests/digestTest.R * R/AES.R: Additional #nocov tags * R/digest.R: Idem * R/hmac.R: Idem * R/sha1.R: Idem 2019-05-19 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.19 * src/SpookyV2.cpp: Add some #nocov tags 2019-05-18 Dirk Eddelbuettel * DESCRIPTION (Version, Date): New minor version * tests/digestTest.Rout.save: Updated reference output 2019-05-12 Kendon Bell * R/digest.R: Account for 'skip' bytes for streaming algos * tests/digestTest.R: Adjust test for streaming_algos 2019-05-09 Dirk Eddelbuettel * src/Makevars: Added to ensure C++11 compilation standard * cleanup: Do not delete src/Makevars now that we have one * tests/digestTest.Rout.save: Updated reference output 2019-05-06 Dirk Eddelbuettel * README.md: Mention spookyhash and Kendon * DESCRIPTION (Description): Mention spookyhash 2019-05-04 Kendon Bell * tests/digestTest.R: Added more tests * src/spooky_serialize.cpp: Added copyright header 2019-05-04 Dirk Eddelbuettel * R/digest.R: Add some #nocov tags * src/SpookyV2.h: Idem * src/SpookyV2.cpp: Idem * src/spooky_serialize.cpp: Idem 2019-05-03 Dirk Eddelbuettel * tests/digestTest.Rout.save: Updated reference output 2019-04-30 Kendon Bell * digest.R: Support spookyhash * src/SpookyV2.h: Idem * src/SpookyV2.cpp: Idem * src/spooky_serialize.cpp: Idem * man/digest.Rd: Document spookyhash 2019-04-23 Kendon Bell * src/digest.c: Switch length counter to R_xlen_t 2018-12-23 Dirk Eddelbuettel * NAMESPACE: Add .registration=TRUE to useDynLib() 2018-11-10 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2018-11-08 Dmitriy Selivanov * src/digest2int.c: Removed (bad) redefinition of uint32_t * tests/digest2intTest.R: Additional test 2018-10-29 Dmitriy Selivanov * DESCRIPTION (Version, Date): minor version * digest2int.R (digest2int): added digest2int * src/digest2int.c (digest2int): added Bob Jenkins `one_at_a_time` function for hashing arbitrary character vectors to integer vectors 2018-10-18 Dirk Eddelbuettel * README.md: Added dependencies badge 2018-10-10 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.6.18 2018-09-16 Dirk Eddelbuettel * src/digest.c (digest): Six more #nocov tags * README.md: Small edits 2018-09-14 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * src/sha2.c: Explicitly #undef SHA256_ and SHA384_ functions not used from this file 2018-09-13 Radford Neal * src/pmurhash.c (DOBYTES): Explicit cast to uint32_t avoids UBSAN 2018-09-13 Jim Hester * src/xxhash.c: Updated to use xxHash v0.6.5 * src/xxhash.h: Ditto * src/digest.c: Ditto 2018-09-11 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.6.17 2018-09-02 Dirk Eddelbuettel * .travis.yml: Simplified as covr can be installed from c2d4u 2018-08-30 Radford Neal * src/sha2.c: Memory alignment changes motivated by 32bit sparc * src/sha2.h: Ditto 2018-08-21 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.6.16 2018-08-20 Dirk Eddelbuettel * tests/digestTest.Rout: Skip one test which creates different results across versions and operating systems * tests/digestTest.Rout.save: Ditto 2018-08-19 Dirk Eddelbuettel * tests/hmacTest.R: Added raw test * tests/hmacTest.Rout.save: Updated reference output accordingly * tests/raw.R: Added test for 'raw' vector input to sha1() * R/sha1.R: Removed no longer needed #nocov tags 2018-07-21 Henrik Bengtsson * DESCRIPTION: digest (>= 0.6.14) requires R (>= 3.0.3) 2018-06-30 Dirk Eddelbuettel * tests/crc32.R: Added test for crc32 and old versus new formats * tests/raw.R: Added small test file for raw tests 2018-06-29 Dirk Eddelbuettel * R/init.R: Provide option 'digestOldCRC32Format' which if TRUE returns without zero padding which can be shorter than eight bytes * R/digest.R: If crc32 selected and option set, return in old format * man/digest.Rd: Document new option 2018-06-28 Dirk Eddelbuettel * src/digest.c (digest): Change print format for crc32 to always return eight characters and no longer drop leading zeros (thanks to Henrik Bengtsson for the heads-up) 2018-06-21 Dirk Eddelbuettel * tests/sha1Test.R: Do not run test using serialize() as its output always reflects the R version used (thanks, Radford Neal) 2018-01-29 Dirk Eddelbuettel * src/sha2.c: Comment-out three unused 'const static' variables 2018-01-28 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.6.15 * R/sha1.R (sha1.POSIXlt): Unclass POSIXlt objects as suggested by Kurt Hornik to accomodate R-devel changes * tests/sha1Test.R: Condition one sha1 test seemingly affected by R-devel serialization changes to run only with R < 3.5.0 2018-01-21 Thierry Onkelinx * sha1() gains an `algo` argument * sha1() handles raw class 2018-01-14 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.6.14 * man/AES.Rd: Use https for nist.gov reference * man/digest.Rd: Idem * man/hmac.Rd: Idem * man/digest.Rd: Use Wikiepedia page as reference for SHA1 as the reference page at NIST has (long) vanished. * man/hmac.Rd: Idem 2018-01-12 Thierry Onkelinx * sha1() handles empty matrices 2017-12-20 Dirk Eddelbuettel * src/raes.c (AESencryptECB,AESdecryptECD): Replace two uses of NAMED with MAYBE_REFERENCED 2017-12-13 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.6.13 2017-12-12 Dirk Eddelbuettel * DESCRIPTION (Version, Date): New minor version * R/digest.R: Support serializeVersion format * man/digest.Rd: Document new option * R/init.R: Set a default version, and internal getter function 2017-10-12 Chris Muir * vignette/sha1.Rmd: Correct simple typo 2017-11-16 Moritz Beller * man/digest.Rd: Replace old Google Code URLs with GitHub ones 2017-02-20 Dirk Eddelbuettel * man/digest.Rd: Expand example section with a Vectorize() use 2017-01-29 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * man/digest.Rd: Note that support for 'raw' is not available for all hashing algorithms * .travis.yml (before_install): Use https for curl fetch 2017-01-26 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.12 2017-01-23 Thierry Onkelinx * NAMESPACE: export sha1.function() and sha1.call() * R/sha1.R: - sha1() gains methods for the class "function" and "call" - sha1() gains a ... argument, currently only relevant for "function" - sha1() takes arguments into account for hash for complex, Date and array. Note that this will lead to different hasheS for these classes and for objects containing these classes * man/sha1.rd: update helppage for sha1() * tests/sha1Test.R: update unit tests for sha1() 2017-01-01 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.6.11 * R/sha1.R (sha1.anova): Added more #nocov marks * src/sha2.c (SHA256_Transform): Idem * tests/AESTest.R (hextextToRaw): Print AES object * tests/AESTest.Rout.save: Updated 2016-12-08 Dirk Eddelbuettel * NAMESPACE: Register (and exported) makeRaw S3 methods * man/makeRaw.Rd: New manual page * tests/hmacTest.R: Direct call to makeRaw() * tests/hmacTest.Rout.save: Ditto * src/digest.c: Additional #nocov tags * src/xxhash.c: Ditto 2016-12-07 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Rolled minor version * README.md: Use shields.io badge for codecov * R/digest.R: Additional #nocov tags * src/sha2.c: Ditto * src/raes.c: Ditto * tests/hmacTest.R: Additional tests * tests/hmacTest.Rout.save: Ditto 2016-11-30 Dirk Eddelbuettel * .travis.yml (before_install): Activate PPA as we (currently) need an updated version of (r-cran)-covr to run coverage * tests/load-unload.R: Comment-out for now as it upsets coverage * tests/digestTest.R: Test two more algorithms * tests/digestTest.Rout.save: Updated reference output * R/digest.R: Added #nocov tags * R/zzz.R (.onUnload): Ditto * src/crc32.c: Ditto * src/pmurhash.c: Ditto * src/raes.c: Ditto * src/sha2.c: Ditto * src/xxhash.c: Ditto 2016-11-26 Dirk Eddelbuettel * .travis.yml (after_success): Integrated Jim Hester's suggestion of activating code coverage sent many moons ago (in PR #12) * .codecov.yml (comment): Added * .Rbuildignore: Exclude .codecov.yml * README.md: Added code coverage badge 2016-10-16 Dirk Eddelbuettel * R/digest.R (digest): Support 'nosharing' option of base::serialize as suggested by Radford Neal whose pqR uses this 2016-08-02 Dirk Eddelbuettel * DESCRIPTION (License): Now GPL (>= 2), cf issue 36 on GH * README.md: Updated badge accordingly 2016-08-02 Dirk Eddelbuettel * DESCRIPTION (Version): Release 0.6.10 * DESCRIPTION (Description): Shortened to one paragraph * DESCRIPTION (BugReports): URL to GH issues added * .travis.yml: Rewritten for run.sh from forked r-travis 2016-07-12 Henrik Bengtsson * src/digest.c: Correct bug with skip and file parameter interaction * tests/digestTest.R: Test code * tests/digestTest.Rout.save: Test reference output * R/zzz.R: Allow for unloading of shared library * tests/load-unload.R: Test code * DESCRIPTION: Rolled minor Version and Date 2016-05-25 Thierry Onkelinx * R/sha1.R: Support for pairlist and name * tests/sha1Test.R: Support for pairlist and name * man/sha1.Rd: Support for pairlist, name, complex, array and Date * NAMESPACE: Support for pairlist, name and array * DESCRIPTION: bump version number and date 2016-05-01 Viliam Simko * R/sha1.R: Support for complex, Date and array * tests/sha1Test.R: Ditto * NAMESPACE: Ditto 2016-04-27 Dirk Eddelbuettel * DESCRIPTION (Author): Add Qiang Kou to Authors * README.md: Ditto 2016-01-25 Dirk Eddelbuettel * src/digest.c (digest): Use XLENGTH if R >= 3.0.0 (issue #29) 2016-01-11 Thierry Onkelinx * R/sha1.R: handle empty list and empty dataframe (#issue 27); take the object class, digits and zapsmall into account (#PR 28) * vignettes/sha1.Rmd: Small edits to reflect changes is sha1() 2016-01-09 Michel Lang * R/sha1.R: Add a length check to sha1(), use vapply() 2016-01-07 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.9 * DESCRIPTION (Date): Bumped Date: to current date 2016-01-06 Dirk Eddelbuettel * vignettes/sha1.Rmd: Small edits 2016-01-06 Thierry Onkelinx * R/sha1.R: Add functions to calculate stable SHA1 with floating points * man/sha1.Rd: Add helpfile for sha1() * tests/num2hexTest.R: unit tests for num2hex() (non exported function) * tests/sha1Test.R: unit tests for sha1() * NAMESPACE: Export sha1 and its methods * DESCRIPTION: Add Thierry Onkelinx as contributor, bump Version and Date * README.md: Add Thierry Onkelinx as contributor * vignette/sha1.Rmd: Added * .travis.yml: Added 'sudo: required' per recent Travis changes 2015-10-14 Dirk Eddelbuettel * man/digest.Rd: Remove references to inaccessible web pages * man/hmac.Rd: Ditto 2015-10-13 Dirk Eddelbuettel * src/digest.c: Use uint32_t instead of int for nchar 2015-10-12 Qiang Kou * src/digest.c: Use XLENGTH instead of LENGTH (PR #17, issue #16) 2015-08-06 Dirk Eddelbuettel * DESCRIPTION (Title): Updated now stressing 'compact' over 'crypto' 2014-12-30 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.8 * DESCRIPTION (Date): Bumped Date: to current date 2014-12-29 Dirk Eddelbuettel * inst/include/pmurhashAPI.h: Added HOWTO comment to top of file 2014-12-26 Dirk Eddelbuettel * src/pmurhash.c: Protect against _BIG_ENDIAN defined but empty * inst/include/pmurhash.h: Consistent four space indentation 2014-12-25 Dirk Eddelbuettel * DESCRIPTION: Bump Date: and Version: * src/init.c: Minor edit and removal of unused headers 2014-12-25 Wush Wu * inst/include/pmurhash.h: Export function * src/init.c: Register function for use by other packages 2014-12-20 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.7 * DESCRIPTION (Date): Bumped Date: to current date 2014-12-19 Dirk Eddelbuettel * cleanup: Also remove src/symbols.rds * src/sha2.c: Apply (slightly edited) patch from https://www.nlnetlabs.nl/bugs-script/attachment.cgi?id=220&action=diff to overcome the strict-aliasing warning * src/digest.c: Use inttypes.h macro PRIx64 only on Windows 2014-12-16 Dirk Eddelbuettel * src/xxhash.c: Remove two semicolons to make gcc -pedantic happy * tests/digestTest.Rout.save: Updated reflecting murmurHash test * src/pmurhash.c: Renamed from PMurHash.c for naming consistency * src/pmurhash.h: Renamed from PMurHash.h for naming consistency 2014-12-16 Jim Hester * src/digest.c: murmurHash implementation * tests/digestTest.R: murmurHash implementation * R/digest.R: murmurHash implementation * src/PMurHash.c: murmurHash implementation * src/PMurHash.h: murmurHash implementation 2014-12-10 Dirk Eddelbuettel * src/xxhash.c: Applied pull request #6 by Jim Hester with updated upstream code and already corrected UBSAN issue identified by CRAN 2014-12-09 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.6 * DESCRIPTION (Date): Bumped Date: to current date * src/digest.c: Applied pull request #5 by Jim Hester providing portable integer printing inttypes.h header 2014-12-08 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.5 * DESCRIPTION (Date): Bumped Date: to current date * NAMESPACE: Expanded useDynLib() declaring C level symbols, in particular using digest_impl to for the C-level digest * R/AES.R: Use R symbols from NAMESPACE declaration in .Call() * R/digest.R: Use R symbol digest_impl to load C level digest 2014-12-07 Dirk Eddelbuettel * DESCRIPTION: Edited Title and Description * R/digest.R: Added GPL copyright header, reindented to four spaces * src/digest.c: Reindented to four spaces * R/AES.R: Reindented to four spaces * R/hmac.R: Reindented to four spaces 2014-12-06 Dirk Eddelbuettel * src/digest.c: Updated GPL copyright header * src/xxhash.c: Removed two spurious ';' * man/digest.Rd: Document 'seed' argument in \usage * tests/digest.Rout.save: Updated for expanded tests * DESCRIPTION: Add Jim Hester to list of Authors 2014-12-05 Dirk Eddelbuettel * R/digest.R: Applied pull request #3 by Jim Hester with support for xxHash (https://code.google.com/p/xxhash/) * src/digest.c: Ditto * src/xxhash.c: xxHash implementation supplied as part of #3 * src/xxhash.h: xxHash implementation supplied as part of #3 * R/digest.R: Applied pull request #4 by Jim Hester with expanded support for xxHash providing xxhash32 and xxhash64 * src/digest.c: Ditto * man/digest.Rd: Added documentation for xxHash, corrected typos * src/digest.R: New support for a seed parameter used by xxHash * tests/digestTest.R: Added tests for xxHash 2014-08-15 Dirk Eddelbuettel * R/hmac.R: Applied (slightly edited) patch for crc32 computation of hmac kindly supplied by Suchen Jin 2013-12-02 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.4 * src/sha2.h (BYTE_ORDER): Define BYTE_ORDER unless already defined, rely on Rconfig.h which itself goes back to an R compile-time test 2013-02-16 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.3 2013-02-06 Hannes Mühleisen * R/hmac.R: Fixed hmac for sha512 hashes * tests/hmacTest.R: Added test cases for hmac with sha512 * tests/hmacTest.Rout.save: Updated accordingly 2013-01-25 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.2 * man/AES.Rd: Switch from paste0() to paste() to permit use on R-oldrelease as per email by Uwe Ligges * tests/AESTest.R: Idem * tests/AESTest.Rout.save: Updated accordingly 2013-01-21 Dirk Eddelbuettel * DESCRIPTION (Version): Version 0.6.1 * inst/GPL-2: Added as a fixed reference input for regression tests via the scripts in tests/ as the versions installed by R differ across OS and installations * tests/digestTest.R: No longer rely on file.path(R.home(),"COPYING") but rather use our own copy of GPL-2; ensure final test does not print * tests/digestTest.Rout.save: Updated accordingly 2013-01-19 Dirk Eddelbuettel * DESCRIPTION (Authors): Added Duncan Murdoch 2013-01-19 Duncan Murdoch * src/aes.c: Devine's AES implementation added * src/aes.h: header for AES implementation * src/raes.c: interface to it * R/AES.R: Add AES object to do AES encryption * tests/AESTest.R: tests from the standards documents * man/AES.Rd: document AES object * NAMESPACE: export AES constructor and print method 2012-11-25 Dirk Eddelbuettel * Release 0.6.0 * src/sha2.h: In order to build on Windows: - Include the newer header file stdint.h - Enforce standard integer types by defining SHA2_USE_INTTYPES_H - Define BYTE_ORDER and default to LITTLE_ENDIAN * src/digest.c: Use uint8_t from stdint.h for sha256 2012-11-24 Dirk Eddelbuettel * src/digest.c: Allow for extra null character in output[] vector * tests/digestTest.Rout.save: Update/Revert a change by Hannes; Naturally we do not get a single set that works for R-release and R-devel. Sigh. 2012-11-24 Hannes Mühleisen * src/digest.c: sha-512 integration * src/sha2.h: Header file for Aaron Gifford's SHA2 implementation * src/sha2.c: Aaron Gifford's sha2 implementation * R/digest.R: enabled new sha-512 algorithm parameter * R/hmac.R: enabled new sha-512 algorithm parameter * man/digest.Rd: documented new sha-512 algorithm parameter * man/hmac.Rd: documented new sha-512 algorithm parameter * tests/digestTest.R: Added sha-512 test cases 2012-03-14 Dirk Eddelbuettel * Release 0.5.2 * Applied patch by Murray Stokely: - R/digest.R: Additional test for file accessibility; segfault can happen if inaccesible file passed down - tests/digestTest.R: New test which leads to segfault in unpatched package, and passes with these changes - src/digest.c: Simpler use of error() via format string * DESCRIPTION: Fixed one typo in extended description * tests/digest.Rout.save: Updated to current output; version 0.5.1 created the same difference so it is presumably once again something that changed in R's serialization. Oh, and R-devel changes it again. 2011-09-20 Dirk Eddelbuettel * Release 0.5.1 * tests/digestTest.Rout.save: Updated reference output too 2011-09-18 Bryan Lewis * tests/digestTest.R: Added basic raw output md5 and sha1 tests 2011-09-14 Dirk Eddelbuettel * src/digest.c: Applied patch contributed by Bryan Lewis which supports output of unmodified raw binary output if a new function parameter 'raw' (which defaults to FALSE) is set to TRUE * R/digest.R: Support new parameter 'raw' * man/digest.Rd: Document new parameter 'raw' 2011-05-29 Dirk Eddelbuettel * Release 0.5.0 2011-05-26 Dirk Eddelbuettel * R/hmac.R: Switched to camelCase identifiers after discussion with Henrik and Mario 2011-05-25 Dirk Eddelbuettel * R/hmac.R: New hmac() function contributed by Mario Frasca * man/hmac.Rd: Documentation contributed by Mario Frasca * tests/hmacTest.R: Added a new regression test file for hmac() * tests/hmacTest.Rout.save: Added new reference output * tests/digestTest.Rout.save: Updated reference digest output for simple R structure to match what R 2.13.0 yields * inst/ChangeLog: moved to ChangeLog (in top-level directory) * INDEX: removed, as no longer needed 2009-12-03 Henrik Bengtsson * Release 0.4.2 * R/digest.R: Bug fix - digest(object, file=TRUE) where object is a directory would cause R to crash. Now it gives an error. 2009-10-06 Dirk Eddelbuettel * DESCRIPTION: set SVN properties Date and Id, fix indentation 2009-09-24 Dirk Eddelbuettel * Release 0.4.1 * src/Makefile.win: Removed as package builds on Windows without it but not with it being present * src/digest.c: Updated Copyright years, set SVN properties Date and Id * R/digest.R: Idem * man/digest.Rd: Idem 2009-09-23 Dirk Eddelbuettel * Release 0.4.0 * src/sha256.c: Added sha-256 implementation by Christophe Devine as found (via Google Code Search) in a number of Open Source projects such as mushclient, aescrypt2, scrypt, and ipanon * src/sha256.h: Idem * src/digest.c: Modified to support SHA-256 * R/digest.R: Idem * man/digest.Rd: Idem, also added more references * src/Makefile.win: Updated for SHA-256, and generally spruced up 2007-09-28 Dirk Eddelbuettel * Release 0.3.1 * DESCRIPTION: Switched to standardised form 'GPL-2' for License: * src/digest.c: Added one explicit (char *) cast 2007-04-27 Dirk Eddelbuettel * Release 0.3.0 * R/digest.R: Adopted two more changes suggested by Henrik 2007-03-12 Dirk Eddelbuettel * R/digest.R: Adopted a few changes suggested by Henrik 2007-03-09 Dirk Eddelbuettel - R/digest.R, man/digest.Rd, Applied two more patches by Simon Urbanek that clean object mangling (for better comparison across R versions, adds an ascii flag, adds skip="auto" support to by pass the version header info, and clean the file option interface. This effectively replaces Henrik's patch relative to the 0.2.3 release. Thanks for the patches, Simon! - tests/digestTest.Rout.save: New reference output; one line changed 2007-03-08 Dirk Eddelbuettel - R/digest.R, man/digest.Rd, src/digest.C: Applied two patches by Simon Urbanek to help improve consistence of digest output across different R versions by allowing digest to 'skip' a certain number of bytes; and by adding support for 'raw' serialization input 2007-01-08 Dirk Eddelbuettel - R/digest.R: Added improvement suggested by Henrik 2006-12-30 Dirk Eddelbuettel * Release 0.2.3 - R/digest.R: Added file.expand() around filename 2006-07-28 Dirk Eddelbuettel * Release 0.2.2 - R/digest.R: Added patch for R 2.4.0 by Henrik Bengtsson - tests/: Added simple unit tests 2005-11-02 Dirk Eddelbuettel * Release 0.2.1 - R/digest.R, src/digest.c, man/digest.Rd: add support for file mode based on a complete set of patches by Jarek Tuszynski 2005-04-06 Dirk Eddelbuettel * Release 0.2.0 - R/digest.R, src/digest.c, man/digest.Rd: add support for crc32 digests based on a complete set of patches by Antoine Lucas - src/{crc32.c,crc32.h,zlib.h,zutil.h,zconf.h}: From zlib 2004-05-26 Dirk Eddelbuettel * Release 0.1.2 - R/zzz.R: remove test for R < 1.8.0 and load of serialize package (as serialize has been removed from CRAN with serialize() in R) 2003-11-29 Dirk Eddelbuettel * Release 0.1.1 - DESCRIPTION: added to RCS, $Date$ is now filled - DESCRIPTION: small rewording in Description field - corrected minor packaging error by removing spurious tarball 2003-11-28 Dirk Eddelbuettel * Release 0.1.0 - DESCRIPTION: added extended Description - inst/ChangeLog: added - man/digest.Rd: added complete test vectors for md5 and sha-1 in example code, values taken from the examples of the C code 2003-10-23 Dirk Eddelbuettel * Release 0.0.1 - initial version digest/README.md0000644000176200001440000000736114151524575013030 0ustar liggesusers## digest: Compact hash representations of arbitrary R objects [![ci](https://github.com/eddelbuettel/digest/workflows/ci/badge.svg)](https://github.com/eddelbuettel/digest/actions?query=workflow%3Aci) [![License](http://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](http://www.gnu.org/licenses/gpl-2.0.html) [![CRAN](http://www.r-pkg.org/badges/version/digest)](https://cran.r-project.org/package=digest) [![Dependencies](https://tinyverse.netlify.com/badge/digest)](https://cran.r-project.org/package=digest) [![Debian package](https://img.shields.io/debian/v/r-cran-digest/sid?color=green)](https://packages.debian.org/sid/r-cran-digest) [![Downloads (monthly)](http://cranlogs.r-pkg.org/badges/digest?color=brightgreen)](https://www.r-pkg.org:443/pkg/digest) [![Downloads (total)](https://cranlogs.r-pkg.org/badges/grand-total/digest?color=brightgreen)](https://www.r-pkg.org:443/pkg/digest) [![CRAN use](https://jangorecki.gitlab.io/rdeps/digest/CRAN_usage.svg?sanitize=true)](https://cran.r-project.org/package=digest) [![CRAN indirect](https://jangorecki.gitlab.io/rdeps/digest/indirect_usage.svg?sanitize=true)](https://cran.r-project.org/package=digest) [![BioConductor use](https://jangorecki.gitlab.io/rdeps/digest/BioC_usage.svg?sanitize=true)](https://cran.r-project.org/package=digest) [![Code Coverage](https://img.shields.io/codecov/c/github/eddelbuettel/digest/master.svg)](https://app.codecov.io/gh/eddelbuettel/digest) [![Last Commit](https://img.shields.io/github/last-commit/eddelbuettel/digest)](https://github.com/eddelbuettel/digest) [![Documentation](https://img.shields.io/badge/documentation-is_here-blue)](https://eddelbuettel.github.io/digest/) Compact hash representations of arbitrary R objects ### Overview The digest package provides a principal function `digest()` for the creation of hash digests of arbitrary R objects (using the md5, sha-1, sha-256, crc32, xxhash, murmurhash, spookyhash and blake3 algorithms) permitting easy comparison of R language objects. #### Examples As R can serialize any object, we can run `digest()` on any object: ```r R> library(digest) R> digest(trees) [1] "12412cbfa6629c5c80029209b2717f08" R> digest(lm(log(Height) ~ log(Girth), data=trees)) [1] "e25b62de327d079b3ccb98f3e96987b1" R> digest(summary(lm(log(Height) ~ log(Girth), data=trees))) [1] "86c8c979ee41a09006949e2ad95feb41" R> ``` By using the hash sum, which is very likely to be unique, to identify an underlying object or calculation, one can easily implement caching strategies. This is a common use of the digest package. #### Other Functions A small number of additional functions is available: - `sha1()` for numerally stable hashsums, - `hmac()` for hashed message authentication codes based on a key, - `AES()` for Advanced Encryption Standard block ciphers. ### Note Please note that this package is not meant to be deployed for cryptographic purposes. More comprehensive and widely tested libraries such as OpenSSL should be used instead. ### Installation The package is on [CRAN](https://cran.r-project.org) and can be installed via a standard ```r install.packages("digest") ``` ### Continued Testing As we rely on the [tinytest](https://cran.r-project.org/package=tinytest) package, the already-installed package can also be verified via ```r tinytest::test_package("digest") ``` at any later point. ### Author Dirk Eddelbuettel, with contributions by Antoine Lucas, Jarek Tuszynski, Henrik Bengtsson, Simon Urbanek, Mario Frasca, Bryan Lewis, Murray Stokely, Hannes Muehleisen, Duncan Murdoch, Jim Hester, Wush Wu, Qiang Kou, Thierry Onkelinx, Michel Lang, Viliam Simko, Kurt Hornik, Radford Neal, Kendon Bell, Matthew de Queljoe, Ion Suruceanu, Bill Denney, Dirk Schumacher, and Winston Chang. ### License GPL (>= 2) digest/man/0000755000176200001440000000000014151455247012314 5ustar liggesusersdigest/man/digest2int.Rd0000644000176200001440000000211213577222753014660 0ustar liggesusers\name{digest2int} \alias{digest2int} \title{hash arbitrary string to integer} \description{ The \code{digest2int} function calculates integer hash of an arbitrary string. This is useful for randomized experiments, feature hashing, etc. } \usage{ digest2int(x, seed = 0L) } \arguments{ \item{x}{An arbitrary character vector.} \item{seed}{an integer for algorithm initial state. Function will produce different hashes for same input and different seed values.} } \value{ The \code{digest2int} function returns integer vector of the same length as input vector \code{x}. } \references{ Jenkins's \code{one_at_a_time} hash: \url{https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time}. } \author{Dmitriy Selivanov \email{selivanov.dmitriy@gmail.com} for the \R interface; Bob Jenkins for original implementation \url{http://www.burtleburtle.net/bob/hash/doobs.html} } \seealso{\code{\link{digest}}} \examples{ current <- digest2int("The quick brown fox jumps over the lazy dog", 0L) target <- 1369346549L stopifnot(identical(target, current)) } \keyword{misc} digest/man/vdigest.Rd0000644000176200001440000000653013540654254014254 0ustar liggesusers\name{getVDigest} \alias{getVDigest} \title{Set a vectorised function for creating hash function digests} \description{ The \code{getVDigest} function extends \code{digest} by allowing one to set a function that returns hash summaries as a character vector of the same length as the input. It also provides a performance advantage when repeated calls are necessary (e.g. applying a hash function repeatedly to an object). The returned function contains the same arguments as \code{digest} with the exception of the \code{raw} argument (see \code{\link{digest}} for more details). } \usage{ getVDigest(algo=c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32", "spookyhash"), errormode=c("stop","warn","silent")) } \arguments{ \item{algo}{The algorithms to be used; currently available choices are \code{md5}, which is also the default, \code{sha1}, \code{crc32}, \code{sha256}, \code{sha512}, \code{xxhash32}, \code{xxhash64}, \code{murmur32} and \code{spookyhash}.} \item{errormode}{A character value denoting a choice for the behaviour in the case of error: \sQuote{stop} aborts (and is the default value), \sQuote{warn} emits a warning and returns \code{NULL} and \sQuote{silent} suppresses the error and returns an empty string.} } \value{ The \code{getVDigest} function returns a function for a given algorithm and error-mode. } \details{ Note that since one hash summary will be returned for each element passed as input, care must be taken when determining whether or not to include the data structure as part of the object. For instance, to return the equivalent output of \code{digest(list("a"))} it would be necessary to wrap the list object itself \code{getVDigest()(list(list("a")))} } \seealso{\code{\link{digest}}, \code{\link{serialize}}, \code{\link{md5sum}}} \examples{ stretch_key <- function(d, n) { md5 <- getVDigest() for (i in seq_len(n)) d <- md5(d, serialize = FALSE) d } stretch_key('abc123', 65e3) sha1 <- getVDigest(algo = 'sha1') sha1(letters) md5Input <- c("", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", paste("12345678901234567890123456789012345678901234567890123456789012", "345678901234567890", sep="")) md5Output <- c("d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a") md5 <- getVDigest() stopifnot(identical(md5(md5Input, serialize = FALSE), md5Output)) stopifnot(identical(digest(list("abc")), md5(list(list("abc"))))) sha512Input <-c( "", "The quick brown fox jumps over the lazy dog." ) sha512Output <- c( paste0("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce", "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"), paste0("91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb", "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed") ) sha512 <- getVDigest(algo = 'sha512') stopifnot(identical(sha512(sha512Input, serialize = FALSE), sha512Output)) } \keyword{misc} digest/man/sha1.Rd0000644000176200001440000001055213630267061013436 0ustar liggesusers\docType{methods} \name{sha1} \alias{sha1} \alias{sha1_attr_digest} \alias{sha1_digest} \alias{sha1.array} \alias{sha1.integer} \alias{sha1.numeric} \alias{sha1.character} \alias{sha1.complex} \alias{sha1.Date} \alias{sha1.factor} \alias{sha1.NULL} \alias{sha1.logical} \alias{sha1.matrix} \alias{sha1.data.frame} \alias{sha1.list} \alias{sha1.pairlist} \alias{sha1.name} \alias{sha1.POSIXlt} \alias{sha1.POSIXct} \alias{sha1.anova} \alias{sha1.function} \alias{sha1.call} \alias{sha1.raw} \alias{sha1.formula} \alias{sha1.(} \title{Calculate a SHA1 hash of an object} \author{Thierry Onkelinx} \usage{ sha1(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{numeric}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{complex}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{Date}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{matrix}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{data.frame}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{array}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{list}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{pairlist}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{POSIXlt}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{POSIXct}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{anova}(x, digits = 4, zapsmall = 7, ..., algo = "sha1") \method{sha1}{function}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{formula}(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{`(`}(...) sha1_digest(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{NULL}(...) \method{sha1}{name}(...) sha1_attr_digest(x, digits = 14, zapsmall = 7, ..., algo = "sha1") \method{sha1}{call}(...) \method{sha1}{character}(...) \method{sha1}{factor}(...) \method{sha1}{integer}(...) \method{sha1}{logical}(...) \method{sha1}{raw}(...) } \arguments{ \item{x}{the object to calculate the SHA1} \item{digits}{the approximate number of significant digits in base 10. Will be converted to a base 16 equivalent. Defaults to \code{digits = 14}, except for sha1.anova where \code{digits = 4}} \item{zapsmall}{the approximate negative magnitude of the smallest relevant digit. Will be converted to a base 2 equivalent. Values smaller than this number are equivalent to 0. Defaults to \code{zapsmall = 7}} \item{...}{If it is the only defined argument, passed to another \code{sha1} method. If other arguments exist, see Details for usage.} \item{algo}{The hashing algoritm to be used by \code{\link{digest}}. Defaults to "sha1"} } \description{ Calculate a SHA1 hash of an object. The main difference with \code{digest(x, algo = "sha1")} is that \code{sha1()} will give the same hash on 32-bit and 64-bit systems. Note that the results depends on the setting of \code{digits} and \code{zapsmall} when handling floating point numbers. The current defaults keep \code{digits} and \code{zapsmall} as large as possible while maintaining the same hash on 32 bit and 64 bit systems. } \details{ \code{sha1_digest()} is a convenience function for objects where attributes cannot be added to apply the \code{digest()} function to its arguments. \code{sha1_attr_digest()} is a convenience function for objects where objects can be added to generate the hash. If generating hashes for objects in other packages, one of these two functions is recommended for use (typically, \code{sha1_attr_digest()}). Extra arguments: environment: An optional extra argument for \code{sha1.function} and \code{sha1.formula} should be TRUE, FALSE or missing. \code{sha1.function} and \code{sha1.formula} will ignore the enviroment of the function only when \code{environment = FALSE}. } \note{ \code{sha1} gained an \code{algo} argument since version 0.6.15. This allows \code{sha1()} to use all hashing algoritms available in \code{digest()}. The hashes created with \code{sha1(x)} from digest >= 0.6.15 are identical to \code{sha1(x)} from digest <= 0.6.14. The only exceptions are hashes created with \code{sha1(x, algo = "sha1")}, they will be different starting from digest 0.6.15 Until version 0.6.22, \code{sha1} ignored the attributes of the object for some classes. This was fixed in version 0.6.23. Use \code{options(sha1PackageVersion = "0.6.22")} to get the old behaviour. Version 0.6.24 and later ignore attributes named \code{srcref}. } digest/man/digest.Rd0000644000176200001440000003313714026227716014070 0ustar liggesusers\name{digest} \alias{digest} \title{Create hash function digests for arbitrary R objects or files} \description{ The \code{digest} function applies one of several cryptographic or non-cryptographics hash function to arbitrary R objects or files. By default, the objects are internally serialized, and the selected hash functions algorithms can be used to compute a compact digest of the serialized object. In order to compare this implementation with others, serialization of the input argument can also be turned off in which the input argument must be a character string for which its digest is returned. } \usage{ digest(object, algo=c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32", "spookyhash", "blake3"), serialize=TRUE, file=FALSE, length=Inf, skip="auto", ascii=FALSE, raw=FALSE, seed=0, errormode=c("stop","warn","silent"), serializeVersion=.getSerializeVersion()) } \arguments{ \item{object}{An arbitrary R object which will then be passed to the \code{\link{serialize}} function, unless the \code{serialize} argument is set to \code{FALSE}.} \item{algo}{The algorithms to be used; currently available choices are \code{md5}, which is also the default, \code{sha1}, \code{crc32}, \code{sha256}, \code{sha512}, \code{xxhash32}, \code{xxhash64}, \code{murmur32}, \code{spookyhash} and \code{blake3}.} \item{serialize}{A logical variable indicating whether the object should be serialized using \code{serialize} (in ASCII form). Setting this to \code{FALSE} allows to compare the digest output of given character strings to known control output. It also allows the use of raw vectors such as the output of non-ASCII serialization. } \item{file}{A logical variable indicating whether the object is a file name or a file name if \code{object} is not specified.} \item{length}{Number of characters to process. By default, when \code{length} is set to \code{Inf}, the whole string or file is processed.} \item{skip}{Number of input bytes to skip before calculating the digest. Negative values are invalid and currently treated as zero. Special value \code{"auto"} will cause serialization header to be skipped if \code{serialize} is set to \code{TRUE} (the serialization header contains the R version number thus skipping it allows the comparison of hashes across platforms and some R versions). } \item{ascii}{This flag is passed to the \code{serialize} function if \code{serialize} is set to \code{TRUE}, determining whether the hash is computed on the ASCII or binary representation.} \item{raw}{A logical variable with a default value of FALSE, implying \code{digest} returns digest output as ASCII hex values. Set to TRUE to return \code{digest} output in raw (binary) form. Note that this option is supported by most but not all of the implemented hashing algorithms} \item{seed}{an integer to seed the random number generator. This is only used in the \code{xxhash32}, \code{xxhash64} and \code{murmur32} functions and can be used to generate additional hashes for the same input if desired.} \item{errormode}{A character value denoting a choice for the behaviour in the case of error: \sQuote{stop} aborts (and is the default value), \sQuote{warn} emits a warning and returns \code{NULL} and \sQuote{silent} suppresses the error and returns an empty string.} \item{serializeVersion}{An integer value specifying the internal version of the serialization format, with 2 being the default; see \code{\link{serialize}} for details. The \code{serializeVersion} field of \code{\link{option}} can also be used to set a different value.} } \value{ The \code{digest} function returns a character string of a fixed length containing the requested digest of the supplied R object. This string is of length 32 for MD5; of length 40 for SHA-1; of length 8 for CRC32 a string; of length 8 for for xxhash32; of length 16 for xxhash64; and of length 8 for murmur32. } \details{ Cryptographic hash functions are well researched and documented. The MD5 algorithm by Ron Rivest is specified in RFC 1321. The SHA-1 algorithm is specified in FIPS-180-1, SHA-2 is described in FIPS-180-2. For md5, sha-1 and sha-256, this R implementation relies on standalone implementations in C by Christophe Devine. For crc32, code from the zlib library by Jean-loup Gailly and Mark Adler is used. For sha-512, a standalone implementation from Aaron Gifford is used. For xxhash32 and xxhash64, the reference implementation by Yann Collet is used. For murmur32, the progressive implementation by Shane Day is used. For spookyhash, the original source code by Bob Jenkins is used. The R implementation that integrates R's serialization directly with the algorithm allowing for memory-efficient incremental calculation of the hash is by Gabe Becker. For blake3, the C implementation by Samuel Neves and Jack O'Connor is used. Please note that this package is not meant to be used for cryptographic purposes for which more comprehensive (and widely tested) libraries such as OpenSSL should be used. Also, it is known that crc32 is not collision-proof. For sha-1, recent results indicate certain cryptographic weaknesses as well. For more details, see for example \url{https://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html}. } \section{Change Management}{ Version 0.6.16 of digest corrects an error in which \code{crc32} was not guaranteeing an eight-character return. We now pad with zero to always return eight characters. Should the previous behaviour be required, set \code{option("digestOldCRC32Format"=TRUE)} and the output will be consistent with prior version (but not be consistentnly eight characters). } \references{ MD5: \url{https://www.ietf.org/rfc/rfc1321.txt}. SHA-1: \url{https://en.wikipedia.org/wiki/SHA-1}. SHA-256: \url{https://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf}. CRC32: The original reference webpage at \code{rocksoft.com} has vanished from the web; see \url{https://en.wikipedia.org/wiki/Cyclic_redundancy_check} for general information on CRC algorithms. \url{https://aarongifford.com/computers/sha.html} for the integrated C implementation of sha-512. The page for the code underlying the C functions used here for sha-1 and md5, and further references, is no longer accessible. Please see \url{https://en.wikipedia.org/wiki/SHA-1} and \url{https://en.wikipedia.org/wiki/MD5}. \url{https://zlib.net} for documentation on the zlib library which supplied the code for crc32. \url{https://en.wikipedia.org/wiki/SHA_hash_functions} for documentation on the sha functions. \url{https://github.com/Cyan4973/xxHash} for documentation on the xxHash functions. \url{https://github.com/aappleby/smhasher} for documentation on MurmurHash. \url{https://burtleburtle.net/bob/hash/spooky.html} for the original source code of SpookyHash. \url{https://github.com/BLAKE3-team/BLAKE3/} for the original source code of blake3. } \author{Dirk Eddelbuettel \email{edd@debian.org} for the \R interface; Antoine Lucas for the integration of crc32; Jarek Tuszynski for the file-based operations; Henrik Bengtsson and Simon Urbanek for improved serialization patches; Christophe Devine for the hash function implementations for sha-1, sha-256 and md5; Jean-Loup Gailly and Mark Adler for crc32; Hannes Muehleisen for the integration of sha-512; Jim Hester for the integration of xxhash32, xxhash64 and murmur32; Kendon Bell for the integration of spookyhash using Gabe Becker's R package fastdigest.} \seealso{\code{\link{serialize}}, \code{\link{md5sum}}} \examples{ ## Standard RFC 1321 test vectors md5Input <- c("", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", paste("12345678901234567890123456789012345678901234567890123456789012", "345678901234567890", sep="")) md5Output <- c("d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a") for (i in seq(along=md5Input)) { md5 <- digest(md5Input[i], serialize=FALSE) stopifnot(identical(md5, md5Output[i])) } sha1Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") sha1Output <- c("a9993e364706816aba3e25717850c26c9cd0d89d", "84983e441c3bd26ebaae4aa1f95129e5e54670f1") for (i in seq(along=sha1Input)) { sha1 <- digest(sha1Input[i], algo="sha1", serialize=FALSE) stopifnot(identical(sha1, sha1Output[i])) } crc32Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") crc32Output <- c("352441c2", "171a3f5f") for (i in seq(along=crc32Input)) { crc32 <- digest(crc32Input[i], algo="crc32", serialize=FALSE) stopifnot(identical(crc32, crc32Output[i])) } sha256Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") sha256Output <- c("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1") for (i in seq(along=sha256Input)) { sha256 <- digest(sha256Input[i], algo="sha256", serialize=FALSE) stopifnot(identical(sha256, sha256Output[i])) } # SHA 512 example sha512Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") sha512Output <- c(paste("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a", "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", sep=""), paste("204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335", "96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445", sep="")) for (i in seq(along=sha512Input)) { sha512 <- digest(sha512Input[i], algo="sha512", serialize=FALSE) stopifnot(identical(sha512, sha512Output[i])) } ## xxhash32 example xxhash32Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "") xxhash32Output <- c("32d153ff", "89ea60c3", "02cc5d05") for (i in seq(along=xxhash32Input)) { xxhash32 <- digest(xxhash32Input[i], algo="xxhash32", serialize=FALSE) cat(xxhash32, "\n") stopifnot(identical(xxhash32, xxhash32Output[i])) } ## xxhash64 example xxhash64Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "") xxhash64Output <- c("44bc2cf5ad770999", "f06103773e8585df", "ef46db3751d8e999") for (i in seq(along=xxhash64Input)) { xxhash64 <- digest(xxhash64Input[i], algo="xxhash64", serialize=FALSE) cat(xxhash64, "\n") stopifnot(identical(xxhash64, xxhash64Output[i])) } ## these outputs were calculated using mmh3 python package murmur32Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "") murmur32Output <- c("b3dd93fa", "ee925b90", "00000000") for (i in seq(along=murmur32Input)) { murmur32 <- digest(murmur32Input[i], algo="murmur32", serialize=FALSE) cat(murmur32, "\n") stopifnot(identical(murmur32, murmur32Output[i])) } ## these outputs were calculated using spooky python package spookyInput <- c("a", "abc", "message digest") spookyOutput <- c("bdc9bba09181101a922a4161f0584275", "67c93775f715ab8ab01178caf86713c6", "9630c2a55c0987a0db44434f9d67a192") for (i in seq(along=spookyInput)) { # skip = 30 skips the serialization header and just hashes the strings spooky <- digest(spookyInput[i], algo="spookyhash", skip = 30) cat(spooky, "\n") stopifnot(identical(spooky, spookyOutput[i])) } ## blake3 example blake3Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "") blake3Output <- c("6437b3ac38465133ffb63b75273a8db548c558465d79db03fd359c6cd5bd9d85", "c19012cc2aaf0dc3d8e5c45a1b79114d2df42abb2a410bf54be09e891af06ff8", "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262") for (i in seq(along=blake3Input)) { blake3 <- digest(blake3Input[i], algo="blake3", serialize=FALSE) cat(blake3, "\n") stopifnot(identical(blake3, blake3Output[i])) } # example of a digest of a standard R list structure digest(list(LETTERS, data.frame(a=letters[1:5], b=matrix(1:10,ncol=2)))) # test 'length' parameter and file input fname <- file.path(R.home(),"COPYING") x <- readChar(fname, file.info(fname)$size) # read file for (alg in c("sha1", "md5", "crc32")) { # partial file h1 <- digest(x , length=18000, algo=alg, serialize=FALSE) h2 <- digest(fname, length=18000, algo=alg, serialize=FALSE, file=TRUE) h3 <- digest( substr(x,1,18000) , algo=alg, serialize=FALSE) stopifnot( identical(h1,h2), identical(h1,h3) ) # whole file h1 <- digest(x , algo=alg, serialize=FALSE) h2 <- digest(fname, algo=alg, serialize=FALSE, file=TRUE) stopifnot( identical(h1,h2) ) } # compare md5 algorithm to other tools library(tools) fname <- file.path(R.home(),"COPYING") h1 <- as.character(md5sum(fname)) h2 <- digest(fname, algo="md5", file=TRUE) stopifnot( identical(h1,h2) ) ## digest is _designed_ to return one has summary per object to for a desired ## For vectorised output see digest::getVDigest() which provides ## better performance than base::Vectorize() md5 <- getVDigest() v <- md5(1:5) # digest integers 1 to 5 stopifnot(identical(v[1], digest(1L)), # check first and third result identical(v[3], digest(3L))) } \keyword{misc} digest/man/AES.Rd0000644000176200001440000001523614151525070013212 0ustar liggesusers\name{AES} \alias{AES} \title{ Create AES block cipher object } \description{ This creates an object that can perform the Advanced Encryption Standard (AES) block cipher. } \usage{ AES(key, mode=c("ECB", "CBC", "CFB", "CTR"), IV=NULL) } \arguments{ \item{key}{ The key as a 16, 24 or 32 byte raw vector for AES-128, AES-192 or AES-256 respectively. } \item{mode}{ The encryption mode to use. Currently only \dQuote{electronic codebook} (ECB), \dQuote{cipher-block chaining} (CBC), \dQuote{cipher feedback} (CFB) and \dQuote{counter} (CTR) modes are supported. } \item{IV}{ The initial vector for CBC and CFB mode or initial counter for CTR mode. } } \value{ An object of class \code{"AES"}. This is a list containing the following component functions: \item{encrypt(text)}{A function to encrypt a text vector. The text may be a single element character vector or a raw vector. It returns the ciphertext as a raw vector.} \item{decrypt(ciphertext, raw = FALSE)}{A function to decrypt the ciphertext. In ECB mode, the same AES object can be used for both encryption and decryption, but in CBC, CFB and CTR modes a new object needs to be created, using the same initial \code{key} and \code{IV} values.} \item{IV()}{Report on the current state of the initialization vector. As blocks are encrypted or decrypted in CBC, CFB or CTR mode, the initialization vector is updated, so both operations can be performed sequentially on subsets of the text or ciphertext.} \item{block_size(), key_size(), mode()}{Report on these aspects of the AES object.} } \details{ The standard NIST definition of CTR mode doesn't define how the counter is updated, it just requires that it be updated with each block and not repeat itself for a long time. This implementation treats it as a 128 bit integer and adds 1 with each successive block. } \author{ The R interface was written by Duncan Murdoch. The design is loosely based on the Python Crypto implementation. The underlying AES implementation is by Christophe Devine. } \references{ United States National Institute of Standards and Technology (2001). "Announcing the ADVANCED ENCRYPTION STANDARD (AES)". Federal Information Processing Standards Publication 197. \url{https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf}. Morris Dworkin (2001). "Recommendation for Block Cipher Modes of Operation". NIST Special Publication 800-38A 2001 Edition. } \examples{ # First in ECB mode: the repeated block is coded the same way each time msg <- as.raw(c(1:16, 1:16)) key <- as.raw(1:16) aes <- AES(key, mode="ECB") aes$encrypt(msg) aes$decrypt(aes$encrypt(msg), raw=TRUE) # Now in CBC mode: each encoding is different iv <- sample(0:255, 16, replace=TRUE) aes <- AES(key, mode="CBC", iv) code <- aes$encrypt(msg) code # Need a new object for decryption in CBC mode aes <- AES(key, mode="CBC", iv) aes$decrypt(code, raw=TRUE) # CFB mode: IV must be the same length as the Block's block size # Two different instances of AES are required for encryption and decryption iv <- sample(0:255, 16, replace=TRUE) aes <- AES(key, mode="CFB", iv) code <- aes$encrypt(msg) code #decrypt aes <- AES(key, mode="CFB", iv) aes$decrypt(code) # FIPS-197 examples hextextToRaw <- function(text) { vals <- matrix(as.integer(as.hexmode(strsplit(text, "")[[1]])), ncol=2, byrow=TRUE) vals <- vals \%*\% c(16, 1) as.raw(vals) } plaintext <- hextextToRaw("00112233445566778899aabbccddeeff") aes128key <- hextextToRaw("000102030405060708090a0b0c0d0e0f") aes128output <- hextextToRaw("69c4e0d86a7b0430d8cdb78070b4c55a") aes <- AES(aes128key) aes128 <- aes$encrypt(plaintext) stopifnot(identical(aes128, aes128output)) stopifnot(identical(plaintext, aes$decrypt(aes128, raw=TRUE))) aes192key <- hextextToRaw("000102030405060708090a0b0c0d0e0f1011121314151617") aes192output <- hextextToRaw("dda97ca4864cdfe06eaf70a0ec0d7191") aes <- AES(aes192key) aes192 <- aes$encrypt(plaintext) stopifnot(identical(aes192, aes192output)) stopifnot(identical(plaintext, aes$decrypt(aes192, raw=TRUE))) aes256key <- hextextToRaw("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") aes256output <- hextextToRaw("8ea2b7ca516745bfeafc49904b496089") aes <- AES(aes256key) aes256 <- aes$encrypt(plaintext) stopifnot(identical(aes256, aes256output)) stopifnot(identical(plaintext, aes$decrypt(aes256, raw=TRUE))) # SP800-38a examples plaintext <- hextextToRaw(paste("6bc1bee22e409f96e93d7e117393172a", "ae2d8a571e03ac9c9eb76fac45af8e51", "30c81c46a35ce411e5fbc1191a0a52ef", "f69f2445df4f9b17ad2b417be66c3710",sep="")) key <- hextextToRaw("2b7e151628aed2a6abf7158809cf4f3c") ecb128output <- hextextToRaw(paste("3ad77bb40d7a3660a89ecaf32466ef97", "f5d3d58503b9699de785895a96fdbaaf", "43b1cd7f598ece23881b00e3ed030688", "7b0c785e27e8ad3f8223207104725dd4",sep="")) aes <- AES(key) ecb128 <- aes$encrypt(plaintext) stopifnot(identical(ecb128, ecb128output)) stopifnot(identical(plaintext, aes$decrypt(ecb128, raw=TRUE))) cbc128output <- hextextToRaw(paste("7649abac8119b246cee98e9b12e9197d", "5086cb9b507219ee95db113a917678b2", "73bed6b8e3c1743b7116e69e22229516", "3ff1caa1681fac09120eca307586e1a7",sep="")) iv <- hextextToRaw("000102030405060708090a0b0c0d0e0f") aes <- AES(key, mode="CBC", IV=iv) cbc128 <- aes$encrypt(plaintext) stopifnot(identical(cbc128, cbc128output)) aes <- AES(key, mode="CBC", IV=iv) stopifnot(identical(plaintext, aes$decrypt(cbc128, raw=TRUE))) cfb128output <- hextextToRaw(paste("3b3fd92eb72dad20333449f8e83cfb4a", "c8a64537a0b3a93fcde3cdad9f1ce58b", "26751f67a3cbb140b1808cf187a4f4df", "c04b05357c5d1c0eeac4c66f9ff7f2e6",sep="")) aes <- AES(key, mode="CFB", IV=iv) cfb128 <- aes$encrypt(plaintext) stopifnot(identical(cfb128, cfb128output)) aes <- AES(key, mode="CFB", IV=iv) stopifnot(identical(plaintext, aes$decrypt(cfb128, raw=TRUE))) ctr128output <- hextextToRaw(paste("874d6191b620e3261bef6864990db6ce", "9806f66b7970fdff8617187bb9fffdff", "5ae4df3edbd5d35e5b4f09020db03eab", "1e031dda2fbe03d1792170a0f3009cee",sep="")) iv <- hextextToRaw("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") aes <- AES(key, mode="CTR", IV=iv) ctr128 <- aes$encrypt(plaintext) stopifnot(identical(ctr128, ctr128output)) aes <- AES(key, mode="CTR", IV=iv) stopifnot(identical(plaintext, aes$decrypt(ctr128, raw=TRUE))) } digest/man/hmac.Rd0000644000176200001440000000662513742111031013505 0ustar liggesusers\name{hmac} \alias{hmac} \title{compute a hash-based message authentication code} \description{ The \code{hmac} function calculates a message authentication code (MAC) involving the specified cryptographic hash function in combination with a given secret key. } \usage{ hmac(key, object, algo = c("md5", "sha1", "crc32", "sha256", "sha512"), serialize = FALSE, raw = FALSE, ...) } \arguments{ \item{key}{An arbitrary character or numeric vector, to use as pre-shared secret key.} \item{object}{An arbitrary R object which will then be passed to the \code{\link{serialize}} function, unless the \code{serialize} argument is set to \code{FALSE}.} \item{algo}{The algorithms to be used; currently available choices are \code{md5}, which is also the default, \code{sha1}, \code{crc32} and \code{sha256}.} \item{serialize}{default value of \code{serialize} is here FALSE, not TRUE as it is in \code{digest}.} \item{raw}{This flag alters the type of the output. Setting this to \code{TRUE} causes the function to return an object of type \code{"raw"} instead of \code{"character"}.} \item{...}{All remaining arguments are passed to \code{digest}. } } \value{ The \code{hmac} function uses the \code{digest} to return a hash digest as specified in the RFC 2104. } \references{ MD5: \url{https://www.ietf.org/rfc/rfc1321.txt}. SHA-1: \url{https://en.wikipedia.org/wiki/SHA-1}. SHA-256: \url{https://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf}. CRC32: The original reference webpage at \code{rocksoft.com} has vanished from the web; see \url{https://en.wikipedia.org/wiki/Cyclic_redundancy_check} for general information on CRC algorithms. \url{https://aarongifford.com/computers/sha.html} for the integrated C implementation of sha-512. The page for the code underlying the C functions used here for sha-1 and md5, and further references, is no longer accessible. Please see \url{https://en.wikipedia.org/wiki/SHA-1} and \url{https://en.wikipedia.org/wiki/MD5}. \url{https://zlib.net} for documentation on the zlib library which supplied the code for crc32. \url{https://en.wikipedia.org/wiki/SHA_hash_functions} for documentation on the sha functions. } \author{Mario Frasca \email{mfrasca@zonnet.nl}.} \seealso{\code{\link{digest}}} \examples{ ## Standard RFC 2104 test vectors current <- hmac('Jefe', 'what do ya want for nothing?', "md5") target <- '750c783e6ab0b503eaa86e310a5db738' stopifnot(identical(target, as.character(current))) current <- hmac(rep(0x0b, 16), 'Hi There', "md5") target <- '9294727a3638bb1c13f48ef8158bfc9d' stopifnot(identical(target, as.character(current))) current <- hmac(rep(0xaa, 16), rep(0xdd, 50), "md5") target <- '56be34521d144c88dbb8c733f0e8b3f6' stopifnot(identical(target, as.character(current))) ## SHA1 tests inspired to the RFC 2104 and checked against the python ## hmac implementation. current <- hmac('Jefe', 'what do ya want for nothing?', "sha1") target <- 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79' stopifnot(identical(target, as.character(current))) current <- hmac(rep(0x0b, 16), 'Hi There', "sha1") target <- '675b0b3a1b4ddf4e124872da6c2f632bfed957e9' stopifnot(identical(target, as.character(current))) current <- hmac(rep(0xaa, 16), rep(0xdd, 50), "sha1") target <- 'd730594d167e35d5956fd8003d0db3d3f46dc7bb' stopifnot(identical(target, as.character(current))) } \keyword{misc} digest/man/makeRaw.Rd0000644000176200001440000000107313022663127014165 0ustar liggesusers\name{makeRaw} \alias{makeRaw} \alias{makeRaw.default} \alias{makeRaw.raw} \alias{makeRaw.character} \alias{makeRaw.digest} \title{Create a raw object} \usage{ makeRaw(object) \method{makeRaw}{raw}(object) \method{makeRaw}{character}(object) \method{makeRaw}{digest}(object) \method{makeRaw}{raw}(object) } \arguments{ \item{object}{The object to convert into a \code{raw} vector} } \description{ A helper function used to create \code{raw} methods. } \value{ A \code{raw} vector is returned. } \author{Dirk Eddelbuettel} \examples{ makeRaw("1234567890ABCDE") }digest/DESCRIPTION0000644000176200001440000000274014151623322013241 0ustar liggesusersPackage: digest Author: Dirk Eddelbuettel with contributions by Antoine Lucas, Jarek Tuszynski, Henrik Bengtsson, Simon Urbanek, Mario Frasca, Bryan Lewis, Murray Stokely, Hannes Muehleisen, Duncan Murdoch, Jim Hester, Wush Wu, Qiang Kou, Thierry Onkelinx, Michel Lang, Viliam Simko, Kurt Hornik, Radford Neal, Kendon Bell, Matthew de Queljoe, Ion Suruceanu, Bill Denney, Dirk Schumacher, and Winston Chang. Version: 0.6.29 Date: 2021-11-30 Maintainer: Dirk Eddelbuettel Title: Create Compact Hash Digests of R Objects Description: Implementation of a function 'digest()' for the creation of hash digests of arbitrary R objects (using the 'md5', 'sha-1', 'sha-256', 'crc32', 'xxhash', 'murmurhash', 'spookyhash' and 'blake3' algorithms) permitting easy comparison of R language objects, as well as functions such as'hmac()' to create hash-based message authentication code. Please note that this package is not meant to be deployed for cryptographic purposes for which more comprehensive (and widely tested) libraries such as 'OpenSSL' should be used. URL: https://github.com/eddelbuettel/digest, http://dirk.eddelbuettel.com/code/digest.html BugReports: https://github.com/eddelbuettel/digest/issues Depends: R (>= 3.3.0) Imports: utils License: GPL (>= 2) Suggests: tinytest, simplermarkdown VignetteBuilder: simplermarkdown NeedsCompilation: yes Packaged: 2021-11-30 23:41:39 UTC; edd Repository: CRAN Date/Publication: 2021-12-01 07:40:02 UTC digest/build/0000755000176200001440000000000014151533263012633 5ustar liggesusersdigest/build/vignette.rds0000644000176200001440000000032214151533263015167 0ustar liggesusersb```b`adb`b2 1# 'f/H4MA kh*+dhhk(A`KBd Ik^bnj1\R RR@g;<E T [fN*ސ89 d Bw(,/׃ @?{49'ݣ\)%ziE@ waKdigest/tests/0000755000176200001440000000000013472546224012704 5ustar liggesusersdigest/tests/tinytest.R0000644000176200001440000000070313472546224014712 0ustar liggesusers if (requireNamespace("tinytest", quietly=TRUE)) { ## Set a seed to make the test deterministic set.seed(42) ## there are several more granular ways to test files in a ## tinytest directory, see its package vignette; tests can also ## run once the package is installed using the same command ## we need version 0.9.3 or later if (packageVersion("tinytest") >= "0.9.3") { tinytest::test_package("digest") } } digest/src/0000755000176200001440000000000014151533263012323 5ustar liggesusersdigest/src/pmurhash.c0000644000176200001440000002544413346570641014335 0ustar liggesusers/*----------------------------------------------------------------------------- * MurmurHash3 was written by Austin Appleby, and is placed in the public * domain. * * This implementation was written by Shane Day, and is also public domain. * * This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A) * with support for progressive processing. */ /*----------------------------------------------------------------------------- If you want to understand the MurmurHash algorithm you would be much better off reading the original source. Just point your browser at: http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp What this version provides? 1. Progressive data feeding. Useful when the entire payload to be hashed does not fit in memory or when the data is streamed through the application. Also useful when hashing a number of strings with a common prefix. A partial hash of a prefix string can be generated and reused for each suffix string. 2. Portability. Plain old C so that it should compile on any old compiler. Both CPU endian and access-alignment neutral, but avoiding inefficient code when possible depending on CPU capabilities. 3. Drop in. I personally like nice self contained public domain code, making it easy to pilfer without loads of refactoring to work properly in the existing application code & makefile structure and mucking around with licence files. Just copy PMurHash.h and PMurHash.c and you're ready to go. How does it work? We can only process entire 32 bit chunks of input, except for the very end that may be shorter. So along with the partial hash we need to give back to the caller a carry containing up to 3 bytes that we were unable to process. This carry also needs to record the number of bytes the carry holds. I use the low 2 bits as a count (0..3) and the carry bytes are shifted into the high byte in stream order. To handle endianess I simply use a macro that reads a uint32_t and define that macro to be a direct read on little endian machines, a read and swap on big endian machines, or a byte-by-byte read if the endianess is unknown. -----------------------------------------------------------------------------*/ #include "pmurhash.h" /* renamed for consistency in digest's src/ */ /* I used ugly type names in the header to avoid potential conflicts with * application or system typedefs & defines. Since I'm not including any more * headers below here I can rename these so that the code reads like C99 */ #undef uint32_t #define uint32_t MH_UINT32 #undef uint8_t #define uint8_t MH_UINT8 /* MSVC warnings we choose to ignore */ #if defined(_MSC_VER) #pragma warning(disable: 4127) /* conditional expression is constant */ #endif /*----------------------------------------------------------------------------- * Endianess, misalignment capabilities and util macros * * The following 3 macros are defined in this section. The other macros defined * are only needed to help derive these 3. * * READ_UINT32(x) Read a little endian unsigned 32-bit int * UNALIGNED_SAFE Defined if READ_UINT32 works on non-word boundaries * ROTL32(x,r) Rotate x left by r bits */ /* Convention is to define __BYTE_ORDER == to one of these values */ #if !defined(__BIG_ENDIAN) #define __BIG_ENDIAN 4321 #endif #if !defined(__LITTLE_ENDIAN) #define __LITTLE_ENDIAN 1234 #endif /* I386 */ #if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(i386) #define __BYTE_ORDER __LITTLE_ENDIAN #define UNALIGNED_SAFE #endif /* gcc 'may' define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ to 1 (Note the trailing __), * or even _LITTLE_ENDIAN or _BIG_ENDIAN (Note the single _ prefix) */ #if !defined(__BYTE_ORDER) /* #if defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__==1 || defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN==1 #define __BYTE_ORDER __LITTLE_ENDIAN #elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 || defined(_BIG_ENDIAN) && _BIG_ENDIAN==1 #define __BYTE_ORDER __BIG_ENDIAN #endif */ #if defined(__LITTLE_ENDIAN__) #if __LITTLE_ENDIAN__==1 #define __BYTE_ORDER __LITTLE_ENDIAN #elif defined(_LITTLE_ENDIAN) #if x_LITTLE_ENDIAN != x #if _LITTLE_ENDIAN==1 #define __BYTE_ORDER __LITTLE_ENDIAN #endif #endif #endif #elif defined(__BIG_ENDIAN__) #if __BIG_ENDIAN__==1 #define __BYTE_ORDER __BIG_ENDIAN #endif #elif defined(_BIG_ENDIAN) #if x_BIG_ENDIAN != x #if _BIG_ENDIAN==1 #define __BYTE_ORDER __BIG_ENDIAN #endif #endif #endif #endif /* gcc (usually) defines xEL/EB macros for ARM and MIPS endianess */ #if !defined(__BYTE_ORDER) #if defined(__ARMEL__) || defined(__MIPSEL__) #define __BYTE_ORDER __LITTLE_ENDIAN #endif #if defined(__ARMEB__) || defined(__MIPSEB__) #define __BYTE_ORDER __BIG_ENDIAN #endif #endif /* Now find best way we can to READ_UINT32 */ #if __BYTE_ORDER==__LITTLE_ENDIAN /* CPU endian matches murmurhash algorithm, so read 32-bit word directly */ #define READ_UINT32(ptr) (*((uint32_t*)(ptr))) #elif __BYTE_ORDER==__BIG_ENDIAN /* TODO: Add additional cases below where a compiler provided bswap32 is available */ #if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3)) #define READ_UINT32(ptr) (__builtin_bswap32(*((uint32_t*)(ptr)))) #else /* Without a known fast bswap32 we're just as well off doing this */ #define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24) #define UNALIGNED_SAFE #endif #else /* Unknown endianess so last resort is to read individual bytes */ #define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24) /* Since we're not doing word-reads we can skip the messing about with realignment */ #define UNALIGNED_SAFE #endif /* Find best way to ROTL32 */ #if defined(_MSC_VER) #include /* Microsoft put _rotl declaration in here */ #define ROTL32(x,r) _rotl(x,r) #else /* gcc recognises this code and generates a rotate instruction for CPUs with one */ #define ROTL32(x,r) (((uint32_t)x << r) | ((uint32_t)x >> (32 - r))) #endif /*----------------------------------------------------------------------------- * Core murmurhash algorithm macros */ #define C1 (0xcc9e2d51) #define C2 (0x1b873593) /* This is the main processing body of the algorithm. It operates * on each full 32-bits of input. */ #define DOBLOCK(h1, k1) do{ \ k1 *= C1; \ k1 = ROTL32(k1,15); \ k1 *= C2; \ \ h1 ^= k1; \ h1 = ROTL32(h1,13); \ h1 = h1*5+0xe6546b64; \ }while(0) /* Append unaligned bytes to carry, forcing hash churn if we have 4 bytes */ /* cnt=bytes to process, h1=name of h1 var, c=carry, n=bytes in c, ptr/len=payload */ #define DOBYTES(cnt, h1, c, n, ptr, len) do{ \ int _i = cnt; \ while(_i--) { \ c = c>>8 | (uint32_t)*ptr++<<24; \ n++; len--; \ if(n==4) { \ DOBLOCK(h1, c); \ n = 0; \ } \ } }while(0) /*---------------------------------------------------------------------------*/ /* Main hashing function. Initialise carry to 0 and h1 to 0 or an initial seed * if wanted. Both ph1 and pcarry are required arguments. */ void PMurHash32_Process(uint32_t *ph1, uint32_t *pcarry, const void *key, int len) { uint32_t h1 = *ph1; uint32_t c = *pcarry; const uint8_t *ptr = (uint8_t*)key; const uint8_t *end; /* Extract carry count from low 2 bits of c value */ int n = c & 3; #if defined(UNALIGNED_SAFE) /* This CPU handles unaligned word access */ /* Consume any carry bytes */ int i = (4-n) & 3; if(i && i <= len) { DOBYTES(i, h1, c, n, ptr, len); /* #nocov */ } /* Process 32-bit chunks */ end = ptr + len/4*4; for( ; ptr < end ; ptr+=4) { uint32_t k1 = READ_UINT32(ptr); DOBLOCK(h1, k1); } #else /*UNALIGNED_SAFE*/ /* This CPU does not handle unaligned word access */ /* Consume enough so that the next data byte is word aligned */ int i = -(long)ptr & 3; if(i && i <= len) { DOBYTES(i, h1, c, n, ptr, len); } /* We're now aligned. Process in aligned blocks. Specialise for each possible carry count */ end = ptr + len/4*4; switch(n) { /* how many bytes in c */ case 0: /* c=[----] w=[3210] b=[3210]=w c'=[----] */ for( ; ptr < end ; ptr+=4) { uint32_t k1 = READ_UINT32(ptr); DOBLOCK(h1, k1); } break; case 1: /* c=[0---] w=[4321] b=[3210]=c>>24|w<<8 c'=[4---] */ for( ; ptr < end ; ptr+=4) { uint32_t k1 = c>>24; c = READ_UINT32(ptr); k1 |= c<<8; DOBLOCK(h1, k1); } break; case 2: /* c=[10--] w=[5432] b=[3210]=c>>16|w<<16 c'=[54--] */ for( ; ptr < end ; ptr+=4) { uint32_t k1 = c>>16; c = READ_UINT32(ptr); k1 |= c<<16; DOBLOCK(h1, k1); } break; case 3: /* c=[210-] w=[6543] b=[3210]=c>>8|w<<24 c'=[654-] */ for( ; ptr < end ; ptr+=4) { uint32_t k1 = c>>8; c = READ_UINT32(ptr); k1 |= c<<24; DOBLOCK(h1, k1); } } #endif /*UNALIGNED_SAFE*/ /* Advance over whole 32-bit chunks, possibly leaving 1..3 bytes */ len -= len/4*4; /* Append any remaining bytes into carry */ DOBYTES(len, h1, c, n, ptr, len); /* Copy out new running hash and carry */ *ph1 = h1; *pcarry = (c & ~0xff) | n; } /*---------------------------------------------------------------------------*/ /* Finalize a hash. To match the original Murmur3A the total_length must be provided */ uint32_t PMurHash32_Result(uint32_t h, uint32_t carry, uint32_t total_length) { uint32_t k1; int n = carry & 3; if(n) { k1 = carry >> (4-n)*8; k1 *= C1; k1 = ROTL32(k1,15); k1 *= C2; h ^= k1; } h ^= total_length; /* fmix */ h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } /*---------------------------------------------------------------------------*/ /* Murmur3A compatable all-at-once */ uint32_t PMurHash32(uint32_t seed, const void *key, int len) { uint32_t h1=seed, carry=0; PMurHash32_Process(&h1, &carry, key, len); return PMurHash32_Result(h1, carry, len); } /*---------------------------------------------------------------------------*/ /* Provide an API suitable for smhasher */ void PMurHash32_test(const void *key, int len, uint32_t seed, void *out) /* #nocov start */ { uint32_t h1=seed, carry=0; const uint8_t *ptr = (uint8_t*)key; const uint8_t *end = ptr + len; #if 0 /* Exercise the progressive processing */ while(ptr < end) { //const uint8_t *mid = ptr + rand()%(end-ptr)+1; const uint8_t *mid = ptr + (rand()&0xF); mid = mid #include #include // https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time uint32_t jenkins_one_at_a_time_hash(const char *key, uint32_t seed) { uint32_t hash = seed; for(; *key; ++key) { hash += *key; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; } SEXP digest2int(SEXP input, SEXP Seed) { uint32_t seed = INTEGER_VALUE(Seed); if (TYPEOF(input) != STRSXP) error("invalid input - should be character vector"); R_xlen_t n = xlength(input); SEXP result = PROTECT(allocVector(INTSXP, n )); memset(INTEGER(result), 0, n * sizeof(int)); int *res_ptr = INTEGER(result); for(R_xlen_t i = 0; i < n; i++) { const char* element_ptr = CHAR(STRING_ELT(input, i)); res_ptr[i] = jenkins_one_at_a_time_hash(element_ptr, seed); } UNPROTECT(1); return(result); } digest/src/zlib.h0000644000176200001440000001733312247504516013446 0ustar liggesusers/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.2, October 3rd, 2004 Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef ZLIB_H #define ZLIB_H #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.2.2" #define ZLIB_VERNUM 0x1220 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. This library can optionally read and write gzip streams in memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field (though see inflate()) */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); #ifdef __cplusplus } #endif #endif /* ZLIB_H */ digest/src/xxhash.c0000644000176200001440000010201213346570104013766 0ustar liggesusers/* #nocov start * xxHash - Fast Hash algorithm * Copyright (C) 2012-2016, Yann Collet * * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You can contact the author at : * - xxHash homepage: http://www.xxhash.com * - xxHash source repository : https://github.com/Cyan4973/xxHash */ /* ************************************* * Tuning parameters ***************************************/ /*!XXH_FORCE_MEMORY_ACCESS : * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. * The below switch allow to select different access method for improved performance. * Method 0 (default) : use `memcpy()`. Safe and portable. * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. * It can generate buggy code on targets which do not support unaligned memory accesses. * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) * See http://stackoverflow.com/a/32095106/646947 for details. * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) # define XXH_FORCE_MEMORY_ACCESS 2 # elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ || defined(__ARM_ARCH_7S__) )) # define XXH_FORCE_MEMORY_ACCESS 1 # endif #endif /*!XXH_ACCEPT_NULL_INPUT_POINTER : * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault. * When this macro is enabled, xxHash actively checks input for null pointer. * It it is, result for null input pointers is the same as a null-length input. */ #ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */ # define XXH_ACCEPT_NULL_INPUT_POINTER 0 #endif /*!XXH_FORCE_NATIVE_FORMAT : * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. * Results are therefore identical for little-endian and big-endian CPU. * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. * Should endian-independence be of no importance for your application, you may set the #define below to 1, * to improve speed for Big-endian CPU. * This option has no impact on Little_Endian CPU. */ #ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ # define XXH_FORCE_NATIVE_FORMAT 0 #endif /*!XXH_FORCE_ALIGN_CHECK : * This is a minor performance trick, only useful with lots of very small keys. * It means : check for aligned/unaligned input. * The check costs one initial branch per hash; * set it to 0 when the input is guaranteed to be aligned, * or when alignment doesn't matter for performance. */ #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ # if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) # define XXH_FORCE_ALIGN_CHECK 0 # else # define XXH_FORCE_ALIGN_CHECK 1 # endif #endif /* ************************************* * Includes & Memory related functions ***************************************/ /*! Modify the local functions below should you wish to use some other memory routines * for malloc(), free() */ #include static void* XXH_malloc(size_t s) { return malloc(s); } static void XXH_free (void* p) { free(p); } /*! and for memcpy() */ #include static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } #include /* assert */ #define XXH_STATIC_LINKING_ONLY #include "xxhash.h" /* ************************************* * Compiler Specific Options ***************************************/ #ifdef _MSC_VER /* Visual Studio */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # define FORCE_INLINE static __forceinline #else # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif # else # define FORCE_INLINE static # endif /* __STDC_VERSION__ */ #endif /* ************************************* * Basic Types ***************************************/ #ifndef MEM_MODULE # if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; # else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; # endif #endif #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ typedef union { U32 u32; } __attribute__((packed)) unalign; static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } #else /* portable and safe solution. Generally efficient. * see : http://stackoverflow.com/a/32095106/646947 */ static U32 XXH_read32(const void* memPtr) { U32 val; memcpy(&val, memPtr, sizeof(val)); return val; } #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ /* **************************************** * Compiler-specific Functions and Macros ******************************************/ #define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) /* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ #if defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) # define XXH_rotl64(x,r) _rotl64(x,r) #else # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) # define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) #endif #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap32 _byteswap_ulong #elif XXH_GCC_VERSION >= 403 # define XXH_swap32 __builtin_bswap32 #else static U32 XXH_swap32 (U32 x) { return ((x << 24) & 0xff000000 ) | ((x << 8) & 0x00ff0000 ) | ((x >> 8) & 0x0000ff00 ) | ((x >> 24) & 0x000000ff ); } #endif /* ************************************* * Architecture Macros ***************************************/ typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ #ifndef XXH_CPU_LITTLE_ENDIAN static int XXH_isLittleEndian(void) { const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } # define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() #endif /* *************************** * Memory reads *****************************/ typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) { if (align==XXH_unaligned) return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); else return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); } FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); } static U32 XXH_readBE32(const void* ptr) { return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); } /* ************************************* * Macros ***************************************/ #define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } /* use after variable declarations */ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } /* ******************************************************************* * 32-bit hash functions *********************************************************************/ static const U32 PRIME32_1 = 2654435761U; static const U32 PRIME32_2 = 2246822519U; static const U32 PRIME32_3 = 3266489917U; static const U32 PRIME32_4 = 668265263U; static const U32 PRIME32_5 = 374761393U; static U32 XXH32_round(U32 seed, U32 input) { seed += input * PRIME32_2; seed = XXH_rotl32(seed, 13); seed *= PRIME32_1; return seed; } /* mix all bits */ static U32 XXH32_avalanche(U32 h32) { h32 ^= h32 >> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return(h32); } #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) static U32 XXH32_finalize(U32 h32, const void* ptr, size_t len, XXH_endianess endian, XXH_alignment align) { const BYTE* p = (const BYTE*)ptr; #define PROCESS1 \ h32 += (*p) * PRIME32_5; \ p++; \ h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; #define PROCESS4 \ h32 += XXH_get32bits(p) * PRIME32_3; \ p+=4; \ h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; switch(len&15) /* or switch(bEnd - p) */ { case 12: PROCESS4; /* fallthrough */ case 8: PROCESS4; /* fallthrough */ case 4: PROCESS4; return XXH32_avalanche(h32); case 13: PROCESS4; /* fallthrough */ case 9: PROCESS4; /* fallthrough */ case 5: PROCESS4; PROCESS1; return XXH32_avalanche(h32); case 14: PROCESS4; /* fallthrough */ case 10: PROCESS4; /* fallthrough */ case 6: PROCESS4; PROCESS1; PROCESS1; return XXH32_avalanche(h32); case 15: PROCESS4; /* fallthrough */ case 11: PROCESS4; /* fallthrough */ case 7: PROCESS4; /* fallthrough */ case 3: PROCESS1; /* fallthrough */ case 2: PROCESS1; /* fallthrough */ case 1: PROCESS1; /* fallthrough */ case 0: return XXH32_avalanche(h32); } assert(0); return h32; /* reaching this point is deemed impossible */ } FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) { const BYTE* p = (const BYTE*)input; const BYTE* bEnd = p + len; U32 h32; #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)16; } #endif if (len>=16) { const BYTE* const limit = bEnd - 15; U32 v1 = seed + PRIME32_1 + PRIME32_2; U32 v2 = seed + PRIME32_2; U32 v3 = seed + 0; U32 v4 = seed - PRIME32_1; do { v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; } while (p < limit); h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); } else { h32 = seed + PRIME32_5; } h32 += (U32)len; return XXH32_finalize(h32, p, len&15, endian, align); } XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) { #if 0 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ XXH32_state_t state; XXH32_reset(&state, seed); XXH32_update(&state, input, len); return XXH32_digest(&state); #else XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if (XXH_FORCE_ALIGN_CHECK) { if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); } } if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); #endif } /*====== Hash streaming ======*/ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) { return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) { XXH_free(statePtr); return XXH_OK; } XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) { memcpy(dstState, srcState, sizeof(*dstState)); } XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) { XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); state.v1 = seed + PRIME32_1 + PRIME32_2; state.v2 = seed + PRIME32_2; state.v3 = seed + 0; state.v4 = seed - PRIME32_1; /* do not write into reserved, planned to be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); return XXH_OK; } FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) { const BYTE* p = (const BYTE*)input; const BYTE* const bEnd = p + len; if (input==NULL) #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) return XXH_OK; #else return XXH_ERROR; #endif state->total_len_32 += (unsigned)len; state->large_len |= (len>=16) | (state->total_len_32>=16); if (state->memsize + len < 16) { /* fill in tmp buffer */ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); state->memsize += (unsigned)len; return XXH_OK; } if (state->memsize) { /* some data left from previous update */ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); { const U32* p32 = state->mem32; state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); } p += 16-state->memsize; state->memsize = 0; } if (p <= bEnd-16) { const BYTE* const limit = bEnd - 16; U32 v1 = state->v1; U32 v2 = state->v2; U32 v3 = state->v3; U32 v4 = state->v4; do { v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; } while (p<=limit); state->v1 = v1; state->v2 = v2; state->v3 = v3; state->v4 = v4; } if (p < bEnd) { XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); state->memsize = (unsigned)(bEnd-p); } return XXH_OK; } XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_update_endian(state_in, input, len, XXH_littleEndian); else return XXH32_update_endian(state_in, input, len, XXH_bigEndian); } FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) { U32 h32; if (state->large_len) { h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); } else { h32 = state->v3 /* == seed */ + PRIME32_5; } h32 += state->total_len_32; return XXH32_finalize(h32, state->mem32, state->memsize, endian, XXH_aligned); } XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_digest_endian(state_in, XXH_littleEndian); else return XXH32_digest_endian(state_in, XXH_bigEndian); } /*====== Canonical representation ======*/ /*! Default XXH result types are basic unsigned 32 and 64 bits. * The canonical representation follows human-readable write convention, aka big-endian (large digits first). * These functions allow transformation of hash result into and from its canonical format. * This way, hash values can be written into a file or buffer, remaining comparable across different systems. */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) { return XXH_readBE32(src); } #ifndef XXH_NO_LONG_LONG /* ******************************************************************* * 64-bit hash functions *********************************************************************/ /*====== Memory access ======*/ #ifndef MEM_MODULE # define MEM_MODULE # if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include typedef uint64_t U64; # else /* if compiler doesn't support unsigned long long, replace by another 64-bit type */ typedef unsigned long long U64; # endif #endif #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64; static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; } #else /* portable and safe solution. Generally efficient. * see : http://stackoverflow.com/a/32095106/646947 */ static U64 XXH_read64(const void* memPtr) { U64 val; memcpy(&val, memPtr, sizeof(val)); return val; } #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap64 _byteswap_uint64 #elif XXH_GCC_VERSION >= 403 # define XXH_swap64 __builtin_bswap64 #else static U64 XXH_swap64 (U64 x) { return ((x << 56) & 0xff00000000000000ULL) | ((x << 40) & 0x00ff000000000000ULL) | ((x << 24) & 0x0000ff0000000000ULL) | ((x << 8) & 0x000000ff00000000ULL) | ((x >> 8) & 0x00000000ff000000ULL) | ((x >> 24) & 0x0000000000ff0000ULL) | ((x >> 40) & 0x000000000000ff00ULL) | ((x >> 56) & 0x00000000000000ffULL); } #endif FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) { if (align==XXH_unaligned) return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); else return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); } FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) { return XXH_readLE64_align(ptr, endian, XXH_unaligned); } static U64 XXH_readBE64(const void* ptr) { return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); } /*====== xxh64 ======*/ static const U64 PRIME64_1 = 11400714785074694791ULL; static const U64 PRIME64_2 = 14029467366897019727ULL; static const U64 PRIME64_3 = 1609587929392839161ULL; static const U64 PRIME64_4 = 9650029242287828579ULL; static const U64 PRIME64_5 = 2870177450012600261ULL; static U64 XXH64_round(U64 acc, U64 input) { acc += input * PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= PRIME64_1; return acc; } static U64 XXH64_mergeRound(U64 acc, U64 val) { val = XXH64_round(0, val); acc ^= val; acc = acc * PRIME64_1 + PRIME64_4; return acc; } static U64 XXH64_avalanche(U64 h64) { h64 ^= h64 >> 33; h64 *= PRIME64_2; h64 ^= h64 >> 29; h64 *= PRIME64_3; h64 ^= h64 >> 32; return h64; } #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) static U64 XXH64_finalize(U64 h64, const void* ptr, size_t len, XXH_endianess endian, XXH_alignment align) { const BYTE* p = (const BYTE*)ptr; #define PROCESS1_64 \ h64 ^= (*p) * PRIME64_5; \ p++; \ h64 = XXH_rotl64(h64, 11) * PRIME64_1; #define PROCESS4_64 \ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; \ p+=4; \ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; #define PROCESS8_64 { \ U64 const k1 = XXH64_round(0, XXH_get64bits(p)); \ p+=8; \ h64 ^= k1; \ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \ } switch(len&31) { case 24: PROCESS8_64; /* fallthrough */ case 16: PROCESS8_64; /* fallthrough */ case 8: PROCESS8_64; return XXH64_avalanche(h64); case 28: PROCESS8_64; /* fallthrough */ case 20: PROCESS8_64; /* fallthrough */ case 12: PROCESS8_64; /* fallthrough */ case 4: PROCESS4_64; return XXH64_avalanche(h64); case 25: PROCESS8_64; /* fallthrough */ case 17: PROCESS8_64; /* fallthrough */ case 9: PROCESS8_64; PROCESS1_64; return XXH64_avalanche(h64); case 29: PROCESS8_64; /* fallthrough */ case 21: PROCESS8_64; /* fallthrough */ case 13: PROCESS8_64; /* fallthrough */ case 5: PROCESS4_64; PROCESS1_64; return XXH64_avalanche(h64); case 26: PROCESS8_64; /* fallthrough */ case 18: PROCESS8_64; /* fallthrough */ case 10: PROCESS8_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 30: PROCESS8_64; /* fallthrough */ case 22: PROCESS8_64; /* fallthrough */ case 14: PROCESS8_64; /* fallthrough */ case 6: PROCESS4_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 27: PROCESS8_64; /* fallthrough */ case 19: PROCESS8_64; /* fallthrough */ case 11: PROCESS8_64; PROCESS1_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 31: PROCESS8_64; /* fallthrough */ case 23: PROCESS8_64; /* fallthrough */ case 15: PROCESS8_64; /* fallthrough */ case 7: PROCESS4_64; /* fallthrough */ case 3: PROCESS1_64; /* fallthrough */ case 2: PROCESS1_64; /* fallthrough */ case 1: PROCESS1_64; /* fallthrough */ case 0: return XXH64_avalanche(h64); } /* impossible to reach */ assert(0); return 0; /* unreachable, but some compilers complain without it */ } FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) { const BYTE* p = (const BYTE*)input; const BYTE* bEnd = p + len; U64 h64; #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)32; } #endif if (len>=32) { const BYTE* const limit = bEnd - 32; U64 v1 = seed + PRIME64_1 + PRIME64_2; U64 v2 = seed + PRIME64_2; U64 v3 = seed + 0; U64 v4 = seed - PRIME64_1; do { v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; } while (p<=limit); h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = seed + PRIME64_5; } h64 += (U64) len; return XXH64_finalize(h64, p, len, endian, align); } XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) { #if 0 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ XXH64_state_t state; XXH64_reset(&state, seed); XXH64_update(&state, input, len); return XXH64_digest(&state); #else XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if (XXH_FORCE_ALIGN_CHECK) { if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); else return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); } } if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); else return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); #endif } /*====== Hash Streaming ======*/ XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) { return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) { XXH_free(statePtr); return XXH_OK; } XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) { memcpy(dstState, srcState, sizeof(*dstState)); } XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) { XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); state.v1 = seed + PRIME64_1 + PRIME64_2; state.v2 = seed + PRIME64_2; state.v3 = seed + 0; state.v4 = seed - PRIME64_1; /* do not write into reserved, planned to be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); return XXH_OK; } FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) { const BYTE* p = (const BYTE*)input; const BYTE* const bEnd = p + len; if (input==NULL) #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) return XXH_OK; #else return XXH_ERROR; #endif state->total_len += len; if (state->memsize + len < 32) { /* fill in tmp buffer */ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); state->memsize += (U32)len; return XXH_OK; } if (state->memsize) { /* tmp buffer is full */ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); p += 32-state->memsize; state->memsize = 0; } if (p+32 <= bEnd) { const BYTE* const limit = bEnd - 32; U64 v1 = state->v1; U64 v2 = state->v2; U64 v3 = state->v3; U64 v4 = state->v4; do { v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; } while (p<=limit); state->v1 = v1; state->v2 = v2; state->v3 = v3; state->v4 = v4; } if (p < bEnd) { XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); state->memsize = (unsigned)(bEnd-p); } return XXH_OK; } XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_update_endian(state_in, input, len, XXH_littleEndian); else return XXH64_update_endian(state_in, input, len, XXH_bigEndian); } FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) { U64 h64; if (state->total_len >= 32) { U64 const v1 = state->v1; U64 const v2 = state->v2; U64 const v3 = state->v3; U64 const v4 = state->v4; h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = state->v3 /*seed*/ + PRIME64_5; } h64 += (U64) state->total_len; return XXH64_finalize(h64, state->mem64, (size_t)state->total_len, endian, XXH_aligned); } XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_digest_endian(state_in, XXH_littleEndian); else return XXH64_digest_endian(state_in, XXH_bigEndian); } /*====== Canonical representation ======*/ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) { return XXH_readBE64(src); } #endif /* XXH_NO_LONG_LONG */ /* # nocov end */ digest/src/md5.c0000644000176200001440000002060613216563247013166 0ustar liggesusers/* * RFC 1321 compliant MD5 implementation, * by Christophe Devine ; * this program is licensed under the GPL. */ #include #include "md5.h" #define GET_UINT32(n,b,i) \ { \ (n) = ( (uint32) (b)[(i) ] ) \ | ( (uint32) (b)[(i) + 1] << 8 ) \ | ( (uint32) (b)[(i) + 2] << 16 ) \ | ( (uint32) (b)[(i) + 3] << 24 ); \ } #define PUT_UINT32(n,b,i) \ { \ (b)[(i) ] = (uint8) ( (n) ); \ (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \ } void md5_starts( md5_context *ctx ) { ctx->total[0] = 0; ctx->total[1] = 0; ctx->state[0] = 0x67452301; ctx->state[1] = 0xEFCDAB89; ctx->state[2] = 0x98BADCFE; ctx->state[3] = 0x10325476; } void md5_process( md5_context *ctx, uint8 data[64] ) { uint32 X[16], A, B, C, D; GET_UINT32( X[0], data, 0 ); GET_UINT32( X[1], data, 4 ); GET_UINT32( X[2], data, 8 ); GET_UINT32( X[3], data, 12 ); GET_UINT32( X[4], data, 16 ); GET_UINT32( X[5], data, 20 ); GET_UINT32( X[6], data, 24 ); GET_UINT32( X[7], data, 28 ); GET_UINT32( X[8], data, 32 ); GET_UINT32( X[9], data, 36 ); GET_UINT32( X[10], data, 40 ); GET_UINT32( X[11], data, 44 ); GET_UINT32( X[12], data, 48 ); GET_UINT32( X[13], data, 52 ); GET_UINT32( X[14], data, 56 ); GET_UINT32( X[15], data, 60 ); #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) #define P(a,b,c,d,k,s,t) \ { \ a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ } A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; #define F(x,y,z) (z ^ (x & (y ^ z))) P( A, B, C, D, 0, 7, 0xD76AA478 ); P( D, A, B, C, 1, 12, 0xE8C7B756 ); P( C, D, A, B, 2, 17, 0x242070DB ); P( B, C, D, A, 3, 22, 0xC1BDCEEE ); P( A, B, C, D, 4, 7, 0xF57C0FAF ); P( D, A, B, C, 5, 12, 0x4787C62A ); P( C, D, A, B, 6, 17, 0xA8304613 ); P( B, C, D, A, 7, 22, 0xFD469501 ); P( A, B, C, D, 8, 7, 0x698098D8 ); P( D, A, B, C, 9, 12, 0x8B44F7AF ); P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); P( B, C, D, A, 11, 22, 0x895CD7BE ); P( A, B, C, D, 12, 7, 0x6B901122 ); P( D, A, B, C, 13, 12, 0xFD987193 ); P( C, D, A, B, 14, 17, 0xA679438E ); P( B, C, D, A, 15, 22, 0x49B40821 ); #undef F #define F(x,y,z) (y ^ (z & (x ^ y))) P( A, B, C, D, 1, 5, 0xF61E2562 ); P( D, A, B, C, 6, 9, 0xC040B340 ); P( C, D, A, B, 11, 14, 0x265E5A51 ); P( B, C, D, A, 0, 20, 0xE9B6C7AA ); P( A, B, C, D, 5, 5, 0xD62F105D ); P( D, A, B, C, 10, 9, 0x02441453 ); P( C, D, A, B, 15, 14, 0xD8A1E681 ); P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); P( A, B, C, D, 9, 5, 0x21E1CDE6 ); P( D, A, B, C, 14, 9, 0xC33707D6 ); P( C, D, A, B, 3, 14, 0xF4D50D87 ); P( B, C, D, A, 8, 20, 0x455A14ED ); P( A, B, C, D, 13, 5, 0xA9E3E905 ); P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); P( C, D, A, B, 7, 14, 0x676F02D9 ); P( B, C, D, A, 12, 20, 0x8D2A4C8A ); #undef F #define F(x,y,z) (x ^ y ^ z) P( A, B, C, D, 5, 4, 0xFFFA3942 ); P( D, A, B, C, 8, 11, 0x8771F681 ); P( C, D, A, B, 11, 16, 0x6D9D6122 ); P( B, C, D, A, 14, 23, 0xFDE5380C ); P( A, B, C, D, 1, 4, 0xA4BEEA44 ); P( D, A, B, C, 4, 11, 0x4BDECFA9 ); P( C, D, A, B, 7, 16, 0xF6BB4B60 ); P( B, C, D, A, 10, 23, 0xBEBFBC70 ); P( A, B, C, D, 13, 4, 0x289B7EC6 ); P( D, A, B, C, 0, 11, 0xEAA127FA ); P( C, D, A, B, 3, 16, 0xD4EF3085 ); P( B, C, D, A, 6, 23, 0x04881D05 ); P( A, B, C, D, 9, 4, 0xD9D4D039 ); P( D, A, B, C, 12, 11, 0xE6DB99E5 ); P( C, D, A, B, 15, 16, 0x1FA27CF8 ); P( B, C, D, A, 2, 23, 0xC4AC5665 ); #undef F #define F(x,y,z) (y ^ (x | ~z)) P( A, B, C, D, 0, 6, 0xF4292244 ); P( D, A, B, C, 7, 10, 0x432AFF97 ); P( C, D, A, B, 14, 15, 0xAB9423A7 ); P( B, C, D, A, 5, 21, 0xFC93A039 ); P( A, B, C, D, 12, 6, 0x655B59C3 ); P( D, A, B, C, 3, 10, 0x8F0CCC92 ); P( C, D, A, B, 10, 15, 0xFFEFF47D ); P( B, C, D, A, 1, 21, 0x85845DD1 ); P( A, B, C, D, 8, 6, 0x6FA87E4F ); P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); P( C, D, A, B, 6, 15, 0xA3014314 ); P( B, C, D, A, 13, 21, 0x4E0811A1 ); P( A, B, C, D, 4, 6, 0xF7537E82 ); P( D, A, B, C, 11, 10, 0xBD3AF235 ); P( C, D, A, B, 2, 15, 0x2AD7D2BB ); P( B, C, D, A, 9, 21, 0xEB86D391 ); #undef F ctx->state[0] += A; ctx->state[1] += B; ctx->state[2] += C; ctx->state[3] += D; } void md5_update( md5_context *ctx, uint8 *input, uint32 length ) { uint32 left, fill; if( ! length ) return; left = ctx->total[0] & 0x3F; fill = 64 - left; ctx->total[0] += length; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < length ) ctx->total[1]++; /* #nocov */ if( left && length >= fill ) { memcpy( (void *) (ctx->buffer + left), (void *) input, fill ); md5_process( ctx, ctx->buffer ); length -= fill; input += fill; left = 0; } while( length >= 64 ) { md5_process( ctx, input ); length -= 64; input += 64; } if( length ) { memcpy( (void *) (ctx->buffer + left), (void *) input, length ); } } static uint8 md5_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void md5_finish( md5_context *ctx, uint8 digest[16] ) { uint32 last, padn; uint32 high, low; uint8 msglen[8]; high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); low = ( ctx->total[0] << 3 ); PUT_UINT32( low, msglen, 0 ); PUT_UINT32( high, msglen, 4 ); last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); md5_update( ctx, md5_padding, padn ); md5_update( ctx, msglen, 8 ); PUT_UINT32( ctx->state[0], digest, 0 ); PUT_UINT32( ctx->state[1], digest, 4 ); PUT_UINT32( ctx->state[2], digest, 8 ); PUT_UINT32( ctx->state[3], digest, 12 ); } #ifdef TEST #include #include /* * those are the standard RFC 1321 test vectors */ static char *msg[] = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012" \ "345678901234567890" }; static char *val[] = { "d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a" }; int main( int argc, char *argv[] ) { FILE *f; int i, j; char output[33]; md5_context ctx; unsigned char buf[1000]; unsigned char md5sum[16]; if( argc < 2 ) { printf( "\n MD5 Validation Tests:\n\n" ); for( i = 0; i < 7; i++ ) { printf( " Test %d ", i + 1 ); md5_starts( &ctx ); md5_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) ); md5_finish( &ctx, md5sum ); for( j = 0; j < 16; j++ ) { sprintf( output + j * 2, "%02x", md5sum[j] ); } if( memcmp( output, val[i], 32 ) ) { printf( "failed!\n" ); return( 1 ); } printf( "passed.\n" ); } printf( "\n" ); } else { if( ! ( f = fopen( argv[1], "rb" ) ) ) { perror( "fopen" ); return( 1 ); } md5_starts( &ctx ); while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) { md5_update( &ctx, buf, i ); } md5_finish( &ctx, md5sum ); for( j = 0; j < 16; j++ ) { printf( "%02x", md5sum[j] ); } printf( " %s\n", argv[1] ); } return( 0 ); } #endif digest/src/sha1.h0000644000176200001440000000064712247504516013342 0ustar liggesusers#ifndef _SHA1_H #define _SHA1_H #ifndef uint8 #define uint8 unsigned char #endif #ifndef uint32 #define uint32 unsigned long int #endif typedef struct { uint32 total[2]; uint32 state[5]; uint8 buffer[64]; } sha1_context; void sha1_starts( sha1_context *ctx ); void sha1_update( sha1_context *ctx, uint8 *input, uint32 length ); void sha1_finish( sha1_context *ctx, uint8 digest[20] ); #endif /* sha1.h */ digest/src/aes.c0000644000176200001440000007520413216563247013255 0ustar liggesusers/* * FIPS-197 compliant AES implementation * * Copyright (C) 2001-2004 Christophe Devine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "aes.h" /* uncomment the following line to run the test suite */ /* #define TEST */ /* uncomment the following line to use pre-computed tables */ /* otherwise the tables will be generated at the first run */ #define FIXED_TABLES #ifndef FIXED_TABLES /* forward S-box & tables */ uint32 FSb[256]; uint32 FT0[256]; uint32 FT1[256]; uint32 FT2[256]; uint32 FT3[256]; /* reverse S-box & tables */ uint32 RSb[256]; uint32 RT0[256]; uint32 RT1[256]; uint32 RT2[256]; uint32 RT3[256]; /* round constants */ uint32 RCON[10]; /* tables generation flag */ int do_init = 1; /* tables generation routine */ #define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \ ( ( x & 0xFFFFFFFF ) >> 8 ) ) #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) #define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 ) void aes_gen_tables( void ) { int i; uint8 x, y; uint8 pow[256]; uint8 log[256]; /* compute pow and log tables over GF(2^8) */ for( i = 0, x = 1; i < 256; i++, x ^= XTIME( x ) ) { pow[i] = x; log[x] = i; } /* calculate the round constants */ for( i = 0, x = 1; i < 10; i++, x = XTIME( x ) ) { RCON[i] = (uint32) x << 24; } /* generate the forward and reverse S-boxes */ FSb[0x00] = 0x63; RSb[0x63] = 0x00; for( i = 1; i < 256; i++ ) { x = pow[255 - log[i]]; y = x; y = ( y << 1 ) | ( y >> 7 ); x ^= y; y = ( y << 1 ) | ( y >> 7 ); x ^= y; y = ( y << 1 ) | ( y >> 7 ); x ^= y; y = ( y << 1 ) | ( y >> 7 ); x ^= y ^ 0x63; FSb[i] = x; RSb[x] = i; } /* generate the forward and reverse tables */ for( i = 0; i < 256; i++ ) { x = (unsigned char) FSb[i]; y = XTIME( x ); FT0[i] = (uint32) ( x ^ y ) ^ ( (uint32) x << 8 ) ^ ( (uint32) x << 16 ) ^ ( (uint32) y << 24 ); FT0[i] &= 0xFFFFFFFF; FT1[i] = ROTR8( FT0[i] ); FT2[i] = ROTR8( FT1[i] ); FT3[i] = ROTR8( FT2[i] ); y = (unsigned char) RSb[i]; RT0[i] = ( (uint32) MUL( 0x0B, y ) ) ^ ( (uint32) MUL( 0x0D, y ) << 8 ) ^ ( (uint32) MUL( 0x09, y ) << 16 ) ^ ( (uint32) MUL( 0x0E, y ) << 24 ); RT0[i] &= 0xFFFFFFFF; RT1[i] = ROTR8( RT0[i] ); RT2[i] = ROTR8( RT1[i] ); RT3[i] = ROTR8( RT2[i] ); } } #else /* forward S-box */ static const uint32 FSb[256] = { 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 }; /* forward tables */ #define FT \ \ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) #define V(a,b,c,d) 0x##a##b##c##d static const uint32 FT0[256] = { FT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c static const uint32 FT1[256] = { FT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b static const uint32 FT2[256] = { FT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a static const uint32 FT3[256] = { FT }; #undef V #undef FT /* reverse S-box */ static const uint32 RSb[256] = { 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D }; /* reverse tables */ #define RT \ \ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) #define V(a,b,c,d) 0x##a##b##c##d static const uint32 RT0[256] = { RT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c static const uint32 RT1[256] = { RT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b static const uint32 RT2[256] = { RT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a static const uint32 RT3[256] = { RT }; #undef V #undef RT /* round constants */ static const uint32 RCON[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; int do_init = 0; void aes_gen_tables( void ) /* #nocov start */ { } /* #nocov end */ #endif /* platform-independant 32-bit integer manipulation macros */ #define GET_UINT32(n,b,i) \ { \ (n) = ( (uint32) (b)[(i) ] << 24 ) \ | ( (uint32) (b)[(i) + 1] << 16 ) \ | ( (uint32) (b)[(i) + 2] << 8 ) \ | ( (uint32) (b)[(i) + 3] ); \ } #define PUT_UINT32(n,b,i) \ { \ (b)[(i) ] = (uint8) ( (n) >> 24 ); \ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 3] = (uint8) ( (n) ); \ } /* decryption key schedule tables */ int KT_init = 1; uint32 KT0[256]; uint32 KT1[256]; uint32 KT2[256]; uint32 KT3[256]; /* AES key scheduling routine */ int aes_set_key( aes_context *ctx, uint8 *key, int nbits ) { int i; uint32 *RK, *SK; if( do_init ) { aes_gen_tables(); /* #nocov start */ do_init = 0; /* #nocov end */ } switch( nbits ) { case 128: ctx->nr = 10; break; case 192: ctx->nr = 12; break; case 256: ctx->nr = 14; break; default : return( 1 ); /* #nocov */ } RK = ctx->erk; for( i = 0; i < (nbits >> 5); i++ ) { GET_UINT32( RK[i], key, i * 4 ); } /* setup encryption round keys */ switch( nbits ) { case 128: for( i = 0; i < 10; i++, RK += 4 ) { RK[4] = RK[0] ^ RCON[i] ^ ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[3] >> 24 ) ] ); RK[5] = RK[1] ^ RK[4]; RK[6] = RK[2] ^ RK[5]; RK[7] = RK[3] ^ RK[6]; } break; case 192: for( i = 0; i < 8; i++, RK += 6 ) { RK[6] = RK[0] ^ RCON[i] ^ ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[5] >> 24 ) ] ); RK[7] = RK[1] ^ RK[6]; RK[8] = RK[2] ^ RK[7]; RK[9] = RK[3] ^ RK[8]; RK[10] = RK[4] ^ RK[9]; RK[11] = RK[5] ^ RK[10]; } break; case 256: for( i = 0; i < 7; i++, RK += 8 ) { RK[8] = RK[0] ^ RCON[i] ^ ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[7] >> 24 ) ] ); RK[9] = RK[1] ^ RK[8]; RK[10] = RK[2] ^ RK[9]; RK[11] = RK[3] ^ RK[10]; RK[12] = RK[4] ^ ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( RK[11] ) ] ); RK[13] = RK[5] ^ RK[12]; RK[14] = RK[6] ^ RK[13]; RK[15] = RK[7] ^ RK[14]; } break; } /* setup decryption round keys */ if( KT_init ) { for( i = 0; i < 256; i++ ) { KT0[i] = RT0[ FSb[i] ]; KT1[i] = RT1[ FSb[i] ]; KT2[i] = RT2[ FSb[i] ]; KT3[i] = RT3[ FSb[i] ]; } KT_init = 0; } SK = ctx->drk; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; for( i = 1; i < ctx->nr; i++ ) { RK -= 8; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; } RK -= 8; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; return( 0 ); } /* AES 128-bit block encryption routine */ void aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) { uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->erk; GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ RK += 4; \ \ X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ FT3[ (uint8) ( Y3 ) ]; \ \ X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ FT3[ (uint8) ( Y0 ) ]; \ \ X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ FT3[ (uint8) ( Y1 ) ]; \ \ X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ FT3[ (uint8) ( Y2 ) ]; \ } AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ if( ctx->nr > 10 ) { AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ } if( ctx->nr > 12 ) { AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y3 ) ] ); X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y0 ) ] ); X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y1 ) ] ); X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y2 ) ] ); PUT_UINT32( X0, output, 0 ); PUT_UINT32( X1, output, 4 ); PUT_UINT32( X2, output, 8 ); PUT_UINT32( X3, output, 12 ); } /* AES 128-bit block decryption routine */ void aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) { uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->drk; GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ RK += 4; \ \ X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ RT3[ (uint8) ( Y1 ) ]; \ \ X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ RT3[ (uint8) ( Y2 ) ]; \ \ X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ RT3[ (uint8) ( Y3 ) ]; \ \ X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ RT3[ (uint8) ( Y0 ) ]; \ } AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ if( ctx->nr > 10 ) { AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ } if( ctx->nr > 12 ) { AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y1 ) ] ); X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y2 ) ] ); X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y3 ) ] ); X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y0 ) ] ); PUT_UINT32( X0, output, 0 ); PUT_UINT32( X1, output, 4 ); PUT_UINT32( X2, output, 8 ); PUT_UINT32( X3, output, 12 ); } #ifdef TEST #include #include /* * Rijndael Monte Carlo Test: ECB mode * source: NIST - rijndael-vals.zip */ static unsigned char AES_enc_test[3][16] = { { 0xA0, 0x43, 0x77, 0xAB, 0xE2, 0x59, 0xB0, 0xD0, 0xB5, 0xBA, 0x2D, 0x40, 0xA5, 0x01, 0x97, 0x1B }, { 0x4E, 0x46, 0xF8, 0xC5, 0x09, 0x2B, 0x29, 0xE2, 0x9A, 0x97, 0x1A, 0x0C, 0xD1, 0xF6, 0x10, 0xFB }, { 0x1F, 0x67, 0x63, 0xDF, 0x80, 0x7A, 0x7E, 0x70, 0x96, 0x0D, 0x4C, 0xD3, 0x11, 0x8E, 0x60, 0x1A } }; static unsigned char AES_dec_test[3][16] = { { 0xF5, 0xBF, 0x8B, 0x37, 0x13, 0x6F, 0x2E, 0x1F, 0x6B, 0xEC, 0x6F, 0x57, 0x20, 0x21, 0xE3, 0xBA }, { 0xF1, 0xA8, 0x1B, 0x68, 0xF6, 0xE5, 0xA6, 0x27, 0x1A, 0x8C, 0xB2, 0x4E, 0x7D, 0x94, 0x91, 0xEF }, { 0x4D, 0xE0, 0xC6, 0xDF, 0x7C, 0xB1, 0x69, 0x72, 0x84, 0x60, 0x4D, 0x60, 0x27, 0x1B, 0xC5, 0x9A } }; int main( void ) { int m, n, i, j; aes_context ctx; unsigned char buf[16]; unsigned char key[32]; for( m = 0; m < 2; m++ ) { printf( "\n Rijndael Monte Carlo Test (ECB mode) - " ); if( m == 0 ) printf( "encryption\n\n" ); if( m == 1 ) printf( "decryption\n\n" ); for( n = 0; n < 3; n++ ) { printf( " Test %d, key size = %3d bits: ", n + 1, 128 + n * 64 ); fflush( stdout ); memset( buf, 0, 16 ); memset( key, 0, 16 + n * 8 ); for( i = 0; i < 400; i++ ) { aes_set_key( &ctx, key, 128 + n * 64 ); for( j = 0; j < 9999; j++ ) { if( m == 0 ) aes_encrypt( &ctx, buf, buf ); if( m == 1 ) aes_decrypt( &ctx, buf, buf ); } if( n > 0 ) { for( j = 0; j < (n << 3); j++ ) { key[j] ^= buf[j + 16 - (n << 3)]; } } if( m == 0 ) aes_encrypt( &ctx, buf, buf ); if( m == 1 ) aes_decrypt( &ctx, buf, buf ); for( j = 0; j < 16; j++ ) { key[j + (n << 3)] ^= buf[j]; } } if( ( m == 0 && memcmp( buf, AES_enc_test[n], 16 ) != 0 ) || ( m == 1 && memcmp( buf, AES_dec_test[n], 16 ) != 0 ) ) { printf( "failed!\n" ); return( 1 ); } printf( "passed.\n" ); } } printf( "\n" ); return( 0 ); } #endif digest/src/blake3_portable.c0000755000176200001440000001437013661213637015535 0ustar liggesusers/* blake3 license: * The C code is copyright Samuel Neves and Jack O'Connor, 2019-2020. * This work is released into the public domain with CC0 1.0. * Alternatively, it is licensed under the Apache License 2.0. * For full license see * https://raw.githubusercontent.com/BLAKE3-team/BLAKE3/master/LICENSE */ #include "blake3_impl.h" #include INLINE void store32(void *dst, uint32_t w) { uint8_t *p = (uint8_t *)dst; p[0] = (uint8_t)(w >> 0); p[1] = (uint8_t)(w >> 8); p[2] = (uint8_t)(w >> 16); p[3] = (uint8_t)(w >> 24); } INLINE uint32_t rotr32(uint32_t w, uint32_t c) { return (w >> c) | (w << (32 - c)); } INLINE void g(uint32_t *state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y) { state[a] = state[a] + state[b] + x; state[d] = rotr32(state[d] ^ state[a], 16); state[c] = state[c] + state[d]; state[b] = rotr32(state[b] ^ state[c], 12); state[a] = state[a] + state[b] + y; state[d] = rotr32(state[d] ^ state[a], 8); state[c] = state[c] + state[d]; state[b] = rotr32(state[b] ^ state[c], 7); } INLINE void round_fn(uint32_t state[16], const uint32_t *msg, size_t round) { // Select the message schedule based on the round. const uint8_t *schedule = MSG_SCHEDULE[round]; // Mix the columns. g(state, 0, 4, 8, 12, msg[schedule[0]], msg[schedule[1]]); g(state, 1, 5, 9, 13, msg[schedule[2]], msg[schedule[3]]); g(state, 2, 6, 10, 14, msg[schedule[4]], msg[schedule[5]]); g(state, 3, 7, 11, 15, msg[schedule[6]], msg[schedule[7]]); // Mix the rows. g(state, 0, 5, 10, 15, msg[schedule[8]], msg[schedule[9]]); g(state, 1, 6, 11, 12, msg[schedule[10]], msg[schedule[11]]); g(state, 2, 7, 8, 13, msg[schedule[12]], msg[schedule[13]]); g(state, 3, 4, 9, 14, msg[schedule[14]], msg[schedule[15]]); } INLINE void compress_pre(uint32_t state[16], const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags) { uint32_t block_words[16]; block_words[0] = load32(block + 4 * 0); block_words[1] = load32(block + 4 * 1); block_words[2] = load32(block + 4 * 2); block_words[3] = load32(block + 4 * 3); block_words[4] = load32(block + 4 * 4); block_words[5] = load32(block + 4 * 5); block_words[6] = load32(block + 4 * 6); block_words[7] = load32(block + 4 * 7); block_words[8] = load32(block + 4 * 8); block_words[9] = load32(block + 4 * 9); block_words[10] = load32(block + 4 * 10); block_words[11] = load32(block + 4 * 11); block_words[12] = load32(block + 4 * 12); block_words[13] = load32(block + 4 * 13); block_words[14] = load32(block + 4 * 14); block_words[15] = load32(block + 4 * 15); state[0] = cv[0]; state[1] = cv[1]; state[2] = cv[2]; state[3] = cv[3]; state[4] = cv[4]; state[5] = cv[5]; state[6] = cv[6]; state[7] = cv[7]; state[8] = IV[0]; state[9] = IV[1]; state[10] = IV[2]; state[11] = IV[3]; state[12] = counter_low(counter); state[13] = counter_high(counter); state[14] = (uint32_t)block_len; state[15] = (uint32_t)flags; round_fn(state, &block_words[0], 0); round_fn(state, &block_words[0], 1); round_fn(state, &block_words[0], 2); round_fn(state, &block_words[0], 3); round_fn(state, &block_words[0], 4); round_fn(state, &block_words[0], 5); round_fn(state, &block_words[0], 6); } void blake3_compress_in_place_portable(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags) { uint32_t state[16]; compress_pre(state, cv, block, block_len, counter, flags); cv[0] = state[0] ^ state[8]; cv[1] = state[1] ^ state[9]; cv[2] = state[2] ^ state[10]; cv[3] = state[3] ^ state[11]; cv[4] = state[4] ^ state[12]; cv[5] = state[5] ^ state[13]; cv[6] = state[6] ^ state[14]; cv[7] = state[7] ^ state[15]; } void blake3_compress_xof_portable(const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags, uint8_t out[64]) { uint32_t state[16]; compress_pre(state, cv, block, block_len, counter, flags); store32(&out[0 * 4], state[0] ^ state[8]); store32(&out[1 * 4], state[1] ^ state[9]); store32(&out[2 * 4], state[2] ^ state[10]); store32(&out[3 * 4], state[3] ^ state[11]); store32(&out[4 * 4], state[4] ^ state[12]); store32(&out[5 * 4], state[5] ^ state[13]); store32(&out[6 * 4], state[6] ^ state[14]); store32(&out[7 * 4], state[7] ^ state[15]); store32(&out[8 * 4], state[8] ^ cv[0]); store32(&out[9 * 4], state[9] ^ cv[1]); store32(&out[10 * 4], state[10] ^ cv[2]); store32(&out[11 * 4], state[11] ^ cv[3]); store32(&out[12 * 4], state[12] ^ cv[4]); store32(&out[13 * 4], state[13] ^ cv[5]); store32(&out[14 * 4], state[14] ^ cv[6]); store32(&out[15 * 4], state[15] ^ cv[7]); } INLINE void hash_one_portable(const uint8_t *input, size_t blocks, const uint32_t key[8], uint64_t counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t out[BLAKE3_OUT_LEN]) { uint32_t cv[8]; memcpy(cv, key, BLAKE3_KEY_LEN); uint8_t block_flags = flags | flags_start; while (blocks > 0) { if (blocks == 1) { block_flags |= flags_end; } blake3_compress_in_place_portable(cv, input, BLAKE3_BLOCK_LEN, counter, block_flags); input = &input[BLAKE3_BLOCK_LEN]; blocks -= 1; block_flags = flags; } memcpy(out, cv, 32); } void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out) { while (num_inputs > 0) { hash_one_portable(inputs[0], blocks, key, counter, flags, flags_start, flags_end, out); if (increment_counter) { counter += 1; } inputs += 1; num_inputs -= 1; out = &out[BLAKE3_OUT_LEN]; } } digest/src/spooky_serialize.cpp0000644000176200001440000000675613463366440016446 0ustar liggesusers// Copyright (C) 2019 Kendon Bell // Copyright (C) 2014 Gabe Becker // // This file is part of digest and is modified from the original source in // the R package fastdigest under the Artistic License 2.0. // // digest is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // digest is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with digest. If not, see . #ifdef HAVE_CONFIG_H #include #endif #define USE_RINTERNALS #include #include #include #include #include "SpookyV2.h" static void OutCharSpooky(R_outpstream_t stream, int c) { // #nocov start SpookyHash *spooky = (SpookyHash *)stream->data; spooky->Update(&c, 1); } // #nocov end static void OutBytesSpooky(R_outpstream_t stream, void *buf, int length) { SpookyHash *spooky = (SpookyHash *)stream->data; uint8 skipped = 0; uint8 to_skip = 0; spooky->GetSkipCounter(&skipped); spooky->GetToSkip(&to_skip); if(skipped < to_skip){ if((skipped + length) > to_skip){ error("Serialization header has an unexpected length. Please file an issue at https://github.com/eddelbuettel/digest/issues."); // #nocov } spooky->UpdateSkipCounter(length); } else { spooky->Update(buf, length); } } static void InitSpookyPStream(R_outpstream_t stream, SpookyHash *spooky, R_pstream_format_t type, int version, SEXP (*phook)(SEXP, SEXP), SEXP pdata) { R_InitOutPStream(stream, (R_pstream_data_t) spooky, type, version, OutCharSpooky, OutBytesSpooky, phook, pdata); } //From serialize.c in R sources /* ought to quote the argument, but it should only be an ENVSXP or STRSXP */ static SEXP CallHook(SEXP x, SEXP fun) { // #nocov start SEXP val, call; PROTECT(call = LCONS(fun, LCONS(x, R_NilValue))); val = eval(call, R_GlobalEnv); UNPROTECT(1); return val; } // #nocov end extern "C" SEXP spookydigest_impl(SEXP s, SEXP to_skip_r, SEXP seed1_r, SEXP seed2_r, SEXP version_r, SEXP fun) { SpookyHash spooky; double seed1_d = NUMERIC_VALUE(seed1_r); double seed2_d = NUMERIC_VALUE(seed2_r); uint64 seed1 = seed1_d; uint64 seed2 = seed2_d; uint8 to_skip = INTEGER_VALUE(to_skip_r); spooky.Init(seed1, seed2, to_skip); R_outpstream_st spooky_stream; R_pstream_format_t type = R_pstream_binary_format; SEXP (*hook)(SEXP, SEXP); int version = INTEGER_VALUE(version_r); hook = fun != R_NilValue ? CallHook : NULL; InitSpookyPStream(&spooky_stream, &spooky, type, version, hook, fun); R_Serialize(s, &spooky_stream); //There are two because they are 64 bit ints and the hash is 128 bits!!! uint64 h1, h2; spooky.Final(&h1, &h2); SEXP ans; PROTECT(ans = allocVector(RAWSXP, 16)); unsigned char *tmp; tmp = (unsigned char *) &h1; for (int i = 0; i < 8; i++) RAW(ans)[i] = tmp[i]; tmp = (unsigned char *) &h2; for (int j = 0; j < 8; j++) RAW(ans)[j + 8] = tmp[j]; UNPROTECT(1); return ans; } digest/src/xxhash.h0000644000176200001440000003223213346570104014001 0ustar liggesusers/* xxHash - Extremely Fast Hash algorithm Header File Copyright (C) 2012-2016, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - xxHash source repository : https://github.com/Cyan4973/xxHash */ /* Notice extracted from xxHash homepage : xxHash is an extremely fast Hash algorithm, running at RAM speed limits. It also successfully passes all tests from the SMHasher suite. Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) Name Speed Q.Score Author xxHash 5.4 GB/s 10 CrapWow 3.2 GB/s 2 Andrew MumurHash 3a 2.7 GB/s 10 Austin Appleby SpookyHash 2.0 GB/s 10 Bob Jenkins SBox 1.4 GB/s 9 Bret Mulvey Lookup3 1.2 GB/s 9 Bob Jenkins SuperFastHash 1.2 GB/s 1 Paul Hsieh CityHash64 1.05 GB/s 10 Pike & Alakuijala FNV 0.55 GB/s 5 Fowler, Noll, Vo CRC32 0.43 GB/s 9 MD5-32 0.33 GB/s 10 Ronald L. Rivest SHA1-32 0.28 GB/s 10 Q.Score is a measure of quality of the hash function. It depends on successfully passing SMHasher test set. 10 is a perfect score. A 64-bit version, named XXH64, is available since r35. It offers much better speed, but for 64-bit applications only. Name Speed on 64 bits Speed on 32 bits XXH64 13.8 GB/s 1.9 GB/s XXH32 6.8 GB/s 6.0 GB/s */ #ifndef XXHASH_H_5627135585666179 #define XXHASH_H_5627135585666179 1 #if defined (__cplusplus) extern "C" { #endif /* **************************** * Definitions ******************************/ #include /* size_t */ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; /* **************************** * API modifier ******************************/ /** XXH_INLINE_ALL (and XXH_PRIVATE_API) * This is useful to include xxhash functions in `static` mode * in order to inline them, and remove their symbol from the public list. * Inlining can offer dramatic performance improvement on small keys. * Methodology : * #define XXH_INLINE_ALL * #include "xxhash.h" * `xxhash.c` is automatically included. * It's not useful to compile and link it as a separate module. */ #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # ifndef XXH_STATIC_LINKING_ONLY # define XXH_STATIC_LINKING_ONLY # endif # if defined(__GNUC__) # define XXH_PUBLIC_API static __inline __attribute__((unused)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) # define XXH_PUBLIC_API static __inline # else /* this version may generate warnings for unused static functions */ # define XXH_PUBLIC_API static # endif #else # define XXH_PUBLIC_API /* do nothing */ #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ /*! XXH_NAMESPACE, aka Namespace Emulation : * * If you want to include _and expose_ xxHash functions from within your own library, * but also want to avoid symbol collisions with other libraries which may also include xxHash, * * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). * * Note that no change is required within the calling program as long as it includes `xxhash.h` : * regular symbol name will be automatically translated by this header. */ #ifdef XXH_NAMESPACE # define XXH_CAT(A,B) A##B # define XXH_NAME2(A,B) XXH_CAT(A,B) # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) # define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) # define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) # define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) # define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) # define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) # define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) # define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) #endif /* ************************************* * Version ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 6 #define XXH_VERSION_RELEASE 5 #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) XXH_PUBLIC_API unsigned XXH_versionNumber (void); /*-********************************************************************** * 32-bit hash ************************************************************************/ typedef unsigned int XXH32_hash_t; /*! XXH32() : Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input". The memory between input & input+length must be valid (allocated and read-accessible). "seed" can be used to alter the result predictably. Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); /*====== Streaming ======*/ typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); /* * Streaming functions generate the xxHash of an input provided in multiple segments. * Note that, for small input, they are slower than single-call functions, due to state management. * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. * * XXH state must first be allocated, using XXH*_createState() . * * Start a new hash by initializing state with a seed, using XXH*_reset(). * * Then, feed the hash state by calling XXH*_update() as many times as necessary. * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. * * Finally, a hash value can be produced anytime, by using XXH*_digest(). * This function returns the nn-bits hash as an int or long long. * * It's still possible to continue inserting input into the hash state after a digest, * and generate some new hashes later on, by calling again XXH*_digest(). * * When done, free XXH state space if it was allocated dynamically. */ /*====== Canonical representation ======*/ typedef struct { unsigned char digest[4]; } XXH32_canonical_t; XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); /* Default result type for XXH functions are primitive unsigned 32 and 64 bits. * The canonical representation uses human-readable write convention, aka big-endian (large digits first). * These functions allow transformation of hash result into and from its canonical format. * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. */ #ifndef XXH_NO_LONG_LONG /*-********************************************************************** * 64-bit hash ************************************************************************/ typedef unsigned long long XXH64_hash_t; /*! XXH64() : Calculate the 64-bit hash of sequence of length "len" stored at memory address "input". "seed" can be used to alter the result predictably. This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark). */ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); /*====== Streaming ======*/ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); /*====== Canonical representation ======*/ typedef struct { unsigned char digest[8]; } XXH64_canonical_t; XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); #endif /* XXH_NO_LONG_LONG */ #ifdef XXH_STATIC_LINKING_ONLY /* ================================================================================================ This section contains declarations which are not guaranteed to remain stable. They may change in future versions, becoming incompatible with a different version of the library. These declarations should only be used with static linking. Never use them in association with dynamic linking ! =================================================================================================== */ /* These definitions are only present to allow * static allocation of XXH state, on stack or in a struct for example. * Never **ever** use members directly. */ #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include struct XXH32_state_s { uint32_t total_len_32; uint32_t large_len; uint32_t v1; uint32_t v2; uint32_t v3; uint32_t v4; uint32_t mem32[4]; uint32_t memsize; uint32_t reserved; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH32_state_t */ struct XXH64_state_s { uint64_t total_len; uint64_t v1; uint64_t v2; uint64_t v3; uint64_t v4; uint64_t mem64[4]; uint32_t memsize; uint32_t reserved[2]; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH64_state_t */ # else struct XXH32_state_s { unsigned total_len_32; unsigned large_len; unsigned v1; unsigned v2; unsigned v3; unsigned v4; unsigned mem32[4]; unsigned memsize; unsigned reserved; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH32_state_t */ # ifndef XXH_NO_LONG_LONG /* remove 64-bit support */ struct XXH64_state_s { unsigned long long total_len; unsigned long long v1; unsigned long long v2; unsigned long long v3; unsigned long long v4; unsigned long long mem64[4]; unsigned memsize; unsigned reserved[2]; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH64_state_t */ # endif # endif #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */ #endif #endif /* XXH_STATIC_LINKING_ONLY */ #if defined (__cplusplus) } #endif #endif /* XXHASH_H_5627135585666179 */ digest/src/sha256.h0000644000176200001440000000067312247504516013515 0ustar liggesusers#ifndef _SHA256_H #define _SHA256_H #ifndef uint8 #define uint8 unsigned char #endif #ifndef uint32 #define uint32 unsigned long int #endif typedef struct { uint32 total[2]; uint32 state[8]; uint8 buffer[64]; } sha256_context; void sha256_starts( sha256_context *ctx ); void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ); void sha256_finish( sha256_context *ctx, uint8 digest[32] ); #endif /* sha256.h */ digest/src/init.c0000644000176200001440000000265013573510446013442 0ustar liggesusers/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- init -- registering the c hash digest functions Copyright (C) 2014 - 2019 Wush Wu and Dirk Eddelbuettel This file is part of digest. digest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. digest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with digest. If not, see . */ #include #include "xxhash.h" #include "pmurhash.h" void R_init_digest(DllInfo *info) { R_RegisterCCallable("digest", "PMurHash32", (DL_FUNC) &PMurHash32); /* tools::package_native_routine_registration_skeleton() reports empty set */ R_registerRoutines(info, NULL, /* slot for .C */ NULL, /* slot for .Call */ NULL, /* slot for .Fortran */ NULL); /* slot for .External */ R_useDynamicSymbols(info, TRUE); /* controls visibility */ } digest/src/crc32.c0000644000176200001440000002203513017636737013417 0ustar liggesusers/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing * tables for updating the shift register in one step with three exclusive-ors * instead of four steps with four exclusive-ors. This results about a factor * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ /* @(#) $Id$ */ /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection on the static variables used to control the first-use generation of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should first call get_crc_table() to initialize the tables before allowing more than one thread to use crc32(). */ #include "zutil.h" /* for STDC and FAR definitions */ /* #include "zlib.h" */ /* for STDC and FAR definitions */ #define local static /* Find a four-byte integer type for crc32_little() and crc32_big(). */ #ifndef NOBYFOUR # ifdef STDC /* need ANSI C limits.h to determine sizes */ # include # define BYFOUR # if (UINT_MAX == 0xffffffffUL) typedef unsigned int u4; # else # if (ULONG_MAX == 0xffffffffUL) typedef unsigned long u4; # else # if (USHRT_MAX == 0xffffffffUL) typedef unsigned short u4; # else # undef BYFOUR /* can't find a four-byte integer type! */ # endif # endif # endif # endif /* STDC */ #endif /* !NOBYFOUR */ /* Definitions for doing the crc four data bytes at a time. */ #ifdef BYFOUR # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long digest_crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); local unsigned long digest_crc32_big OF((unsigned long, const unsigned char FAR *, unsigned)); # define TBLS 8 #else # define TBLS 1 #endif /* BYFOUR */ #ifdef DYNAMIC_CRC_TABLE local volatile int crc_table_empty = 1; local unsigned long FAR crc_table[TBLS][256]; local void digest_make_crc_table OF((void)); /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The first table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRCs on data a byte at a time for all combinations of CRC register values and incoming bytes. The remaining tables allow for word-at-a-time CRC calculation for both big-endian and little- endian machines, where a word is four bytes. */ local void digest_make_crc_table() { unsigned long c; int n, k; unsigned long poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ static volatile int first = 1; /* flag to limit concurrent making */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* See if another task is already doing this (not thread-safe, but better than nothing -- significantly reduces duration of vulnerability in case the advice about DYNAMIC_CRC_TABLE is ignored) */ if (first) { first = 0; /* make exclusive-or pattern from polynomial (0xedb88320UL) */ poly = 0UL; for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) poly |= 1UL << (31 - p[n]); /* generate a crc for every 8-bit value */ for (n = 0; n < 256; n++) { c = (unsigned long)n; for (k = 0; k < 8; k++) c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[0][n] = c; } #ifdef BYFOUR /* generate crc for each value followed by one, two, and three zeros, and then the byte reversal of those as well as the first table */ for (n = 0; n < 256; n++) { c = crc_table[0][n]; crc_table[4][n] = REV(c); for (k = 1; k < 4; k++) { c = crc_table[0][c & 0xff] ^ (c >> 8); crc_table[k][n] = c; crc_table[k + 4][n] = REV(c); } } #endif /* BYFOUR */ crc_table_empty = 0; } else { /* not first */ /* wait for the other guy to finish (not efficient, but rare) */ while (crc_table_empty) ; } } #else /* !DYNAMIC_CRC_TABLE */ /* ======================================================================== * Tables of CRC-32s of all single-byte values, made by make_crc_table(). */ #include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ unsigned long ZEXPORT digest_crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { if (buf == Z_NULL) return 0UL; #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) digest_make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { u4 endian; endian = 1; if (*((unsigned char *)(&endian))) return digest_crc32_little(crc, buf, len); else return digest_crc32_big(crc, buf, len); /* #nocov */ } #endif /* BYFOUR */ crc = crc ^ 0xffffffffUL; while (len >= 8) { DO8; len -= 8; } if (len) do { DO1; } while (--len); return crc ^ 0xffffffffUL; } #ifdef BYFOUR /* ========================================================================= */ #define DOLIT4 c ^= *buf4++; \ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ local unsigned long digest_crc32_little(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = (u4)crc; c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); /* #nocov */ len--; /* #nocov */ } buf4 = (const u4 FAR *)buf; while (len >= 32) { DOLIT32; len -= 32; } while (len >= 4) { DOLIT4; len -= 4; } buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); } while (--len); c = ~c; return (unsigned long)c; } /* ========================================================================= */ #define DOBIG4 c ^= *++buf4; \ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ local unsigned long digest_crc32_big(crc, buf, len) /* #nocov start */ unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = REV((u4)crc); c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); len--; } buf4 = (const u4 FAR *)buf; buf4--; while (len >= 32) { DOBIG32; len -= 32; } while (len >= 4) { DOBIG4; len -= 4; } buf4++; buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); } while (--len); c = ~c; return (unsigned long)(REV(c)); } /* #nocov end */ #endif /* BYFOUR */ digest/src/crc32.h0000644000176200001440000007355012247504516013425 0ustar liggesusers/* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ local const unsigned long FAR crc_table[TBLS][256] = { { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL #ifdef BYFOUR }, { 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, 0x9324fd72UL }, { 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, 0xbe9834edUL }, { 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, 0xde0506f1UL }, { 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, 0x8def022dUL }, { 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, 0x72fd2493UL }, { 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, 0xed3498beUL }, { 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, 0xf10605deUL #endif } }; digest/src/blake3.h0000755000176200001440000000414213661213637013646 0ustar liggesusers/* blake3 license: * The C code is copyright Samuel Neves and Jack O'Connor, 2019-2020. * This work is released into the public domain with CC0 1.0. * Alternatively, it is licensed under the Apache License 2.0. * For full license see * https://raw.githubusercontent.com/BLAKE3-team/BLAKE3/master/LICENSE */ #ifndef BLAKE3_H #define BLAKE3_H #include #include #define BLAKE3_NO_AVX512 #define BLAKE3_NO_SSE41 #define BLAKE3_NO_AVX2 #ifdef __cplusplus extern "C" { #endif #define BLAKE3_KEY_LEN 32 #define BLAKE3_OUT_LEN 32 #define BLAKE3_BLOCK_LEN 64 #define BLAKE3_CHUNK_LEN 1024 #define BLAKE3_MAX_DEPTH 54 #define BLAKE3_MAX_SIMD_DEGREE 16 // This struct is a private implementation detail. It has to be here because // it's part of blake3_hasher below. typedef struct { uint32_t cv[8]; uint64_t chunk_counter; uint8_t buf[BLAKE3_BLOCK_LEN]; uint8_t buf_len; uint8_t blocks_compressed; uint8_t flags; } blake3_chunk_state; typedef struct { uint32_t key[8]; blake3_chunk_state chunk; uint8_t cv_stack_len; // The stack size is MAX_DEPTH + 1 because we do lazy merging. For example, // with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk // requires a 4th entry, rather than merging everything down to 1, because we // don't know whether more input is coming. This is different from how the // reference implementation does things. uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN]; } blake3_hasher; void blake3_hasher_init(blake3_hasher *self); void blake3_hasher_init_keyed(blake3_hasher *self, const uint8_t key[BLAKE3_KEY_LEN]); void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context); void blake3_hasher_update(blake3_hasher *self, const void *input, size_t input_len); void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, size_t out_len); void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, uint8_t *out, size_t out_len); #ifdef __cplusplus } #endif #endif /* BLAKE3_H */ digest/src/sha1.c0000644000176200001440000002150613216563247013335 0ustar liggesusers/* * FIPS-180-1 compliant SHA-1 implementation, * by Christophe Devine ; * this program is licensed under the GPL. */ #include #include "sha1.h" #define GET_UINT32(n,b,i) \ { \ (n) = ( (uint32) (b)[(i) ] << 24 ) \ | ( (uint32) (b)[(i) + 1] << 16 ) \ | ( (uint32) (b)[(i) + 2] << 8 ) \ | ( (uint32) (b)[(i) + 3] ); \ } #define PUT_UINT32(n,b,i) \ { \ (b)[(i) ] = (uint8) ( (n) >> 24 ); \ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 3] = (uint8) ( (n) ); \ } void sha1_starts( sha1_context *ctx ) { ctx->total[0] = 0; ctx->total[1] = 0; ctx->state[0] = 0x67452301; ctx->state[1] = 0xEFCDAB89; ctx->state[2] = 0x98BADCFE; ctx->state[3] = 0x10325476; ctx->state[4] = 0xC3D2E1F0; } void sha1_process( sha1_context *ctx, uint8 data[64] ) { uint32 temp, W[16], A, B, C, D, E; GET_UINT32( W[0], data, 0 ); GET_UINT32( W[1], data, 4 ); GET_UINT32( W[2], data, 8 ); GET_UINT32( W[3], data, 12 ); GET_UINT32( W[4], data, 16 ); GET_UINT32( W[5], data, 20 ); GET_UINT32( W[6], data, 24 ); GET_UINT32( W[7], data, 28 ); GET_UINT32( W[8], data, 32 ); GET_UINT32( W[9], data, 36 ); GET_UINT32( W[10], data, 40 ); GET_UINT32( W[11], data, 44 ); GET_UINT32( W[12], data, 48 ); GET_UINT32( W[13], data, 52 ); GET_UINT32( W[14], data, 56 ); GET_UINT32( W[15], data, 60 ); #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) #define R(t) \ ( \ temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ ( W[t & 0x0F] = S(temp,1) ) \ ) #define P(a,b,c,d,e,x) \ { \ e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ } A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; E = ctx->state[4]; #define F(x,y,z) (z ^ (x & (y ^ z))) #define K 0x5A827999 P( A, B, C, D, E, W[0] ); P( E, A, B, C, D, W[1] ); P( D, E, A, B, C, W[2] ); P( C, D, E, A, B, W[3] ); P( B, C, D, E, A, W[4] ); P( A, B, C, D, E, W[5] ); P( E, A, B, C, D, W[6] ); P( D, E, A, B, C, W[7] ); P( C, D, E, A, B, W[8] ); P( B, C, D, E, A, W[9] ); P( A, B, C, D, E, W[10] ); P( E, A, B, C, D, W[11] ); P( D, E, A, B, C, W[12] ); P( C, D, E, A, B, W[13] ); P( B, C, D, E, A, W[14] ); P( A, B, C, D, E, W[15] ); P( E, A, B, C, D, R(16) ); P( D, E, A, B, C, R(17) ); P( C, D, E, A, B, R(18) ); P( B, C, D, E, A, R(19) ); #undef K #undef F #define F(x,y,z) (x ^ y ^ z) #define K 0x6ED9EBA1 P( A, B, C, D, E, R(20) ); P( E, A, B, C, D, R(21) ); P( D, E, A, B, C, R(22) ); P( C, D, E, A, B, R(23) ); P( B, C, D, E, A, R(24) ); P( A, B, C, D, E, R(25) ); P( E, A, B, C, D, R(26) ); P( D, E, A, B, C, R(27) ); P( C, D, E, A, B, R(28) ); P( B, C, D, E, A, R(29) ); P( A, B, C, D, E, R(30) ); P( E, A, B, C, D, R(31) ); P( D, E, A, B, C, R(32) ); P( C, D, E, A, B, R(33) ); P( B, C, D, E, A, R(34) ); P( A, B, C, D, E, R(35) ); P( E, A, B, C, D, R(36) ); P( D, E, A, B, C, R(37) ); P( C, D, E, A, B, R(38) ); P( B, C, D, E, A, R(39) ); #undef K #undef F #define F(x,y,z) ((x & y) | (z & (x | y))) #define K 0x8F1BBCDC P( A, B, C, D, E, R(40) ); P( E, A, B, C, D, R(41) ); P( D, E, A, B, C, R(42) ); P( C, D, E, A, B, R(43) ); P( B, C, D, E, A, R(44) ); P( A, B, C, D, E, R(45) ); P( E, A, B, C, D, R(46) ); P( D, E, A, B, C, R(47) ); P( C, D, E, A, B, R(48) ); P( B, C, D, E, A, R(49) ); P( A, B, C, D, E, R(50) ); P( E, A, B, C, D, R(51) ); P( D, E, A, B, C, R(52) ); P( C, D, E, A, B, R(53) ); P( B, C, D, E, A, R(54) ); P( A, B, C, D, E, R(55) ); P( E, A, B, C, D, R(56) ); P( D, E, A, B, C, R(57) ); P( C, D, E, A, B, R(58) ); P( B, C, D, E, A, R(59) ); #undef K #undef F #define F(x,y,z) (x ^ y ^ z) #define K 0xCA62C1D6 P( A, B, C, D, E, R(60) ); P( E, A, B, C, D, R(61) ); P( D, E, A, B, C, R(62) ); P( C, D, E, A, B, R(63) ); P( B, C, D, E, A, R(64) ); P( A, B, C, D, E, R(65) ); P( E, A, B, C, D, R(66) ); P( D, E, A, B, C, R(67) ); P( C, D, E, A, B, R(68) ); P( B, C, D, E, A, R(69) ); P( A, B, C, D, E, R(70) ); P( E, A, B, C, D, R(71) ); P( D, E, A, B, C, R(72) ); P( C, D, E, A, B, R(73) ); P( B, C, D, E, A, R(74) ); P( A, B, C, D, E, R(75) ); P( E, A, B, C, D, R(76) ); P( D, E, A, B, C, R(77) ); P( C, D, E, A, B, R(78) ); P( B, C, D, E, A, R(79) ); #undef K #undef F ctx->state[0] += A; ctx->state[1] += B; ctx->state[2] += C; ctx->state[3] += D; ctx->state[4] += E; } void sha1_update( sha1_context *ctx, uint8 *input, uint32 length ) { uint32 left, fill; if( ! length ) return; left = ctx->total[0] & 0x3F; fill = 64 - left; ctx->total[0] += length; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < length ) ctx->total[1]++; /* #nocov */ if( left && length >= fill ) { memcpy( (void *) (ctx->buffer + left), (void *) input, fill ); sha1_process( ctx, ctx->buffer ); length -= fill; input += fill; left = 0; } while( length >= 64 ) { sha1_process( ctx, input ); length -= 64; input += 64; } if( length ) { memcpy( (void *) (ctx->buffer + left), (void *) input, length ); } } static uint8 sha1_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void sha1_finish( sha1_context *ctx, uint8 digest[20] ) { uint32 last, padn; uint32 high, low; uint8 msglen[8]; high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); low = ( ctx->total[0] << 3 ); PUT_UINT32( high, msglen, 0 ); PUT_UINT32( low, msglen, 4 ); last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); sha1_update( ctx, sha1_padding, padn ); sha1_update( ctx, msglen, 8 ); PUT_UINT32( ctx->state[0], digest, 0 ); PUT_UINT32( ctx->state[1], digest, 4 ); PUT_UINT32( ctx->state[2], digest, 8 ); PUT_UINT32( ctx->state[3], digest, 12 ); PUT_UINT32( ctx->state[4], digest, 16 ); } #ifdef TEST #include #include /* * those are the standard FIPS-180-1 test vectors */ static char *msg[] = { "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", NULL }; static char *val[] = { "a9993e364706816aba3e25717850c26c9cd0d89d", "84983e441c3bd26ebaae4aa1f95129e5e54670f1", "34aa973cd4c4daa4f61eeb2bdbad27316534016f" }; int main( int argc, char *argv[] ) { FILE *f; int i, j; char output[41]; sha1_context ctx; unsigned char buf[1000]; unsigned char sha1sum[20]; if( argc < 2 ) { printf( "\n SHA-1 Validation Tests:\n\n" ); for( i = 0; i < 3; i++ ) { printf( " Test %d ", i + 1 ); sha1_starts( &ctx ); if( i < 2 ) { sha1_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) ); } else { memset( buf, 'a', 1000 ); for( j = 0; j < 1000; j++ ) { sha1_update( &ctx, (uint8 *) buf, 1000 ); } } sha1_finish( &ctx, sha1sum ); for( j = 0; j < 20; j++ ) { sprintf( output + j * 2, "%02x", sha1sum[j] ); } if( memcmp( output, val[i], 40 ) ) { printf( "failed!\n" ); return( 1 ); } printf( "passed.\n" ); } printf( "\n" ); } else { if( ! ( f = fopen( argv[1], "rb" ) ) ) { perror( "fopen" ); return( 1 ); } sha1_starts( &ctx ); while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) { sha1_update( &ctx, buf, i ); } sha1_finish( &ctx, sha1sum ); for( j = 0; j < 20; j++ ) { printf( "%02x", sha1sum[j] ); } printf( " %s\n", argv[1] ); } return( 0 ); } #endif digest/src/digest.c0000644000176200001440000004145214151530521013746 0ustar liggesusers/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- digest -- hash digest functions for R Copyright (C) 2003 - 2016 Dirk Eddelbuettel This file is part of digest. digest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. digest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with digest. If not, see . */ #include #include #include #include #include #include #include #include #include "sha1.h" #include "sha2.h" #include "sha256.h" #include "md5.h" #include "zlib.h" #include "xxhash.h" #include "pmurhash.h" #include "blake3.h" #ifdef _WIN32 #include #endif unsigned long ZEXPORT digest_crc32(unsigned long crc, const unsigned char FAR *buf, unsigned len); static const char *sha2_hex_digits = "0123456789abcdef"; FILE* open_with_widechar_on_windows(const char* txt) { FILE* out; #ifdef _WIN32 wchar_t* buf; size_t len = MultiByteToWideChar(CP_UTF8, 0, txt, -1, NULL, 0); if (len <= 0) { error("Cannot convert file to Unicode: %s", txt); } buf = (wchar_t*) R_alloc(len, sizeof(wchar_t)); if (buf == NULL) { error("Could not allocate buffer of size: %ll", len); } MultiByteToWideChar(CP_UTF8, 0, txt, -1, buf, len); out = _wfopen(buf, L"rb"); #else out = fopen(txt, "rb"); #endif return out; } SEXP digest(SEXP Txt, SEXP Algo, SEXP Length, SEXP Skip, SEXP Leave_raw, SEXP Seed) { size_t BUF_SIZE = 1024; FILE *fp=0; char *txt; int algo = INTEGER_VALUE(Algo); int length = INTEGER_VALUE(Length); int skip = INTEGER_VALUE(Skip); int seed = INTEGER_VALUE(Seed); int leaveRaw = INTEGER_VALUE(Leave_raw); SEXP result = R_NilValue; char output[128+1], *outputp = output; /* 33 for md5, 41 for sha1, 65 for sha256, 128 for sha512; plus trailing NULL */ R_xlen_t nChar; int output_length = -1; if (IS_RAW(Txt)) { /* Txt is either RAW */ txt = (char*) RAW(Txt); #if defined(R_VERSION) && R_VERSION >= R_Version(3,0,0) nChar = XLENGTH(Txt); #else nChar = LENGTH(Txt); #endif } else { /* or a string */ txt = (char*) STRING_VALUE(Txt); nChar = strlen(txt); if (algo >= 100) { fp = open_with_widechar_on_windows(txt); if (!fp) { error("Cannot open input file: %s", txt); /* #nocov */ } } } if (skip > 0 && algo < 100) { if (skip>=nChar) { nChar=0; /* #nocov */ } else { nChar -= skip; txt += skip; } } if (length>=0 && length> 4]; *outputp++ = sha2_hex_digits[*d & 0x0f]; d++; } *outputp = (char)0; } break; } case 6: { /* xxhash32 case */ unsigned int val = XXH32(txt, nChar, seed); sprintf(output, "%08x", val); break; } case 7: { /* xxhash64 case */ unsigned long long val = XXH64(txt, nChar, seed); #if defined(WIN32) && !defined(_UCRT) sprintf(output, "%016" PRIx64, val); #else sprintf(output, "%016llx", val); #endif break; } case 8: { /* MurmurHash3 32 */ unsigned int val = PMurHash32(seed, txt, nChar); sprintf(output, "%08x", val); break; } case 10: { /* blake3 */ output_length = BLAKE3_OUT_LEN; blake3_hasher hasher; blake3_hasher_init(&hasher); blake3_hasher_update(&hasher, txt, nChar); uint8_t val[BLAKE3_OUT_LEN]; blake3_hasher_finalize(&hasher, val, BLAKE3_OUT_LEN); if (leaveRaw) { memcpy(output, val, BLAKE3_OUT_LEN); } else { for (size_t i = 0; i < BLAKE3_OUT_LEN; i++) { sprintf(output + i * 2, "%02x", val[i]); } } break; } case 101: { /* md5 file case */ int j; md5_context ctx; output_length = 16; unsigned char buf[BUF_SIZE]; unsigned char md5sum[16]; if (skip > 0) fseek(fp, skip, SEEK_SET); md5_starts( &ctx ); if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; md5_update( &ctx, buf, nChar ); length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) md5_update( &ctx, buf, nChar ); } md5_finish( &ctx, md5sum ); memcpy(output, md5sum, 16); if (!leaveRaw) for (j = 0; j < 16; j++) sprintf(output + j * 2, "%02x", md5sum[j]); break; } case 102: { /* sha1 file case */ int j; sha1_context ctx; output_length = 20; unsigned char buf[BUF_SIZE]; unsigned char sha1sum[20]; if (skip > 0) fseek(fp, skip, SEEK_SET); sha1_starts ( &ctx ); if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; sha1_update( &ctx, buf, nChar ); length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) sha1_update( &ctx, buf, nChar ); } sha1_finish ( &ctx, sha1sum ); memcpy(output, sha1sum, 20); if (!leaveRaw) for ( j = 0; j < 20; j++ ) sprintf( output + j * 2, "%02x", sha1sum[j] ); break; } case 103: { /* crc32 file case */ unsigned char buf[BUF_SIZE]; unsigned long val; if (skip > 0) fseek(fp, skip, SEEK_SET); val = digest_crc32(0L, 0, 0); if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; val = digest_crc32(val , buf, (unsigned) nChar); length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) val = digest_crc32(val , buf, (unsigned) nChar); } sprintf(output, "%08x", (unsigned int) val); break; } case 104: { /* sha256 file case */ int j; sha256_context ctx; output_length = 32; unsigned char buf[BUF_SIZE]; unsigned char sha256sum[32]; if (skip > 0) fseek(fp, skip, SEEK_SET); sha256_starts ( &ctx ); if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; sha256_update( &ctx, buf, nChar ); length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) sha256_update( &ctx, buf, nChar ); } sha256_finish ( &ctx, sha256sum ); memcpy(output, sha256sum, 32); if (!leaveRaw) for ( j = 0; j < 32; j++ ) sprintf( output + j * 2, "%02x", sha256sum[j] ); break; } case 105: { /* sha2-512 file case */ int j; SHA512_CTX ctx; output_length = SHA512_DIGEST_LENGTH; uint8_t sha512sum[output_length], *d = sha512sum; unsigned char buf[BUF_SIZE]; if (skip > 0) fseek(fp, skip, SEEK_SET); SHA512_Init(&ctx); if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; SHA512_Update( &ctx, buf, nChar ); length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) SHA512_Update( &ctx, buf, nChar ); } /* Calling SHA512_Final, because SHA512_End will already convert the hash to a string, and we also want RAW */ SHA512_Final(sha512sum, &ctx); memcpy(output, sha512sum, output_length); /* adapted from SHA512_End */ if (!leaveRaw) { for (j = 0; j < output_length; j++) { *outputp++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *outputp++ = sha2_hex_digits[*d & 0x0f]; d++; } *outputp = (char)0; } break; } case 106: { /* xxhash32 */ unsigned char buf[BUF_SIZE]; XXH32_state_t* const state = XXH32_createState(); if (skip > 0) fseek(fp, skip, SEEK_SET); XXH_errorcode const resetResult = XXH32_reset(state, seed); if (resetResult == XXH_ERROR) { error("Error in `XXH32_reset()`"); /* #nocov */ } if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; XXH_errorcode const updateResult = XXH32_update(state, buf, nChar); if (updateResult == XXH_ERROR) { error("Error in `XXH32_update()`"); /* #nocov */ } length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) { XXH_errorcode const updateResult = XXH32_update(state, buf, nChar); if (updateResult == XXH_ERROR) { error("Error in `XXH32_update()`"); /* #nocov */ } } } unsigned int val = XXH32_digest(state); XXH32_freeState(state); sprintf(output, "%08x", val); break; } case 107: { /* xxhash64 */ unsigned char buf[BUF_SIZE]; XXH64_state_t* const state = XXH64_createState(); if (skip > 0) fseek(fp, skip, SEEK_SET); XXH_errorcode const resetResult = XXH64_reset(state, seed); if (resetResult == XXH_ERROR) { error("Error in `XXH64_reset()`"); /* #nocov */ } if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; XXH_errorcode const updateResult = XXH64_update(state, buf, nChar); if (updateResult == XXH_ERROR) { error("Error in `XXH64_update()`"); /* #nocov */ } length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) { XXH_errorcode const updateResult = XXH64_update(state, buf, nChar); if (updateResult == XXH_ERROR) { error("Error in `XXH64_update()`"); /* #nocov */ } } } unsigned long long val = XXH64_digest(state); XXH64_freeState(state); #ifdef WIN32 sprintf(output, "%016" PRIx64, val); #else sprintf(output, "%016llx", val); #endif break; } case 108: { /* murmur32 */ unsigned int h1=seed, carry=0; unsigned char buf[BUF_SIZE]; size_t total_length = 0; if (skip > 0) fseek(fp, skip, SEEK_SET); if (length>=0) { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; PMurHash32_Process(&h1, &carry, buf, nChar); length -= nChar; total_length += nChar; } } else { while( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) { PMurHash32_Process(&h1, &carry, buf, nChar); total_length += nChar; } } unsigned int val = PMurHash32_Result(h1, carry, total_length); sprintf(output, "%08x", val); break; } case 110: { /* blake3 file case */ output_length = BLAKE3_OUT_LEN; unsigned char buf[BUF_SIZE]; uint8_t val[BLAKE3_OUT_LEN]; blake3_hasher hasher; blake3_hasher_init(&hasher); if (skip > 0) fseek(fp, skip, SEEK_SET); if (length>=0) { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0 && length>0) { if (nChar>length) nChar=length; blake3_hasher_update( &hasher, buf, nChar ); length -= nChar; } } else { while ( ( nChar = fread( buf, 1, sizeof( buf ), fp ) ) > 0) blake3_hasher_update( &hasher, buf, nChar ); } blake3_hasher_finalize(&hasher, val, BLAKE3_OUT_LEN); if (leaveRaw) { memcpy(output, val, BLAKE3_OUT_LEN); } else { for (size_t i = 0; i < BLAKE3_OUT_LEN; i++) { sprintf(output + i * 2, "%02x", val[i]); } } break; } default: { error("Unsupported algorithm code"); /* should not be reached due to test in R */ /* #nocov */ } } /* end switch */ if (algo >= 100 && fp) { fclose(fp); } if (leaveRaw && output_length > 0) { PROTECT(result=allocVector(RAWSXP, output_length)); memcpy(RAW(result), output, output_length); } else { PROTECT(result=allocVector(STRSXP, 1)); SET_STRING_ELT(result, 0, mkChar(output)); } UNPROTECT(1); return result; } SEXP vdigest(SEXP Txt, SEXP Algo, SEXP Length, SEXP Skip, SEXP Leave_raw, SEXP Seed){ R_xlen_t n = length(Txt); if (TYPEOF(Txt) == RAWSXP || n == 0) return(digest(Txt, Algo, Length, Skip, Leave_raw, Seed)); SEXP ans = PROTECT(allocVector(STRSXP, n)); SEXP d = R_NilValue; if (TYPEOF(Txt) == VECSXP){ for (R_xlen_t i = 0; i < n; i++){ d = digest(VECTOR_ELT(Txt, i), Algo, Length, Skip, Leave_raw, Seed); SET_STRING_ELT(ans, i, STRING_ELT(d, 0)); } } else { for (R_xlen_t i = 0; i < n; i++){ d = digest(STRING_ELT(Txt, i), Algo, Length, Skip, Leave_raw, Seed); SET_STRING_ELT(ans, i, STRING_ELT(d, 0)); } } UNPROTECT(1); return ans; } digest/src/sha2.c0000644000176200001440000010021013346720011013310 0ustar liggesusers/* * FILE: sha2.c * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Modified by R. Neal, 2018, to avoid mis-alignment faults. * */ #include /* memcpy()/memset() or bcopy()/bzero() */ #include /* assert() */ #include "sha2.h" /* * ASSERT NOTE: * Some sanity checking code is included using assert(). On my FreeBSD * system, this additional code can be removed by compiling with NDEBUG * defined. Check your own systems manpage on assert() to see how to * compile WITHOUT the sanity checking code on your system. * * UNROLLED TRANSFORM LOOP NOTE: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform * loop version for the hash transform rounds (defined using macros * later in this file). Either define on the command line, for example: * * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c * * or define below: * * #define SHA2_UNROLL_TRANSFORM * */ /*** SHA-256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: * * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are * equivilent. * * If your system does not define the above, then you can do so by * hand like this: * * #define LITTLE_ENDIAN 1234 * #define BIG_ENDIAN 4321 * * And for little-endian machines, add: * * #define BYTE_ORDER LITTLE_ENDIAN * * Or for big-endian machines: * * #define BYTE_ORDER BIG_ENDIAN * * The FreeBSD machine this was written on defines BYTE_ORDER * appropriately by including (which in turn includes * where the appropriate definitions are actually * made). */ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN #endif /* * Define the followingsha2_* types to types of the correct length on * the native archtecture. Most BSD systems and Linux define u_intXX_t * types. Machines with very recent ANSI C headers, can use the * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H * during compile or in the sha.h header file. * * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t * will need to define these three typedefs below (and the appropriate * ones in sha.h too) by hand according to their system architecture. * * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. */ #ifdef SHA2_USE_INTTYPES_H typedef uint8_t sha2_byte; /* Exactly 1 byte */ typedef uint32_t sha2_word32; /* Exactly 4 bytes */ typedef uint64_t sha2_word64; /* Exactly 8 bytes */ #else /* SHA2_USE_INTTYPES_H */ typedef u_int8_t sha2_byte; /* Exactly 1 byte */ typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ #endif /* SHA2_USE_INTTYPES_H */ /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ sha2_word32 tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ } #define REVERSE64(w,x) { \ sha2_word64 tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ ((tmp & 0x0000ffff0000ffffULL) << 16); \ } #endif /* BYTE_ORDER == LITTLE_ENDIAN */ /* * Macro for incrementally adding the unsigned 64-bit integer n to the * unsigned 128-bit integer (represented using a two-element array of * 64-bit words): */ #define ADDINC128(w,n) { \ (w)[0] += (sha2_word64)(n); \ if ((w)[0] < (n)) { \ (w)[1]++; \ } \ } /* * Macros for copying blocks of memory and for zeroing out ranges * of memory. Using these macros makes it easy to switch from * using memset()/memcpy() and using bzero()/bcopy(). * * Please define either SHA2_USE_MEMSET_MEMCPY or define * SHA2_USE_BZERO_BCOPY depending on which function set you * choose to use: */ #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) /* Default to memset()/memcpy() if no option is specified */ #define SHA2_USE_MEMSET_MEMCPY 1 #endif #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) /* Abort with an error if BOTH options are defined */ #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! #endif #ifdef SHA2_USE_MEMSET_MEMCPY #define MEMSET_BZERO(p,l) memset((p), 0, (l)) #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) #endif #ifdef SHA2_USE_BZERO_BCOPY #define MEMSET_BZERO(p,l) bzero((p), (l)) #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) #endif /*** THE SIX LOGICAL FUNCTIONS ****************************************/ /* * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * * NOTE: The naming of R and S appears backwards here (R is a SHIFT and * S is a ROTATION) because the SHA-256/384/512 description document * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * same "backwards" definition. */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ #define R(b,x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) /* Four of six logical functions used in SHA-256: */ #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) /*** INTERNAL FUNCTION PROTOTYPES *************************************/ /* NOTE: These should not be accessed directly from outside this * library -- they are intended for private internal visibility/use * only. */ static void SHA512_Last(SHA512_CTX*); /*static void SHA256_Transform(SHA256_CTX*);*/ static void SHA512_Transform(SHA512_CTX*); /* /\*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************\/ */ /* /\* Hash constant words K for SHA-256: *\/ */ /* const static sha2_word32 K256[64] = { */ /* 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, */ /* 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, */ /* 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, */ /* 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, */ /* 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, */ /* 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, */ /* 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, */ /* 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, */ /* 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, */ /* 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, */ /* 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, */ /* 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, */ /* 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, */ /* 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, */ /* 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, */ /* 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL */ /* }; */ /* /\* Initial hash value H for SHA-256: *\/ */ /* const static sha2_word32 sha256_initial_hash_value[8] = { */ /* 0x6a09e667UL, */ /* 0xbb67ae85UL, */ /* 0x3c6ef372UL, */ /* 0xa54ff53aUL, */ /* 0x510e527fUL, */ /* 0x9b05688cUL, */ /* 0x1f83d9abUL, */ /* 0x5be0cd19UL */ /* }; */ /* Hash constant words K for SHA-384 and SHA-512: */ const static sha2_word64 K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; /* /\* Initial hash value H for SHA-384 *\/ */ /* const static sha2_word64 sha384_initial_hash_value[8] = { */ /* 0xcbbb9d5dc1059ed8ULL, */ /* 0x629a292a367cd507ULL, */ /* 0x9159015a3070dd17ULL, */ /* 0x152fecd8f70e5939ULL, */ /* 0x67332667ffc00b31ULL, */ /* 0x8eb44a8768581511ULL, */ /* 0xdb0c2e0d64f98fa7ULL, */ /* 0x47b5481dbefa4fa4ULL */ /* }; */ /* Initial hash value H for SHA-512 */ const static sha2_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; /* * Constant used by SHA256/384/512_End() functions for converting the * digest to a readable hexadecimal character string: */ static const char *sha2_hex_digits = "0123456789abcdef"; /*** SHA-256: *********************************************************/ #if 0 void SHA256_Init(SHA256_CTX* context) { /* #nocov start */ if (context == (SHA256_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); context->bitcount = 0; } /* #nocov end */ #endif #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE32(W256[j], W256[j]); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ s0 = W256[(j+1)&0x0f]; \ s0 = sigma0_256(s0); \ s1 = W256[(j+14)&0x0f]; \ s1 = sigma1_256(s1); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #if 0 static void SHA256_Transform(SHA256_CTX* context) { sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { /* Rounds 0 to 15 (unrolled): */ ROUND256_0_TO_15(a,b,c,d,e,f,g,h); ROUND256_0_TO_15(h,a,b,c,d,e,f,g); ROUND256_0_TO_15(g,h,a,b,c,d,e,f); ROUND256_0_TO_15(f,g,h,a,b,c,d,e); ROUND256_0_TO_15(e,f,g,h,a,b,c,d); ROUND256_0_TO_15(d,e,f,g,h,a,b,c); ROUND256_0_TO_15(c,d,e,f,g,h,a,b); ROUND256_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds to 64: */ do { ROUND256(a,b,c,d,e,f,g,h); ROUND256(h,a,b,c,d,e,f,g); ROUND256(g,h,a,b,c,d,e,f); ROUND256(f,g,h,a,b,c,d,e); ROUND256(e,f,g,h,a,b,c,d); ROUND256(d,e,f,g,h,a,b,c); ROUND256(c,d,e,f,g,h,a,b); ROUND256(b,c,d,e,f,g,h,a); } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #endif #else /* SHA2_UNROLL_TRANSFORM */ #if 0 static void SHA256_Transform(SHA256_CTX* context) { // #nocov sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, T2, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* convert to host byte order */ REVERSE32(W256[j],W256[j]); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-256 compression function to update a..h with copy */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W256[(j+1)&0x0f]; s0 = sigma0_256(s0); s1 = W256[(j+14)&0x0f]; s1 = sigma1_256(s1); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } // #nocov #endif /* around SHA256_Transform */ #endif /* SHA2_UNROLL_TRANSFORM */ #if 0 void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { // #nocov unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); context->bitcount += freespace << 3; len -= freespace; data += freespace; SHA256_Transform(context); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); SHA256_Transform(context); context->bitcount += SHA256_BLOCK_LENGTH << 3; len -= SHA256_BLOCK_LENGTH; data += SHA256_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); context->bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; } // #nocov void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { // #nocov sha2_word32 *d = (sha2_word32*)digest; unsigned int usedspace; /* Sanity check: */ assert(context != (SHA256_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount,context->bitcount); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA256_BLOCK_LENGTH) { MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA256_Transform(context); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); } } else { /* Set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Set the bit count: */ /* *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; */ MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], &context->bitcount, sizeof(sha2_word64)); /* Final transform: */ SHA256_Transform(context); #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE32(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); #endif } /* Clean up state data: */ MEMSET_BZERO(context, sizeof(SHA256_CTX)); usedspace = 0; } // #nocov char *SHA256_End(SHA256_CTX* context, char buffer[]) { /* #nocov start */ sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA256_CTX*)0); if (buffer != (char*)0) { SHA256_Final(digest, context); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA256_CTX)); } MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); return buffer; } char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { SHA256_CTX context; SHA256_Init(&context); SHA256_Update(&context, data, len); return SHA256_End(&context, digest); } /* #nocov end */ #endif /* SHA256_ functions */ /*** SHA-512: *********************************************************/ void SHA512_Init(SHA512_CTX* context) { if (context == (SHA512_CTX*)0) { return; // #nocov } MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE64(W512[j], W512[j]); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ (d) += T1, \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ s0 = W512[(j+1)&0x0f]; \ s0 = sigma0_512(s0); \ s1 = W512[(j+14)&0x0f]; \ s1 = sigma1_512(s1); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ static void SHA512_Transform(SHA512_CTX* context) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { ROUND512_0_TO_15(a,b,c,d,e,f,g,h); ROUND512_0_TO_15(h,a,b,c,d,e,f,g); ROUND512_0_TO_15(g,h,a,b,c,d,e,f); ROUND512_0_TO_15(f,g,h,a,b,c,d,e); ROUND512_0_TO_15(e,f,g,h,a,b,c,d); ROUND512_0_TO_15(d,e,f,g,h,a,b,c); ROUND512_0_TO_15(c,d,e,f,g,h,a,b); ROUND512_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds up to 79: */ do { ROUND512(a,b,c,d,e,f,g,h); ROUND512(h,a,b,c,d,e,f,g); ROUND512(g,h,a,b,c,d,e,f); ROUND512(f,g,h,a,b,c,d,e); ROUND512(e,f,g,h,a,b,c,d); ROUND512(d,e,f,g,h,a,b,c); ROUND512(c,d,e,f,g,h,a,b); ROUND512(b,c,d,e,f,g,h,a); } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ static void SHA512_Transform(SHA512_CTX* context) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Convert TO host byte order */ REVERSE64(W512[j], W512[j]); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-512 compression function to update a..h with copy */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W512[(j+1)&0x0f]; s0 = sigma0_512(s0); s1 = W512[(j+14)&0x0f]; s1 = sigma1_512(s1); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; if (usedspace > 0) { /* #nocov start */ /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; SHA512_Transform(context); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; return; } } /* #nocov end */ while (len >= SHA512_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); SHA512_Transform(context); ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); len -= SHA512_BLOCK_LENGTH; data += SHA512_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); ADDINC128(context->bitcount, len << 3); } /* Clean up: */ usedspace = freespace = 0; } static void SHA512_Last(SHA512_CTX* context) { unsigned int usedspace; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount[0],context->bitcount[0]); REVERSE64(context->bitcount[1],context->bitcount[1]); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); } else { /* #nocov start */ if (usedspace < SHA512_BLOCK_LENGTH) { MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA512_Transform(context); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); } /* #nocov end */ } else { /* Prepare for final transform: */ MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Store the length of input data (in bits): */ /* *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; */ /* *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; */ MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], &context->bitcount[1], sizeof(sha2_word64)); MEMCPY_BCOPY(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8], &context->bitcount[0], sizeof(sha2_word64)); /* Final transform: */ SHA512_Transform(context); } void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA512_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(SHA512_CTX)); } char *SHA512_End(SHA512_CTX* context, char buffer[]) { /* #nocov start */ sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA512_CTX*)0); if (buffer != (char*)0) { SHA512_Final(digest, context); for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA512_CTX)); } MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); return buffer; } char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { SHA512_CTX context; SHA512_Init(&context); SHA512_Update(&context, data, len); return SHA512_End(&context, digest); } /*** SHA-384: *********************************************************/ #if 0 void SHA384_Init(SHA384_CTX* context) { if (context == (SHA384_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { SHA512_Update((SHA512_CTX*)context, data, len); } void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA384_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last((SHA512_CTX*)context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 6; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(SHA384_CTX)); } char *SHA384_End(SHA384_CTX* context, char buffer[]) { sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA384_CTX*)0); if (buffer != (char*)0) { SHA384_Final(digest, context); for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA384_CTX)); } MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); return buffer; } char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { SHA384_CTX context; SHA384_Init(&context); SHA384_Update(&context, data, len); return SHA384_End(&context, digest); } /* #nocov end */ #endif digest/src/zutil.h0000644000176200001440000000505312247504516013651 0ustar liggesusers/* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id$ */ #ifndef ZUTIL_H #define ZUTIL_H #define ZLIB_INTERNAL #include "zlib.h" #ifdef STDC # include # include # include #endif #ifdef NO_ERRNO_H extern int errno; #else # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ return (strm->msg = (char*)ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # if defined(__TURBOC__) || defined(__BORLANDC__) # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include # endif # else /* MSC or DJGPP */ # include # endif #endif #if (defined(_MSC_VER) && (_MSC_VER > 600)) # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; # define _PTRDIFF_T_DEFINED # endif # else # define fdopen(fd,type) _fdopen(fd,type) # endif #endif #endif /* ZUTIL_H */ digest/src/sha2.h0000644000176200001440000001606513343737703013350 0ustar liggesusers/* * FILE: sha2.h * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ */ #ifndef __SHA2_H__ #define __SHA2_H__ #ifdef __cplusplus extern "C" { #endif #include /* configuration settings learned when R was compiled */ /* * Import u_intXX_t size_t type definitions from system headers. You * may need to change this, or define these things yourself in this * file. */ #include #ifdef SHA2_USE_INTTYPES_H #include #endif /* SHA2_USE_INTTYPES_H */ /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) #define SHA384_BLOCK_LENGTH 128 #define SHA384_DIGEST_LENGTH 48 #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) #define SHA512_BLOCK_LENGTH 128 #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) /*** SHA-256/384/512 Context Structures *******************************/ /* NOTE: If your architecture does not define either u_intXX_t types or * uintXX_t (from inttypes.h), you may need to define things by hand * for your system: */ // edd 24 Nov 2012 -- gcc on Windows does not know u_int_{8,32,64}_t #define SHA2_USE_INTTYPES_H 1 #include #ifdef WIN32 #ifndef BYTE_ORDER #define LITTLE_ENDIAN 1234 #define BIG_ENDIAN 4321 #define BYTE_ORDER LITTLE_ENDIAN #endif #endif // edd 02 Dec 2013 use Rconfig.h to define BYTE_ORDER, unless already defined #ifndef BYTE_ORDER // see sha2.c comments, and on the internet at large #define LITTLE_ENDIAN 1234 #define BIG_ENDIAN 4321 #ifdef WORDS_BIGENDIAN #define BYTE_ORDER BIG_ENDIAN #else #define BYTE_ORDER LITTLE_ENDIAN #endif #endif #if 0 typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ #endif /* * Most BSD systems already define u_intXX_t types, as does Linux. * Some systems, however, like Compaq's Tru64 Unix instead can use * uintXX_t types defined by very recent ANSI C standards and included * in the file: * * #include * * If you choose to use then please define: * * #define SHA2_USE_INTTYPES_H * * Or on the command line during compile: * * cc -DSHA2_USE_INTTYPES_H ... */ #ifdef SHA2_USE_INTTYPES_H typedef struct _SHA256_CTX { uint32_t state[8]; uint64_t bitcount; uint8_t buffer[SHA256_BLOCK_LENGTH]; /* must be 32-bit aligned */ } SHA256_CTX; typedef struct _SHA512_CTX { uint64_t state[8]; uint64_t bitcount[2]; uint8_t buffer[SHA512_BLOCK_LENGTH]; /* must be 64-bit aligned */ } SHA512_CTX; #else /* SHA2_USE_INTTYPES_H */ typedef struct _SHA256_CTX { u_int32_t state[8]; u_int64_t bitcount; u_int8_t buffer[SHA256_BLOCK_LENGTH]; /* must be 32-bit aligned */ } SHA256_CTX; typedef struct _SHA512_CTX { u_int64_t state[8]; u_int64_t bitcount[2]; u_int8_t buffer[SHA512_BLOCK_LENGTH]; /* must be 64-bit aligned */ } SHA512_CTX; #endif /* SHA2_USE_INTTYPES_H */ typedef SHA512_CTX SHA384_CTX; /*** SHA-256/384/512 Function Prototypes ******************************/ #ifndef NOPROTO #ifdef SHA2_USE_INTTYPES_H void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #else /* SHA2_USE_INTTYPES_H */ void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #endif /* SHA2_USE_INTTYPES_H */ #else /* NOPROTO */ void SHA256_Init(); void SHA256_Update(); void SHA256_Final(); char* SHA256_End(); char* SHA256_Data(); void SHA384_Init(); void SHA384_Update(); void SHA384_Final(); char* SHA384_End(); char* SHA384_Data(); void SHA512_Init(); void SHA512_Update(); void SHA512_Final(); char* SHA512_End(); char* SHA512_Data(); #endif /* NOPROTO */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __SHA2_H__ */ digest/src/Makevars0000644000176200001440000000002113464677426014030 0ustar liggesusers CXX_STD = CXX11 digest/src/blake3_dispatch.c0000755000176200001440000001717213743560000015515 0ustar liggesusers/* blake3 license: * The C code is copyright Samuel Neves and Jack O'Connor, 2019-2020. * This work is released into the public domain with CC0 1.0. * Alternatively, it is licensed under the Apache License 2.0. * For full license see * https://raw.githubusercontent.com/BLAKE3-team/BLAKE3/master/LICENSE */ #include #include #include #include "blake3_impl.h" // Commenting out this block as intrinic headers are not need or used // and the 'non-MSC and non-GNU' leads to an error on Solaris // #if defined(IS_X86) // #if defined(_MSC_VER) // #include // #elif defined(__GNUC__) // #include // #else // #error "Unimplemented!" // #endif // #endif // This function is disabled in this R package for now // #if defined(IS_X86) // static uint64_t xgetbv() { // #if defined(_MSC_VER) // return _xgetbv(0); // #else // uint32_t eax = 0, edx = 0; // __asm__ __volatile__("xgetbv\n" : "=a"(eax), "=d"(edx) : "c"(0)); // return ((uint64_t)edx << 32) | eax; // #endif // } // // static void cpuid(uint32_t out[4], uint32_t id) { // #if defined(_MSC_VER) // __cpuid((int *)out, id); // #elif defined(__i386__) || defined(_M_IX86) // __asm__ __volatile__("movl %%ebx, %1\n" // "cpuid\n" // "xchgl %1, %%ebx\n" // : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) // : "a"(id)); // #else // __asm__ __volatile__("cpuid\n" // : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) // : "a"(id)); // #endif // } // // static void cpuidex(uint32_t out[4], uint32_t id, uint32_t sid) { // #if defined(_MSC_VER) // __cpuidex((int *)out, id, sid); // #elif defined(__i386__) || defined(_M_IX86) // __asm__ __volatile__("movl %%ebx, %1\n" // "cpuid\n" // "xchgl %1, %%ebx\n" // : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) // : "a"(id), "c"(sid)); // #else // __asm__ __volatile__("cpuid\n" // : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) // : "a"(id), "c"(sid)); // #endif // } // // #endif enum cpu_feature { SSE2 = 1 << 0, SSSE3 = 1 << 1, SSE41 = 1 << 2, AVX = 1 << 3, AVX2 = 1 << 4, AVX512F = 1 << 5, AVX512VL = 1 << 6, /* ... */ UNDEFINED = 1 << 30 }; // This function is disabled in this R package for now // #if !defined(BLAKE3_TESTING) // static /* Allow the variable to be controlled manually for testing */ // #endif // enum cpu_feature g_cpu_features = UNDEFINED; // // #if !defined(BLAKE3_TESTING) // static // #endif // enum cpu_feature // get_cpu_features() { // // if (g_cpu_features != UNDEFINED) { // return g_cpu_features; // } else { // #if defined(IS_X86) // uint32_t regs[4] = {0}; // uint32_t *eax = ®s[0], *ebx = ®s[1], *ecx = ®s[2], *edx = ®s[3]; // (void)edx; // enum cpu_feature features = 0; // cpuid(regs, 0); // const int max_id = *eax; // cpuid(regs, 1); // #if defined(__amd64__) || defined(_M_X64) // features |= SSE2; // #else // if (*edx & (1UL << 26)) // features |= SSE2; // #endif // if (*ecx & (1UL << 0)) // features |= SSSE3; // if (*ecx & (1UL << 19)) // features |= SSE41; // // if (*ecx & (1UL << 27)) { // OSXSAVE // const uint64_t mask = xgetbv(); // if ((mask & 6) == 6) { // SSE and AVX states // if (*ecx & (1UL << 28)) // features |= AVX; // if (max_id >= 7) { // cpuidex(regs, 7, 0); // if (*ebx & (1UL << 5)) // features |= AVX2; // if ((mask & 224) == 224) { // Opmask, ZMM_Hi256, Hi16_Zmm // if (*ebx & (1UL << 31)) // features |= AVX512VL; // if (*ebx & (1UL << 16)) // features |= AVX512F; // } // } // } // } // g_cpu_features = features; // return features; // #else // /* How to detect NEON? */ // return 0; // #endif // } // } void blake3_compress_in_place(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags) { #if defined(IS_X86) // const enum cpu_feature features = get_cpu_features(); // never true for this R package #if !defined(BLAKE3_NO_AVX512) if (features & AVX512VL) { blake3_compress_in_place_avx512(cv, block, block_len, counter, flags); return; } #endif #if !defined(BLAKE3_NO_SSE41) if (features & SSE41) { blake3_compress_in_place_sse41(cv, block, block_len, counter, flags); return; } #endif #endif blake3_compress_in_place_portable(cv, block, block_len, counter, flags); } void blake3_compress_xof(const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags, uint8_t out[64]) { #if defined(IS_X86) // const enum cpu_feature features = get_cpu_features(); // never true for this R package #if !defined(BLAKE3_NO_AVX512) if (features & AVX512VL) { blake3_compress_xof_avx512(cv, block, block_len, counter, flags, out); return; } #endif #if !defined(BLAKE3_NO_SSE41) if (features & SSE41) { blake3_compress_xof_sse41(cv, block, block_len, counter, flags, out); return; } #endif #endif blake3_compress_xof_portable(cv, block, block_len, counter, flags, out); } void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out) { #if defined(IS_X86) // const enum cpu_feature features = get_cpu_features(); // never true for this R package #if !defined(BLAKE3_NO_AVX512) if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) { blake3_hash_many_avx512(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out); return; } #endif #if !defined(BLAKE3_NO_AVX2) if (features & AVX2) { blake3_hash_many_avx2(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out); return; } #endif #if !defined(BLAKE3_NO_SSE41) if (features & SSE41) { blake3_hash_many_sse41(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out); return; } #endif #endif #if defined(BLAKE3_USE_NEON) blake3_hash_many_neon(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out); return; #endif blake3_hash_many_portable(inputs, num_inputs, blocks, key, counter, increment_counter, flags, flags_start, flags_end, out); } // The dynamically detected SIMD degree of the current platform. size_t blake3_simd_degree(void) { #if defined(IS_X86) // const enum cpu_feature features = get_cpu_features(); // never true for this R package #if !defined(BLAKE3_NO_AVX512) if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) { return 16; } #endif #if !defined(BLAKE3_NO_AVX2) if (features & AVX2) { return 8; } #endif #if !defined(BLAKE3_NO_SSE41) if (features & SSE41) { return 4; } #endif #endif #if defined(BLAKE3_USE_NEON) return 4; #endif return 1; } digest/src/zconf.h0000644000176200001440000002217512247504516013625 0ustar liggesusers/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2004 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #ifndef ZCONF_H #define ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ #ifdef Z_PREFIX # define deflateInit_ z_deflateInit_ # define deflate z_deflate # define deflateEnd z_deflateEnd # define inflateInit_ z_inflateInit_ # define inflate z_inflate # define inflateEnd z_inflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateSetDictionary z_deflateSetDictionary # define deflateCopy z_deflateCopy # define deflateReset z_deflateReset # define deflateParams z_deflateParams # define deflateBound z_deflateBound # define deflatePrime z_deflatePrime # define inflateInit2_ z_inflateInit2_ # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateCopy z_inflateCopy # define inflateReset z_inflateReset # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound # define uncompress z_uncompress # define adler32 z_adler32 # define crc32 z_crc32 # define get_crc_table z_get_crc_table # define zError z_zError # define Byte z_Byte # define uInt z_uInt # define uLong z_uLong # define Bytef z_Bytef # define charf z_charf # define intf z_intf # define uIntf z_uIntf # define uLongf z_uLongf # define voidpf z_voidpf # define voidp z_voidp #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) # define WIN32 #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ # include /* for off_t */ # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ # endif # define z_off_t off_t #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if defined(__OS400__) # define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf # ifdef FAR # undef FAR # endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) # pragma map(deflateInit_,"DEIN") # pragma map(deflateInit2_,"DEIN2") # pragma map(deflateEnd,"DEEND") # pragma map(deflateBound,"DEBND") # pragma map(inflateInit_,"ININ") # pragma map(inflateInit2_,"ININ2") # pragma map(inflateEnd,"INEND") # pragma map(inflateSync,"INSY") # pragma map(inflateSetDictionary,"INSEDI") # pragma map(compressBound,"CMBND") # pragma map(inflate_table,"INTABL") # pragma map(inflate_fast,"INFA") # pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ digest/src/blake3.c0000755000176200001440000006463413661213637013655 0ustar liggesusers/* blake3 license: * The C code is copyright Samuel Neves and Jack O'Connor, 2019-2020. * This work is released into the public domain with CC0 1.0. * Alternatively, it is licensed under the Apache License 2.0. * For full license see * https://raw.githubusercontent.com/BLAKE3-team/BLAKE3/master/LICENSE */ #include #include #include #include "blake3.h" #include "blake3_impl.h" INLINE void chunk_state_init(blake3_chunk_state *self, const uint32_t key[8], uint8_t flags) { memcpy(self->cv, key, BLAKE3_KEY_LEN); self->chunk_counter = 0; memset(self->buf, 0, BLAKE3_BLOCK_LEN); self->buf_len = 0; self->blocks_compressed = 0; self->flags = flags; } INLINE void chunk_state_reset(blake3_chunk_state *self, const uint32_t key[8], uint64_t chunk_counter) { memcpy(self->cv, key, BLAKE3_KEY_LEN); self->chunk_counter = chunk_counter; self->blocks_compressed = 0; memset(self->buf, 0, BLAKE3_BLOCK_LEN); self->buf_len = 0; } INLINE size_t chunk_state_len(const blake3_chunk_state *self) { return (BLAKE3_BLOCK_LEN * (size_t)self->blocks_compressed) + ((size_t)self->buf_len); } INLINE size_t chunk_state_fill_buf(blake3_chunk_state *self, const uint8_t *input, size_t input_len) { size_t take = BLAKE3_BLOCK_LEN - ((size_t)self->buf_len); if (take > input_len) { take = input_len; } uint8_t *dest = self->buf + ((size_t)self->buf_len); memcpy(dest, input, take); self->buf_len += (uint8_t)take; return take; } INLINE uint8_t chunk_state_maybe_start_flag(const blake3_chunk_state *self) { if (self->blocks_compressed == 0) { return CHUNK_START; } else { return 0; } } typedef struct { uint32_t input_cv[8]; uint64_t counter; uint8_t block[BLAKE3_BLOCK_LEN]; uint8_t block_len; uint8_t flags; } output_t; INLINE output_t make_output(const uint32_t input_cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags) { output_t ret; memcpy(ret.input_cv, input_cv, 32); memcpy(ret.block, block, BLAKE3_BLOCK_LEN); ret.block_len = block_len; ret.counter = counter; ret.flags = flags; return ret; } // Chaining values within a given chunk (specifically the compress_in_place // interface) are represented as words. This avoids unnecessary bytes<->words // conversion overhead in the portable implementation. However, the hash_many // interface handles both user input and parent node blocks, so it accepts // bytes. For that reason, chaining values in the CV stack are represented as // bytes. INLINE void output_chaining_value(const output_t *self, uint8_t cv[32]) { uint32_t cv_words[8]; memcpy(cv_words, self->input_cv, 32); blake3_compress_in_place(cv_words, self->block, self->block_len, self->counter, self->flags); memcpy(cv, cv_words, 32); } INLINE void output_root_bytes(const output_t *self, uint64_t seek, uint8_t *out, size_t out_len) { uint64_t output_block_counter = seek / 64; size_t offset_within_block = seek % 64; uint8_t wide_buf[64]; while (out_len > 0) { blake3_compress_xof(self->input_cv, self->block, self->block_len, output_block_counter, self->flags | ROOT, wide_buf); size_t available_bytes = 64 - offset_within_block; size_t memcpy_len; if (out_len > available_bytes) { memcpy_len = available_bytes; } else { memcpy_len = out_len; } memcpy(out, wide_buf + offset_within_block, memcpy_len); out += memcpy_len; out_len -= memcpy_len; output_block_counter += 1; offset_within_block = 0; } } INLINE void chunk_state_update(blake3_chunk_state *self, const uint8_t *input, size_t input_len) { if (self->buf_len > 0) { size_t take = chunk_state_fill_buf(self, input, input_len); input += take; input_len -= take; if (input_len > 0) { blake3_compress_in_place( self->cv, self->buf, BLAKE3_BLOCK_LEN, self->chunk_counter, self->flags | chunk_state_maybe_start_flag(self)); self->blocks_compressed += 1; self->buf_len = 0; memset(self->buf, 0, BLAKE3_BLOCK_LEN); } } while (input_len > BLAKE3_BLOCK_LEN) { blake3_compress_in_place(self->cv, input, BLAKE3_BLOCK_LEN, self->chunk_counter, self->flags | chunk_state_maybe_start_flag(self)); self->blocks_compressed += 1; input += BLAKE3_BLOCK_LEN; input_len -= BLAKE3_BLOCK_LEN; } size_t take = chunk_state_fill_buf(self, input, input_len); input += take; input_len -= take; } INLINE output_t chunk_state_output(const blake3_chunk_state *self) { uint8_t block_flags = self->flags | chunk_state_maybe_start_flag(self) | CHUNK_END; return make_output(self->cv, self->buf, self->buf_len, self->chunk_counter, block_flags); } INLINE output_t parent_output(const uint8_t block[BLAKE3_BLOCK_LEN], const uint32_t key[8], uint8_t flags) { return make_output(key, block, BLAKE3_BLOCK_LEN, 0, flags | PARENT); } // Given some input larger than one chunk, return the number of bytes that // should go in the left subtree. This is the largest power-of-2 number of // chunks that leaves at least 1 byte for the right subtree. INLINE size_t left_len(size_t content_len) { // Subtract 1 to reserve at least one byte for the right side. content_len // should always be greater than BLAKE3_CHUNK_LEN. size_t full_chunks = (content_len - 1) / BLAKE3_CHUNK_LEN; return round_down_to_power_of_2(full_chunks) * BLAKE3_CHUNK_LEN; } // Use SIMD parallelism to hash up to MAX_SIMD_DEGREE chunks at the same time // on a single thread. Write out the chunk chaining values and return the // number of chunks hashed. These chunks are never the root and never empty; // those cases use a different codepath. INLINE size_t compress_chunks_parallel(const uint8_t *input, size_t input_len, const uint32_t key[8], uint64_t chunk_counter, uint8_t flags, uint8_t *out) { #if defined(BLAKE3_TESTING) assert(0 < input_len); assert(input_len <= MAX_SIMD_DEGREE * BLAKE3_CHUNK_LEN); #endif const uint8_t *chunks_array[MAX_SIMD_DEGREE]; size_t input_position = 0; size_t chunks_array_len = 0; while (input_len - input_position >= BLAKE3_CHUNK_LEN) { chunks_array[chunks_array_len] = &input[input_position]; input_position += BLAKE3_CHUNK_LEN; chunks_array_len += 1; } blake3_hash_many(chunks_array, chunks_array_len, BLAKE3_CHUNK_LEN / BLAKE3_BLOCK_LEN, key, chunk_counter, true, flags, CHUNK_START, CHUNK_END, out); // Hash the remaining partial chunk, if there is one. Note that the empty // chunk (meaning the empty message) is a different codepath. if (input_len > input_position) { uint64_t counter = chunk_counter + (uint64_t)chunks_array_len; blake3_chunk_state chunk_state; chunk_state_init(&chunk_state, key, flags); chunk_state.chunk_counter = counter; chunk_state_update(&chunk_state, &input[input_position], input_len - input_position); output_t output = chunk_state_output(&chunk_state); output_chaining_value(&output, &out[chunks_array_len * BLAKE3_OUT_LEN]); return chunks_array_len + 1; } else { return chunks_array_len; } } // Use SIMD parallelism to hash up to MAX_SIMD_DEGREE parents at the same time // on a single thread. Write out the parent chaining values and return the // number of parents hashed. (If there's an odd input chaining value left over, // return it as an additional output.) These parents are never the root and // never empty; those cases use a different codepath. INLINE size_t compress_parents_parallel(const uint8_t *child_chaining_values, size_t num_chaining_values, const uint32_t key[8], uint8_t flags, uint8_t *out) { #if defined(BLAKE3_TESTING) assert(2 <= num_chaining_values); assert(num_chaining_values <= 2 * MAX_SIMD_DEGREE_OR_2); #endif const uint8_t *parents_array[MAX_SIMD_DEGREE_OR_2]; size_t parents_array_len = 0; while (num_chaining_values - (2 * parents_array_len) >= 2) { parents_array[parents_array_len] = &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN]; parents_array_len += 1; } blake3_hash_many(parents_array, parents_array_len, 1, key, 0, // Parents always use counter 0. false, flags | PARENT, 0, // Parents have no start flags. 0, // Parents have no end flags. out); // If there's an odd child left over, it becomes an output. if (num_chaining_values > 2 * parents_array_len) { memcpy(&out[parents_array_len * BLAKE3_OUT_LEN], &child_chaining_values[2 * parents_array_len * BLAKE3_OUT_LEN], BLAKE3_OUT_LEN); return parents_array_len + 1; } else { return parents_array_len; } } // The wide helper function returns (writes out) an array of chaining values // and returns the length of that array. The number of chaining values returned // is the dyanmically detected SIMD degree, at most MAX_SIMD_DEGREE. Or fewer, // if the input is shorter than that many chunks. The reason for maintaining a // wide array of chaining values going back up the tree, is to allow the // implementation to hash as many parents in parallel as possible. // // As a special case when the SIMD degree is 1, this function will still return // at least 2 outputs. This guarantees that this function doesn't perform the // root compression. (If it did, it would use the wrong flags, and also we // wouldn't be able to implement exendable ouput.) Note that this function is // not used when the whole input is only 1 chunk long; that's a different // codepath. // // Why not just have the caller split the input on the first update(), instead // of implementing this special rule? Because we don't want to limit SIMD or // multi-threading parallelism for that update(). static size_t blake3_compress_subtree_wide(const uint8_t *input, size_t input_len, const uint32_t key[8], uint64_t chunk_counter, uint8_t flags, uint8_t *out) { // Note that the single chunk case does *not* bump the SIMD degree up to 2 // when it is 1. If this implementation adds multi-threading in the future, // this gives us the option of multi-threading even the 2-chunk case, which // can help performance on smaller platforms. if (input_len <= blake3_simd_degree() * BLAKE3_CHUNK_LEN) { return compress_chunks_parallel(input, input_len, key, chunk_counter, flags, out); } // With more than simd_degree chunks, we need to recurse. Start by dividing // the input into left and right subtrees. (Note that this is only optimal // as long as the SIMD degree is a power of 2. If we ever get a SIMD degree // of 3 or something, we'll need a more complicated strategy.) size_t left_input_len = left_len(input_len); size_t right_input_len = input_len - left_input_len; const uint8_t *right_input = &input[left_input_len]; uint64_t right_chunk_counter = chunk_counter + (uint64_t)(left_input_len / BLAKE3_CHUNK_LEN); // Make space for the child outputs. Here we use MAX_SIMD_DEGREE_OR_2 to // account for the special case of returning 2 outputs when the SIMD degree // is 1. uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN]; size_t degree = blake3_simd_degree(); if (left_input_len > BLAKE3_CHUNK_LEN && degree == 1) { // The special case: We always use a degree of at least two, to make // sure there are two outputs. Except, as noted above, at the chunk // level, where we allow degree=1. (Note that the 1-chunk-input case is // a different codepath.) degree = 2; } uint8_t *right_cvs = &cv_array[degree * BLAKE3_OUT_LEN]; // Recurse! If this implementation adds multi-threading support in the // future, this is where it will go. size_t left_n = blake3_compress_subtree_wide(input, left_input_len, key, chunk_counter, flags, cv_array); size_t right_n = blake3_compress_subtree_wide( right_input, right_input_len, key, right_chunk_counter, flags, right_cvs); // The special case again. If simd_degree=1, then we'll have left_n=1 and // right_n=1. Rather than compressing them into a single output, return // them directly, to make sure we always have at least two outputs. if (left_n == 1) { memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN); return 2; } // Otherwise, do one layer of parent node compression. size_t num_chaining_values = left_n + right_n; return compress_parents_parallel(cv_array, num_chaining_values, key, flags, out); } // Hash a subtree with compress_subtree_wide(), and then condense the resulting // list of chaining values down to a single parent node. Don't compress that // last parent node, however. Instead, return its message bytes (the // concatenated chaining values of its children). This is necessary when the // first call to update() supplies a complete subtree, because the topmost // parent node of that subtree could end up being the root. It's also necessary // for extended output in the general case. // // As with compress_subtree_wide(), this function is not used on inputs of 1 // chunk or less. That's a different codepath. INLINE void compress_subtree_to_parent_node( const uint8_t *input, size_t input_len, const uint32_t key[8], uint64_t chunk_counter, uint8_t flags, uint8_t out[2 * BLAKE3_OUT_LEN]) { #if defined(BLAKE3_TESTING) assert(input_len > BLAKE3_CHUNK_LEN); #endif uint8_t cv_array[2 * MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN]; size_t num_cvs = blake3_compress_subtree_wide(input, input_len, key, chunk_counter, flags, cv_array); // If MAX_SIMD_DEGREE is greater than 2 and there's enough input, // compress_subtree_wide() returns more than 2 chaining values. Condense // them into 2 by forming parent nodes repeatedly. uint8_t out_array[MAX_SIMD_DEGREE_OR_2 * BLAKE3_OUT_LEN / 2]; while (num_cvs > 2) { num_cvs = compress_parents_parallel(cv_array, num_cvs, key, flags, out_array); memcpy(cv_array, out_array, num_cvs * BLAKE3_OUT_LEN); } memcpy(out, cv_array, 2 * BLAKE3_OUT_LEN); } INLINE void hasher_init_base(blake3_hasher *self, const uint32_t key[8], uint8_t flags) { memcpy(self->key, key, BLAKE3_KEY_LEN); chunk_state_init(&self->chunk, key, flags); self->cv_stack_len = 0; } void blake3_hasher_init(blake3_hasher *self) { hasher_init_base(self, IV, 0); } void blake3_hasher_init_keyed(blake3_hasher *self, const uint8_t key[BLAKE3_KEY_LEN]) { uint32_t key_words[8]; load_key_words(key, key_words); hasher_init_base(self, key_words, KEYED_HASH); } void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context) { blake3_hasher context_hasher; hasher_init_base(&context_hasher, IV, DERIVE_KEY_CONTEXT); blake3_hasher_update(&context_hasher, context, strlen(context)); uint8_t context_key[BLAKE3_KEY_LEN]; blake3_hasher_finalize(&context_hasher, context_key, BLAKE3_KEY_LEN); uint32_t context_key_words[8]; load_key_words(context_key, context_key_words); hasher_init_base(self, context_key_words, DERIVE_KEY_MATERIAL); } // As described in hasher_push_cv() below, we do "lazy merging", delaying // merges until right before the next CV is about to be added. This is // different from the reference implementation. Another difference is that we // aren't always merging 1 chunk at a time. Instead, each CV might represent // any power-of-two number of chunks, as long as the smaller-above-larger stack // order is maintained. Instead of the "count the trailing 0-bits" algorithm // described in the spec, we use a "count the total number of 1-bits" variant // that doesn't require us to retain the subtree size of the CV on top of the // stack. The principle is the same: each CV that should remain in the stack is // represented by a 1-bit in the total number of chunks (or bytes) so far. INLINE void hasher_merge_cv_stack(blake3_hasher *self, uint64_t total_len) { size_t post_merge_stack_len = (size_t)popcnt(total_len); while (self->cv_stack_len > post_merge_stack_len) { uint8_t *parent_node = &self->cv_stack[(self->cv_stack_len - 2) * BLAKE3_OUT_LEN]; output_t output = parent_output(parent_node, self->key, self->chunk.flags); output_chaining_value(&output, parent_node); self->cv_stack_len -= 1; } } // In reference_impl.rs, we merge the new CV with existing CVs from the stack // before pushing it. We can do that because we know more input is coming, so // we know none of the merges are root. // // This setting is different. We want to feed as much input as possible to // compress_subtree_wide(), without setting aside anything for the chunk_state. // If the user gives us 64 KiB, we want to parallelize over all 64 KiB at once // as a single subtree, if at all possible. // // This leads to two problems: // 1) This 64 KiB input might be the only call that ever gets made to update. // In this case, the root node of the 64 KiB subtree would be the root node // of the whole tree, and it would need to be ROOT finalized. We can't // compress it until we know. // 2) This 64 KiB input might complete a larger tree, whose root node is // similarly going to be the the root of the whole tree. For example, maybe // we have 196 KiB (that is, 128 + 64) hashed so far. We can't compress the // node at the root of the 256 KiB subtree until we know how to finalize it. // // The second problem is solved with "lazy merging". That is, when we're about // to add a CV to the stack, we don't merge it with anything first, as the // reference impl does. Instead we do merges using the *previous* CV that was // added, which is sitting on top of the stack, and we put the new CV // (unmerged) on top of the stack afterwards. This guarantees that we never // merge the root node until finalize(). // // Solving the first problem requires an additional tool, // compress_subtree_to_parent_node(). That function always returns the top // *two* chaining values of the subtree it's compressing. We then do lazy // merging with each of them separately, so that the second CV will always // remain unmerged. (That also helps us support extendable output when we're // hashing an input all-at-once.) INLINE void hasher_push_cv(blake3_hasher *self, uint8_t new_cv[BLAKE3_OUT_LEN], uint64_t chunk_counter) { hasher_merge_cv_stack(self, chunk_counter); memcpy(&self->cv_stack[self->cv_stack_len * BLAKE3_OUT_LEN], new_cv, BLAKE3_OUT_LEN); self->cv_stack_len += 1; } void blake3_hasher_update(blake3_hasher *self, const void *input, size_t input_len) { // Explicitly checking for zero avoids causing UB by passing a null pointer // to memcpy. This comes up in practice with things like: // std::vector v; // blake3_hasher_update(&hasher, v.data(), v.size()); if (input_len == 0) { return; } const uint8_t *input_bytes = (const uint8_t *)input; // If we have some partial chunk bytes in the internal chunk_state, we need // to finish that chunk first. if (chunk_state_len(&self->chunk) > 0) { size_t take = BLAKE3_CHUNK_LEN - chunk_state_len(&self->chunk); if (take > input_len) { take = input_len; } chunk_state_update(&self->chunk, input_bytes, take); input_bytes += take; input_len -= take; // If we've filled the current chunk and there's more coming, finalize this // chunk and proceed. In this case we know it's not the root. if (input_len > 0) { output_t output = chunk_state_output(&self->chunk); uint8_t chunk_cv[32]; output_chaining_value(&output, chunk_cv); hasher_push_cv(self, chunk_cv, self->chunk.chunk_counter); chunk_state_reset(&self->chunk, self->key, self->chunk.chunk_counter + 1); } else { return; } } // Now the chunk_state is clear, and we have more input. If there's more than // a single chunk (so, definitely not the root chunk), hash the largest whole // subtree we can, with the full benefits of SIMD (and maybe in the future, // multi-threading) parallelism. Two restrictions: // - The subtree has to be a power-of-2 number of chunks. Only subtrees along // the right edge can be incomplete, and we don't know where the right edge // is going to be until we get to finalize(). // - The subtree must evenly divide the total number of chunks up until this // point (if total is not 0). If the current incomplete subtree is only // waiting for 1 more chunk, we can't hash a subtree of 4 chunks. We have // to complete the current subtree first. // Because we might need to break up the input to form powers of 2, or to // evenly divide what we already have, this part runs in a loop. while (input_len > BLAKE3_CHUNK_LEN) { size_t subtree_len = round_down_to_power_of_2(input_len); uint64_t count_so_far = self->chunk.chunk_counter * BLAKE3_CHUNK_LEN; // Shrink the subtree_len until it evenly divides the count so far. We know // that subtree_len itself is a power of 2, so we can use a bitmasking // trick instead of an actual remainder operation. (Note that if the caller // consistently passes power-of-2 inputs of the same size, as is hopefully // typical, this loop condition will always fail, and subtree_len will // always be the full length of the input.) // // An aside: We don't have to shrink subtree_len quite this much. For // example, if count_so_far is 1, we could pass 2 chunks to // compress_subtree_to_parent_node. Since we'll get 2 CVs back, we'll still // get the right answer in the end, and we might get to use 2-way SIMD // parallelism. The problem with this optimization, is that it gets us // stuck always hashing 2 chunks. The total number of chunks will remain // odd, and we'll never graduate to higher degrees of parallelism. See // https://github.com/BLAKE3-team/BLAKE3/issues/69. while ((((uint64_t)(subtree_len - 1)) & count_so_far) != 0) { subtree_len /= 2; } // The shrunken subtree_len might now be 1 chunk long. If so, hash that one // chunk by itself. Otherwise, compress the subtree into a pair of CVs. uint64_t subtree_chunks = subtree_len / BLAKE3_CHUNK_LEN; if (subtree_len <= BLAKE3_CHUNK_LEN) { blake3_chunk_state chunk_state; chunk_state_init(&chunk_state, self->key, self->chunk.flags); chunk_state.chunk_counter = self->chunk.chunk_counter; chunk_state_update(&chunk_state, input_bytes, subtree_len); output_t output = chunk_state_output(&chunk_state); uint8_t cv[BLAKE3_OUT_LEN]; output_chaining_value(&output, cv); hasher_push_cv(self, cv, chunk_state.chunk_counter); } else { // This is the high-performance happy path, though getting here depends // on the caller giving us a long enough input. uint8_t cv_pair[2 * BLAKE3_OUT_LEN]; compress_subtree_to_parent_node(input_bytes, subtree_len, self->key, self->chunk.chunk_counter, self->chunk.flags, cv_pair); hasher_push_cv(self, cv_pair, self->chunk.chunk_counter); hasher_push_cv(self, &cv_pair[BLAKE3_OUT_LEN], self->chunk.chunk_counter + (subtree_chunks / 2)); } self->chunk.chunk_counter += subtree_chunks; input_bytes += subtree_len; input_len -= subtree_len; } // If there's any remaining input less than a full chunk, add it to the chunk // state. In that case, also do a final merge loop to make sure the subtree // stack doesn't contain any unmerged pairs. The remaining input means we // know these merges are non-root. This merge loop isn't strictly necessary // here, because hasher_push_chunk_cv already does its own merge loop, but it // simplifies blake3_hasher_finalize below. if (input_len > 0) { chunk_state_update(&self->chunk, input_bytes, input_len); hasher_merge_cv_stack(self, self->chunk.chunk_counter); } } void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out, size_t out_len) { blake3_hasher_finalize_seek(self, 0, out, out_len); } void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek, uint8_t *out, size_t out_len) { // Explicitly checking for zero avoids causing UB by passing a null pointer // to memcpy. This comes up in practice with things like: // std::vector v; // blake3_hasher_finalize(&hasher, v.data(), v.size()); if (out_len == 0) { return; } // If the subtree stack is empty, then the current chunk is the root. if (self->cv_stack_len == 0) { output_t output = chunk_state_output(&self->chunk); output_root_bytes(&output, seek, out, out_len); return; } // If there are any bytes in the chunk state, finalize that chunk and do a // roll-up merge between that chunk hash and every subtree in the stack. In // this case, the extra merge loop at the end of blake3_hasher_update // guarantees that none of the subtrees in the stack need to be merged with // each other first. Otherwise, if there are no bytes in the chunk state, // then the top of the stack is a chunk hash, and we start the merge from // that. output_t output; size_t cvs_remaining; if (chunk_state_len(&self->chunk) > 0) { cvs_remaining = self->cv_stack_len; output = chunk_state_output(&self->chunk); } else { // There are always at least 2 CVs in the stack in this case. cvs_remaining = self->cv_stack_len - 2; output = parent_output(&self->cv_stack[cvs_remaining * 32], self->key, self->chunk.flags); } while (cvs_remaining > 0) { cvs_remaining -= 1; uint8_t parent_block[BLAKE3_BLOCK_LEN]; memcpy(parent_block, &self->cv_stack[cvs_remaining * 32], 32); output_chaining_value(&output, &parent_block[32]); output = parent_output(parent_block, self->key, self->chunk.flags); } output_root_bytes(&output, seek, out, out_len); } digest/src/blake3_impl.h0000755000176200001440000002103713661213637014671 0ustar liggesusers/* blake3 license: * The C code is copyright Samuel Neves and Jack O'Connor, 2019-2020. * This work is released into the public domain with CC0 1.0. * Alternatively, it is licensed under the Apache License 2.0. * For full license see * https://raw.githubusercontent.com/BLAKE3-team/BLAKE3/master/LICENSE */ #ifndef BLAKE3_IMPL_H #define BLAKE3_IMPL_H #include #include #include #include #include #include "blake3.h" // internal flags enum blake3_flags { CHUNK_START = 1 << 0, CHUNK_END = 1 << 1, PARENT = 1 << 2, ROOT = 1 << 3, KEYED_HASH = 1 << 4, DERIVE_KEY_CONTEXT = 1 << 5, DERIVE_KEY_MATERIAL = 1 << 6, }; // This C implementation tries to support recent versions of GCC, Clang, and // MSVC. #if defined(_MSC_VER) #define INLINE static __forceinline #else #define INLINE static inline __attribute__((always_inline)) #endif #if defined(__x86_64__) || defined(_M_X64) #define IS_X86 #define IS_X86_64 #endif #if defined(__i386__) || defined(_M_IX86) #define IS_X86 #define IS_X86_32 #endif #if defined(IS_X86) #if defined(_MSC_VER) #include #endif #include #endif #if defined(IS_X86) #define MAX_SIMD_DEGREE 16 #elif defined(BLAKE3_USE_NEON) #define MAX_SIMD_DEGREE 4 #else #define MAX_SIMD_DEGREE 1 #endif // There are some places where we want a static size that's equal to the // MAX_SIMD_DEGREE, but also at least 2. #define MAX_SIMD_DEGREE_OR_2 (MAX_SIMD_DEGREE > 2 ? MAX_SIMD_DEGREE : 2) static const uint32_t IV[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL}; static const uint8_t MSG_SCHEDULE[7][16] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8}, {3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1}, {10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6}, {12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4}, {9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7}, {11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13}, }; /* Find index of the highest set bit */ /* x is assumed to be nonzero. */ static unsigned int highest_one(uint64_t x) { #if defined(__GNUC__) || defined(__clang__) return 63 ^ __builtin_clzll(x); #elif defined(_MSC_VER) && defined(IS_X86_64) unsigned long index; _BitScanReverse64(&index, x); return index; #elif defined(_MSC_VER) && defined(IS_X86_32) if(x >> 32) { unsigned long index; _BitScanReverse(&index, x >> 32); return 32 + index; } else { unsigned long index; _BitScanReverse(&index, x); return index; } #else unsigned int c = 0; if(x & 0xffffffff00000000ULL) { x >>= 32; c += 32; } if(x & 0x00000000ffff0000ULL) { x >>= 16; c += 16; } if(x & 0x000000000000ff00ULL) { x >>= 8; c += 8; } if(x & 0x00000000000000f0ULL) { x >>= 4; c += 4; } if(x & 0x000000000000000cULL) { x >>= 2; c += 2; } if(x & 0x0000000000000002ULL) { c += 1; } return c; #endif } // Count the number of 1 bits. INLINE unsigned int popcnt(uint64_t x) { #if defined(__GNUC__) || defined(__clang__) return __builtin_popcountll(x); #else unsigned int count = 0; while (x != 0) { count += 1; x &= x - 1; } return count; #endif } // Largest power of two less than or equal to x. As a special case, returns 1 // when x is 0. INLINE uint64_t round_down_to_power_of_2(uint64_t x) { return 1ULL << highest_one(x | 1); } INLINE uint32_t counter_low(uint64_t counter) { return (uint32_t)counter; } INLINE uint32_t counter_high(uint64_t counter) { return (uint32_t)(counter >> 32); } INLINE uint32_t load32(const void *src) { const uint8_t *p = (const uint8_t *)src; return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) | ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24); } INLINE void load_key_words(const uint8_t key[BLAKE3_KEY_LEN], uint32_t key_words[8]) { key_words[0] = load32(&key[0 * 4]); key_words[1] = load32(&key[1 * 4]); key_words[2] = load32(&key[2 * 4]); key_words[3] = load32(&key[3 * 4]); key_words[4] = load32(&key[4 * 4]); key_words[5] = load32(&key[5 * 4]); key_words[6] = load32(&key[6 * 4]); key_words[7] = load32(&key[7 * 4]); } void blake3_compress_in_place(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags); void blake3_compress_xof(const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags, uint8_t out[64]); void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out); size_t blake3_simd_degree(void); // Declarations for implementation-specific functions. void blake3_compress_in_place_portable(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags); void blake3_compress_xof_portable(const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags, uint8_t out[64]); void blake3_hash_many_portable(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out); #if defined(IS_X86) #if !defined(BLAKE3_NO_SSE41) void blake3_compress_in_place_sse41(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags); void blake3_compress_xof_sse41(const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags, uint8_t out[64]); void blake3_hash_many_sse41(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out); #endif #if !defined(BLAKE3_NO_AVX2) void blake3_hash_many_avx2(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out); #endif #if !defined(BLAKE3_NO_AVX512) void blake3_compress_in_place_avx512(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags); void blake3_compress_xof_avx512(const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint64_t counter, uint8_t flags, uint8_t out[64]); void blake3_hash_many_avx512(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out); #endif #endif #if defined(BLAKE3_USE_NEON) void blake3_hash_many_neon(const uint8_t *const *inputs, size_t num_inputs, size_t blocks, const uint32_t key[8], uint64_t counter, bool increment_counter, uint8_t flags, uint8_t flags_start, uint8_t flags_end, uint8_t *out); #endif #endif /* BLAKE3_IMPL_H */ digest/src/aes.h0000644000176200001440000000104512247504516013247 0ustar liggesusers#ifndef _AES_H #define _AES_H #ifndef uint8 #define uint8 unsigned char #endif #ifndef uint32 #define uint32 unsigned long int #endif typedef struct { uint32 erk[64]; /* encryption round keys */ uint32 drk[64]; /* decryption round keys */ int nr; /* number of rounds */ } aes_context; int aes_set_key( aes_context *ctx, uint8 *key, int nbits ); void aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); void aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); #endif /* aes.h */ digest/src/SpookyV2.h0000644000176200001440000002644413463366440014210 0ustar liggesusers// // SpookyHash: a 128-bit noncryptographic hash function // By Bob Jenkins, public domain // Oct 31 2010: alpha, framework + SpookyHash::Mix appears right // Oct 31 2011: alpha again, Mix only good to 2^^69 but rest appears right // Dec 31 2011: beta, improved Mix, tested it for 2-bit deltas // Feb 2 2012: production, same bits as beta // Feb 5 2012: adjusted definitions of uint* to be more portable // Mar 30 2012: 3 bytes/cycle, not 4. Alpha was 4 but wasn't thorough enough. // August 5 2012: SpookyV2 (different results) // Kendon Bell April 30 2019: Added counters to help with skipping first n bytes // Kendon Bell May 04 2019: Deleted original source code that doesn't get used // // Up to 3 bytes/cycle for long messages. Reasonably fast for short messages. // All 1 or 2 bit deltas achieve avalanche within 1% bias per output bit. // // This was developed for and tested on 64-bit x86-compatible processors. // It assumes the processor is little-endian. There is a macro // controlling whether unaligned reads are allowed (by default they are). // This should be an equally good hash on big-endian machines, but it will // compute different results on them than on little-endian machines. // // Google's CityHash has similar specs to SpookyHash, and CityHash is faster // on new Intel boxes. MD4 and MD5 also have similar specs, but they are orders // of magnitude slower. CRCs are two or more times slower, but unlike // SpookyHash, they have nice math for combining the CRCs of pieces to form // the CRCs of wholes. There are also cryptographic hashes, but those are even // slower than MD5. // #include #ifdef _MSC_VER # define INLINE __forceinline typedef unsigned __int64 uint64; typedef unsigned __int32 uint32; typedef unsigned __int16 uint16; typedef unsigned __int8 uint8; #else # include # define INLINE inline typedef uint64_t uint64; typedef uint32_t uint32; typedef uint16_t uint16; typedef uint8_t uint8; #endif class SpookyHash { public: // // Init: initialize the context of a SpookyHash // void Init( uint64 seed1, // any 64-bit value will do, including 0 uint64 seed2, uint8 to_skip); // different seeds produce independent hashes // // Update: add a piece of a message to a SpookyHash state // void Update( const void *message, // message fragment size_t length); // length of message fragment in bytes // // Final: compute the hash for the current SpookyHash state // // This does not modify the state; you can keep updating it afterward // // The result is the same as if SpookyHash() had been called with // all the pieces concatenated into one message. // void Final( uint64 *hash1, // out only: first 64 bits of hash value. uint64 *hash2); // out only: second 64 bits of hash value. // // left rotate a 64-bit value by k bytes // static INLINE uint64 Rot64(uint64 x, int k) { return (x << k) | (x >> (64 - k)); } // // This is used if the input is 96 bytes long or longer. // // The internal state is fully overwritten every 96 bytes. // Every input bit appears to cause at least 128 bits of entropy // before 96 other bytes are combined, when run forward or backward // For every input bit, // Two inputs differing in just that input bit // Where "differ" means xor or subtraction // And the base value is random // When run forward or backwards one Mix // I tried 3 pairs of each; they all differed by at least 212 bits. // static INLINE void Mix( const uint64 *data, uint64 &s0, uint64 &s1, uint64 &s2, uint64 &s3, uint64 &s4, uint64 &s5, uint64 &s6, uint64 &s7, uint64 &s8, uint64 &s9, uint64 &s10,uint64 &s11) { s0 += data[0]; s2 ^= s10; s11 ^= s0; s0 = Rot64(s0,11); s11 += s1; s1 += data[1]; s3 ^= s11; s0 ^= s1; s1 = Rot64(s1,32); s0 += s2; s2 += data[2]; s4 ^= s0; s1 ^= s2; s2 = Rot64(s2,43); s1 += s3; s3 += data[3]; s5 ^= s1; s2 ^= s3; s3 = Rot64(s3,31); s2 += s4; s4 += data[4]; s6 ^= s2; s3 ^= s4; s4 = Rot64(s4,17); s3 += s5; s5 += data[5]; s7 ^= s3; s4 ^= s5; s5 = Rot64(s5,28); s4 += s6; s6 += data[6]; s8 ^= s4; s5 ^= s6; s6 = Rot64(s6,39); s5 += s7; s7 += data[7]; s9 ^= s5; s6 ^= s7; s7 = Rot64(s7,57); s6 += s8; s8 += data[8]; s10 ^= s6; s7 ^= s8; s8 = Rot64(s8,55); s7 += s9; s9 += data[9]; s11 ^= s7; s8 ^= s9; s9 = Rot64(s9,54); s8 += s10; s10 += data[10]; s0 ^= s8; s9 ^= s10; s10 = Rot64(s10,22); s9 += s11; s11 += data[11]; s1 ^= s9; s10 ^= s11; s11 = Rot64(s11,46); s10 += s0; } // // Mix all 12 inputs together so that h0, h1 are a hash of them all. // // For two inputs differing in just the input bits // Where "differ" means xor or subtraction // And the base value is random, or a counting value starting at that bit // The final result will have each bit of h0, h1 flip // For every input bit, // with probability 50 +- .3% // For every pair of input bits, // with probability 50 +- 3% // // This does not rely on the last Mix() call having already mixed some. // Two iterations was almost good enough for a 64-bit result, but a // 128-bit result is reported, so End() does three iterations. // static INLINE void EndPartial( uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3, uint64 &h4, uint64 &h5, uint64 &h6, uint64 &h7, uint64 &h8, uint64 &h9, uint64 &h10,uint64 &h11) { h11+= h1; h2 ^= h11; h1 = Rot64(h1,44); h0 += h2; h3 ^= h0; h2 = Rot64(h2,15); h1 += h3; h4 ^= h1; h3 = Rot64(h3,34); h2 += h4; h5 ^= h2; h4 = Rot64(h4,21); h3 += h5; h6 ^= h3; h5 = Rot64(h5,38); h4 += h6; h7 ^= h4; h6 = Rot64(h6,33); h5 += h7; h8 ^= h5; h7 = Rot64(h7,10); h6 += h8; h9 ^= h6; h8 = Rot64(h8,13); h7 += h9; h10^= h7; h9 = Rot64(h9,38); h8 += h10; h11^= h8; h10= Rot64(h10,53); h9 += h11; h0 ^= h9; h11= Rot64(h11,42); h10+= h0; h1 ^= h10; h0 = Rot64(h0,54); } static INLINE void End( const uint64 *data, uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3, uint64 &h4, uint64 &h5, uint64 &h6, uint64 &h7, uint64 &h8, uint64 &h9, uint64 &h10,uint64 &h11) { h0 += data[0]; h1 += data[1]; h2 += data[2]; h3 += data[3]; h4 += data[4]; h5 += data[5]; h6 += data[6]; h7 += data[7]; h8 += data[8]; h9 += data[9]; h10 += data[10]; h11 += data[11]; EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); } // // The goal is for each bit of the input to expand into 128 bits of // apparent entropy before it is fully overwritten. // n trials both set and cleared at least m bits of h0 h1 h2 h3 // n: 2 m: 29 // n: 3 m: 46 // n: 4 m: 57 // n: 5 m: 107 // n: 6 m: 146 // n: 7 m: 152 // when run forwards or backwards // for all 1-bit and 2-bit diffs // with diffs defined by either xor or subtraction // with a base of all zeros plus a counter, or plus another bit, or random // static INLINE void ShortMix(uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3) { h2 = Rot64(h2,50); h2 += h3; h0 ^= h2; h3 = Rot64(h3,52); h3 += h0; h1 ^= h3; h0 = Rot64(h0,30); h0 += h1; h2 ^= h0; h1 = Rot64(h1,41); h1 += h2; h3 ^= h1; h2 = Rot64(h2,54); h2 += h3; h0 ^= h2; h3 = Rot64(h3,48); h3 += h0; h1 ^= h3; h0 = Rot64(h0,38); h0 += h1; h2 ^= h0; h1 = Rot64(h1,37); h1 += h2; h3 ^= h1; h2 = Rot64(h2,62); h2 += h3; h0 ^= h2; h3 = Rot64(h3,34); h3 += h0; h1 ^= h3; h0 = Rot64(h0,5); h0 += h1; h2 ^= h0; h1 = Rot64(h1,36); h1 += h2; h3 ^= h1; } // // Mix all 4 inputs together so that h0, h1 are a hash of them all. // // For two inputs differing in just the input bits // Where "differ" means xor or subtraction // And the base value is random, or a counting value starting at that bit // The final result will have each bit of h0, h1 flip // For every input bit, // with probability 50 +- .3% (it is probably better than that) // For every pair of input bits, // with probability 50 +- .75% (the worst case is approximately that) // static INLINE void ShortEnd(uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3) { h3 ^= h2; h2 = Rot64(h2,15); h3 += h2; h0 ^= h3; h3 = Rot64(h3,52); h0 += h3; h1 ^= h0; h0 = Rot64(h0,26); h1 += h0; h2 ^= h1; h1 = Rot64(h1,51); h2 += h1; h3 ^= h2; h2 = Rot64(h2,28); h3 += h2; h0 ^= h3; h3 = Rot64(h3,9); h0 += h3; h1 ^= h0; h0 = Rot64(h0,47); h1 += h0; h2 ^= h1; h1 = Rot64(h1,54); h2 += h1; h3 ^= h2; h2 = Rot64(h2,32); h3 += h2; h0 ^= h3; h3 = Rot64(h3,25); h0 += h3; h1 ^= h0; h0 = Rot64(h0,63); h1 += h0; } // Added by Kendon Bell 2019-04-30 // UpdateSkipCounter: update the skip counter // GetSkipCounter: get the skip counter // void UpdateSkipCounter( size_t length); // length of message fragment skipped void GetSkipCounter( uint8 *count); // length of message fragment skipped void GetToSkip( uint8 *to_skip); // value of skip parameter private: // // Short is used for messages under 192 bytes in length // Short has a low startup cost, the normal mode is good for long // keys, the cost crossover is at about 192 bytes. The two modes were // held to the same quality bar. // static void Short( const void *message, // message (array of bytes, not necessarily aligned) size_t length, // length of message (in bytes) uint64 *hash1, // in/out: in the seed, out the hash value uint64 *hash2); // in/out: in the seed, out the hash value // number of uint64's in internal state static const size_t sc_numVars = 12; // size of the internal state static const size_t sc_blockSize = sc_numVars*8; // size of buffer of unhashed data, in bytes static const size_t sc_bufSize = 2*sc_blockSize; // // sc_const: a constant which: // * is not zero // * is odd // * is a not-very-regular mix of 1's and 0's // * does not need any other special mathematical properties // static const uint64 sc_const = 0xdeadbeefdeadbeefLL; uint64 m_data[2*sc_numVars]; // unhashed data, for partial messages uint64 m_state[sc_numVars]; // internal state of the hash size_t m_length; // total length of the input so far uint8 m_remainder; // length of unhashed data stashed in m_data // Added by Kendon Bell 2019-04-30 uint8 m_skipped; // length of original message already skipped uint8 m_to_skip; // parameter for how many bytes to skip at the front of the object }; digest/src/raes.c0000644000176200001440000000473613226665522013441 0ustar liggesusers /* This is a simple R interface to Christophe Devine's AES implementation */ #include "aes.h" #include #include static aes_context ctx; void encrypt(unsigned char *key, int *len, unsigned char *text) { /* #nocov start */ aes_set_key(&ctx, key, 8*(*len)); aes_encrypt(&ctx, text, text); } void decrypt(unsigned char *key, int *len, unsigned char *code) { aes_set_key(&ctx, key, 8*(*len)); aes_decrypt(&ctx, code, code); } static void AESFinalizer(SEXP ptr) { void *ctx = R_ExternalPtrAddr(ptr); if (!ctx) return; Free(ctx); R_ClearExternalPtr(ptr); } /* #nocov end */ SEXP AESinit(SEXP key) { int nbits = 8*length(key); int status; SEXP result; aes_context *ctx; if (TYPEOF(key) != RAWSXP) error("key must be a raw vector"); /* #nocov */ if (nbits != 128 && nbits != 192 && nbits != 256) error("AES only supports 16, 24 and 32 byte keys"); /* #nocov */ ctx = (aes_context*)Calloc(sizeof(*ctx), char); status = aes_set_key(ctx, (uint8 *) RAW(key), nbits); if (status) error("AES initialization failed"); /* #nocov */ result = R_MakeExternalPtr(ctx, install("AES_context"), R_NilValue); PROTECT(result); R_RegisterCFinalizerEx(result, AESFinalizer, FALSE); UNPROTECT(1); return result; } SEXP AESencryptECB(SEXP context, SEXP text) { aes_context *ctx = R_ExternalPtrAddr(context); int len = length(text); unsigned char *block; if (!ctx) error("AES context not initialized"); /* #nocov */ if (TYPEOF(text) != RAWSXP) error("Text must be a raw vector"); /* #nocov */ if (len % 16) error("Text length must be a multiple of 16 bytes"); /* #nocov */ if (MAYBE_REFERENCED(text)) text = duplicate(text); block = RAW(text); while (len > 0) { aes_encrypt(ctx, block, block); block += 16; len -= 16; } return(text); } SEXP AESdecryptECB(SEXP context, SEXP ciphertext) { aes_context *ctx = R_ExternalPtrAddr(context); int len = length(ciphertext); unsigned char *block; if (!ctx) error("AES context not initialized"); /* #nocov */ if (TYPEOF(ciphertext) != RAWSXP) error("Ciphertext must be a raw vector"); /* #nocov */ if (len % 16) error("Ciphertext length must be a multiple of 16 bytes"); /* #nocov */ if (MAYBE_REFERENCED(ciphertext)) ciphertext = duplicate(ciphertext); block = RAW(ciphertext); while (len > 0) { aes_decrypt(ctx, block, block); block += 16; len -= 16; } return(ciphertext); } digest/src/SpookyV2.cpp0000644000176200001440000001677714000635134014536 0ustar liggesusers// Spooky Hash // A 128-bit noncryptographic hash, for checksums and table lookup // By Bob Jenkins. Public domain. // Oct 31 2010: published framework, disclaimer ShortHash isn't right // Nov 7 2010: disabled ShortHash // Oct 31 2011: replace End, ShortMix, ShortEnd, enable ShortHash again // April 10 2012: buffer overflow on platforms without unaligned reads // July 12 2012: was passing out variables in final to in/out in short // July 30 2012: I reintroduced the buffer overflow // August 5 2012: SpookyV2: d = should be d += in short hash, and remove extra mix from long hash // Kendon Bell April 30 2019: Added counters to help with skipping first n bytes // Kendon Bell May 04 2019: Deleted original source code that doesn't get used #include #include "SpookyV2.h" // DE 2021-01-16 This defaults to 1 but is seen to trigger SAN warnings (c.f. GitHub issue #167) #define ALLOW_UNALIGNED_READS 0 // // short hash ... it could be used on any message, // but it's used by Spooky just for short messages. // void SpookyHash::Short( const void *message, size_t length, uint64 *hash1, uint64 *hash2) { uint64 buf[2*sc_numVars]; union { const uint8 *p8; uint32 *p32; uint64 *p64; size_t i; } u; u.p8 = (const uint8 *)message; if (!ALLOW_UNALIGNED_READS && (u.i & 0x7)) { memcpy(buf, message, length); u.p64 = buf; } size_t remainder = length%32; uint64 a=*hash1; uint64 b=*hash2; uint64 c=sc_const; uint64 d=sc_const; if (length > 15) { const uint64 *end = u.p64 + (length/32)*4; // handle all complete sets of 32 bytes for (; u.p64 < end; u.p64 += 4) { c += u.p64[0]; d += u.p64[1]; ShortMix(a,b,c,d); a += u.p64[2]; b += u.p64[3]; } //Handle the case of 16+ remaining bytes. if (remainder >= 16) { c += u.p64[0]; d += u.p64[1]; ShortMix(a,b,c,d); u.p64 += 2; remainder -= 16; } } // Handle the last 0..15 bytes, and its length d += ((uint64)length) << 56; switch (remainder) { case 15: d += ((uint64)u.p8[14]) << 48; // #nocov case 14: d += ((uint64)u.p8[13]) << 40; case 13: d += ((uint64)u.p8[12]) << 32; case 12: d += u.p32[2]; c += u.p64[0]; break; case 11: d += ((uint64)u.p8[10]) << 16; // #nocov case 10: d += ((uint64)u.p8[9]) << 8; case 9: d += (uint64)u.p8[8]; case 8: c += u.p64[0]; break; case 7: c += ((uint64)u.p8[6]) << 48; // #nocov case 6: c += ((uint64)u.p8[5]) << 40; // #nocov case 5: c += ((uint64)u.p8[4]) << 32; // #nocov case 4: c += u.p32[0]; // #nocov break; // #nocov case 3: c += ((uint64)u.p8[2]) << 16; case 2: c += ((uint64)u.p8[1]) << 8; case 1: c += (uint64)u.p8[0]; break; case 0: c += sc_const; d += sc_const; } ShortEnd(a,b,c,d); *hash1 = a; *hash2 = b; } // init spooky state void SpookyHash::Init(uint64 seed1, uint64 seed2, uint8 to_skip) { m_length = 0; m_remainder = 0; m_state[0] = seed1; m_state[1] = seed2; m_skipped = 0; m_to_skip = to_skip; } // add a message fragment to the state void SpookyHash::Update(const void *message, size_t length) { uint64 h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11; size_t newLength = length + m_remainder; uint8 remainder; union { const uint8 *p8; uint64 *p64; size_t i; } u; const uint64 *end; // Is this message fragment too short? If it is, stuff it away. if (newLength < sc_bufSize) { memcpy(&((uint8 *)m_data)[m_remainder], message, length); m_length = length + m_length; m_remainder = (uint8)newLength; return; } // init the variables if (m_length < sc_bufSize) { h0=h3=h6=h9 = m_state[0]; h1=h4=h7=h10 = m_state[1]; h2=h5=h8=h11 = sc_const; } else { h0 = m_state[0]; h1 = m_state[1]; h2 = m_state[2]; h3 = m_state[3]; h4 = m_state[4]; h5 = m_state[5]; h6 = m_state[6]; h7 = m_state[7]; h8 = m_state[8]; h9 = m_state[9]; h10 = m_state[10]; h11 = m_state[11]; } m_length = length + m_length; // if we've got anything stuffed away, use it now if (m_remainder) { uint8 prefix = sc_bufSize-m_remainder; memcpy(&(((uint8 *)m_data)[m_remainder]), message, prefix); u.p64 = m_data; Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); Mix(&u.p64[sc_numVars], h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); u.p8 = ((const uint8 *)message) + prefix; length -= prefix; } else { u.p8 = (const uint8 *)message; // #nocov } // handle all whole blocks of sc_blockSize bytes end = u.p64 + (length/sc_blockSize)*sc_numVars; remainder = (uint8)(length-((const uint8 *)end-u.p8)); if (ALLOW_UNALIGNED_READS || (u.i & 0x7) == 0) { while (u.p64 < end) { Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); u.p64 += sc_numVars; } } else { while (u.p64 < end) { memcpy(m_data, u.p8, sc_blockSize); Mix(m_data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); u.p64 += sc_numVars; } } // stuff away the last few bytes m_remainder = remainder; memcpy(m_data, end, remainder); // stuff away the variables m_state[0] = h0; m_state[1] = h1; m_state[2] = h2; m_state[3] = h3; m_state[4] = h4; m_state[5] = h5; m_state[6] = h6; m_state[7] = h7; m_state[8] = h8; m_state[9] = h9; m_state[10] = h10; m_state[11] = h11; } // report the hash for the concatenation of all message fragments so far void SpookyHash::Final(uint64 *hash1, uint64 *hash2) { // init the variables if (m_length < sc_bufSize) { *hash1 = m_state[0]; *hash2 = m_state[1]; Short( m_data, m_length, hash1, hash2); return; } const uint64 *data = (const uint64 *)m_data; uint8 remainder = m_remainder; uint64 h0 = m_state[0]; uint64 h1 = m_state[1]; uint64 h2 = m_state[2]; uint64 h3 = m_state[3]; uint64 h4 = m_state[4]; uint64 h5 = m_state[5]; uint64 h6 = m_state[6]; uint64 h7 = m_state[7]; uint64 h8 = m_state[8]; uint64 h9 = m_state[9]; uint64 h10 = m_state[10]; uint64 h11 = m_state[11]; if (remainder >= sc_blockSize) { // m_data can contain two blocks; handle any whole first block Mix(data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); // #nocov start data += sc_numVars; remainder -= sc_blockSize; // #nocov end } // mix in the last partial block, and the length mod sc_blockSize memset(&((uint8 *)data)[remainder], 0, (sc_blockSize-remainder)); ((uint8 *)data)[sc_blockSize-1] = remainder; // do some final mixing End(data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11); *hash1 = h0; *hash2 = h1; } void SpookyHash::UpdateSkipCounter(size_t length) { m_skipped = m_skipped + length; } void SpookyHash::GetSkipCounter(uint8 *count) { *count = m_skipped; } void SpookyHash::GetToSkip(uint8 *to_skip) { *to_skip = m_to_skip; } digest/src/md5.h0000644000176200001440000000063512247504516013170 0ustar liggesusers#ifndef _MD5_H #define _MD5_H #ifndef uint8 #define uint8 unsigned char #endif #ifndef uint32 #define uint32 unsigned long int #endif typedef struct { uint32 total[2]; uint32 state[4]; uint8 buffer[64]; } md5_context; void md5_starts( md5_context *ctx ); void md5_update( md5_context *ctx, uint8 *input, uint32 length ); void md5_finish( md5_context *ctx, uint8 digest[16] ); #endif /* md5.h */ digest/src/sha256.c0000644000176200001440000002560113216563247013511 0ustar liggesusers/* * FIPS-180-2 compliant SHA-256 implementation * * Copyright (C) 2001-2003 Christophe Devine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "sha256.h" #define GET_UINT32(n,b,i) \ { \ (n) = ( (uint32) (b)[(i) ] << 24 ) \ | ( (uint32) (b)[(i) + 1] << 16 ) \ | ( (uint32) (b)[(i) + 2] << 8 ) \ | ( (uint32) (b)[(i) + 3] ); \ } #define PUT_UINT32(n,b,i) \ { \ (b)[(i) ] = (uint8) ( (n) >> 24 ); \ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 3] = (uint8) ( (n) ); \ } void sha256_starts( sha256_context *ctx ) { ctx->total[0] = 0; ctx->total[1] = 0; ctx->state[0] = 0x6A09E667; ctx->state[1] = 0xBB67AE85; ctx->state[2] = 0x3C6EF372; ctx->state[3] = 0xA54FF53A; ctx->state[4] = 0x510E527F; ctx->state[5] = 0x9B05688C; ctx->state[6] = 0x1F83D9AB; ctx->state[7] = 0x5BE0CD19; } void sha256_process( sha256_context *ctx, uint8 data[64] ) { uint32 temp1, temp2, W[64]; uint32 A, B, C, D, E, F, G, H; GET_UINT32( W[0], data, 0 ); GET_UINT32( W[1], data, 4 ); GET_UINT32( W[2], data, 8 ); GET_UINT32( W[3], data, 12 ); GET_UINT32( W[4], data, 16 ); GET_UINT32( W[5], data, 20 ); GET_UINT32( W[6], data, 24 ); GET_UINT32( W[7], data, 28 ); GET_UINT32( W[8], data, 32 ); GET_UINT32( W[9], data, 36 ); GET_UINT32( W[10], data, 40 ); GET_UINT32( W[11], data, 44 ); GET_UINT32( W[12], data, 48 ); GET_UINT32( W[13], data, 52 ); GET_UINT32( W[14], data, 56 ); GET_UINT32( W[15], data, 60 ); #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) #define F0(x,y,z) ((x & y) | (z & (x | y))) #define F1(x,y,z) (z ^ (x & (y ^ z))) #define R(t) \ ( \ W[t] = S1(W[t - 2]) + W[t - 7] + \ S0(W[t - 15]) + W[t - 16] \ ) #define P(a,b,c,d,e,f,g,h,x,K) \ { \ temp1 = h + S3(e) + F1(e,f,g) + K + x; \ temp2 = S2(a) + F0(a,b,c); \ d += temp1; h = temp1 + temp2; \ } A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; E = ctx->state[4]; F = ctx->state[5]; G = ctx->state[6]; H = ctx->state[7]; P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); ctx->state[0] += A; ctx->state[1] += B; ctx->state[2] += C; ctx->state[3] += D; ctx->state[4] += E; ctx->state[5] += F; ctx->state[6] += G; ctx->state[7] += H; } void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ) { uint32 left, fill; if( ! length ) return; left = ctx->total[0] & 0x3F; fill = 64 - left; ctx->total[0] += length; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < length ) ctx->total[1]++; /* #nocov */ if( left && length >= fill ) { memcpy( (void *) (ctx->buffer + left), (void *) input, fill ); sha256_process( ctx, ctx->buffer ); length -= fill; input += fill; left = 0; } while( length >= 64 ) { sha256_process( ctx, input ); length -= 64; input += 64; } if( length ) { memcpy( (void *) (ctx->buffer + left), (void *) input, length ); } } static uint8 sha256_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void sha256_finish( sha256_context *ctx, uint8 digest[32] ) { uint32 last, padn; uint32 high, low; uint8 msglen[8]; high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); low = ( ctx->total[0] << 3 ); PUT_UINT32( high, msglen, 0 ); PUT_UINT32( low, msglen, 4 ); last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); sha256_update( ctx, sha256_padding, padn ); sha256_update( ctx, msglen, 8 ); PUT_UINT32( ctx->state[0], digest, 0 ); PUT_UINT32( ctx->state[1], digest, 4 ); PUT_UINT32( ctx->state[2], digest, 8 ); PUT_UINT32( ctx->state[3], digest, 12 ); PUT_UINT32( ctx->state[4], digest, 16 ); PUT_UINT32( ctx->state[5], digest, 20 ); PUT_UINT32( ctx->state[6], digest, 24 ); PUT_UINT32( ctx->state[7], digest, 28 ); } #ifdef TEST #include #include /* * those are the standard FIPS-180-2 test vectors */ static char *msg[] = { "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", NULL }; static char *val[] = { "ba7816bf8f01cfea414140de5dae2223" \ "b00361a396177a9cb410ff61f20015ad", "248d6a61d20638b8e5c026930c3e6039" \ "a33ce45964ff2167f6ecedd419db06c1", "cdc76e5c9914fb9281a1c7e284d73e67" \ "f1809a48a497200e046d39ccc7112cd0" }; int main( int argc, char *argv[] ) { FILE *f; int i, j; char output[65]; sha256_context ctx; unsigned char buf[1000]; unsigned char sha256sum[32]; if( argc < 2 ) { printf( "\n SHA-256 Validation Tests:\n\n" ); for( i = 0; i < 3; i++ ) { printf( " Test %d ", i + 1 ); sha256_starts( &ctx ); if( i < 2 ) { sha256_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) ); } else { memset( buf, 'a', 1000 ); for( j = 0; j < 1000; j++ ) { sha256_update( &ctx, (uint8 *) buf, 1000 ); } } sha256_finish( &ctx, sha256sum ); for( j = 0; j < 32; j++ ) { sprintf( output + j * 2, "%02x", sha256sum[j] ); } if( memcmp( output, val[i], 64 ) ) { printf( "failed!\n" ); return( 1 ); } printf( "passed.\n" ); } printf( "\n" ); } else { if( ! ( f = fopen( argv[1], "rb" ) ) ) { perror( "fopen" ); return( 1 ); } sha256_starts( &ctx ); while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) { sha256_update( &ctx, buf, i ); } sha256_finish( &ctx, sha256sum ); for( j = 0; j < 32; j++ ) { printf( "%02x", sha256sum[j] ); } printf( " %s\n", argv[1] ); } return( 0 ); } #endif digest/src/pmurhash.h0000644000176200001440000000367612444156327014344 0ustar liggesusers/*----------------------------------------------------------------------------- * MurmurHash3 was written by Austin Appleby, and is placed in the public * domain. * * This implementation was written by Shane Day, and is also public domain. * * This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A) * with support for progressive processing. */ /* ------------------------------------------------------------------------- */ /* Determine what native type to use for uint32_t */ /* We can't use the name 'uint32_t' here because it will conflict with * any version provided by the system headers or application. */ /* First look for special cases */ #if defined(_MSC_VER) #define MH_UINT32 unsigned long #endif /* If the compiler says it's C99 then take its word for it */ #if !defined(MH_UINT32) && ( \ defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L ) #include #define MH_UINT32 uint32_t #endif /* Otherwise try testing against max value macros from limit.h */ #if !defined(MH_UINT32) #include #if (USHRT_MAX == 0xffffffffUL) #define MH_UINT32 unsigned short #elif (UINT_MAX == 0xffffffffUL) #define MH_UINT32 unsigned int #elif (ULONG_MAX == 0xffffffffUL) #define MH_UINT32 unsigned long #endif #endif #if !defined(MH_UINT32) #error Unable to determine type name for unsigned 32-bit int #endif /* I'm yet to work on a platform where 'unsigned char' is not 8 bits */ #define MH_UINT8 unsigned char /* ------------------------------------------------------------------------- */ /* Prototypes */ #ifdef __cplusplus extern "C" { #endif void PMurHash32_Process(MH_UINT32 *ph1, MH_UINT32 *pcarry, const void *key, int len); MH_UINT32 PMurHash32_Result(MH_UINT32 h1, MH_UINT32 carry, MH_UINT32 total_length); MH_UINT32 PMurHash32(MH_UINT32 seed, const void *key, int len); void PMurHash32_test(const void *key, int len, MH_UINT32 seed, void *out); #ifdef __cplusplus } #endif digest/vignettes/0000755000176200001440000000000014151533263013544 5ustar liggesusersdigest/vignettes/sha1.md0000644000176200001440000001620314146242237014726 0ustar liggesusers --- title: "Calculating SHA1 hashes with digest() and sha1()" author: "Thierry Onkelinx and Dirk Eddelbuettel" date: "Written Jan 2016, updated Jan 2018 and Oct 2020" css: "water.css" --- NB: This vignette is (still) work-in-progress and not yet complete. ## Short intro on hashes TBD ## Difference between `digest()` and `sha1()` R [FAQ 7.31](https://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f) illustrates potential problems with floating point arithmetic. Mathematically the equality $x = \sqrt{x}^2$ should hold. But the precision of floating points numbers is finite. Hence some rounding is done, leading to numbers which are no longer identical. An illustration: ```{#faq7_31 .R} # FAQ 7.31 a0 <- 2 b <- sqrt(a0) a1 <- b ^ 2 identical(a0, a1) a0 - a1 a <- c(a0, a1) # hexadecimal representation sprintf("%a", a) ``` Although the difference is small, any difference will result in different hash when using the `digest()` function. However, the `sha1()` function tackles this problem by using the hexadecimal representation of the numbers and truncates that representation to a certain number of digits prior to calculating the hash function. ```{#faq7_31digest .R} library(digest) # different hashes with digest sapply(a, digest, algo = "sha1") # same hash with sha1 with default digits (14) sapply(a, sha1) # larger digits can lead to different hashes sapply(a, sha1, digits = 15) # decreasing the number of digits gives a stronger truncation # the hash will change when then truncation gives a different result # case where truncating gives same hexadecimal value sapply(a, sha1, digits = 13) sapply(a, sha1, digits = 10) # case where truncating gives different hexadecimal value c(sha1(pi), sha1(pi, digits = 13), sha1(pi, digits = 10)) ``` The result of floating point arithematic on 32-bit and 64-bit can be slightly different. E.g. `print(pi ^ 11, 22)` returns `294204.01797389047` on 32-bit and `294204.01797389053` on 64-bit. Note that only the last 2 digits are different. | command | 32-bit | 64-bit| | - | - | - | | `print(pi ^ 11, 22)` | `294204.01797389047` | `294204.01797389053` | | `sprintf("%a", pi ^ 11)`| `"0x1.1f4f01267bf5fp+18"` | `"0x1.1f4f01267bf6p+18"` | | `digest(pi ^ 11, algo = "sha1")` | `"c5efc7f167df1bb402b27cf9b405d7cebfba339a"` | `"b61f6fea5e2a7952692cefe8bba86a00af3de713"`| | `sha1(pi ^ 11, digits = 14)` | `"5c7740500b8f78ec2354ea6af58ea69634d9b7b1"` | `"4f3e296b9922a7ddece2183b1478d0685609a359"` | | `sha1(pi ^ 11, digits = 13)` | `"372289f87396b0877ccb4790cf40bcb5e658cad7"` | `"372289f87396b0877ccb4790cf40bcb5e658cad7"` | | `sha1(pi ^ 11, digits = 10)` | `"c05965af43f9566bfb5622f335817f674abfc9e4"` | `"c05965af43f9566bfb5622f335817f674abfc9e4"` | ## Choosing `digest()` or `sha1()` TBD ## Creating a sha1 method for other classes ### How to 1. Identify the relevant components for the hash. 1. Determine the class of each relevant component and check if they are handled by `sha1()`. - Write a method for each component class not yet handled by `sha1`. 1. Extract the relevant components. 1. Combine the relevant components into a list. Not required in case of a single component. 1. Apply `sha1()` on the (list of) relevant component(s). 1. Turn this into a function with name sha1._classname_. 1. sha1._classname_ needs exactly the same arguments as `sha1()` 1. Choose sensible defaults for the arguments - `zapsmall = 7` is recommended. - `digits = 14` is recommended in case all numerics are data. - `digits = 4` is recommended in case some numerics stem from floating point arithmetic. ### summary.lm Let's illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma. ```{#sha1_lm_sum .R} # taken from the help file of lm.influence lm_SR <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings) lm_sum <- summary(lm_SR) class(lm_sum) # str() gives the structure of the lm object str(lm_sum) # extract the coefficients and their standard error coef_sum <- coef(lm_sum)[, c("Estimate", "Std. Error")] # extract sigma sigma <- lm_sum$sigma # check the class of each component class(coef_sum) class(sigma) # sha1() has methods for both matrix and numeric # because the values originate from floating point arithmetic it is better to use a low number of digits sha1(coef_sum, digits = 4) sha1(sigma, digits = 4) # we want a single hash # combining the components in a list is a solution that works sha1(list(coef_sum, sigma), digits = 4) # now turn everything into an S3 method # - a function with name "sha1.classname" # - must have the same arguments as sha1() sha1.summary.lm <- function(x, digits = 4, zapsmall = 7){ coef_sum <- coef(x)[, c("Estimate", "Std. Error")] sigma <- x$sigma combined <- list(coef_sum, sigma) sha1(combined, digits = digits, zapsmall = zapsmall) } sha1(lm_sum) # try an altered dataset LCS2 <- LifeCycleSavings[rownames(LifeCycleSavings) != "Zambia", ] lm_SR2 <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LCS2) sha1(summary(lm_SR2)) ``` ### lm Let's illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma. ```{#sha1_lm .R} class(lm_SR) # str() gives the structure of the lm object str(lm_SR) # extract the model and the terms lm_model <- lm_SR$model lm_terms <- lm_SR$terms # check their class class(lm_model) # handled by sha1() class(lm_terms) # not handled by sha1() # define a method for formula sha1.formula <- function(x, digits = 14, zapsmall = 7, ..., algo = "sha1"){ sha1(as.character(x), digits = digits, zapsmall = zapsmall, algo = algo) } sha1(lm_terms) sha1(lm_model) # define a method for lm sha1.lm <- function(x, digits = 14, zapsmall = 7, ..., algo = "sha1"){ lm_model <- x$model lm_terms <- x$terms combined <- list(lm_model, lm_terms) sha1(combined, digits = digits, zapsmall = zapsmall, ..., algo = algo) } sha1(lm_SR) sha1(lm_SR2) ``` ## Using hashes to track changes in analysis Use case - automated analysis - update frequency of the data might be lower than the frequency of automated analysis - similar analyses on many datasets (e.g. many species in ecology) - analyses that require a lot of computing time - not rerunning an analysis because nothing has changed saves enough resources to compensate the overhead of tracking changes - Bundle all relevant information on an analysis in a class - data - method - formula - other metadata - resulting model - calculate `sha1()` file fingerprint ~ `sha1()` on the stable parts status fingerprint ~ `sha1()` on the parts that result for the model 1. Prepare analysis objects 1. Store each analysis object in a rda file which uses the file fingerprint as filename - File will already exist when no change in analysis - Don't overwrite existing files 1. Loop over all rda files - Do nothing if the analysis was run - Otherwise run the analysis and update the status and status fingerprint digest/vignettes/water.css0000644000176200001440000000225114146242237015402 0ustar liggesusers/* our addition */ body { max-width: 50rem; margin-left: auto; margin-right: auto; font-family: system-ui; } /* Inline codes */ code { padding: 2px; border-radius: unset; } /* Code blocks */ pre { background-color: unset; border: solid #aaa 1px; padding: 8px; } pre.numberSource { margin: 0; padding-left: 0; } div.sourceCode { overflow: visible; } pre, pre.sourceCode { overflow-x: auto; } pre>code { white-space: pre; overflow: visible; background-color: unset; padding: 0; } pre.sourceCode.numberSource { overflow-x: visible; } pre.sourceCode.numberSource>code { white-space: pre-wrap } pre.sourceCode.numberSource>code>span { left: 8px; text-indent: -4.6em; } /* code folding */ .chunk-summary { text-align: right; } .chunk-summary+pre, .chunk-summary+div.sourceCode { margin-top: 2px; } /* TOC */ nav > ul { border: .0625rem solid #444; border-radius: 4px; margin: 5px; padding: 5px; } nav ul { list-style-type: none; padding-inline-start: 1rem; } nav ul li { padding: 0; } nav ul ul { margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; } nav code { background-color: unset; color: unset; } digest/R/0000755000176200001440000000000014122616624011736 5ustar liggesusersdigest/R/hmac.R0000644000176200001440000000522613546165263013005 0ustar liggesusers ## hmac -- Hash-based message authentication code for R ## ## Copyright (C) 2011 - 2019 Mario Frasca and Dirk Eddelbuettel ## Copyright (C) 2012 - 2019 Hannes Muehleisen and Dirk Eddelbuettel ## ## This file is part of digest. ## ## digest is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. ## ## digest is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with digest. If not, see . makeRaw <- function(object) ## generic function, converts an object to a raw UseMethod('makeRaw') makeRaw.raw <- function(object) object makeRaw.character <- function(object) charToRaw(object) # splits a hex-string into the values it contains. makeRaw.digest <- function(object) { parts <- sapply(seq(1, nchar(object), 2), function(i) { substr(object, i, i + 1) }) as.raw(as.hexmode(parts)) } makeRaw.default <- function(object) as.raw(object) # key shall be padded if its length is smaller than the block size of the # respective algorithm, hashed if longer. block sizes are as follows: # # md5 64 # sha1 64 # crc32 4 # sha256 64 # sha512 128 (doh!) padWithZeros <- function(k,algo) { blocksize <- 64 if (algo == "crc32") blocksize <- 4 # #nocov if (algo == "sha512") blocksize <- 128 k <- makeRaw(k) if(length(k) > blocksize) {# not while() k <-digest(k, algo=algo, serialize=FALSE,raw=TRUE) if (algo == "crc32") { k <- substring(k, seq(1,7,2), seq(2,8,2)) # #nocov k <- makeRaw(strtoi(k,16)) # #nocov } } makeRaw(c(k, rep(0, blocksize - length(k)))) } hmac <- function(key, object, algo=c("md5", "sha1", "crc32", "sha256", "sha512"), serialize=FALSE, raw=FALSE, ...) { padded.key <- padWithZeros(key,algo) i.xored.key <- xor(padded.key, makeRaw(0x36)) character.digest <- digest(c(i.xored.key, makeRaw(object)), algo=algo, serialize=serialize, ...) raw.digest <- makeRaw.digest(character.digest) o.xored.key <- xor(padded.key, makeRaw(0x5c)) result <- digest(c(o.xored.key, raw.digest), algo=algo, serialize=serialize, ...) if (raw) result <- makeRaw.digest(result) return(result) } digest/R/zzz.R0000644000176200001440000000015013017636737012723 0ustar liggesusers.onUnload <- function (libpath) { # nocov start library.dynam.unload("digest", libpath) } # nocov end digest/R/vdigest.R0000644000176200001440000001606514122616624013536 0ustar liggesusers ## vdigest -- Vectorist digest functions for R ## ## Copyright (C) 2019 Matthew de Queljoe and Dirk Eddelbuettel ## ## This file is part of digest. ## ## digest is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. ## ## digest is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with digest. If not, see . getVDigest <- function(algo = c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32", "spookyhash"), errormode=c("stop","warn","silent")){ algo <- match.arg(algo, c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32", "spookyhash")) errormode <- match.arg(errormode, c("stop","warn","silent")) algoint <- algo_int(algo) non_streaming_algos <- c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32") if (algo %in% non_streaming_algos) return(non_streaming_digest(algo, errormode, algoint)) streaming_digest(algo, errormode, algoint) } non_streaming_digest <- function(algo, errormode, algoint){ function(object, serialize=TRUE, file=FALSE, length=Inf, skip="auto", ascii=FALSE, seed=0, serializeVersion=.getSerializeVersion()){ if (is.infinite(length)) length <- -1 # internally we use -1 for infinite len if (is.character(file) && missing(object)) { object <- file # nocov file <- TRUE # nocov } if (serialize && !file) { ## support the 'nosharing' option in pqR's serialize() object <- if (.hasNoSharing()) serialize_( object, connection = NULL, ascii = ascii, nosharing = TRUE, version = serializeVersion ) else serialize_(object, connection = NULL, ascii = ascii, version = serializeVersion) ## we support raw vectors, so no mangling of 'object' is necessary ## regardless of R version ## skip="auto" - skips the serialization header [SU] if (any(!is.na(pmatch(skip,"auto")))) skip <- set_skip(object, ascii) } else if (!is.character(object) && !inherits(object,"raw")) { return(.errorhandler(paste("Argument object must be of type character", # #nocov "or raw vector if serialize is FALSE"), mode=errormode)) # #nocov } if (file && !is.character(object)) return(.errorhandler("file=TRUE can only be used with a character object", # #nocov mode=errormode)) # #nocov if (file) { algoint <- algoint+100 object <- path.expand(object) if (.isWindows()) object <- enc2utf8(object) check_file(object, errormode) } ## if skip is auto (or any other text for that matter), we just turn it ## into 0 because auto should have been converted into a number earlier ## if it was valid [SU] if (is.character(skip)) skip <- 0 val <- .Call( vdigest_impl, object, as.integer(algoint), as.integer(length), as.integer(skip), 0L, # raw always FALSE as.integer(seed) ) ## crc32 output was not guaranteed to be eight chars long, which we corrected ## this allows to get the old behaviour back for compatibility if ((algoint == 3 || algoint == 103) && .getCRC32PreferOldOutput()) { val <- sub("^0+", "", val) # #nocov } return(val) } } streaming_digest <- function(algo, errormode, algoint){ function(object, serialize=TRUE, file=FALSE, length=Inf, skip="auto", ascii=FALSE, seed=0, serializeVersion=.getSerializeVersion()){ if (is.infinite(length)) length <- -1 # internally we use -1 for infinite len if (is.character(file) && missing(object)) { object <- file # nocov file <- TRUE # nocov } if (!serialize){ .errorhandler(paste0(algo, " algorithm is not available without serialization."), # #nocov mode=errormode) # #nocov } if (serialize && !file) { ## we support raw vectors, so no mangling of 'object' is necessary ## regardless of R version ## skip="auto" - skips the serialization header [SU] if (any(!is.na(pmatch(skip,"auto")))) skip <- set_skip(object, ascii) } if (file) return(.errorhandler(paste0(algo, " algorithm can not be used with files."), # #nocov mode=errormode)) # #nocov ## if skip is auto (or any other text for that matter), we just turn it ## into 0 because auto should have been converted into a number earlier ## if it was valid [SU] if (is.character(skip)) skip <- 0 # #nocov if (algo == "spookyhash"){ # 0s are the seeds. They are included to enable testing against fastdigest. val <- vapply(object, function(o) paste( .Call(spookydigest_impl, o, skip, 0, 0, serializeVersion), collapse = "" ), character(1), USE.NAMES = FALSE) } ## crc32 output was not guaranteed to be eight chars long, which we corrected ## this allows to get the old behaviour back for compatibility if ((algoint == 3 || algoint == 103) && .getCRC32PreferOldOutput()) { val <- sub("^0+", "", val) # #nocov } return(val) } } serialize_ <- function(object, ...){ if (length(object)) return(lapply(object, serialize, ...)) serialize(object, ...) } digest/R/init.R0000644000176200001440000000515013770750231013026 0ustar liggesusers ## digest -- hash digest functions for R ## ## Copyright (C) 2003 - 2019 Dirk Eddelbuettel ## ## This file is part of digest. ## ## digest is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. ## ## digest is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with digest. If not, see . .pkgenv <- new.env(parent=emptyenv()) .onLoad <- function(libname, pkgname) { ## we set a default level of two, with a possible override .pkgenv[["serializeVersion"]] <- getOption("serializeVersion", 2L) # #nocov ## allow old crc32 behaviour .pkgenv[["crc32Preference"]] <- getOption("digestOldCRC32Format", FALSE) ## allow version specific sha1 behaviour .pkgenv[["sha1PackageVersion"]] <- getOption("sha1PackageVersion", packageVersion("digest")) ## cache if we are on Windows as the call is a little expensive (GH issue #137) .pkgenv[["isWindows"]] <- Sys.info()[["sysname"]] == "Windows" ## cache if serialize() supports 'nosharing' .pkgenv[["hasNoSharing"]] <- "nosharing" %in% names(formals(serialize)) } .getSerializeVersion <- function() { ## return the options() value if set, otherwise the package env value ## doing it as a two-step ensure we can set a different default later getOption("serializeVersion", .pkgenv[["serializeVersion"]]) } .getCRC32PreferOldOutput <- function() { ## return the options() value if set, otherwise the package env value ## doing it as a two-step ensure we can set a different default later getOption("digestOldCRC32Format", .pkgenv[["crc32Preference"]]) } .getsha1PackageVersion <- function() { ## return the options() value if set, otherwise the package env value ## doing it as a two-step ensure we can set a different default later package_version( getOption("sha1PackageVersion", .pkgenv[["sha1PackageVersion"]]) ) } .isWindows <- function() { ## return the cached value of Sys.info()[["sysname"]] == "Windows" .pkgenv[["isWindows"]] } .hasNoSharing <- function() { ## return the cached value of "nosharing" %in% names(formals(serialize)) .pkgenv[["hasNoSharing"]] } digest/R/AES.R0000644000176200001440000001212713546164511012476 0ustar liggesusers## AES -- Advanced Encryption Standard (AES) block cipher for R ## ## Copyright (C) 2013 - 2019 Duncan Murdoch and Dirk Eddelbuettel ## Copyright (C) 2019 Ion Suruceanu ## ## This file is part of digest. ## ## digest is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. ## ## digest is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with digest. If not, see . ## This is loosely modelled on the AES code from the Python Crypto package. ## Currently only ECB, CBC, CFB and CTR modes are supported... modes <- c("ECB", "CBC", "CFB", "PGP", "OFB", "CTR", "OPENPGP") AES <- function(key, mode=c("ECB", "CBC", "CFB", "CTR"), IV=NULL) { mode <- match(match.arg(mode), modes) if (!(mode %in% c(1:3, 6))) stop("Only ECB, CBC, CFB and CTR mode encryption are supported.") # #nocov key <- as.raw(key) IV <- as.raw(IV) context <- .Call(AESinit, key) block_size <- 16 key_size <- length(key) rm(key) encrypt <- function(text) { if (typeof(text) == "character") text <- charToRaw(text) # #nocov if (mode == 1) .Call(AESencryptECB, context, text) else if (mode == 2) { len <- length(text) if (len %% 16 != 0) stop("Text length must be a multiple of 16 bytes") # #nocov result <- raw(length(text)) for (i in seq_len(len/16)) { ind <- (i-1)*16 + 1:16 IV <<- .Call(AESencryptECB, context, xor(text[ind], IV)) result[ind] <- IV } result } else if (mode == 3) { if (length(IV) != block_size) { stop("IV length must equal block size") } result <- raw(length(text)) blocks <- split(text, ceiling(seq_along(text)/block_size)) i <- 0 for (b in blocks) { if (block_size == length(IV)) { out <- .Call(AESencryptECB, context, IV) } len <- length(b) ind <- i*length(IV)+1:len i <- i + 1 result[ind] <- xor(b, out[0:len]) IV <<- result[ind] } result } else if (mode == 6) { len <- length(text) blocks <- (len + 15) %/% 16 result <- raw(16*blocks) zero <- as.raw(0) for (i in 1:blocks) { result[16*(i-1)+1:16] <- IV byte <- 16 repeat { IV[byte] <<- as.raw((as.integer(IV[byte]) + 1) %% 256) if (IV[byte] != zero || byte == 1) break byte <- byte - 1 } } result <- .Call(AESencryptECB, context, result) length(result) <- len xor(text, result) } } decrypt <- function(ciphertext, raw = FALSE) { if (mode == 1) result <- .Call(AESdecryptECB, context, ciphertext) else if (mode == 2) { len <- length(ciphertext) if (len %% 16 != 0) stop("Ciphertext length must be a multiple of 16 bytes") # #nocov result <- raw(length(ciphertext)) for (i in seq_len(len/16)) { ind <- (i-1)*16 + 1:16 res <- .Call(AESdecryptECB, context, ciphertext[ind]) result[ind] <- xor(res, IV) IV <<- ciphertext[ind] } } else if (mode == 3) { if (length(IV) != block_size) { stop("IV length must equal block size") } result <- raw(length(ciphertext)) blocks <- split(ciphertext, ceiling(seq_along(ciphertext)/block_size)) i <- 0 for (b in blocks) { if (block_size == length(IV)) { out <- .Call(AESencryptECB, context, IV) } len <- length(b) ind <- i*length(IV)+1:len i <- i + 1 result[ind] <- xor(b, out[0:len]) IV <<- b } } else if (mode == 6) result <- encrypt(ciphertext) if (!raw) result <- rawToChar(result) # #nocov result } structure(list(encrypt=encrypt, decrypt=decrypt, block_size=function() block_size, IV=function() IV, key_size=function() key_size, mode=function() modes[mode]), class = "AES") } print.AES <- function(x, ...) # #nocov cat("AES cipher object; mode", x$mode(), "key size", x$key_size(), "\n") # #nocov digest/R/digest.R0000644000176200001440000001576513737376416013373 0ustar liggesusers ## digest -- hash digest functions for R ## ## Copyright (C) 2003 - 2019 Dirk Eddelbuettel ## Copyright (C) 2009 - 2019 Henrik Bengtsson ## Copyright (C) 2012 - 2019 Hannes Muehleisen ## Copyright (C) 2014 - 2019 Jim Hester ## Copyright (C) 2019 Kendon Bell ## Copyright (C) 2019 Matthew de Queljoe ## ## This file is part of digest. ## ## digest is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. ## ## digest is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with digest. If not, see . digest <- function(object, algo=c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32", "spookyhash", "blake3"), serialize=TRUE, file=FALSE, length=Inf, skip="auto", ascii=FALSE, raw=FALSE, seed=0, errormode=c("stop","warn","silent"), serializeVersion=.getSerializeVersion()) { # Explicitly specify choices; this is much faster than having match.arg() # infer them from the function's formals. algo <- match.arg(algo, c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32", "spookyhash", "blake3")) errormode <- match.arg(errormode, c("stop", "warn", "silent")) if (is.infinite(length)) { length <- -1 # internally we use -1 for infinite len } if (is.character(file) && missing(object)) { object <- file # nocov file <- TRUE # nocov } is_streaming_algo <- algo == "spookyhash" if (is_streaming_algo && !serialize) { .errorhandler(paste0(algo, " algorithm is not available without serialization."), # #nocov mode=errormode) # #nocov } if (serialize && !file) { if (!is_streaming_algo) { ## support the 'nosharing' option in pqR's serialize() object <- if (.hasNoSharing()) serialize (object, connection=NULL, ascii=ascii, nosharing=TRUE, version=serializeVersion) else serialize (object, connection=NULL, ascii=ascii, version=serializeVersion) } ## we support raw vectors, so no mangling of 'object' is necessary ## regardless of R version ## skip="auto" - skips the serialization header [SU] if (is.character(skip) && skip == "auto") skip <- set_skip(object, ascii) } else if (!is.character(object) && !inherits(object,"raw") && !is_streaming_algo) { return(.errorhandler(paste("Argument object must be of type character", # #nocov "or raw vector if serialize is FALSE"), mode=errormode)) # #nocov } if (file && !is.character(object)) return(.errorhandler("file=TRUE can only be used with a character object", # #nocov mode=errormode)) # #nocov if (file && is_streaming_algo) return(.errorhandler(paste0(algo, " algorithm can not be used with files."), # #nocov mode=errormode)) # #nocov ## HB 14 Mar 2007: null op, only turned to char if alreadt char ##if (!inherits(object,"raw")) ## object <- as.character(object) algoint <- algo_int(algo) if (file) { algoint <- algoint+100 object <- path.expand(object) if (.isWindows()) object <- enc2utf8(object) check_file(object, errormode) } ## if skip is auto (or any other text for that matter), we just turn it ## into 0 because auto should have been converted into a number earlier ## if it was valid [SU] if (is.character(skip)) skip <- 0 if (!is_streaming_algo) { val <- .Call(digest_impl, object, as.integer(algoint), as.integer(length), as.integer(skip), as.integer(raw), as.integer(seed)) } else if (algo == "spookyhash"){ # 0s are the seeds. They are included to enable testing against fastdigest. val <- paste(.Call(spookydigest_impl, object, skip, 0, 0, serializeVersion, NULL), collapse="") } ## crc32 output was not guaranteed to be eight chars long, which we corrected ## this allows to get the old behaviour back for compatibility if ((algoint == 3 || algoint == 103) && .getCRC32PreferOldOutput()) { val <- sub("^0+", "", val) } return(val) } ## utility functions used by digest() and getVDigest() below .errorhandler <- function(txt, obj="", mode="stop") { if (mode == "stop") { # nocov start stop(txt, obj, call.=FALSE) } else if (mode == "warn") { warning(txt, obj, call.=FALSE) return(invisible(NA)) } else { return(invisible(NULL)) # nocov end } } algo_int <- function(algo) switch( algo, md5 = 1, sha1 = 2, crc32 = 3, sha256 = 4, sha512 = 5, xxhash32 = 6, xxhash64 = 7, murmur32 = 8, spookyhash = 9, blake3 = 10 ) ## HB 14 Mar 2007: ## Exclude serialization header (non-data dependent bytes but R ## version specific). In ASCII, the header consists of for rows ## ending with a newline ('\n'). We need to skip these. ## The end of 4th row is *typically* within the first 18 bytes set_skip <- function(object, ascii){ if (!ascii) return(14) ## Was: skip <- if (ascii) 18 else 14 which(object[1:30] == as.raw(10))[4] # nocov } check_file <- function(object, errormode){ if (!file.exists(object)) { return(.errorhandler("The file does not exist: ", object, mode=errormode)) # nocov start } if (!isTRUE(!file.info(object)$isdir)) { return(.errorhandler("The specified pathname is not a file: ", object, mode=errormode)) } if (file.access(object, 4)) { return(.errorhandler("The specified file is not readable: ", object, mode=errormode)) # #nocov end } } digest/R/digest2int.R0000644000176200001440000000013113371554565014142 0ustar liggesusersdigest2int <- function(x, seed = 0L) { .Call(digest2int_impl, x, as.integer(seed)) } digest/R/sha1.R0000644000176200001440000003055013574673675012743 0ustar liggesusers ## sha1 -- SHA1 hash generation for R ## ## Copyright (C) 2015 - 2019 Thierry Onkelinx and Dirk Eddelbuettel ## Copyright (C) 2016 - 2019 Viliam Simko ## ## This file is part of digest. ## ## digest is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. ## ## digest is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with digest. If not, see . # functions written by Thierry Onkelinx sha1 <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1"){ UseMethod("sha1") } sha1.default <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { if (is.list(x)) { return( sha1.list(x, digits = digits, zapsmall = zapsmall, ..., algo = algo) ) } stop( # #nocov start "sha1() has no method for the '", paste(class(x), collapse = "', '"), "' class", call. = FALSE ) # #nocov end } sha1.numeric <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1"){ y <- num2hex( x, digits = digits, zapsmall = zapsmall ) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } sha1.matrix <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1"){ # needed to make results comparable between 32-bit and 64-bit if (storage.mode(x) == "double") { y <- matrix( #return a matrix with the same dimensions as x apply( x, 2, num2hex, digits = digits, zapsmall = zapsmall ), ncol = ncol(x) ) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } else { attr(x, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(x, algo = algo) } } sha1.complex <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { # a vector of complex numbers is converted into 2-column matrix (Re,Im) y <- cbind(Re(x), Im(x)) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) sha1(y, digits = digits, zapsmall = zapsmall, ..., algo = algo) } sha1.Date <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { y <- as.numeric(x) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) sha1(y, digits = digits, zapsmall = zapsmall, ..., algo = algo) } sha1.array <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { # Array x encoded as list of two elements: # 1. lengths of all dimensions of x # 2. all cells of x as a single vector y <- list( dimension = dim(x), value = as.numeric(x)) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) sha1(y, digits = digits, zapsmall = zapsmall, ..., algo = algo) } sha1.data.frame <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1"){ if (length(x)) { # needed to make results comparable between 32-bit and 64-bit y <- vapply( x, sha1, digits = digits, zapsmall = zapsmall, ..., algo = algo, FUN.VALUE = NA_character_ ) } else { y <- x } y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } sha1.list <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1"){ if (length(x)) { # needed to make results comparable between 32-bit and 64-bit y <- vapply( x, sha1, digits = digits, zapsmall = zapsmall, ..., algo = algo, FUN.VALUE = NA_character_ ) } else { y <- x } y <- add_attributes(x, y) attr(y, "digest::sha1") <- list( class = class(x), digits = as.integer(digits), zapsmall = as.integer(zapsmall), ... = ... ) digest(y, algo = algo) } sha1.POSIXlt <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { y <- do.call( data.frame, lapply(unclass(as.POSIXlt(x)), unlist) ) y$sec <- num2hex(y$sec, digits = digits, zapsmall = zapsmall) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } sha1.POSIXct <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { y <- sha1( as.POSIXlt(x), digits = digits, zapsmall = zapsmall, ..., algo = algo ) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } sha1.anova <- function(x, digits = 4L, zapsmall = 7L, ..., algo = "sha1"){ if (digits > 4) { warning("Hash on 32 bit might be different from hash on 64 bit with digits > 4") # #nocov } y <- apply( x, 1, num2hex, digits = digits, zapsmall = zapsmall ) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } sha1.pairlist <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { # needed to make results comparable between 32-bit and 64-bit y <- vapply( x, sha1, digits = digits, zapsmall = zapsmall, ..., algo = algo, FUN.VALUE = NA_character_ ) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } sha1.function <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1"){ dots <- list(...) if (is.null(dots$environment)) { dots$environment <- TRUE } if (isTRUE(dots$environment)) { y <- list( formals = formals(x), body = as.character(body(x)), environment = digest(environment(x), algo = algo) ) } else { y <- list( formals = formals(x), body = as.character(body(x)) ) } y <- vapply( y, sha1, digits = digits, zapsmall = zapsmall, environment = dots$environment, ... = dots, algo = algo, FUN.VALUE = NA_character_ ) y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = y, digits = digits, zapsmall = zapsmall, algo = algo, dots ) digest(y, algo = algo) } sha1.formula <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1"){ dots <- list(...) if (is.null(dots$environment)) { dots$environment <- TRUE } y <- vapply( x, sha1, digits = digits, zapsmall = zapsmall, ... = dots, algo = algo, FUN.VALUE = NA_character_ ) if (isTRUE(dots$environment)) { y <- c( y, digest(environment(x), algo = algo) ) } y <- add_attributes(x, y) attr(y, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(y, algo = algo) } "sha1.(" <- function(...) {sha1.formula(...)} add_attributes <- function(x, y) { if (.getsha1PackageVersion() < package_version("0.6.22.2")) { return(y) } extra <- attributes(x) if (package_version("0.6.23.2") <= .getsha1PackageVersion()) { extra <- extra[names(extra) != "srcref"] } attributes(y) <- c(attributes(y), "digest::attributes" = extra) return(y) } # sha1_attr_digest variants #### sha1_attr_digest <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { # attributes can be set on objects calling sha1_attr_digest() attr(x, "digest::sha1") <- attr_sha1( x = x, digits = digits, zapsmall = zapsmall, algo = algo, ... ) digest(x, algo = algo) } sha1.call <- function(...) {sha1_attr_digest(...)} sha1.character <- function(...) {sha1_attr_digest(...)} sha1.factor <- function(...) {sha1_attr_digest(...)} sha1.logical <- function(...) {sha1_attr_digest(...)} sha1.integer <- function(...) {sha1_attr_digest(...)} sha1.raw <- function(...) {sha1_attr_digest(...)} # sha1_digest variants #### sha1_digest <- function(x, digits = 14L, zapsmall = 7L, ..., algo = "sha1") { # attributes cannot be set on objects calling sha1_digest() digest(x, algo = algo) } sha1.name <- function(...) {sha1_digest(...)} sha1.NULL <- function(...) {sha1_digest(...)} # Support Functions #### attr_sha1 <- function(x, digits, zapsmall, algo, ...) { if (algo == "sha1") { return( list( class = class(x), digits = as.integer(digits), zapsmall = as.integer(zapsmall), ... ) ) } list( class = class(x), digits = as.integer(digits), zapsmall = as.integer(zapsmall), algo = algo, ... ) } num2hex <- function(x, digits = 14L, zapsmall = 7L){ if (!is.numeric(x)) { stop("x is not numeric") # #nocov } if (!is.integer(digits)) { if (!all.equal(as.integer(digits), digits)) { stop("digits is not integer") # #nocov } digits <- as.integer(digits) } if (length(digits) != 1) { stop("digits must contain exactly one integer") # #nocov } if (digits < 1) { stop("digits must be positive") # #nocov } if (!is.integer(zapsmall)) { if (!all.equal(as.integer(zapsmall), zapsmall)) { stop("zapsmall is not integer") # #nocov } zapsmall <- as.integer(zapsmall) } if (length(zapsmall) != 1) { stop("zapsmall must contain exactly one integer") # #nocov } if (zapsmall < 1) { stop("zapsmall must be positive") # #nocov } if (length(x) == 0) { return(character(0)) } x.na <- is.na(x) if (all(x.na)) { return(x) } x.inf <- is.infinite(x) output <- rep(NA_character_, length(x)) output[x.inf & x > 0] <- "Inf" output[x.inf & x < 0] <- "-Inf" # detect "small" numbers x.zero <- !x.na & !x.inf & abs(x) <= (2^floor(log2(10 ^ -zapsmall))) output[x.zero] <- "0" # The calculations for non-na, non-inf, non-zero values are computationally # more intense. Don't do them unless necessary. x.finite <- !(x.na | x.inf | x.zero) if (!any(x.finite)) { return(output) } x_abs <- abs(x[x.finite]) exponent <- floor(log2(x_abs)) negative <- c("", "-")[(x[x.finite] < 0) + 1] x.hex <- sprintf("%a", x_abs*2^-exponent) nc_x <- nchar(x.hex) digits.hex <- ceiling(log(10 ^ digits, base = 16)) # select mantissa (starting format is 0x1.[0-9a-f]+p[+-][0-9]+), remove the # beginning through the decimal place, including the fact that exact powers # of two will not have a decimal place. # Remove the beginning through the decimal place (if it exists). mask_decimal <- startsWith(x.hex, "0x1.") start_character <- 4 + mask_decimal # select required precision stop_character <- pmin(nc_x - 3, start_character + digits.hex - 1) mantissa <- substring(x.hex, start_character, stop_character) # Drop trailing zeros mantissa <- gsub(x = mantissa, pattern = "0*$", replacement = "") output[x.finite] <- sprintf("%s%s %d", negative, mantissa, exponent) return(output) } digest/MD50000644000176200001440000000725014151623322012044 0ustar liggesusers2fc0e3940421860e55a9109374870a86 *ChangeLog 3ed4e0c8fb5b7926ffcf7bf560777ea8 *DESCRIPTION 14402ee218da75987f233d61fa84ab8d *NAMESPACE 82c734f29cbd8b0e29893316d3d5a480 *R/AES.R 82f716f31c280b6ed497d65744547a96 *R/digest.R 481f6406e42aeaf0eb9da80ebd1c3601 *R/digest2int.R 3afa681f8cae1c57282057525baf3731 *R/hmac.R b2f7b3b1b1d0f9da2e62a57aab863601 *R/init.R 14cddbd8465ff30bec5a355855130888 *R/sha1.R d7ca1ce5d34263179fd46b4992e70fb0 *R/vdigest.R a673761518607ae09b8f6357c6304c60 *R/zzz.R 17c07684899ec251f1c18785c32b4bc2 *README.md 44e7d30ab5a91d849e5fee71c6e03370 *build/vignette.rds b47a60fc7c78d503aba2c3af8d8f3d9a *cleanup cdd17dda453ee280bdbaac3b405874d6 *demo/00Index 247a7f1a523cb39feb2941b00b82906a *demo/vectorised.R b234ee4d69f5fce4486a80fdaf4a4263 *inst/GPL-2 0473d4bde070176922b60166512ee4e7 *inst/doc/sha1.R 2bafc9dc174d4c0c7a4f997c4e38ab22 *inst/doc/sha1.html 6b37c59ba0b533a23e48589c49be6851 *inst/doc/sha1.md 82a62fb6337a2be9ae069fee3d50b614 *inst/include/pmurhashAPI.h 4d75623e0ffe3c04eac1752b7d3d8f6b *inst/tinytest/test_aes.R f930ce5c1f9bbcd3b6fe97fd7b5b27f8 *inst/tinytest/test_blake3.R 052184be0e884920438e1779a03f8759 *inst/tinytest/test_crc32.R 8ec7f892f2bcb4b146f78078f987237b *inst/tinytest/test_digest.R 6681e580fd409258ed4fbdeb77a14cd4 *inst/tinytest/test_digest2int.R 8e8415ddde36eb03eae83e0ae0e5bb0c *inst/tinytest/test_encoding.R 2b3efdc9712ac7f956f79a80da4d0d00 *inst/tinytest/test_hmac.R 557fbd734cbf96e7946b9dca3eaa9afe *inst/tinytest/test_misc.R 40f6e8975785e79091b3a9dffd430e2b *inst/tinytest/test_new_matrix_behaviour.R 1d71bffa7dc302062c44ed92b57bdbcc *inst/tinytest/test_num2hex.R 612e0a4832b86b69c8c04f2916f3b16a *inst/tinytest/test_raw.R 6e3548a6e9bdf2681f6bdc173ee0a8d2 *inst/tinytest/test_sha1.R 55e4ec1fa130abc4983c8833d05f8fba *man/AES.Rd 7396690702d85e5b7d84f6efd570214c *man/digest.Rd d45f3ac5c54a9b0f08ba342b22b9d332 *man/digest2int.Rd 4e1c2885b0335799671cc924991f5471 *man/hmac.Rd 9d566e9d729f574b922fb174f20f1d3b *man/makeRaw.Rd b00315435b5f3bf83ef66af1911270ec *man/sha1.Rd f1cd7ff7ffb82a0d16b703cd320d70ed *man/vdigest.Rd 1f06212fc4eccfc3c1eb9a2738b5926b *src/Makevars 8d217da07ceab19fbe07c05853a936c2 *src/SpookyV2.cpp 29f0a9285b34812cdf91dcf65d0594c4 *src/SpookyV2.h a529d657388750546c7e03442eb01c31 *src/aes.c 12398d282dd19894ed5548fc55fff7c4 *src/aes.h 90974df9d6984b6a4f06aae3d75bbe6a *src/blake3.c 23350b7351de5b42a6aff1bbeadd4338 *src/blake3.h 5d44f6c6e0e8333b0d343beba8c4f772 *src/blake3_dispatch.c 653116045f28590f7408b41ee0d9b152 *src/blake3_impl.h ceb8de8ba5e178fef7ed7964ae300ee4 *src/blake3_portable.c 2cb721d135ea8eec6aeceedcd26706e5 *src/crc32.c 4d1cfa258e52f3f91b09afdba248fec5 *src/crc32.h 3b9024c395fc1ff4b960d28d8191daa9 *src/digest.c dc3762ab113fccd9ae068ae763906c89 *src/digest2int.c 05344eb938698407395c04bf91c9c150 *src/init.c 972a4374ab3e726afbab89332562daf2 *src/md5.c 9847470291dc6d9a7d86ae83d225745e *src/md5.h 3c8dc8288322e8acc3e0686d8d6d1808 *src/pmurhash.c 798a590806add96318b6cfab0d2805ce *src/pmurhash.h 64d967be5b5ec3024bf284dede078d48 *src/raes.c 2501b53d87d8f7e46cdbfe7b4f132643 *src/sha1.c 7cf279b5c8a6743e49a2c37d105733f5 *src/sha1.h 5c39551f3c33f278cdcb27f82987afd2 *src/sha2.c 8cb23ad7160a7a9faf1f3b2b6ed3c6bc *src/sha2.h c8089bc1a0cda904888249da6af7f29c *src/sha256.c 82a758ff49a4a2c5dfc82852d57f9a44 *src/sha256.h a2c26c568d10a100c53fc67035bc06ec *src/spooky_serialize.cpp b5e69e428568b486a50e2d56625fc7e0 *src/xxhash.c e402c69cf0dba5f5a6d8004cf91b6c81 *src/xxhash.h 9f96783529fb4458a873ed787b5d2630 *src/zconf.h 95fdcdaa6c64cf71726e192d5eb1b608 *src/zlib.h c4564a01a95ad6d04fec9c4ef0561cee *src/zutil.h 55b29bb6c8292127b5a709d9eeb3c3bb *tests/tinytest.R 6b37c59ba0b533a23e48589c49be6851 *vignettes/sha1.md c337c0e0c1e0c0dd67a87649ff442d9f *vignettes/water.css digest/inst/0000755000176200001440000000000014151533263012511 5ustar liggesusersdigest/inst/GPL-20000644000176200001440000004325412247504516013230 0ustar liggesusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. digest/inst/doc/0000755000176200001440000000000014151533263013256 5ustar liggesusersdigest/inst/doc/sha1.R0000644000176200001440000000537014151533263014242 0ustar liggesusers# faq7_31 # FAQ 7.31 a0 <- 2 b <- sqrt(a0) a1 <- b ^ 2 identical(a0, a1) a0 - a1 a <- c(a0, a1) # hexadecimal representation sprintf("%a", a) # faq7_31digest library(digest) # different hashes with digest sapply(a, digest, algo = "sha1") # same hash with sha1 with default digits (14) sapply(a, sha1) # larger digits can lead to different hashes sapply(a, sha1, digits = 15) # decreasing the number of digits gives a stronger truncation # the hash will change when then truncation gives a different result # case where truncating gives same hexadecimal value sapply(a, sha1, digits = 13) sapply(a, sha1, digits = 10) # case where truncating gives different hexadecimal value c(sha1(pi), sha1(pi, digits = 13), sha1(pi, digits = 10)) # sha1_lm_sum # taken from the help file of lm.influence lm_SR <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings) lm_sum <- summary(lm_SR) class(lm_sum) # str() gives the structure of the lm object str(lm_sum) # extract the coefficients and their standard error coef_sum <- coef(lm_sum)[, c("Estimate", "Std. Error")] # extract sigma sigma <- lm_sum$sigma # check the class of each component class(coef_sum) class(sigma) # sha1() has methods for both matrix and numeric # because the values originate from floating point arithmetic it is better to use a low number of digits sha1(coef_sum, digits = 4) sha1(sigma, digits = 4) # we want a single hash # combining the components in a list is a solution that works sha1(list(coef_sum, sigma), digits = 4) # now turn everything into an S3 method # - a function with name "sha1.classname" # - must have the same arguments as sha1() sha1.summary.lm <- function(x, digits = 4, zapsmall = 7){ coef_sum <- coef(x)[, c("Estimate", "Std. Error")] sigma <- x$sigma combined <- list(coef_sum, sigma) sha1(combined, digits = digits, zapsmall = zapsmall) } sha1(lm_sum) # try an altered dataset LCS2 <- LifeCycleSavings[rownames(LifeCycleSavings) != "Zambia", ] lm_SR2 <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LCS2) sha1(summary(lm_SR2)) # sha1_lm class(lm_SR) # str() gives the structure of the lm object str(lm_SR) # extract the model and the terms lm_model <- lm_SR$model lm_terms <- lm_SR$terms # check their class class(lm_model) # handled by sha1() class(lm_terms) # not handled by sha1() # define a method for formula sha1.formula <- function(x, digits = 14, zapsmall = 7, ..., algo = "sha1"){ sha1(as.character(x), digits = digits, zapsmall = zapsmall, algo = algo) } sha1(lm_terms) sha1(lm_model) # define a method for lm sha1.lm <- function(x, digits = 14, zapsmall = 7, ..., algo = "sha1"){ lm_model <- x$model lm_terms <- x$terms combined <- list(lm_model, lm_terms) sha1(combined, digits = digits, zapsmall = zapsmall, ..., algo = algo) } sha1(lm_SR) sha1(lm_SR2) digest/inst/doc/sha1.md0000644000176200001440000001620314146242237014440 0ustar liggesusers --- title: "Calculating SHA1 hashes with digest() and sha1()" author: "Thierry Onkelinx and Dirk Eddelbuettel" date: "Written Jan 2016, updated Jan 2018 and Oct 2020" css: "water.css" --- NB: This vignette is (still) work-in-progress and not yet complete. ## Short intro on hashes TBD ## Difference between `digest()` and `sha1()` R [FAQ 7.31](https://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f) illustrates potential problems with floating point arithmetic. Mathematically the equality $x = \sqrt{x}^2$ should hold. But the precision of floating points numbers is finite. Hence some rounding is done, leading to numbers which are no longer identical. An illustration: ```{#faq7_31 .R} # FAQ 7.31 a0 <- 2 b <- sqrt(a0) a1 <- b ^ 2 identical(a0, a1) a0 - a1 a <- c(a0, a1) # hexadecimal representation sprintf("%a", a) ``` Although the difference is small, any difference will result in different hash when using the `digest()` function. However, the `sha1()` function tackles this problem by using the hexadecimal representation of the numbers and truncates that representation to a certain number of digits prior to calculating the hash function. ```{#faq7_31digest .R} library(digest) # different hashes with digest sapply(a, digest, algo = "sha1") # same hash with sha1 with default digits (14) sapply(a, sha1) # larger digits can lead to different hashes sapply(a, sha1, digits = 15) # decreasing the number of digits gives a stronger truncation # the hash will change when then truncation gives a different result # case where truncating gives same hexadecimal value sapply(a, sha1, digits = 13) sapply(a, sha1, digits = 10) # case where truncating gives different hexadecimal value c(sha1(pi), sha1(pi, digits = 13), sha1(pi, digits = 10)) ``` The result of floating point arithematic on 32-bit and 64-bit can be slightly different. E.g. `print(pi ^ 11, 22)` returns `294204.01797389047` on 32-bit and `294204.01797389053` on 64-bit. Note that only the last 2 digits are different. | command | 32-bit | 64-bit| | - | - | - | | `print(pi ^ 11, 22)` | `294204.01797389047` | `294204.01797389053` | | `sprintf("%a", pi ^ 11)`| `"0x1.1f4f01267bf5fp+18"` | `"0x1.1f4f01267bf6p+18"` | | `digest(pi ^ 11, algo = "sha1")` | `"c5efc7f167df1bb402b27cf9b405d7cebfba339a"` | `"b61f6fea5e2a7952692cefe8bba86a00af3de713"`| | `sha1(pi ^ 11, digits = 14)` | `"5c7740500b8f78ec2354ea6af58ea69634d9b7b1"` | `"4f3e296b9922a7ddece2183b1478d0685609a359"` | | `sha1(pi ^ 11, digits = 13)` | `"372289f87396b0877ccb4790cf40bcb5e658cad7"` | `"372289f87396b0877ccb4790cf40bcb5e658cad7"` | | `sha1(pi ^ 11, digits = 10)` | `"c05965af43f9566bfb5622f335817f674abfc9e4"` | `"c05965af43f9566bfb5622f335817f674abfc9e4"` | ## Choosing `digest()` or `sha1()` TBD ## Creating a sha1 method for other classes ### How to 1. Identify the relevant components for the hash. 1. Determine the class of each relevant component and check if they are handled by `sha1()`. - Write a method for each component class not yet handled by `sha1`. 1. Extract the relevant components. 1. Combine the relevant components into a list. Not required in case of a single component. 1. Apply `sha1()` on the (list of) relevant component(s). 1. Turn this into a function with name sha1._classname_. 1. sha1._classname_ needs exactly the same arguments as `sha1()` 1. Choose sensible defaults for the arguments - `zapsmall = 7` is recommended. - `digits = 14` is recommended in case all numerics are data. - `digits = 4` is recommended in case some numerics stem from floating point arithmetic. ### summary.lm Let's illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma. ```{#sha1_lm_sum .R} # taken from the help file of lm.influence lm_SR <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings) lm_sum <- summary(lm_SR) class(lm_sum) # str() gives the structure of the lm object str(lm_sum) # extract the coefficients and their standard error coef_sum <- coef(lm_sum)[, c("Estimate", "Std. Error")] # extract sigma sigma <- lm_sum$sigma # check the class of each component class(coef_sum) class(sigma) # sha1() has methods for both matrix and numeric # because the values originate from floating point arithmetic it is better to use a low number of digits sha1(coef_sum, digits = 4) sha1(sigma, digits = 4) # we want a single hash # combining the components in a list is a solution that works sha1(list(coef_sum, sigma), digits = 4) # now turn everything into an S3 method # - a function with name "sha1.classname" # - must have the same arguments as sha1() sha1.summary.lm <- function(x, digits = 4, zapsmall = 7){ coef_sum <- coef(x)[, c("Estimate", "Std. Error")] sigma <- x$sigma combined <- list(coef_sum, sigma) sha1(combined, digits = digits, zapsmall = zapsmall) } sha1(lm_sum) # try an altered dataset LCS2 <- LifeCycleSavings[rownames(LifeCycleSavings) != "Zambia", ] lm_SR2 <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LCS2) sha1(summary(lm_SR2)) ``` ### lm Let's illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma. ```{#sha1_lm .R} class(lm_SR) # str() gives the structure of the lm object str(lm_SR) # extract the model and the terms lm_model <- lm_SR$model lm_terms <- lm_SR$terms # check their class class(lm_model) # handled by sha1() class(lm_terms) # not handled by sha1() # define a method for formula sha1.formula <- function(x, digits = 14, zapsmall = 7, ..., algo = "sha1"){ sha1(as.character(x), digits = digits, zapsmall = zapsmall, algo = algo) } sha1(lm_terms) sha1(lm_model) # define a method for lm sha1.lm <- function(x, digits = 14, zapsmall = 7, ..., algo = "sha1"){ lm_model <- x$model lm_terms <- x$terms combined <- list(lm_model, lm_terms) sha1(combined, digits = digits, zapsmall = zapsmall, ..., algo = algo) } sha1(lm_SR) sha1(lm_SR2) ``` ## Using hashes to track changes in analysis Use case - automated analysis - update frequency of the data might be lower than the frequency of automated analysis - similar analyses on many datasets (e.g. many species in ecology) - analyses that require a lot of computing time - not rerunning an analysis because nothing has changed saves enough resources to compensate the overhead of tracking changes - Bundle all relevant information on an analysis in a class - data - method - formula - other metadata - resulting model - calculate `sha1()` file fingerprint ~ `sha1()` on the stable parts status fingerprint ~ `sha1()` on the parts that result for the model 1. Prepare analysis objects 1. Store each analysis object in a rda file which uses the file fingerprint as filename - File will already exist when no change in analysis - Don't overwrite existing files 1. Loop over all rda files - Do nothing if the analysis was run - Otherwise run the analysis and update the status and status fingerprint digest/inst/doc/sha1.html0000644000176200001440000020455514151533263015013 0ustar liggesusers Calculating SHA1 hashes with digest() and sha1()

Calculating SHA1 hashes with digest() and sha1()

Thierry Onkelinx and Dirk Eddelbuettel

Written Jan 2016, updated Jan 2018 and Oct 2020

NB: This vignette is (still) work-in-progress and not yet complete.

Short intro on hashes

TBD

Difference between digest() and sha1()

R FAQ 7.31 illustrates potential problems with floating point arithmetic. Mathematically the equality $x = \sqrt{x}^2$ should hold. But the precision of floating points numbers is finite. Hence some rounding is done, leading to numbers which are no longer identical.

An illustration:

> a0 <- 2
> b <- sqrt(a0)
> a1 <- b^2
> identical(a0, a1)
[1] FALSE
> a0 - a1
[1] -4.440892e-16
> a <- c(a0, a1)
> sprintf("%a", a)
[1] "0x1p+1"               "0x1.0000000000001p+1"

Although the difference is small, any difference will result in different hash when using the digest() function. However, the sha1() function tackles this problem by using the hexadecimal representation of the numbers and truncates that representation to a certain number of digits prior to calculating the hash function.

> library(digest)
> sapply(a, digest, algo = "sha1")
[1] "315a5aa84aa6cfa4f3fb4b652a596770be0365e8"
[2] "5e3999bf79c230f7430e97d7f30070a7eff5ec92"
> sapply(a, sha1)
[1] "8a938d8f5fb9b8ccb6893aa1068babcc517f32d4"
[2] "8a938d8f5fb9b8ccb6893aa1068babcc517f32d4"
> sapply(a, sha1, digits = 15)
[1] "98eb1dc9fada00b945d3ef01c77049ee5a4b7b9c"
[2] "5a173e2445df1134908037f69ac005fbd8afee74"
> sapply(a, sha1, digits = 13)
[1] "43b3b465c975af322c85473190a9214b79b79bf6"
[2] "43b3b465c975af322c85473190a9214b79b79bf6"
> sapply(a, sha1, digits = 10)
[1] "6b537a9693c750ed535ca90527152f06e358aa3a"
[2] "6b537a9693c750ed535ca90527152f06e358aa3a"
> c(sha1(pi), sha1(pi, digits = 13), sha1(pi, digits = 10))
[1] "169388cf1ce60dc4e9904a22bc934c5db33d975b"
[2] "20dc38536b6689d5f2d053f30efb09c44af78378"
[3] "3a727417bd1807af2f0148cf3de69abff32c23ec"

The result of floating point arithematic on 32-bit and 64-bit can be slightly different. E.g. print(pi ^ 11, 22) returns 294204.01797389047 on 32-bit and 294204.01797389053 on 64-bit. Note that only the last 2 digits are different.

command 32-bit 64-bit
print(pi ^ 11, 22) 294204.01797389047 294204.01797389053
sprintf("%a", pi ^ 11) "0x1.1f4f01267bf5fp+18" "0x1.1f4f01267bf6p+18"
digest(pi ^ 11, algo = "sha1") "c5efc7f167df1bb402b27cf9b405d7cebfba339a" "b61f6fea5e2a7952692cefe8bba86a00af3de713"
sha1(pi ^ 11, digits = 14) "5c7740500b8f78ec2354ea6af58ea69634d9b7b1" "4f3e296b9922a7ddece2183b1478d0685609a359"
sha1(pi ^ 11, digits = 13) "372289f87396b0877ccb4790cf40bcb5e658cad7" "372289f87396b0877ccb4790cf40bcb5e658cad7"
sha1(pi ^ 11, digits = 10) "c05965af43f9566bfb5622f335817f674abfc9e4" "c05965af43f9566bfb5622f335817f674abfc9e4"

Choosing digest() or sha1()

TBD

Creating a sha1 method for other classes

How to

  1. Identify the relevant components for the hash.
  2. Determine the class of each relevant component and check if they are handled by sha1().
    • Write a method for each component class not yet handled by sha1.
  3. Extract the relevant components.
  4. Combine the relevant components into a list. Not required in case of a single component.
  5. Apply sha1() on the (list of) relevant component(s).
  6. Turn this into a function with name sha1._classname_.
  7. sha1._classname_ needs exactly the same arguments as sha1()
  8. Choose sensible defaults for the arguments
    • zapsmall = 7 is recommended.
    • digits = 14 is recommended in case all numerics are data.
    • digits = 4 is recommended in case some numerics stem from floating point arithmetic.

summary.lm

Let’s illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma.

> lm_SR <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
> lm_sum <- summary(lm_SR)
> class(lm_sum)
[1] "summary.lm"
> str(lm_sum)
List of 11
 $ call         : language lm(formula = sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
 $ terms        :Classes 'terms', 'formula'  language sr ~ pop15 + pop75 + dpi + ddpi
  .. ..- attr(*, "variables")= language list(sr, pop15, pop75, dpi, ddpi)
  .. ..- attr(*, "factors")= int [1:5, 1:4] 0 1 0 0 0 0 0 1 0 0 ...
  .. .. ..- attr(*, "dimnames")=List of 2
  .. .. .. ..$ : chr [1:5] "sr" "pop15" "pop75" "dpi" ...
  .. .. .. ..$ : chr [1:4] "pop15" "pop75" "dpi" "ddpi"
  .. ..- attr(*, "term.labels")= chr [1:4] "pop15" "pop75" "dpi" "ddpi"
  .. ..- attr(*, "order")= int [1:4] 1 1 1 1
  .. ..- attr(*, "intercept")= int 1
  .. ..- attr(*, "response")= int 1
  .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
  .. ..- attr(*, "predvars")= language list(sr, pop15, pop75, dpi, ddpi)
  .. ..- attr(*, "dataClasses")= Named chr [1:5] "numeric" "numeric" "numeric" "numeric" ...
  .. .. ..- attr(*, "names")= chr [1:5] "sr" "pop15" "pop75" "dpi" ...
 $ residuals    : Named num [1:50] 0.864 0.616 2.219 -0.698 3.553 ...
  ..- attr(*, "names")= chr [1:50] "Australia" "Austria" "Belgium" "Bolivia" ...
 $ coefficients : num [1:5, 1:4] 28.566087 -0.461193 -1.691498 -0.000337 0.409695 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:5] "(Intercept)" "pop15" "pop75" "dpi" ...
  .. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
 $ aliased      : Named logi [1:5] FALSE FALSE FALSE FALSE FALSE
  ..- attr(*, "names")= chr [1:5] "(Intercept)" "pop15" "pop75" "dpi" ...
 $ sigma        : num 3.8
 $ df           : int [1:3] 5 45 5
 $ r.squared    : num 0.338
 $ adj.r.squared: num 0.28
 $ fstatistic   : Named num [1:3] 5.76 4 45
  ..- attr(*, "names")= chr [1:3] "value" "numdf" "dendf"
 $ cov.unscaled : num [1:5, 1:5] 3.74 -7.24e-02 -4.46e-01 -7.86e-05 -1.88e-02 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:5] "(Intercept)" "pop15" "pop75" "dpi" ...
  .. ..$ : chr [1:5] "(Intercept)" "pop15" "pop75" "dpi" ...
 - attr(*, "class")= chr "summary.lm"
> coef_sum <- coef(lm_sum)[, c("Estimate", "Std. Error")]
> sigma <- lm_sum$sigma
> class(coef_sum)
[1] "matrix" "array" 
> class(sigma)
[1] "numeric"
> sha1(coef_sum, digits = 4)
[1] "3f0b0c552f94d753fcc8deb4d3e9fc11a83197af"
> sha1(sigma, digits = 4)
[1] "cbc83d1791ef1eeadd824ea9a038891b5889056b"
> sha1(list(coef_sum, sigma), digits = 4)
[1] "476d27265365cd41662eedf059b335d38a221cc2"
> sha1.summary.lm <- function(x, digits = 4, zapsmall = 7) {
+     coef_sum <- coef(x)[, c("Estimate", "Std. Error")]
+     sigma <- x$sigma
+     com .... [TRUNCATED] 
> sha1(lm_sum)
[1] "476d27265365cd41662eedf059b335d38a221cc2"
> LCS2 <- LifeCycleSavings[rownames(LifeCycleSavings) != 
+     "Zambia", ]
> lm_SR2 <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LCS2)
> sha1(summary(lm_SR2))
[1] "90beb028833bf0542997fde7c3f19e5b9fdfeef4"

lm

Let’s illustrate this using the summary of a simple linear regression. Suppose that we want a hash that takes into account the coefficients, their standard error and sigma.

> class(lm_SR)
[1] "lm"
> str(lm_SR)
List of 12
 $ coefficients : Named num [1:5] 28.566087 -0.461193 -1.691498 -0.000337 0.409695
  ..- attr(*, "names")= chr [1:5] "(Intercept)" "pop15" "pop75" "dpi" ...
 $ residuals    : Named num [1:50] 0.864 0.616 2.219 -0.698 3.553 ...
  ..- attr(*, "names")= chr [1:50] "Australia" "Austria" "Belgium" "Bolivia" ...
 $ effects      : Named num [1:50] -68.38 -14.29 7.3 -3.52 -7.94 ...
  ..- attr(*, "names")= chr [1:50] "(Intercept)" "pop15" "pop75" "dpi" ...
 $ rank         : int 5
 $ fitted.values: Named num [1:50] 10.57 11.45 10.95 6.45 9.33 ...
  ..- attr(*, "names")= chr [1:50] "Australia" "Austria" "Belgium" "Bolivia" ...
 $ assign       : int [1:5] 0 1 2 3 4
 $ qr           :List of 5
  ..$ qr   : num [1:50, 1:5] -7.071 0.141 0.141 0.141 0.141 ...
  .. ..- attr(*, "dimnames")=List of 2
  .. .. ..$ : chr [1:50] "Australia" "Austria" "Belgium" "Bolivia" ...
  .. .. ..$ : chr [1:5] "(Intercept)" "pop15" "pop75" "dpi" ...
  .. ..- attr(*, "assign")= int [1:5] 0 1 2 3 4
  ..$ qraux: num [1:5] 1.14 1.17 1.16 1.15 1.05
  ..$ pivot: int [1:5] 1 2 3 4 5
  ..$ tol  : num 1e-07
  ..$ rank : int 5
  ..- attr(*, "class")= chr "qr"
 $ df.residual  : int 45
 $ xlevels      : Named list()
 $ call         : language lm(formula = sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
 $ terms        :Classes 'terms', 'formula'  language sr ~ pop15 + pop75 + dpi + ddpi
  .. ..- attr(*, "variables")= language list(sr, pop15, pop75, dpi, ddpi)
  .. ..- attr(*, "factors")= int [1:5, 1:4] 0 1 0 0 0 0 0 1 0 0 ...
  .. .. ..- attr(*, "dimnames")=List of 2
  .. .. .. ..$ : chr [1:5] "sr" "pop15" "pop75" "dpi" ...
  .. .. .. ..$ : chr [1:4] "pop15" "pop75" "dpi" "ddpi"
  .. ..- attr(*, "term.labels")= chr [1:4] "pop15" "pop75" "dpi" "ddpi"
  .. ..- attr(*, "order")= int [1:4] 1 1 1 1
  .. ..- attr(*, "intercept")= int 1
  .. ..- attr(*, "response")= int 1
  .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
  .. ..- attr(*, "predvars")= language list(sr, pop15, pop75, dpi, ddpi)
  .. ..- attr(*, "dataClasses")= Named chr [1:5] "numeric" "numeric" "numeric" "numeric" ...
  .. .. ..- attr(*, "names")= chr [1:5] "sr" "pop15" "pop75" "dpi" ...
 $ model        :'data.frame':  50 obs. of  5 variables:
  ..$ sr   : num [1:50] 11.43 12.07 13.17 5.75 12.88 ...
  ..$ pop15: num [1:50] 29.4 23.3 23.8 41.9 42.2 ...
  ..$ pop75: num [1:50] 2.87 4.41 4.43 1.67 0.83 2.85 1.34 0.67 1.06 1.14 ...
  ..$ dpi  : num [1:50] 2330 1508 2108 189 728 ...
  ..$ ddpi : num [1:50] 2.87 3.93 3.82 0.22 4.56 2.43 2.67 6.51 3.08 2.8 ...
  ..- attr(*, "terms")=Classes 'terms', 'formula'  language sr ~ pop15 + pop75 + dpi + ddpi
  .. .. ..- attr(*, "variables")= language list(sr, pop15, pop75, dpi, ddpi)
  .. .. ..- attr(*, "factors")= int [1:5, 1:4] 0 1 0 0 0 0 0 1 0 0 ...
  .. .. .. ..- attr(*, "dimnames")=List of 2
  .. .. .. .. ..$ : chr [1:5] "sr" "pop15" "pop75" "dpi" ...
  .. .. .. .. ..$ : chr [1:4] "pop15" "pop75" "dpi" "ddpi"
  .. .. ..- attr(*, "term.labels")= chr [1:4] "pop15" "pop75" "dpi" "ddpi"
  .. .. ..- attr(*, "order")= int [1:4] 1 1 1 1
  .. .. ..- attr(*, "intercept")= int 1
  .. .. ..- attr(*, "response")= int 1
  .. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
  .. .. ..- attr(*, "predvars")= language list(sr, pop15, pop75, dpi, ddpi)
  .. .. ..- attr(*, "dataClasses")= Named chr [1:5] "numeric" "numeric" "numeric" "numeric" ...
  .. .. .. ..- attr(*, "names")= chr [1:5] "sr" "pop15" "pop75" "dpi" ...
 - attr(*, "class")= chr "lm"
> lm_model <- lm_SR$model
> lm_terms <- lm_SR$terms
> class(lm_model)
[1] "data.frame"
> class(lm_terms)
[1] "terms"   "formula"
> sha1.formula <- function(x, digits = 14, zapsmall = 7, 
+     ..., algo = "sha1") {
+     sha1(as.character(x), digits = digits, zapsmall = zapsmall .... [TRUNCATED] 
> sha1(lm_terms)
[1] "2737d209720aa7d1c0555050ad06ebe89f3850cd"
> sha1(lm_model)
[1] "27b7dd9e3e09b9577da6947b8473b63a1d0b6eb4"
> sha1.lm <- function(x, digits = 14, zapsmall = 7, 
+     ..., algo = "sha1") {
+     lm_model <- x$model
+     lm_terms <- x$terms
+     combined <- .... [TRUNCATED] 
> sha1(lm_SR)
[1] "7eda2a9d58e458c8e782e40ce140d62b836b2a2f"
> sha1(lm_SR2)
[1] "4d3abdb1f17bd12fdf9d9b91a2ad04c07824fe4a"

Using hashes to track changes in analysis

Use case

  • automated analysis

  • update frequency of the data might be lower than the frequency of automated analysis

  • similar analyses on many datasets (e.g. many species in ecology)

  • analyses that require a lot of computing time

    • not rerunning an analysis because nothing has changed saves enough resources to compensate the overhead of tracking changes
  • Bundle all relevant information on an analysis in a class

    • data
    • method
    • formula
    • other metadata
    • resulting model
  • calculate sha1()

    file fingerprint ~ sha1() on the stable parts

    status fingerprint ~ sha1() on the parts that result for the model

  1. Prepare analysis objects
  2. Store each analysis object in a rda file which uses the file fingerprint as filename
    • File will already exist when no change in analysis
    • Don’t overwrite existing files
  3. Loop over all rda files
    • Do nothing if the analysis was run
    • Otherwise run the analysis and update the status and status fingerprint
digest/inst/include/0000755000176200001440000000000012450374665014145 5ustar liggesusersdigest/inst/include/pmurhashAPI.h0000644000176200001440000000613512450374665016504 0ustar liggesusers/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- pmurhashAPI.h -- interface file for external clients Copyright (C) 2014 Wush Wu and Dirk Eddelbuettel This file is part of digest. digest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. digest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with digest. If not, see . */ /* Purpose: Provide MurmurHash3A for use by C / C++ code of other R packages Usage: 1) In your package, add 'LinkingTo: digest' to the DESCRIPTION file. This ensure that R will know the path to this file. 2) In your source code, add '#include ' This ensures the compiler knows the declaration of the function interface. 3) In your package's source code, call 'res = PMurHash32(seed, key, len);' where res and seed are of type MH_UINT32 (which is defined appropriately below). 4) The local function here sets a static pointer to the actual MurmurHash32 implementation in this package. R takes care of the function registration, export and import --- meaning that no build-time linking of your package is needed resulting in simpler and more robust build steps. */ #ifndef __PMURHASH_H__ #define __PMURHASH_H__ #include #include #ifdef HAVE_VISIBILITY_ATTRIBUTE # define attribute_hidden __attribute__ ((visibility ("hidden"))) #else # define attribute_hidden #endif #ifdef __cplusplus extern "C" { #endif /* First look for special cases */ #if defined(_MSC_VER) #define MH_UINT32 unsigned long #endif /* If the compiler says it's C99 then take its word for it */ #if !defined(MH_UINT32) && ( \ defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L ) #include #define MH_UINT32 uint32_t #endif /* Otherwise try testing against max value macros from limit.h */ #if !defined(MH_UINT32) #include #if (USHRT_MAX == 0xffffffffUL) #define MH_UINT32 unsigned short #elif (UINT_MAX == 0xffffffffUL) #define MH_UINT32 unsigned int #elif (ULONG_MAX == 0xffffffffUL) #define MH_UINT32 unsigned long #endif #endif #if !defined(MH_UINT32) #error Unable to determine type name for unsigned 32-bit int #endif MH_UINT32 attribute_hidden PMurHash32(MH_UINT32 seed, const void *key, int len) { static MH_UINT32(*f)(MH_UINT32, const void*, int) = NULL; if (!f) { f = (MH_UINT32(*)(MH_UINT32, const void*, int)) R_GetCCallable("digest", "PMurHash32"); } return f(seed, key, len); } #ifdef __cplusplus } #endif #endif /* __PMURHASH_H__ */ digest/inst/tinytest/0000755000176200001440000000000014122616624014375 5ustar liggesusersdigest/inst/tinytest/test_encoding.R0000644000176200001440000000135114122616624017345 0ustar liggesusers isWindows <- Sys.info()[["sysname"]] == "Windows" if (!isWindows) exit_file("Skipping test on non-Windows platform") d <- tempfile() dir.create(d) # A file path not representable in latin-1 f <- file.path(d, "tricky-ő") # We need to use a binary mode connection so the newlines # are consistent across platforms con <- file(f, open = "wb") writeLines("foobar", con = con) close(con) expect_identical(digest::digest(file = f), "14758f1afd44c09b7992073ccf00b43d") expect_identical(digest::digest(f, file = TRUE), "14758f1afd44c09b7992073ccf00b43d") vd <- getVDigest() expect_identical(vd(file = f), "14758f1afd44c09b7992073ccf00b43d") expect_identical(vd(f, file = TRUE), "14758f1afd44c09b7992073ccf00b43d") unlink(d, recursive = TRUE) digest/inst/tinytest/test_sha1.R0000644000176200001440000003243513574673675016445 0ustar liggesusers ## tests for digest, taken from the examples in the manual page suppressMessages(library(digest)) # calculate sha1 fingerprints x.numeric <- c(seq(0, 1, length = 4 ^ 3), -Inf, Inf, NA, NaN) x.list <- list(letters, x.numeric) x.dataframe <- data.frame(X = letters, Y = x.numeric[2], Z = factor(letters), stringsAsFactors = FALSE) x.matrix.num <- as.matrix(x.numeric) x.matrix.letter <- as.matrix(letters) x.dataframe.round <- x.dataframe x.dataframe.round$Y <- signif(x.dataframe.round$Y, 14) x.factor <- factor(letters) x.array.num <- as.array(x.numeric) x.formula <- a~b+c|d x.paren_formula <- a~(b+c) x.no_paren_formula <- a~b+c # tests using detailed numbers expect_false(identical(x.numeric, signif(x.numeric, 14))) expect_false(identical(x.matrix.num, signif(x.matrix.num, 14))) # returns the correct SHA1 expect_true( identical( sha1(x.numeric), { z <- digest:::num2hex(x.numeric) attr(z, "digest::sha1") <- list( class = class(x.numeric), digits = 14L, zapsmall = 7L ) digest(z, algo = "sha1") } ) ) # Verify that all numeric values (especially +-Inf and NA/NaN) return unique # SHA1 hashes expect_false( any(duplicated(sapply(x.numeric, sha1))) ) expect_true( identical( sha1(letters), { z <- letters attr(z, "digest::sha1") <- list( class = "character", digits = 14L, zapsmall = 7L ) digest(z, algo = "sha1") } ) ) expect_true( identical( sha1(x.list), { z <- sapply(x.list, sha1) attr(z, "digest::sha1") <- list( class = "list", digits = 14L, zapsmall = 7L ) digest(z, algo = "sha1") } ) ) options(sha1PackageVersion = "0.6.22.1") expect_true( identical( sha1(x.dataframe), { z <- sapply(x.dataframe, sha1) attr(z, "digest::sha1") <- list( class = "data.frame", digits = 14L, zapsmall = 7L ) digest(z, algo = "sha1") } ) ) ## expect_true( ## identical( ## sha1(x.matrix.num), ## { ## z <- matrix( ## apply(x.matrix.num, 2, digest:::num2hex), ## ncol = ncol(x.matrix.num) ## ) ## attr(z, "digest::sha1") <- list( ## class = "matrix", ## digits = 14L, ## zapsmall = 7L ## ) ## digest(z, algo = "sha1") ## } ## ) ## ) ## expect_true( ## identical( ## sha1(x.matrix.letter), ## { ## z <- x.matrix.letter ## attr(z, "digest::sha1") <- list( ## class = "matrix", ## digits = 14L, ## zapsmall = 7L ## ) ## digest(z, algo = "sha1") ## } ## ) ## ) stopifnot( identical( sha1(x.factor), { z <- x.factor attr(z, "digest::sha1") <- list( class = "factor", digits = 14L, zapsmall = 7L ) digest(z, algo = "sha1") } ) ) # a matrix and a vector should have a different hash expect_true( !identical( sha1(x.numeric), sha1(matrix(x.numeric, nrow = 1)) ) ) expect_true( !identical( sha1(x.numeric), sha1(matrix(x.numeric, ncol = 1)) ) ) expect_true( !identical( sha1(letters), sha1(matrix(letters, nrow = 1)) ) ) expect_true( !identical( sha1(letters), sha1(matrix(letters, ncol = 1)) ) ) # character(0) and numeric(0) should have a different hash expect_true(!identical(sha1(character(0)), sha1(numeric(0)))) # a POSIXct and a POSIXlt should give a different hash z <- as.POSIXct("2015-01-02 03:04:06.07", tz = "UTC") expect_true( !identical( sha1(z), sha1(as.POSIXlt(z)) ) ) lm.model.0 <- lm(weight ~ Time, data = ChickWeight) lm.model.1 <- lm(weight ~ 1, data = ChickWeight) glm.model.0 <- glm(weight ~ Time, data = ChickWeight, family = poisson) glm.model.1 <- glm(weight ~ 1, data = ChickWeight, family = poisson) anova.list <- list( lm = anova(lm.model.0, lm.model.1), glm = anova(glm.model.0, glm.model.1), glm.test = anova(glm.model.0, glm.model.1, test = "Chisq") ) # works with lm anova" expect_true( identical( sha1(anova.list[["lm"]]), { y <- apply( anova.list[["lm"]], 1, digest:::num2hex, digits = 4, zapsmall = 7 ) attr(y, "digest::sha1") <- list( class = c("anova", "data.frame"), digits = 4L, zapsmall = 7L ) digest(y, algo = "sha1") } ) ) # works with glm anova" expect_true( identical( sha1(anova.list[["glm"]]), { y <- apply( anova.list[["glm"]], 1, digest:::num2hex, digits = 4, zapsmall = 7 ) attr(y, "digest::sha1") <- list( class = c("anova", "data.frame"), digits = 4L, zapsmall = 7L ) digest(y, algo = "sha1") } ) ) expect_true( identical( sha1(anova.list[["glm.test"]]), { y <- apply( anova.list[["glm.test"]], 1, digest:::num2hex, digits = 4, zapsmall = 7 ) attr(y, "digest::sha1") <- list( class = c("anova", "data.frame"), digits = 4L, zapsmall = 7L ) digest(y, algo = "sha1") } ) ) expect_true( identical( sha1(x.formula, environment=FALSE), { y <- sapply( X=x.formula, FUN=sha1, digits=14L, zapsmall=7L, ...=list(environment=FALSE), algo="sha1" ) attr(y, "digest::sha1") <- list( class="formula", digits=14L, zapsmall=7L, environment=FALSE ) digest(y, algo="sha1") } ) ) expect_true( identical( sha1(x.formula), { y <- c( sapply( X=x.formula, FUN=sha1, digits=14L, zapsmall=7L, ...=list(environment=TRUE), algo="sha1" ), digest(environment(x.formula), algo="sha1") ) attr(y, "digest::sha1") <- list( class="formula", digits=14L, zapsmall=7L ) digest(y, algo="sha1") } ) ) expect_true( sha1(x.paren_formula) != sha1(x.no_paren_formula) ) test.element <- list( # NULL NULL, # empty classes logical(0), integer(0), numeric(0), character(0), list(), data.frame(), # scalar TRUE, FALSE, 1L, 1, "a", # date. Make sure to add the time zone. Otherwise the test might fail as.POSIXct("2015-01-02 03:04:06.07", tz = "UTC"), # vector c(TRUE, FALSE), 1:3, seq(0, 10, length = 4), letters[1:3], factor(letters[4:6]), as.POSIXct(c("2015-01-02 03:04:06.07", "1960-12-31 23:59:59"), tz = "UTC") ) select.vector <- which(sapply(test.element, length) > 1) test.element <- c( test.element, # add a data.frame list(expand.grid(test.element[select.vector])), # add a list list(test.element[select.vector]), # add matrices list(matrix(1:10)), list(matrix(seq(0, 10, length = 4))), list(matrix(letters)) ) # different values for digits or zapsmall gives different hashes # expect for NULL expect_true( identical( sha1(NULL, digits = 14), sha1(NULL, digits = 13) ) ) expect_true( identical( sha1(NULL, zapsmall = 14), sha1(NULL, zapsmall = 13) ) ) for (i in tail(seq_along(test.element), -1)) { expect_true( !identical( sha1(test.element[[i]], digits = 14), sha1(test.element[[i]], digits = 13) ) ) expect_true( !identical( sha1(test.element[[i]], zapsmall = 7), sha1(test.element[[i]], zapsmall = 6) ) ) } test.element <- c(test.element, anova.list) #cat("\ncorrect <- c(\n") #cat( # sprintf(" \"%s\"", sapply(test.element, sha1)), # sep = ",\n" #) #cat(")\n") correct <- c( "8d9c05ec7ae28b219c4c56edbce6a721bd68af82", "d61eeea290dd09c5a3eba41c2b3174b6e4e2366d", "af23305d27f0409c91bdb86ba7c0cdb2e09a5dc6", "0c9ca70ce773deb0d9c0b0579c3b94856edf15cc", "095886422ad26e315c0960ef6b09842a1f9cc0ce", "6cc04c6c432bb91e210efe0b25c6ca809e6df2e3", "c1113ba008a349de64da2a7a724e501c1eb3929b", "6e12370bdc6fc457cc154f0525e22c6aa6439f4d", "1c1b5393c68a643bc79c277c6d7374d0b30cd985", "b48c17a2ac82601ff38df374f87d76005fb61cbd", "35280c99aa6a48bfc2810b72b763ccac0f632207", "f757cc017308d217f35ed8f0c001a57b97308fb7", "cfcf101b8449af67d34cdc1bcb0432fe9e4de08e", "a14384d1997440bad13b97b3ccfb3b8c0392e79a", "555f6bea49e58a2c2541060a21c2d4f9078c3086", "631d18dec342e2cb87614864ba525ebb9ad6a124", "b6c04f16b6fdacc794ea75c8c8dd210f99fafa65", "25485ba7e315956267b3fdc521b421bbb046325d", "6def3ca353dfc1a904bddd00e6a410d41ac7ab01", "cf220bcf84c3d0ab1b01f8f764396941d15ff20f", "2af8021b838f613aee7670bed19d0ddf1d6bc0c1", "270ed85d46524a59e3274d89a1bbf693521cb6af", "60e09482f12fda20f7d4a70e379c969c5a73f512", "10380001af2a541b5feefc7aab9f719b67330a42", "4580ff07f27eb8321421efac1676a80d9239572a", "d3022c5a223caaf77e9c564e024199e5d6f51bd5", "f54742ac61edd8c3980354620816c762b524dfc7" ) # each object should yield a different hash expect_true(!any(duplicated(correct))) # returns the same SHA1 on both 32-bit and 64-bit OS" ## for (i in seq_along(test.element)) { ## expect_true( ## identical( ## sha1(test.element[[i]]), ## correct[i] ## ) ## ) ## } # does work with empty lists and data.frames expect_true(is.character(sha1(list()))) expect_true(is.character(sha1(data.frame()))) expect_true(is.character(sha1(list(a = 1, b = list(), c = data.frame())))) # does work with complex type expect_true(is.character(sha1(2 + 5i))) # single complex number expect_true(is.character(sha1(1:10 + 5i))) # vector of complex numbers # complex number with only the real part should be different from real number expect_true(sha1(2) != sha1(2 + 0i)) # does work with Date type expect_true(is.character(sha1(Sys.Date()))) expect_true(sha1(as.Date("1980-01-01")) != sha1(as.Date("1990-01-01"))) # different hashes for differently shaped arrays that contain the same data data <- 1:8 a <- array(data, dim = c(2,2,2)) # cube 2x2x2 b <- array(data, dim = c(2,4,1)) # matrix 2x4 expect_true(sha1(a) != sha1(b)) # test error message junk <- pi class(junk) <- c("A", "B") #error.message <- try(sha1(junk)) #expect_true(grepl("sha1\\(\\) has no method for the 'A', 'B' class", error.message)) junk <- function( x, y = list(...), test = TRUE, start = NULL, text = "abc", family = poisson, ... ){ sha1(x) } #expect_true(sha1(junk) == "be194e8cdae926c13fd4e2c65bf6cb7a28dd0505") expect_true(sha1(junk) == sha1(junk, environment = TRUE)) expect_true(sha1(junk) != sha1(junk, environment = FALSE)) #expect_true(sha1(matrix(integer(0))) == "e13485e1b995f3e36d43674dcbfedea08ce237bc") expect_true( !identical( sha1(matrix(integer(0))), sha1(matrix(character(0))) ) ) expect_true( !identical( sha1(matrix(integer(0))), sha1(matrix(numeric(0))) ) ) ## if (getRversion() < "3.5.0") { ## expect_true( ## identical( ## sha1(serialize("e13485e1b995f3e36d43674dcbfedea08ce237bc", NULL)), ## "93ab6a61f1a2ad50d4bf58396dc38cd3821b2eaf" ## ) ## ) ## } x <- letters for (algo in c("md5", "sha1", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32")) { y <- x attr(y, "digest::sha1") <- digest:::attr_sha1(x, 14L, 7L, algo = algo) expect_true( identical( sha1(x, algo = algo), digest(y, algo = algo) ) ) } expect_true(is.character(sha1(sessionInfo()))) # check the effect of attributes from version 0.6.22.2 options(sha1PackageVersion = utils::packageVersion("digest")) check_attribute_effect <- function(x) { y <- x attr(y, "test") <- "junk" expect_false(sha1(x) == sha1(y)) } test.element <- list(2 + 5i, x.array.num, Sys.Date(), Sys.time(), y ~ x) test.element <- c(test.element, list(x.dataframe), anova.list, function(x){x}) for (z in test.element) { check_attribute_effect(z) } # check that sha1() on contributed functions maintain there hash after storing f <- tempfile(fileext = ".rds") x <- digest::sha1 saveRDS(x, f) y <- readRDS(f) expect_identical(sha1(x), sha1(y)) expect_identical(sha1(x, environment = FALSE), sha1(y, environment = FALSE)) digest/inst/tinytest/test_digest.R0000644000176200001440000002311313737376416017053 0ustar liggesusers ## tests for digest, taken from the examples in the manual page suppressMessages(library(digest)) ## Standard RFC 1321 test vectors md5Input <- c("", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", paste("12345678901234567890123456789012345678901234567890123456789012", "345678901234567890", sep="")) md5Output <- c("d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a") for (i in seq(along.with=md5Input)) { md5 <- digest(md5Input[i], serialize=FALSE) expect_true(identical(md5, md5Output[i])) #cat(md5, "\n") } md5 <- getVDigest() expect_identical(md5(md5Input, serialize = FALSE), md5Output) expect_identical(digest(NULL), md5(NULL)) expect_identical(digest(character(0)), md5(character(0))) expect_identical(digest(list("abc")), md5(list(list("abc")))) expect_identical(digest(list(NULL)), md5(list(list(NULL)))) expect_identical(digest(character(0), serialize = FALSE), md5(character(0), serialize = FALSE)) ## md5 raw output test for (i in seq(along.with=md5Input)) { md5 <- digest(md5Input[i], serialize=FALSE, raw=TRUE) md5 <- gsub(" ","",capture.output(cat(md5))) expect_true(identical(md5, md5Output[i])) #cat(md5, "\n") } sha1Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", NULL) sha1Output <- c("a9993e364706816aba3e25717850c26c9cd0d89d", "84983e441c3bd26ebaae4aa1f95129e5e54670f1", "34aa973cd4c4daa4f61eeb2bdbad27316534016f") for (i in seq(along.with=sha1Input)) { sha1 <- digest(sha1Input[i], algo="sha1", serialize=FALSE) expect_true(identical(sha1, sha1Output[i])) #cat(sha1, "\n") } sha1 <- getVDigest(algo = 'sha1') expect_identical(sha1(sha1Input, serialize = FALSE), sha1Output[1:2]) ## sha1 raw output test for (i in seq(along.with=sha1Input)) { sha1 <- digest(sha1Input[i], algo="sha1", serialize=FALSE, raw=TRUE) #print(sha1) sha1 <- gsub(" ","",capture.output(cat(sha1))) #print(sha1) #print(sha1Output[i]) expect_true(identical(sha1, sha1Output[i])) #cat(sha1, "\n") } ## sha512 test sha512Input <-c( "", "The quick brown fox jumps over the lazy dog." ) sha512Output <- c( "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed") for (i in seq(along.with=sha512Input)) { sha512 <- digest(sha512Input[i], algo="sha512", serialize=FALSE) expect_true(identical(sha512, sha512Output[i])) #cat(sha512, "\n") } sha512 <- getVDigest(algo = 'sha512') expect_identical(sha512(sha512Input, serialize = FALSE), sha512Output[1:2]) ## sha512 raw output test for (i in seq(along.with=sha512Input)) { sha512 <- digest(sha512Input[i], algo="sha512", serialize=FALSE, raw=TRUE) #print(sha512) sha512 <- gsub(" ","",capture.output(cat(sha512))) #print(sha512) #print(sha512Output[i]) expect_true(identical(sha512, sha512Output[i])) #cat(sha512, "\n") } crc32Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", NULL) crc32Output <- c("352441c2", "171a3f5f", "2ef80172") for (i in seq(along.with=crc32Input)) { crc32 <- digest(crc32Input[i], algo="crc32", serialize=FALSE) expect_true(identical(crc32, crc32Output[i])) #cat(crc32, "\n") } crc32 <- getVDigest(algo = 'crc32') expect_identical(crc32(crc32Input, serialize = FALSE), crc32Output[1:2]) ## one of the FIPS- sha1 <- digest("abc", algo="sha1", serialize=FALSE) expect_true(identical(sha1, "a9993e364706816aba3e25717850c26c9cd0d89d")) ## This one seems to give slightly different output depending on the R version used ## ## # example of a digest of a standard R list structure ## cat(digest(list(LETTERS, data.frame(a=letters[1:5], ## b=matrix(1:10, ## ncol=2)))), "\n") ## these outputs were calculated using xxh32sum xxhash32Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "") xxhash32Output <- c("32d153ff", "89ea60c3", "02cc5d05") for (i in seq(along.with=xxhash32Input)) { xxhash32 <- digest(xxhash32Input[i], algo="xxhash32", serialize=FALSE) #cat(xxhash32, "\n") expect_true(identical(xxhash32, xxhash32Output[i])) } xxhash32 <- getVDigest(algo = 'xxhash32') expect_identical(xxhash32(xxhash32Input, serialize = FALSE), xxhash32Output) ## these outputs were calculated using xxh64sum xxhash64Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "") xxhash64Output <- c("44bc2cf5ad770999", "f06103773e8585df", "ef46db3751d8e999") for (i in seq(along.with=xxhash64Input)) { xxhash64 <- digest(xxhash64Input[i], algo="xxhash64", serialize=FALSE) #cat(xxhash64, "\n") expect_true(identical(xxhash64, xxhash64Output[i])) } xxhash64 <- getVDigest(algo = 'xxhash64') expect_identical(xxhash64(xxhash64Input, serialize = FALSE), xxhash64Output) ## these outputs were calculated using mmh3 python package ## the first two are also shown at this StackOverflow question on test vectors ## https://stackoverflow.com/questions/14747343/murmurhash3-test-vectors murmur32Input <- c("abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "") murmur32Output <- c("b3dd93fa", "ee925b90", "00000000") for (i in seq(along.with=murmur32Input)) { murmur32 <- digest(murmur32Input[i], algo="murmur32", serialize=FALSE) #cat(murmur32, "\n") expect_true(identical(murmur32, murmur32Output[i])) } murmur32 <- getVDigest(algo = 'murmur32') expect_identical(murmur32(murmur32Input, serialize = FALSE), murmur32Output) ## tests for digest spooky expect_true(require(digest)) ## test vectors (originally for md5) spookyInput <- c("", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", paste("12345678901234567890123456789012345678901234567890123456789012", "345678901234567890", sep="")) # from spooky import hash128 # from binascii import hexlify # # spookyInput = [ # "", # "a", # "abc", # "message digest", # "abcdefghijklmnopqrstuvwxyz", # "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", # "12345678901234567890123456789012345678901234567890123456789012345678901234567890" # ] # # for s in spookyInput: # hexlify(hash128(s).to_bytes(16, 'little')).decode() # # '1909f56bfc062723c751e8b465ee728b' # 'bdc9bba09181101a922a4161f0584275' # '67c93775f715ab8ab01178caf86713c6' # '9630c2a55c0987a0db44434f9d67a192' # '5172de938ce149a98f4d06d3c3168ffe' # 'b5b3b2d0f08b58aa07f551895f929f81' # '3621ec01112dafa1610a4bd23041966b' spookyOutputPython <- c( '1909f56bfc062723c751e8b465ee728b', 'bdc9bba09181101a922a4161f0584275', '67c93775f715ab8ab01178caf86713c6', '9630c2a55c0987a0db44434f9d67a192', '5172de938ce149a98f4d06d3c3168ffe', 'b5b3b2d0f08b58aa07f551895f929f81', '3621ec01112dafa1610a4bd23041966b' ) ## spooky raw output test for (i in seq(along.with=spookyInput)) { # skip = 30 skips the entire serialization header for a length 1 character vector # this is equivalent to raw = TRUE and matches the python spooky implementation for those vectors spooky <- digest(spookyInput[i], algo = "spookyhash", skip = 30) expect_true(identical(spooky, spookyOutputPython[i])) #cat(spooky, "\n") } expect_identical( getVDigest(algo = 'spookyhash')(spookyInput, skip = 30), spookyOutputPython ) ## some extras to get coverage up - these aren't tested against reference output, ## just output from R 3.6.0 spookyInput <- c("a", "aaaaaaaaa", "aaaaaaaaaaaaa") spookyOutput <- c( "b7a3573ba6139dfdc52db30acba87f46", "fd876ecaa5d1e442600333118f223e02", "91848873bf91d06ad321bbd47400a556" ) for (i in seq(along.with=spookyInput)) { spooky <- digest(spookyInput[i], algo = "spookyhash") expect_true(identical(spooky, spookyOutput[i])) #cat(spooky, "\n") } expect_identical( getVDigest(algo = 'spookyhash')(spookyInput), spookyOutput ) # test a bigger object spooky <- digest(iris, algo = "spookyhash") expect_true(identical(spooky, "af58add8b4f7044582b331083bc239ff")) expect_identical(getVDigest('spookyhash')(list(iris)), "af58add8b4f7044582b331083bc239ff") #cat(spooky, "\n") # test error message #error.message <- try(digest(spookyInput[i], algo = "spookyhash", serialize = FALSE)) #expect_true( # grepl("spookyhash algorithm is not available without serialization.", error.message) #) ## Ensure that all values of algo are actually allowed (in case a new one is ## added in the future). The call to match.arg() passes choices explicitly ## because it is significantly faster to do it than to have it automatically ## infer the possible choices from the function's formals. # Grab the possible values of algo, then call digest() for each one. algos <- eval(formals(digest)$algo) for (algo in algos) { digest(123, algo = algo) } # Same for getVDigest algos <- eval(formals(getVDigest)$algo) for (algo in algos) { getVDigest(algo = algo) } digest/inst/tinytest/test_aes.R0000644000176200001440000001121713545111302016320 0ustar liggesusers ## tests for AES, taken from the examples in the manual page suppressMessages(library(digest)) # FIPS-197 examples hextextToRaw <- function(text) { vals <- matrix(as.integer(as.hexmode(strsplit(text, "")[[1]])), ncol=2, byrow=TRUE) vals <- vals %*% c(16, 1) as.raw(vals) } plaintext <- hextextToRaw("00112233445566778899aabbccddeeff") aes128key <- hextextToRaw("000102030405060708090a0b0c0d0e0f") aes128output <- hextextToRaw("69c4e0d86a7b0430d8cdb78070b4c55a") aes <- AES(aes128key) #aes aes128 <- aes$encrypt(plaintext) #aes128 expect_true(identical(aes128, aes128output)) expect_true(identical(plaintext, aes$decrypt(aes128, raw=TRUE))) aes192key <- hextextToRaw("000102030405060708090a0b0c0d0e0f1011121314151617") aes192output <- hextextToRaw("dda97ca4864cdfe06eaf70a0ec0d7191") aes <- AES(aes192key) #aes aes192 <- aes$encrypt(plaintext) #aes192 expect_true(identical(aes192, aes192output)) expect_true(identical(plaintext, aes$decrypt(aes192, raw=TRUE))) aes256key <- hextextToRaw("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") aes256output <- hextextToRaw("8ea2b7ca516745bfeafc49904b496089") aes <- AES(aes256key) aes256 <- aes$encrypt(plaintext) #aes256 expect_true(identical(aes256, aes256output)) expect_true(identical(plaintext, aes$decrypt(aes256, raw=TRUE))) # SP800-38a examples plaintext <- hextextToRaw(paste("6bc1bee22e409f96e93d7e117393172a", "ae2d8a571e03ac9c9eb76fac45af8e51", "30c81c46a35ce411e5fbc1191a0a52ef", "f69f2445df4f9b17ad2b417be66c3710",sep="")) key <- hextextToRaw("2b7e151628aed2a6abf7158809cf4f3c") ecb128output <- hextextToRaw(paste("3ad77bb40d7a3660a89ecaf32466ef97", "f5d3d58503b9699de785895a96fdbaaf", "43b1cd7f598ece23881b00e3ed030688", "7b0c785e27e8ad3f8223207104725dd4",sep="")) aes <- AES(key) ecb128 <- aes$encrypt(plaintext) #ecb128 expect_true(identical(ecb128, ecb128output)) expect_true(identical(plaintext, aes$decrypt(ecb128, raw=TRUE))) cbc128output <- hextextToRaw(paste("7649abac8119b246cee98e9b12e9197d", "5086cb9b507219ee95db113a917678b2", "73bed6b8e3c1743b7116e69e22229516", "3ff1caa1681fac09120eca307586e1a7",sep="")) iv <- hextextToRaw("000102030405060708090a0b0c0d0e0f") aes <- AES(key, mode="CBC", IV=iv) cbc128 <- aes$encrypt(plaintext) #cbc128 expect_true(identical(cbc128, cbc128output)) aes <- AES(key, mode="CBC", IV=iv) expect_true(identical(plaintext, aes$decrypt(cbc128, raw=TRUE))) ctr128output <- hextextToRaw(paste("874d6191b620e3261bef6864990db6ce", "9806f66b7970fdff8617187bb9fffdff", "5ae4df3edbd5d35e5b4f09020db03eab", "1e031dda2fbe03d1792170a0f3009cee",sep="")) iv <- hextextToRaw("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") aes <- AES(key, mode="CTR", IV=iv) ctr128 <- aes$encrypt(plaintext) #ctr128 expect_true(identical(ctr128, ctr128output)) aes <- AES(key, mode="CTR", IV=iv) expect_true(identical(plaintext, aes$decrypt(ctr128, raw=TRUE))) #cfb key <- hextextToRaw("2b7e151628aed2a6abf7158809cf4f3c") iv <- hextextToRaw("000102030405060708090a0b0c0d0e0f") #cfb not a multiplier of 16 text <- "This is very secret string" key <- hextextToRaw("2b7e151628aed2a6abf7158809cf4f3c") iv <- hextextToRaw("000102030405060708090a0b0c0d0e0f") cfb128output <- hextextToRaw(paste("04960ebfb9044196ac6c4590bbdc8903", "e1259a479e199af94518",sep="")) aes <- AES(key, mode="CFB", IV=iv) cfb128 <- aes$encrypt(text) expect_true(identical(cfb128, cfb128output)) aes <- AES(key, mode="CFB", IV=iv) expect_true(identical(text, aes$decrypt(cfb128, raw=FALSE))) #cfb128 cfb128output <- hextextToRaw(paste("3b3fd92eb72dad20333449f8e83cfb4a", "c8a64537a0b3a93fcde3cdad9f1ce58b", "26751f67a3cbb140b1808cf187a4f4df", "c04b05357c5d1c0eeac4c66f9ff7f2e6",sep="")) aes <- AES(key, mode="CFB", IV=iv) cfb128 <- aes$encrypt(plaintext) expect_true(identical(cfb128, cfb128output)) aes <- AES(key, mode="CFB", IV=iv) expect_true(identical(plaintext, aes$decrypt(cfb128, raw=TRUE))) # test throws exeception on IV null or not a multiplier of 16 bytes aes <- AES(key, mode="CFB", IV=NULL) expect_error(aes$encrypt(plaintext)) expect_error(aes$decrypt(plaintext)) aes <- AES(key, mode="CFB", IV=raw(15)) expect_error(aes$encrypt(plaintext)) expect_error(aes$decrypt(plaintext)) digest/inst/tinytest/test_hmac.R0000644000176200001440000000710513503674673016504 0ustar liggesusers ## tests for hmac, taken from the examples in the manual page suppressMessages(library(digest)) ## Standard RFC 2104 test vectors current <- hmac('Jefe', 'what do ya want for nothing?', "md5") target <- '750c783e6ab0b503eaa86e310a5db738' expect_true(identical(target, as.character(current))) #cat(current, "\n") current <- hmac('Jefe', 'what do ya want for nothing?', "md5") target <- '750c783e6ab0b503eaa86e310a5db738' expect_true(identical(target, as.character(current))) #cat(current, "\n") current <- hmac(rep(0x0b, 16), 'Hi There', "md5") target <- '9294727a3638bb1c13f48ef8158bfc9d' expect_true(identical(target, as.character(current))) #cat(current, "\n") current <- hmac(rep(0xaa, 16), rep(0xdd, 50), "md5") target <- '56be34521d144c88dbb8c733f0e8b3f6' expect_true(identical(target, as.character(current))) #cat(current, "\n") ## test for key longer than block size. key should be hashed itself. current <- hmac('ThisKeyIsLongerThan64BytesAndThereforeLongerThanTheHashDigestByFour', 'what do ya want for nothing?', "md5") target <- '109af8ddd9cccbf8927d354da8be892b' expect_true(identical(target, as.character(current))) #cat(current, "\n") ## SHA1 tests inspired to the RFC 2104 and checked against the python ## hmac implementation. current <- hmac('Jefe', 'what do ya want for nothing?', "sha1") target <- 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79' expect_true(identical(target, as.character(current))) #cat(current, "\n") current <- hmac(rep(0x0b, 16), 'Hi There', "sha1") target <- '675b0b3a1b4ddf4e124872da6c2f632bfed957e9' expect_true(identical(target, as.character(current))) #cat(current, "\n") current <- hmac(rep(0xaa, 16), rep(0xdd, 50), "sha1") target <- 'd730594d167e35d5956fd8003d0db3d3f46dc7bb' expect_true(identical(target, as.character(current))) #cat(current, "\n") ## SHA256 tests from wikipedia current <- hmac('key', 'The quick brown fox jumps over the lazy dog', 'sha256') target <- 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8' expect_true(identical(target, as.character(current))) #cat(current, "\n") ## SHA512 tests inspired, one from RFC 2104 and one from user, checked against python hmac # python code: # from hashlib import sha512 # import hmac # print(hmac.new("love","message",sha512).hexdigest()) current <- hmac('Jefe', 'what do ya want for nothing?', "sha512") target <- '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737' expect_true(identical(target, as.character(current))) #cat(current, "\n") current <- hmac('love', 'message', 'sha512') target <- 'f955821b3f6161673eb20985c677e3dc101860cafef3321ee31641acad9fcd85d9c7d3481ed3e4e1f4fa7af41d7e6ea9606d51e9bc7205d0091a4ee87d90fb9c' expect_true(identical(target, as.character(current))) #cat(current, "\n") ## test for key longer than block size. key should be hashed itself. current <- hmac('verylongkeyinfactlongerthanthedigestandthereforehashedbyitselfonlyifwegettothislengthsoonpleasepleasebutiddoesnotlooksoogoodahthereweare', 'message', 'sha512') target <- '54b274484a8b8a371c8ae898f453d37c90d488b0c88c89dd705de06b18263d50c28069f1f778c8a997a61a4d53a06bc8e8719ad11a553c49140bb93a4636882e' expect_true(identical(target, as.character(current))) #cat(current, "\n") ## motivated by coverage report rw <- charToRaw("123456789ABCDEF") expect_true(all.equal(makeRaw(rw), rw)) current <- hmac('Jefe', 'what do ya want for nothing?', "md5", raw=TRUE) target <- as.raw(c(0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38)) expect_true(identical(target, current)) #digest:::padWithZeros(rw, "crc32") digest/inst/tinytest/test_digest2int.R0000644000176200001440000000102713503674673017645 0ustar liggesusers suppressMessages(library(digest)) input <- letters[1:5] hashed_seed_0 <- c(-902917054L, 14385563L, -289776295L, 592496261L, 286663184L) expect_equal(digest2int(input), hashed_seed_0) hashed_seed_1 <- c(14385563L, -289776295L, 592496261L, 286663184L, 1208324078L) expect_equal(digest2int(input, 1L), hashed_seed_1) # should fail if uint32_t on the system is not a 32-bit unsigned integer expect_equal(digest2int("cat sat on the mat"), 562079877L) expect_equal(digest2int("The quick brown fox jumps over the lazy dog"), 1369346549L) digest/inst/tinytest/test_raw.R0000644000176200001440000000126413503674673016365 0ustar liggesusers ## tests for raw output suppressMessages(library(digest)) current <- hmac("Jefe", 'what do ya want for nothing?', "md5", raw=TRUE) expected <- as.raw(c(0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38)) expect_equal(current, expected) current <- digest("The quick brown fox", algo="sha1", raw=TRUE) expected <- as.raw(c(0x5f, 0x79, 0x8c, 0xb4, 0xd8, 0x14, 0x4e, 0xec, 0x35, 0xf4, 0xd0, 0x79, 0x3e, 0xf2, 0x1e, 0x55, 0xce, 0xb6, 0xa7, 0x88)) expect_equal(current, expected) ## feed raw to sha1() to test sha1.raw() as well expect_true(sha1(expected) == "75a2995eeec0fcb5d7fa97c676a37f4e224981a1") digest/inst/tinytest/test_num2hex.R0000644000176200001440000000320013537453061017143 0ustar liggesusers## tests for digest, taken from the examples in the manual page suppressMessages(library(digest)) # zap small numbers to zero zapsmall <- 1:10 border <- 2 ^ floor(log2(10 ^ -zapsmall)) expect_equal( sapply( seq_along(zapsmall), function(i) { digest:::num2hex(border[i] * -1:1, digits = 6, zapsmall = zapsmall[i]) } ), matrix( "0", ncol = length(zapsmall), nrow = 3 ) ) # handle 0 correct expect_equal(digest:::num2hex(0), "0") # digits are consistent x <- pi x.hex <- sapply(1:16, digest:::num2hex, x = x) x.hex <- x.hex[c(TRUE, diff(nchar(x.hex)) > 0)] exponent <- unique(gsub("^[0-9a-f]* ", "", x.hex)) expect_equal(length(exponent), 1L) mantissa <- gsub(" [0-9]*$", "", x.hex) ignore(expect_true)(all( sapply( head(seq_along(mantissa), -1), function(i){ all( grepl( paste0("^", mantissa[i], ".*"), tail(mantissa, -i) ) ) } ) )) #it keeps NA values x <- c(pi, NA, 0) expect_equal(is.na(digest:::num2hex(x)), is.na(x)) x <- c(pi, NA, pi) expect_equal(is.na(digest:::num2hex(x)), is.na(x)) x <- as.numeric(c(NA, NA, NA)) expect_equal(is.na(digest:::num2hex(x)), is.na(x)) # handles empty vectors expect_equal(digest:::num2hex(numeric(0)), character(0)) # example from FAQ 7.31 # tests if all trailing zero's are removed expect_true(identical(digest:::num2hex(2, digits = 14), digest:::num2hex(sqrt(2) ^ 2, digits = 14))) expect_true(!identical(digest:::num2hex(2, digits = 15), digest:::num2hex(sqrt(2) ^ 2, digits = 15))) digest/inst/tinytest/test_misc.R0000644000176200001440000000421113553177457016525 0ustar liggesusers## a few tests split off the test_digest.R file suppressMessages(library(digest)) ## test 'length' parameter and file input ##fname <- file.path(R.home(),"COPYING") ## not invariant across OSs fname <- system.file("GPL-2", package="digest") x <- readChar(fname, file.info(fname)$size) # read file xskip <- substring(x, first=20+1) for (alg in c("sha1", "md5", "crc32", "sha256", "sha512", "xxhash32", "xxhash64", "murmur32")) { # partial file h1 <- digest(x , length=18000, algo=alg, serialize=FALSE) h2 <- digest(fname, length=18000, algo=alg, serialize=FALSE, file=TRUE) expect_true(identical(h1,h2)) h3 <- digest(substr(x,1,18000) , algo=alg, serialize=FALSE) expect_true(identical(h1,h3)) #cat(h1, "\n", h2, "\n", h3, "\n") expect_identical( getVDigest(alg)(x, length = 18e3, serialize = FALSE), getVDigest(alg)(fname, length = 18e3, serialize = FALSE, file = TRUE) ) # whole file h4 <- digest(x , algo=alg, serialize=FALSE) h5 <- digest(fname, algo=alg, serialize=FALSE, file=TRUE) expect_true( identical(h4,h5) ) expect_identical( getVDigest(alg)(x, serialize = FALSE), getVDigest(alg)(fname, serialize = FALSE, file = TRUE) ) ## Assert that 'skip' works h6 <- digest(xskip, algo=alg, serialize=FALSE) h7 <- digest(fname, algo=alg, serialize=FALSE, skip=20, file=TRUE) expect_true( identical(h6, h7) ) expect_identical( getVDigest(alg)(xskip, serialize = FALSE), getVDigest(alg)(fname, serialize = FALSE, skip = 20, file = TRUE) ) } ## compare md5 algorithm to other tools library(tools) ##fname <- file.path(R.home(),"COPYING") ## not invariant across OSs fname <- system.file("GPL-2", package="digest") h1 <- as.character(md5sum(fname)) h2 <- digest(fname, algo="md5", file=TRUE) expect_true( identical(h1,h2) ) ## Make sure we don't core dump with unreadable files. fname <- tempfile() #cat("Hello World, you won't have access to read me", file=fname) on.exit(unlink(fname)) Sys.chmod(fname, mode="0000") try(res <- digest(fname, file=TRUE), silent=TRUE) digest/inst/tinytest/test_new_matrix_behaviour.R0000644000176200001440000000673513574673675022036 0ustar liggesusers if (getRversion() >= '4.0.0') exit_file("Skip tests for R 4.0.0 or later") library(digest) x.numeric <- c(seq(0, 1, length = 4 ^ 3), -Inf, Inf, NA, NaN) x.list <- list(letters, x.numeric) x.dataframe <- data.frame(X = letters, Y = x.numeric[2], Z = factor(letters), stringsAsFactors = FALSE) x.matrix.num <- as.matrix(x.numeric) x.matrix.letter <- as.matrix(letters) x.dataframe.round <- x.dataframe x.dataframe.round$Y <- signif(x.dataframe.round$Y, 14) x.factor <- factor(letters) x.array.num <- as.array(x.numeric) x.formula <- a~b+c|d x.paren_formula <- a~(b+c) x.no_paren_formula <- a~b+c test.element <- list( # NULL NULL, # empty classes logical(0), integer(0), numeric(0), character(0), list(), data.frame(), # scalar TRUE, FALSE, 1L, 1, "a", # date. Make sure to add the time zone. Otherwise the test might fail as.POSIXct("2015-01-02 03:04:06.07", tz = "UTC"), # vector c(TRUE, FALSE), 1:3, seq(0, 10, length = 4), letters[1:3], factor(letters[4:6]), as.POSIXct(c("2015-01-02 03:04:06.07", "1960-12-31 23:59:59"), tz = "UTC") ) expect_true( identical( sha1(x.matrix.num), { z <- matrix( apply(x.matrix.num, 2, digest:::num2hex), ncol = ncol(x.matrix.num) ) z <- digest:::add_attributes(x.matrix.num, z) attr(z, "digest::sha1") <- list( class = "matrix", digits = 14L, zapsmall = 7L ) digest(z, algo = "sha1") } ) ) expect_true( identical( sha1(x.matrix.letter), { z <- x.matrix.letter attr(z, "digest::sha1") <- list( class = "matrix", digits = 14L, zapsmall = 7L ) digest(z, algo = "sha1") } ) ) correct <- c( "8d9c05ec7ae28b219c4c56edbce6a721bd68af82", "d61eeea290dd09c5a3eba41c2b3174b6e4e2366d", "af23305d27f0409c91bdb86ba7c0cdb2e09a5dc6", "0c9ca70ce773deb0d9c0b0579c3b94856edf15cc", "095886422ad26e315c0960ef6b09842a1f9cc0ce", "6cc04c6c432bb91e210efe0b25c6ca809e6df2e3", "c1113ba008a349de64da2a7a724e501c1eb3929b", "6e12370bdc6fc457cc154f0525e22c6aa6439f4d", "1c1b5393c68a643bc79c277c6d7374d0b30cd985", "b48c17a2ac82601ff38df374f87d76005fb61cbd", "35280c99aa6a48bfc2810b72b763ccac0f632207", "f757cc017308d217f35ed8f0c001a57b97308fb7", "cfcf101b8449af67d34cdc1bcb0432fe9e4de08e", "a14384d1997440bad13b97b3ccfb3b8c0392e79a", "555f6bea49e58a2c2541060a21c2d4f9078c3086", "631d18dec342e2cb87614864ba525ebb9ad6a124", "b6c04f16b6fdacc794ea75c8c8dd210f99fafa65", "25485ba7e315956267b3fdc521b421bbb046325d", "6def3ca353dfc1a904bddd00e6a410d41ac7ab01", "cf220bcf84c3d0ab1b01f8f764396941d15ff20f", "2af8021b838f613aee7670bed19d0ddf1d6bc0c1", "270ed85d46524a59e3274d89a1bbf693521cb6af", "60e09482f12fda20f7d4a70e379c969c5a73f512", "10380001af2a541b5feefc7aab9f719b67330a42", "4580ff07f27eb8321421efac1676a80d9239572a", "d3022c5a223caaf77e9c564e024199e5d6f51bd5", "f54742ac61edd8c3980354620816c762b524dfc7" ) for (i in seq_along(test.element)) { if (i == 7 || i == 13 || i == 19) next expect_true( identical( sha1(test.element[[i]]), correct[i] ) ) } expect_true( sha1(matrix(integer(0))) == "e13485e1b995f3e36d43674dcbfedea08ce237bc" ) digest/inst/tinytest/test_crc32.R0000644000176200001440000000104513503674673016505 0ustar liggesusers ## tests for old versus new (ie guaranteed eight chars, added in 0.6.16) format for crc32 suppressMessages(library(digest)) args <- c(0L, 51L, 126L, 8480L, 60929L, 180832L) resOld <- c("b7fa0888", "82a699e", "4754b3", "b3da3", "e67c", "872") resNew <- c("b7fa0888", "082a699e", "004754b3", "000b3da3", "0000e67c", "00000872") options("digestOldCRC32Format" = TRUE) expect_identical(sapply(args, digest, algo="crc32"), resOld) options("digestOldCRC32Format" = FALSE) expect_identical(sapply(args, digest, algo="crc32"), resNew) digest/inst/tinytest/test_blake3.R0000644000176200001440000000303013741612225016713 0ustar liggesuserssuppressMessages(library(digest)) isWindows <- Sys.info()[["sysname"]] == "Windows" res <- digest(charToRaw("test"), "blake3", serialize = FALSE) # generated using the blake3 rust implementation expected <- "4878ca0425c739fa427f7eda20fe845f6b2e46ba5fe2a14df5b1e32f50603215" expect_equal( res, expected ) res <- digest(charToRaw("test"), "blake3", serialize = FALSE, raw = TRUE) expect_equal( paste0(res, collapse = ""), expected ) ## blake3 example blake3Input <- c( "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "" ) blake3Output <- c( "6437b3ac38465133ffb63b75273a8db548c558465d79db03fd359c6cd5bd9d85", "c19012cc2aaf0dc3d8e5c45a1b79114d2df42abb2a410bf54be09e891af06ff8", "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262" ) for (i in seq(along = blake3Input)) { blake3 <- digest(blake3Input[i], algo = "blake3", serialize = FALSE) expect_equal( blake3, blake3Output[i] ) } if (isWindows) exit_file("Skipping remainder on Windows platform") # test file # used the b3sum rust crate file <- tempfile() writeLines("test", file) res <- digest(file = file, algo = "blake3") try(file.remove(file)) expect_equal( res, "dea2b412aa90f1b43a06ca5e8b8feafec45ae1357971322749480f4e1572eaa2" ) # try another long text file <- tempfile() text <- paste0(rep(LETTERS, 1000), collapse = "-") writeLines(text, file) res <- digest(file = file, algo = "blake3") try(file.remove(file)) expect_equal( res, "a84aef38d9a7ad55fa458d9d1857eb895832e358385e8b6466c6af54ea46eeaa" ) digest/cleanup0000755000176200001440000000015414151533263013111 0ustar liggesusers#!/bin/sh rm -f config.* src/symbols.rds \ src/*.o src/*.d src/*.a src/*.dll src/*.so src/*.rc */*~ *~