diff --git a/beacon_chain/spec/digest.nim b/beacon_chain/spec/digest.nim index 0ffbff3283..9a18c789de 100644 --- a/beacon_chain/spec/digest.nim +++ b/beacon_chain/spec/digest.nim @@ -22,18 +22,27 @@ {.push raises: [Defect].} import + # Standard library + std/hashes, + #Status libraries chronicles, nimcrypto/[sha2, hash], stew/byteutils, hashes, - eth/common/eth_types_json_serialization + eth/common/eth_types_json_serialization, + blscurve export hash.`$`, sha2, readValue, writeValue type Eth2Digest* = MDigest[32 * 8] ## `hash32` from spec - Eth2Hash* = sha256 ## Context for hash function + +when BLS_BACKEND == BLST: + export blscurve.update + type Eth2DigestCtx* = BLST_SHA256_CTX +else: + type Eth2DigestCtx* = sha2.sha256 func shortLog*(x: Eth2Digest): string = x.data.toOpenArray(0, 3).toHex() @@ -44,26 +53,52 @@ chronicles.formatIt Eth2Digest: # TODO: expose an in-place digest function # when hashing in loop or into a buffer # See: https://github.com/cheatfate/nimcrypto/blob/b90ba3abd/nimcrypto/sha2.nim#L570 -func eth2digest*(v: openArray[byte]): Eth2Digest {.inline.} = - # We use the init-update-finish interface to avoid - # the expensive burning/clearing memory (20~30% perf) - # TODO: security implication? - var ctx: sha256 - ctx.init() - ctx.update(v) - ctx.finish() +func eth2digest*(v: openArray[byte]): Eth2Digest {.noInit.} = + ## Apply the Eth2 Hash function + ## Do NOT use for secret data. + when BLS_BACKEND == BLST: + # BLST has a fast assembly optimized SHA256 + result.data.bls_sha256_digest(v) + else: + # We use the init-update-finish interface to avoid + # the expensive burning/clearing memory (20~30% perf) + var ctx: Eth2DigestCtx + ctx.init() + ctx.update(v) + ctx.finish() -func update*(ctx: var Sha2Context; digest: Eth2Digest) = +when BLS_BACKEND == BLST: + func update*(ctx: var BLST_SHA256_CTX; digest: Eth2Digest) = + ctx.update digest.data +func update*(ctx: var sha256; digest: Eth2Digest) = ctx.update digest.data template withEth2Hash*(body: untyped): Eth2Digest = ## This little helper will init the hash function and return the sliced ## hash: ## let hashOfData = withHash: h.update(data) - var h {.inject.}: sha256 - init(h) - body - finish(h) + when nimvm: + # In SSZ, computeZeroHashes require compile-time SHA256 + block: + var h {.inject.}: sha256 + init(h) + body + finish(h) + else: + when BLS_BACKEND == BLST: + block: + var h {.inject, noInit.}: Eth2DigestCtx + init(h) + body + var res {.noInit.}: Eth2Digest + finalize(res.data, h) + res + else: + block: + var h {.inject, noInit.}: Eth2DigestCtx + init(h) + body + finish(h) func hash*(x: Eth2Digest): Hash = ## Hash for digests for Nim hash tables diff --git a/vendor/nim-blscurve b/vendor/nim-blscurve index da9ae49dab..eed30c0623 160000 --- a/vendor/nim-blscurve +++ b/vendor/nim-blscurve @@ -1 +1 @@ -Subproject commit da9ae49dab4cbb95b2cdaa68ecc221ee15c67a9a +Subproject commit eed30c06231438b87fe25127326e40cb2bf412e3