From 0f288597986dfc5a90d32ac50f8f934e1f51133f Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:45:47 +0000 Subject: [PATCH] use sha3-256 from secretbase for archive() --- DESCRIPTION | 3 ++- NAMESPACE | 2 +- NEWS.md | 11 +++++++++++ R/archive.R | 35 +++++++++++++++-------------------- R/ichimoku-package.R | 5 +++-- README.Rmd | 2 +- README.md | 2 +- man/archive.Rd | 6 +++--- tests/testthat/test-archive.R | 9 ++------- vignettes/reference.Rmd | 9 +++++---- 10 files changed, 44 insertions(+), 40 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3c8ce8c3..c4c65656 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: ichimoku Type: Package Title: Visualization and Tools for Ichimoku Kinko Hyo Strategies -Version: 1.4.13 +Version: 1.4.13.9000 Description: An implementation of 'Ichimoku Kinko Hyo', also commonly known as 'cloud charts'. Static and interactive visualizations with tools for creating, backtesting and development of quantitative 'ichimoku' strategies. @@ -33,6 +33,7 @@ Imports: mirai (>= 0.12.0), nanonext (>= 0.12.0), RcppSimdJson (>= 0.1.9), + secretbase, shiny (>= 1.4.0), xts, zoo diff --git a/NAMESPACE b/NAMESPACE index 2fa6ccbd..1cd71785 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -80,8 +80,8 @@ importFrom(ggplot2,theme) importFrom(ggplot2,theme_grey) importFrom(mirai,mirai) importFrom(nanonext,ncurl) -importFrom(nanonext,sha256) importFrom(nanonext,strcat) +importFrom(secretbase,sha3) importFrom(shiny,HTML) importFrom(shiny,checkboxInput) importFrom(shiny,column) diff --git a/NEWS.md b/NEWS.md index 46f4e77e..139de17e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,14 @@ +# ichimoku 1.4.13.9000 (development) + +#### New features: + +* `archive()` updated to use the fast and memory-efficient implementation of SHA3-256 from {secretbase} for data verification. + + Note: archive files created using earlier package versions can no longer be verified using `archive()` but may nevertheless be loaded using `readRDS()`. + +#### Updates: + +* Requires secretbase. + # ichimoku 1.4.13 #### Updates: diff --git a/R/archive.R b/R/archive.R index 614e948a..b5ffb930 100644 --- a/R/archive.R +++ b/R/archive.R @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2023 Hibiki AI Limited +# Copyright (C) 2021-2024 Hibiki AI Limited # # This file is part of ichimoku. # @@ -45,12 +45,12 @@ #' #' @section Data Verification: #' -#' A SHA256 hash of the original object is written to the archive. This +#' A SHA3-256 hash of the original object is written to the archive. This #' allows the data integrity of the restored object to be verified when the #' archive is read back. #' -#' For write operations: confirmation of the SHA256 hash written to file is -#' displayed. +#' For write operations: confirmation of the SHA3-256 hash written to file +#' is displayed. #' #' For read operations: a 'data verified' message is issued if the SHA256 #' hash found within the data file has been authenticated. @@ -128,7 +128,7 @@ archive <- function(..., object, file) { #' Write Objects to Archive #' -#' Internal function used to write objects, along with their sha256 hash value, +#' Internal function used to write objects, along with their SHA3-256 hash value, #' to archive files in the native RData format. #' #' @param object an object. @@ -152,9 +152,9 @@ writeArchive <- function(object, file) { } } - x_archive_sha256 <- sha256(object) - save(object, x_archive_sha256, file = file, compress = TRUE) - message(sprintf("Archive written to '%s'\nSHA256: %s", file, x_archive_sha256)) + x_archive_secure_hash <- sha3(object) + save(object, x_archive_secure_hash, file = file, compress = TRUE) + message(sprintf("Archive written to '%s'\nSHA3-256: %s", file, x_archive_secure_hash)) invisible(file) } @@ -162,7 +162,7 @@ writeArchive <- function(object, file) { #' Read Objects from Archive #' #' Internal function used to read objects from native RData files with stored -#' sha256 hash values. +#' SHA3-256 hash values. #' #' @param file the name of the file or a connection where the object is saved to #' or read from. @@ -176,21 +176,16 @@ readArchive <- function(file) { is.character(file) || stop("in archive(file): 'file' must be supplied as a string.\nDid you omit the surrounding quotes \"\"?", call. = FALSE) - object <- x_archive_sha256 <- NULL + object <- x_archive_secure_hash <- NULL x_archive_names <- load(file) - x_archive_names[2L] == "x_archive_sha256" && x_archive_names[1L] == "object" || + x_archive_names[2L] == "x_archive_secure_hash" && x_archive_names[1L] == "object" || stop("archive file was not created by archive()", call. = FALSE) message("Archive read from '", file, "'") - if (is.na(x_archive_sha256[1L])) { - # for legacy compatibility with previous implementations of archive - message("Data unverified: SHA256 hash not present") - } else { - sha256 <- sha256(object) - if (identical(sha256, x_archive_sha256)) - message("Data verified by SHA256: ", sha256) else - warning(sprintf("SHA256 of restored object: %s\ndoes not match the original: %s", sha256, x_archive_sha256), call. = FALSE) - } + sha256 <- sha3(object) + if (identical(sha256, x_archive_secure_hash)) + message("Data verified by SHA3-256: ", sha256) else + warning(sprintf("SHA3-256 of restored object: %s\ndoes not match the original: %s", sha256, x_archive_secure_hash), call. = FALSE) object diff --git a/R/ichimoku-package.R b/R/ichimoku-package.R index 617ea20b..ac00f8ef 100644 --- a/R/ichimoku-package.R +++ b/R/ichimoku-package.R @@ -83,13 +83,14 @@ #' scale_x_continuous scale_y_continuous Stat StatIdentity theme theme_grey #' %+replace% #' @importFrom mirai mirai -#' @importFrom nanonext ncurl sha256 strcat +#' @importFrom nanonext ncurl strcat +#' @importFrom secretbase sha3 +#' @importFrom RcppSimdJson is_valid_json #' @importFrom shiny checkboxInput column downloadButton downloadHandler HTML #' fillPage fluidPage fluidRow hoverOpts invalidateLater isolate #' numericInput observeEvent plotOutput reactive reactiveVal renderPlot #' renderUI req runApp selectInput shinyApp sliderInput stopApp tags #' textInput uiOutput wellPanel -#' @importFrom RcppSimdJson is_valid_json #' @importFrom stats na.omit sd #' @importFrom utils packageVersion str #' @importFrom xts endpoints diff --git a/README.Rmd b/README.Rmd index 401b6aaf..8dd6a214 100644 --- a/README.Rmd +++ b/README.Rmd @@ -19,7 +19,7 @@ knitr::opts_chunk$set( [![CRAN Status](https://www.r-pkg.org/badges/version/ichimoku?color=00008b)](https://CRAN.R-project.org/package=ichimoku) [![ichimoku status badge](https://shikokuchuo.r-universe.dev/badges/ichimoku?color=a4d1eb)](https://shikokuchuo.r-universe.dev/ichimoku) [![R-CMD-check](https://github.com/shikokuchuo/ichimoku/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/shikokuchuo/ichimoku/actions/workflows/R-CMD-check.yaml) -[![codecov](https://codecov.io/gh/shikokuchuo/ichimoku/branch/main/graph/badge.svg)](https://app.codecov.io/gh/shikokuchuo/ichimoku) +[![codecov](https://codecov.io/gh/shikokuchuo/ichimoku/graph/badge.svg)](https://app.codecov.io/gh/shikokuchuo/ichimoku) [![DOI](https://zenodo.org/badge/367928545.svg)](https://zenodo.org/badge/latestdoi/367928545) diff --git a/README.md b/README.md index f5b338a3..942fe134 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Status](https://www.r-pkg.org/badges/version/ichimoku?color=00008b)](https://CRA [![ichimoku status badge](https://shikokuchuo.r-universe.dev/badges/ichimoku?color=a4d1eb)](https://shikokuchuo.r-universe.dev/ichimoku) [![R-CMD-check](https://github.com/shikokuchuo/ichimoku/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/shikokuchuo/ichimoku/actions/workflows/R-CMD-check.yaml) -[![codecov](https://codecov.io/gh/shikokuchuo/ichimoku/branch/main/graph/badge.svg)](https://app.codecov.io/gh/shikokuchuo/ichimoku) +[![codecov](https://codecov.io/gh/shikokuchuo/ichimoku/graph/badge.svg)](https://app.codecov.io/gh/shikokuchuo/ichimoku) [![DOI](https://zenodo.org/badge/367928545.svg)](https://zenodo.org/badge/latestdoi/367928545) diff --git a/man/archive.Rd b/man/archive.Rd index 2891cc4f..183ee3b5 100644 --- a/man/archive.Rd +++ b/man/archive.Rd @@ -40,12 +40,12 @@ For read operations: specify only 'file', or alternatively if no \section{Data Verification}{ - A SHA256 hash of the original object is written to the archive. This + A SHA3-256 hash of the original object is written to the archive. This allows the data integrity of the restored object to be verified when the archive is read back. - For write operations: confirmation of the SHA256 hash written to file is - displayed. + For write operations: confirmation of the SHA3-256 hash written to file + is displayed. For read operations: a 'data verified' message is issued if the SHA256 hash found within the data file has been authenticated. diff --git a/tests/testthat/test-archive.R b/tests/testthat/test-archive.R index 8e5e9cf5..0da22a2d 100644 --- a/tests/testthat/test-archive.R +++ b/tests/testthat/test-archive.R @@ -17,14 +17,9 @@ test_that("archive functions ok", { save(sample_ohlc_data, file = file) expect_error(archive(file), "was not created") unlink(file) + x_archive_secure_hash <- "010101010101" file <- tempfile() - x_archive_sha256 <- NA - save(object, x_archive_sha256, file = file) - expect_message(restored <- archive(file), "unverified") - unlink(file) - x_archive_sha256 <- "010101010101" - file <- tempfile() - save(object, x_archive_sha256, file = file) + save(object, x_archive_secure_hash, file = file) expect_warning(expect_message(restored <- archive(file), "Archive read"), "does not match the original") unlink(file) }) diff --git a/vignettes/reference.Rmd b/vignettes/reference.Rmd index 701909a4..09d2dc02 100644 --- a/vignettes/reference.Rmd +++ b/vignettes/reference.Rmd @@ -349,11 +349,11 @@ object <- archive() #### Data Integrity Verification -Data integrity verification is performed by the MbedTLS cryptographic-grade SHA256 hashing algorithm from the 'nanonext' package. +Data integrity verification is performed by the SHA3-256 cryptographic hash algorithm from the 'secretbase' package. -When an archive is written, the serialised object is hashed and the hash is also stored in the archive. The SHA256 hash value is printed to the console as confirmation. +When an archive is written, the serialised object is hashed and the hash is also stored in the archive. The SHA3-256 hash value is printed to the console as confirmation. -When an archive is read back, the SHA256 hash of the restored object is checked against the hash of the original stored in the archive. If identical, a 'data verified' message is printed to the console along with the authenticated SHA256 hash. +When an archive is read back, the SHA3-256 hash of the restored object is checked against the hash of the original stored in the archive. If identical, a 'data verified' message is printed to the console along with the authenticated SHA3-256 hash. ## Supplementary Information @@ -427,7 +427,8 @@ ichimoku currently has the following external package dependencies: - shiny - for interactive and live visualizations - xts, zoo - for enhanced time series methods - mirai - for running applications in background processes -- nanonext - for interfacing with external APIs and verifying the data integrity of archived objects +- nanonext - for interfacing with external APIs +- secretbase - for verifying the data integrity of archived objects - RcppSimdJson - for parsing data received from external APIs Optional (enables additional features):