ref: 0b5b219f27ff55efda4f33df0ca3cd87140be712
parent: 552823815f7c52c16111045b638ba8bab322e7ac
author: sgilles@umd.edu <sgilles@umd.edu>
date: Sat Aug 8 20:54:20 EDT 2020
Fix crypto keccak functions with multiple adds.
--- a/lib/crypto/sha3.myr
+++ b/lib/crypto/sha3.myr
@@ -187,13 +187,13 @@
std.slcp(tail[ntail:ntail + n], data[:n])
data = data[n:]
if n + ntail < blocksz
- -> n + ntail
+ -> len
;;
addblock(x, tail)
keccakf(x)
;;
while data.len >= blocksz
- addblock(x, data)
+ addblock(x, data[:blocksz])
keccakf(x)
data = data[blocksz:]
;;
--- a/lib/crypto/test/sha3.myr
+++ b/lib/crypto/test/sha3.myr
@@ -113,5 +113,98 @@
"\x4B\x5C\xBF\x78\x28\x65\x8E\x6A"), \
"invalid hash result {r}", ret[:])
}],
+
+ [.name="keccak224multiadd", .fn = keccak224multiadd],
+ [.name="keccak256multiadd", .fn = keccak256multiadd],
+ [.name="keccak384multiadd", .fn = keccak384multiadd],
+ [.name="keccak512multiadd", .fn = keccak512multiadd],
][:])
+}
+
+const toadd = [
+ [ "", "", "", "", "" ][:],
+ [ "a", "b" ][:],
+
+ /* Hover around the blocksz mark */
+ [ "a seventy-one byte string to make keccak-512 touch the limit (blocksz).", "" ][:],
+ [ "a seventy-one byte string to make keccak-512 touch the limit (blocksz).", "_" ][:],
+ [ "a seventy-one byte string to make keccak-512 touch the limit (blocksz).", "_", "_" ][:],
+ [ "a seventy-one byte string to make keccak-512 touch the limit (blocksz).", "__" ][:],
+
+ /* Go between blocksz and blocksz + 4 to stress addblock */
+ [ "Call me Ishmael. Some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, ",
+ "I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. ",
+ "Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul;", ][:],
+][:]
+
+const keccak224multiadd = {c
+ for l : toadd
+ var st : crypto.keccak224
+ crypto.keccak224init(&st)
+
+ var merged : std.strbuf# = std.mksb()
+ for data : l
+ std.sbputs(merged, data)
+ crypto.keccak224add(&st, data)
+ ;;
+
+ var hm = crypto.keccak224(std.sbfin(merged))
+ var hi = crypto.keccak224fin(&st)
+
+ testr.check(c, std.sleq(hm[0:28], hi[0:28]), "incremental keccak224 disagrees with all-at-once")
+ ;;
+}
+
+const keccak256multiadd = {c
+ for l : toadd
+ var st : crypto.keccak256
+ crypto.keccak256init(&st)
+
+ var merged : std.strbuf# = std.mksb()
+ for data : l
+ std.sbputs(merged, data)
+ crypto.keccak256add(&st, data)
+ ;;
+
+ var hm = crypto.keccak256(std.sbfin(merged))
+ var hi = crypto.keccak256fin(&st)
+
+ testr.check(c, std.sleq(hm[0:32], hi[0:32]), "incremental keccak256 disagrees with all-at-once")
+ ;;
+}
+
+const keccak384multiadd = {c
+ for l : toadd
+ var st : crypto.keccak384
+ crypto.keccak384init(&st)
+
+ var merged : std.strbuf# = std.mksb()
+ for data : l
+ std.sbputs(merged, data)
+ crypto.keccak384add(&st, data)
+ ;;
+
+ var hm = crypto.keccak384(std.sbfin(merged))
+ var hi = crypto.keccak384fin(&st)
+
+ testr.check(c, std.sleq(hm[0:48], hi[0:48]), "incremental keccak384 disagrees with all-at-once")
+ ;;
+}
+
+const keccak512multiadd = {c
+ for l : toadd
+ var st : crypto.keccak512
+ crypto.keccak512init(&st)
+
+ var merged : std.strbuf# = std.mksb()
+ for data : l
+ std.sbputs(merged, data)
+ crypto.keccak512add(&st, data)
+ ;;
+
+ var hm = crypto.keccak512(std.sbfin(merged))
+ var hi = crypto.keccak512fin(&st)
+
+ testr.check(c, std.sleq(hm[0:64], hi[0:64]), "incremental keccak512 disagrees with all-at-once")
+ ;;
}