Skip to content

Commit b65ec5c

Browse files
committed
Remove usage of unnecessary buffer for inner digest
1 parent c5d78f8 commit b65ec5c

File tree

1 file changed

+36
-45
lines changed

1 file changed

+36
-45
lines changed

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/ParallelDigest.kt

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ import org.kotlincrypto.core.xof.Xof
3434
public sealed class ParallelDigest: SHAKEDigest {
3535

3636
private val inner: SHAKEDigest
37-
private val innerBuf: ByteArray
38-
private var innerBufPos: Int
37+
private val innerBlockSize: Int
38+
private var innerPos: Int
3939
private var countLo: Int
4040
private var countHi: Int
4141

@@ -60,8 +60,8 @@ public sealed class ParallelDigest: SHAKEDigest {
6060
BIT_STRENGTH_256 -> CSHAKE256(N = null, S = null)
6161
else -> throw IllegalArgumentException("bitStrength must be $BIT_STRENGTH_128 or $BIT_STRENGTH_256")
6262
}
63-
this.innerBuf = ByteArray(B)
64-
this.innerBufPos = 0
63+
this.innerBlockSize = B
64+
this.innerPos = 0
6565
this.countLo = 0
6666
this.countHi = 0
6767

@@ -72,22 +72,21 @@ public sealed class ParallelDigest: SHAKEDigest {
7272

7373
protected constructor(other: ParallelDigest): super(other) {
7474
this.inner = other.inner.copy()
75-
this.innerBuf = other.innerBuf.copyOf()
76-
this.innerBufPos = other.innerBufPos
75+
this.innerBlockSize = other.innerBlockSize
76+
this.innerPos = other.innerPos
7777
this.countLo = other.countLo
7878
this.countHi = other.countHi
7979
}
8080

8181
public abstract override fun copy(): ParallelDigest
8282

8383
protected final override fun digestProtected(buf: ByteArray, bufPos: Int): ByteArray {
84-
val buffered = if (innerBufPos != 0) {
84+
val buffered = if (innerPos != 0) {
8585
// If there's any buffered bytes left,
86-
// process them to append them to the
86+
// process them and prefix to the
8787
// buffer here as additional input.
88-
inner.update(innerBuf, 0, innerBufPos)
89-
increment()
90-
innerBufPos = 0
88+
innerPos = 0
89+
incrementCount()
9190
inner.digest()
9291
} else {
9392
ByteArray(0)
@@ -118,75 +117,67 @@ public sealed class ParallelDigest: SHAKEDigest {
118117
}
119118

120119
protected final override fun updateProtected(input: Byte) {
121-
val buf = innerBuf
122-
val bufPos = innerBufPos++
123-
buf[bufPos] = input
124-
if (bufPos + 1 != buf.size) return
125-
processBlock(buf, 0)
126-
innerBufPos = 0
120+
inner.update(input)
121+
if (++innerPos != innerBlockSize) return
122+
processBlock()
123+
innerPos = 0
127124
}
128125

129126
protected final override fun updateProtected(input: ByteArray, offset: Int, len: Int) {
130-
val buf = innerBuf
131-
val blockSize = buf.size
132127
var inputPos = offset
133128
val inputLimit = inputPos + len
134-
var bufPos = innerBufPos
129+
var innerPos = innerPos
135130

136-
if (bufPos > 0) {
137-
if (bufPos + len < blockSize) {
138-
input.copyInto(buf, bufPos, inputPos, inputLimit)
139-
innerBufPos = bufPos + len
131+
if (innerPos > 0) {
132+
if (innerPos + len < innerBlockSize) {
133+
// Not enough input to process a block
134+
inner.update(input, offset, len)
135+
this.innerPos = innerPos + len
140136
return
141137
}
142138

143-
val needed = blockSize - bufPos
144-
input.copyInto(buf, bufPos, inputPos, inputPos + needed)
145-
processBlock(buf, 0)
146-
bufPos = 0
139+
val needed = innerBlockSize - innerPos
140+
inner.update(input, inputPos, needed)
141+
processBlock()
142+
innerPos = 0
147143
inputPos += needed
148144
}
149145

150146
while (inputPos < inputLimit) {
151-
val nextPos = inputPos + blockSize
147+
val nextPos = inputPos + innerBlockSize
152148

153149
if (nextPos > inputLimit) {
154-
input.copyInto(buf, 0, inputPos, inputLimit)
155-
bufPos = inputLimit - inputPos
150+
innerPos = inputLimit - inputPos
151+
inner.update(input, inputPos, innerPos)
156152
break
157153
}
158154

159-
processBlock(input, inputPos)
155+
inner.update(input, inputPos, innerBlockSize)
156+
processBlock()
160157
inputPos = nextPos
161158
}
162159

163-
innerBufPos = bufPos
160+
this.innerPos = innerPos
164161
}
165162

166-
private inline fun processBlock(input: ByteArray, offset: Int) {
167-
inner.update(input, offset, innerBuf.size)
163+
private inline fun processBlock() {
168164
super.updateProtected(inner.digest(), 0, inner.digestLength())
169-
increment()
165+
incrementCount()
170166
}
171167

172168
protected final override fun resetProtected() {
173169
super.resetProtected()
174-
this.innerBuf.fill(0)
175-
this.innerBufPos = 0
170+
this.inner.reset()
171+
this.innerPos = 0
176172
this.countLo = 0
177173
this.countHi = 0
178174

179-
// No need to reset inner as digest() is always called
180-
// when processing blocks which leaves it in a perpetually
181-
// reset state.
182-
// this.inner.reset()
183-
184175
@OptIn(InternalKotlinCryptoApi::class)
185-
val encBSize = Xof.Utils.leftEncode(innerBuf.size)
176+
val encBSize = Xof.Utils.leftEncode(innerBlockSize)
186177
super.updateProtected(encBSize, 0, encBSize.size)
187178
}
188179

189-
private inline fun increment() { if (++countLo == 0) countHi++ }
180+
private inline fun incrementCount() { if (++countLo == 0) countHi++ }
190181

191182
private companion object {
192183
private const val PARALLEL_HASH = "ParallelHash"

0 commit comments

Comments
 (0)