0

I am interested in taking an existing hash and resuming the SHA256 encryption from that point. It seems doable in C++:

This is what I have tried:

irb(main):007:0> sha2 = Digest::SHA2.new                                        => #<Digest::SHA2:256 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855>
irb(main):008:0> sha2 << "string1"
=> #<Digest::SHA2:256 93fedde43203e0a76172135221b8636313635d7afff96a490ae9066330505d47>
irb(main):009:0> sha2 << "string2"
=> #<Digest::SHA2:256 bac09aa72e632e76c36e6c1c4e502b73c3da7fca68c475273dc5517815587cc4>
irb(main):010:0> 

The above code updates the SHA2 digest object, in session. I want to start a new session...lets call it newshaw2 by assigning the same original hash as created when I passed String1 to sha2, as above.

I want to "make" newshaw2 as the object 93fedde43203e0a76172135221b8636313635d7afff96a490ae9066330505d47.

Setting it equal: newshaw2 = '93fedde43203e0a76172135221b8636313635d7afff96a490ae9066330505d47' just makes this a string object, not a digest.

Once, I have successfully assigned newsha2 with the hash then I would update with string2 to resume the hashing process.

rpthomps
  • 11
  • 4

1 Answers1

0

It sounds like you want to be able to create a new Digest::SHA2 object and set its initial value to an existing hash without having to recalculate that hash.

For example, if you use Digest::SHA2 to calculate the hash for a 10 GB file, then is there any way to make a new Digest::SHA2 with that hash value but without having to rehash all 10 GB?

The answer is no, Digest does not have this capability. You can confirm that in one of a few ways. First, look at the public methods available on the object to see that there are no options to do this:

Digest::SHA256.new.public_methods - Object.public_methods
=> [:update, :digest_length, :block_length, :<<, :reset, :digest, :file, :base64digest, :base64digest!, :hexdigest!, :length, :digest!, :size, :hexdigest]

Then take a look at the source for initialize in Digest::SHA2 and you'll see there's no argument to set the initial state when calling new.

There may be something I missed because the source code for Digest is a little hard to follow because Digest is a mix of Ruby and C. For example, if you look at ext/digest/sha2/lib/sha2.rb you'll see that initialize is just calling Digest::SHA256. But there's no sha256.rb file to be found at ext/digest/sha2/lib. That's because it's defined by ext/digest/sha2/sha2init.c, with methods defined in ext/digest/sha2/sha2.c.

One other possible solution would be to marshal the data to a bytestream but that isn't possible with Digest::SHA2 objects:

Marshal.dump(Digest::SHA2.new)
TypeError: no _dump_data is defined for class Digest::SHA256

Someone else asked a similar question at Can I serialize a ruby Digest::SHA1 instance object? that was not answered. A possible solution for SHA1 digests was listed at https://gist.github.com/parameme/2280705, and you may be able to adapt it, but that gist is 9 years old and the Ruby version at the time was 1.9.3, so it's possible that it will not work on Ruby 2.7.

All my research indicates that you will have to recalculate the hash to get the object to the desired state.

anothermh
  • 9,815
  • 3
  • 33
  • 52
  • Thanks for your attention to this. I will see if I can write something on my own using some of your suggestions. Have a nice day. – rpthomps Aug 30 '20 at 14:18
  • @rpthomps The linked gist causes a segmentation fault in Ruby 2.7.1 but not in 2.6.6, so it's probably something you can adapt to SHA256 without a lot of work as long as you're flexible on the Ruby version. – anothermh Sep 02 '20 at 16:27
  • Thanks again for your continued research. – rpthomps Sep 07 '20 at 12:56