Skip to content

Commit

Permalink
Remove reset for hash/signature functions - they should be single-u…
Browse files Browse the repository at this point in the history
…se for now
  • Loading branch information
whyoleg committed Sep 21, 2024
1 parent 7307cd7 commit 15fa767
Show file tree
Hide file tree
Showing 21 changed files with 112 additions and 245 deletions.
3 changes: 0 additions & 3 deletions cryptography-core/api/cryptography-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -652,11 +652,9 @@ public abstract interface class dev/whyoleg/cryptography/functions/HashFunction
public abstract fun hashIntoByteArray ([BI)I
public static synthetic fun hashIntoByteArray$default (Ldev/whyoleg/cryptography/functions/HashFunction;[BIILjava/lang/Object;)I
public abstract fun hashToByteArray ()[B
public abstract fun reset ()V
}

public abstract interface class dev/whyoleg/cryptography/functions/SignFunction : dev/whyoleg/cryptography/functions/UpdateFunction {
public abstract fun reset ()V
public fun sign ()Lkotlinx/io/bytestring/ByteString;
public abstract fun signIntoByteArray ([BI)I
public static synthetic fun signIntoByteArray$default (Ldev/whyoleg/cryptography/functions/SignFunction;[BIILjava/lang/Object;)I
Expand All @@ -674,7 +672,6 @@ public abstract interface class dev/whyoleg/cryptography/functions/UpdateFunctio
}

public abstract interface class dev/whyoleg/cryptography/functions/VerifyFunction : dev/whyoleg/cryptography/functions/UpdateFunction {
public abstract fun reset ()V
public fun verify (Lkotlinx/io/bytestring/ByteString;II)Z
public abstract fun verify ([BII)Z
public static synthetic fun verify$default (Ldev/whyoleg/cryptography/functions/VerifyFunction;Lkotlinx/io/bytestring/ByteString;IIILjava/lang/Object;)Z
Expand Down
3 changes: 0 additions & 3 deletions cryptography-core/api/cryptography-core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -535,12 +535,10 @@ abstract interface dev.whyoleg.cryptography.algorithms/PBKDF2 : dev.whyoleg.cryp
abstract interface dev.whyoleg.cryptography.functions/HashFunction : dev.whyoleg.cryptography.functions/UpdateFunction { // dev.whyoleg.cryptography.functions/HashFunction|null[0]
abstract fun hashIntoByteArray(kotlin/ByteArray, kotlin/Int = ...): kotlin/Int // dev.whyoleg.cryptography.functions/HashFunction.hashIntoByteArray|hashIntoByteArray(kotlin.ByteArray;kotlin.Int){}[0]
abstract fun hashToByteArray(): kotlin/ByteArray // dev.whyoleg.cryptography.functions/HashFunction.hashToByteArray|hashToByteArray(){}[0]
abstract fun reset() // dev.whyoleg.cryptography.functions/HashFunction.reset|reset(){}[0]
open fun hash(): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.functions/HashFunction.hash|hash(){}[0]
}

abstract interface dev.whyoleg.cryptography.functions/SignFunction : dev.whyoleg.cryptography.functions/UpdateFunction { // dev.whyoleg.cryptography.functions/SignFunction|null[0]
abstract fun reset() // dev.whyoleg.cryptography.functions/SignFunction.reset|reset(){}[0]
abstract fun signIntoByteArray(kotlin/ByteArray, kotlin/Int = ...): kotlin/Int // dev.whyoleg.cryptography.functions/SignFunction.signIntoByteArray|signIntoByteArray(kotlin.ByteArray;kotlin.Int){}[0]
abstract fun signToByteArray(): kotlin/ByteArray // dev.whyoleg.cryptography.functions/SignFunction.signToByteArray|signToByteArray(){}[0]
open fun sign(): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.functions/SignFunction.sign|sign(){}[0]
Expand All @@ -555,7 +553,6 @@ abstract interface dev.whyoleg.cryptography.functions/UpdateFunction : kotlin/Au
}

abstract interface dev.whyoleg.cryptography.functions/VerifyFunction : dev.whyoleg.cryptography.functions/UpdateFunction { // dev.whyoleg.cryptography.functions/VerifyFunction|null[0]
abstract fun reset() // dev.whyoleg.cryptography.functions/VerifyFunction.reset|reset(){}[0]
abstract fun verify(kotlin/ByteArray, kotlin/Int = ..., kotlin/Int = ...): kotlin/Boolean // dev.whyoleg.cryptography.functions/VerifyFunction.verify|verify(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
open fun verify(kotlinx.io.bytestring/ByteString, kotlin/Int = ..., kotlin/Int = ...): kotlin/Boolean // dev.whyoleg.cryptography.functions/VerifyFunction.verify|verify(kotlinx.io.bytestring.ByteString;kotlin.Int;kotlin.Int){}[0]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ public interface HashFunction : UpdateFunction {
public fun hashIntoByteArray(destination: ByteArray, destinationOffset: Int = 0): Int
public fun hashToByteArray(): ByteArray
public fun hash(): ByteString = hashToByteArray().asByteString()
public fun reset()
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ public interface SignFunction : UpdateFunction {
public fun signIntoByteArray(destination: ByteArray, destinationOffset: Int = 0): Int
public fun signToByteArray(): ByteArray
public fun sign(): ByteString = signToByteArray().asByteString()
public fun reset()
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import kotlinx.io.bytestring.*

public interface VerifyFunction : UpdateFunction {
public fun verify(signature: ByteArray, startIndex: Int = 0, endIndex: Int = signature.size): Boolean
public fun verify(signature: ByteString, startIndex: Int = 0, endIndex: Int = signature.size): Boolean =
verify(signature.asByteArray(), startIndex, endIndex)

public fun reset()
public fun verify(signature: ByteString, startIndex: Int = 0, endIndex: Int = signature.size): Boolean {
return verify(signature.asByteArray(), startIndex, endIndex)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,33 +91,6 @@ abstract class DigestTest(provider: CryptographyProvider) : ProviderTest(provide
}
}

@Test
fun testFunctionReuse() = testAlgorithm(SHA256) {
if (!supportsFunctions()) return@testAlgorithm

val hasher = algorithm.hasher()
val bytes1 = ByteString(CryptographyRandom.nextBytes(10000))
val bytes2 = ByteString(CryptographyRandom.nextBytes(10000))

val digest1 = hasher.hash(bytes1)
val digest2 = hasher.hash(bytes2)
hasher.createHashFunction().use { function ->
function.update(bytes1)
assertContentEquals(digest1, function.hash())

function.update(bytes2)
assertContentEquals(digest2, function.hash())

// update and then discard
function.update(bytes1)
function.update(bytes1)
function.reset()
// update after reset
function.update(bytes1)
assertContentEquals(digest1, function.hash())
}
}

@Test
fun testFunctionSource() = testAlgorithm(SHA256) {
val hasher = algorithm.hasher()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,21 @@ internal class CCDigest<CTX : CPointed>(
override val id: CryptographyAlgorithmId<Digest>,
) : Hasher, Digest {
override fun hasher(): Hasher = this
override fun createHashFunction(): HashFunction = CCHashFunction(
algorithm = hashAlgorithm,
context = Resource(hashAlgorithm.alloc(), nativeHeap::free)
)
override fun createHashFunction(): HashFunction {
val context = hashAlgorithm.alloc()
// TODO: error handle
hashAlgorithm.ccInit(context)
return CCHashFunction(
algorithm = hashAlgorithm,
context = Resource(context, nativeHeap::free)
)
}
}

private class CCHashFunction<CTX : CPointed>(
private val algorithm: CCHashAlgorithm<CTX>,
private val context: Resource<CPointer<CTX>>,
) : HashFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) {
init {
reset()
}

override fun update(source: ByteArray, startIndex: Int, endIndex: Int) {
checkBounds(source.size, startIndex, endIndex)

Expand All @@ -46,7 +47,7 @@ private class CCHashFunction<CTX : CPointed>(
destination.usePinned {
check(algorithm.ccFinal(context, it.safeAddressOf(destinationOffset).reinterpret()) > 0)
}
reset()
close()
return algorithm.digestSize
}

Expand All @@ -55,9 +56,4 @@ private class CCHashFunction<CTX : CPointed>(
hashIntoByteArray(output)
return output
}

override fun reset() {
val context = context.access()
check(algorithm.ccInit(context) > 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,26 +83,25 @@ private class HmacSignature(
private val key: ByteArray,
private val digestSize: Int,
) : SignatureGenerator, SignatureVerifier {
private fun createFunction() = HmacFunction(
hmacAlgorithm = hmacAlgorithm,
key = key,
digestSize = digestSize,
context = Resource(nativeHeap.alloc<CCHmacContext>().ptr, nativeHeap::free)
)

@OptIn(UnsafeNumber::class)
private fun createFunction(): HmacFunction {
val context = nativeHeap.alloc<CCHmacContext>().ptr
// TODO: error handle?
key.usePinned {
CCHmacInit(context, hmacAlgorithm, it.safeAddressOf(0), key.size.convert())
}
return HmacFunction(digestSize, Resource(context, nativeHeap::free))
}

override fun createSignFunction(): SignFunction = createFunction()
override fun createVerifyFunction(): VerifyFunction = createFunction()
}

private class HmacFunction(
private val hmacAlgorithm: CCHmacAlgorithm,
private val key: ByteArray,
private val digestSize: Int,
private val context: Resource<CPointer<CCHmacContext>>,
) : SignFunction, VerifyFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) {
init {
reset()
}

@OptIn(UnsafeNumber::class)
override fun update(source: ByteArray, startIndex: Int, endIndex: Int) {
Expand All @@ -121,7 +120,7 @@ private class HmacFunction(
destination.usePinned {
CCHmacFinal(context, it.safeAddressOf(destinationOffset))
}
reset()
close()
return digestSize
}

Expand All @@ -135,12 +134,4 @@ private class HmacFunction(
checkBounds(signature.size, startIndex, endIndex)
return signToByteArray().contentEquals(signature.copyOfRange(startIndex, endIndex))
}

@OptIn(UnsafeNumber::class)
override fun reset() {
val context = context.access()
key.usePinned {
CCHmacInit(context, hmacAlgorithm, it.safeAddressOf(0), key.size.convert())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,6 @@ private class EcdsaRawSignatureGenerator(
return rawSignature
}

override fun reset() {
derSignFunction.reset()
}

override fun close() {
derSignFunction.close()
}
Expand Down Expand Up @@ -322,10 +318,6 @@ private class EcdsaRawSignatureVerifier(
return derVerifyFunction.verify(derSignature)
}

override fun reset() {
derVerifyFunction.reset()
}

override fun close() {
derVerifyFunction.close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,13 @@ private class SecVerifyFunction(
result
}
}
}

override fun reset() {
ensureNotClosed()
accumulator = EmptyByteArray
}.also {
close()
}

override fun close() {
isClosed = true
accumulator = EmptyByteArray
}
}

Expand Down Expand Up @@ -118,14 +116,12 @@ private class SecSignFunction(

signature.toByteArray()
}
}

override fun reset() {
ensureNotClosed()
accumulator = EmptyByteArray
}.also {
close()
}

override fun close() {
isClosed = true
accumulator = EmptyByteArray
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ internal class JdkDigest(
) : Hasher, Digest {
private val messageDigest = state.messageDigest(algorithm)
override fun hasher(): Hasher = this
override fun createHashFunction(): HashFunction = JdkHashFunction(messageDigest.borrowResource())
override fun createHashFunction(): HashFunction = JdkHashFunction(messageDigest.borrowResource().also {
it.access().reset()
})
}

private class JdkHashFunction(private val messageDigest: Pooled.Resource<JMessageDigest>) : HashFunction {
Expand All @@ -34,17 +36,12 @@ private class JdkHashFunction(private val messageDigest: Pooled.Resource<JMessag

checkBounds(destination.size, destinationOffset, destinationOffset + messageDigest.digestLength)

return messageDigest.digest(destination, destinationOffset, messageDigest.digestLength)
return messageDigest.digest(destination, destinationOffset, messageDigest.digestLength).also { close() }
}

override fun hashToByteArray(): ByteArray {
val messageDigest = messageDigest.access()
return messageDigest.digest()
}

override fun reset() {
val messageDigest = messageDigest.access()
messageDigest.reset()
return messageDigest.digest().also { close() }
}

override fun close() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ private class EcdsaRawSignatureGenerator(
return rawSignature
}

override fun reset() {
derSignFunction.reset()
}

override fun close() {
derSignFunction.close()
}
Expand Down Expand Up @@ -134,10 +130,6 @@ private class EcdsaRawSignatureVerifier(
return derVerifyFunction.verify(derSignature)
}

override fun reset() {
derVerifyFunction.reset()
}

override fun close() {
derVerifyFunction.close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ internal class JdkMacSignature(
override fun createVerifyFunction(): VerifyFunction = createFunction()
}

private class JdkMacFunction(
private val mac: Pooled.Resource<JMac>,
) : SignFunction, VerifyFunction {
private class JdkMacFunction(private val mac: Pooled.Resource<JMac>) : SignFunction, VerifyFunction {
override fun update(source: ByteArray, startIndex: Int, endIndex: Int) {
checkBounds(source.size, startIndex, endIndex)
val mac = mac.access()
Expand All @@ -39,24 +37,20 @@ private class JdkMacFunction(

checkBounds(destination.size, destinationOffset, destinationOffset + mac.macLength)

mac.doFinal(destination, destinationOffset)
mac.doFinal(destination, destinationOffset).also { close() }
return mac.macLength
}

override fun signToByteArray(): ByteArray {
val mac = mac.access()
return mac.doFinal()
return mac.doFinal().also { close() }
}

override fun verify(signature: ByteArray, startIndex: Int, endIndex: Int): Boolean {
checkBounds(signature.size, startIndex, endIndex)
return signToByteArray().contentEquals(signature.copyOfRange(startIndex, endIndex))
}

override fun reset() {
mac.access().reset()
}

override fun close() {
mac.close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,14 @@ internal class JdkSignatureGenerator(
private val parameters: AlgorithmParameterSpec?,
) : SignatureGenerator {
private val signature = state.signature(algorithm)
override fun createSignFunction(): SignFunction = JdkSignFunction(state, key, parameters, signature.borrowResource())
override fun createSignFunction(): SignFunction = JdkSignFunction(signature.borrowResource().also {
val jsignature = it.access()
jsignature.initSign(key, state.secureRandom)
parameters?.let(jsignature::setParameter)
})
}

private class JdkSignFunction(
private val state: JdkCryptographyState,
private val key: JPrivateKey,
private val parameters: AlgorithmParameterSpec?,
private val jsignature: Pooled.Resource<JSignature>,
) : SignFunction {
init {
reset()
}

private class JdkSignFunction(private val jsignature: Pooled.Resource<JSignature>) : SignFunction {
override fun update(source: ByteArray, startIndex: Int, endIndex: Int) {
checkBounds(source.size, startIndex, endIndex)
val jsignature = jsignature.access()
Expand All @@ -46,13 +41,7 @@ private class JdkSignFunction(

override fun signToByteArray(): ByteArray {
val jsignature = jsignature.access()
return jsignature.sign()
}

override fun reset() {
val jsignature = jsignature.access()
jsignature.initSign(key, state.secureRandom)
parameters?.let(jsignature::setParameter)
return jsignature.sign().also { close() }
}

override fun close() {
Expand Down
Loading

0 comments on commit 15fa767

Please sign in to comment.