Skip to content

Commit 7c9d447

Browse files
authored
refactor!: separate hashing functions into new subproject (#632)
1 parent 0cf3757 commit 7c9d447

File tree

29 files changed

+287
-162
lines changed

29 files changed

+287
-162
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": "d4678053-b78b-486c-a2b3-8029ee5590bd",
3+
"type": "misc",
4+
"description": "Refactor hashing functions into new subproject"
5+
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ kotlin.mpp.stability.nowarn=true
55
kotlin.native.ignoreDisabledTargets=true
66

77
# SDK
8-
sdkVersion=0.8.6-SNAPSHOT
8+
sdkVersion=0.9.0-SNAPSHOT
99

1010
# kotlin
1111
kotlinVersion=1.6.10

runtime/hashing/build.gradle.kts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
description = "Hashing functions for Smithy services generated by smithy-kotlin"
7+
extra["displayName"] = "Smithy :: Kotlin :: Hashing"
8+
extra["moduleName"] = "aws.smithy.kotlin.runtime.hashing"
9+
10+
kotlin {
11+
sourceSets {
12+
commonMain {
13+
dependencies {
14+
implementation(project(":runtime:utils"))
15+
}
16+
}
17+
18+
all {
19+
languageSettings.optIn("aws.smithy.kotlin.runtime.util.InternalApi")
20+
}
21+
}
22+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
package aws.smithy.kotlin.runtime.hashing
6+
7+
import aws.smithy.kotlin.runtime.util.InternalApi
8+
9+
@InternalApi
10+
abstract class Crc32Base : HashFunction {
11+
override val blockSizeBytes: Int = 4
12+
override val digestSizeBytes: Int = 4
13+
14+
abstract fun digestValue(): UInt
15+
}
16+
17+
/**
18+
* CRC-32 checksum. Note: [digest] will return the bytes (big endian) of the CRC32 integer value. Access [digestValue]
19+
* directly to avoid doing the integer conversion yourself.
20+
*/
21+
@InternalApi
22+
expect class Crc32() : Crc32Base
23+
24+
/**
25+
* Compute the MD5 hash of the current [ByteArray]
26+
*/
27+
@InternalApi
28+
fun ByteArray.crc32(): UInt = Crc32().apply { update(this@crc32) }.digestValue()
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
package aws.smithy.kotlin.runtime.hashing
6+
7+
import aws.smithy.kotlin.runtime.util.InternalApi
8+
9+
/**
10+
* A cryptographic hash function (algorithm)
11+
*/
12+
@InternalApi
13+
interface HashFunction {
14+
/**
15+
* The size of the hashing block in bytes.
16+
*/
17+
val blockSizeBytes: Int
18+
19+
/**
20+
* The size of the digest output in bytes.
21+
*/
22+
val digestSizeBytes: Int
23+
24+
/**
25+
* Update the running hash with [input] bytes. This can be called multiple times.
26+
*/
27+
fun update(input: ByteArray)
28+
29+
/**
30+
* Finalize the hash computation and return the digest bytes. The hash function will be [reset] after the call is
31+
* made.
32+
*/
33+
fun digest(): ByteArray
34+
35+
/**
36+
* Resets the digest to its initial state discarding any accumulated digest state.
37+
*/
38+
fun reset()
39+
}
40+
41+
internal fun hash(fn: HashFunction, input: ByteArray): ByteArray = fn.apply { update(input) }.digest()
42+
43+
/**
44+
* Compute a hash of the current [ByteArray]
45+
*/
46+
@InternalApi
47+
fun ByteArray.hash(fn: HashFunction): ByteArray = hash(fn, this)
48+
49+
/**
50+
* A function that returns a new instance of a [HashFunction].
51+
*/
52+
@InternalApi
53+
typealias HashSupplier = () -> HashFunction
54+
55+
/**
56+
* Compute a hash of the current [ByteArray]
57+
*/
58+
@InternalApi
59+
fun ByteArray.hash(hashSupplier: HashSupplier): ByteArray = hash(hashSupplier(), this)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
package aws.smithy.kotlin.runtime.hashing
6+
7+
import aws.smithy.kotlin.runtime.util.InternalApi
8+
9+
@InternalApi
10+
abstract class Md5Base : HashFunction {
11+
override val blockSizeBytes: Int = 64
12+
override val digestSizeBytes: Int = 16
13+
}
14+
15+
/**
16+
* Implementation of RFC1321 MD5 digest
17+
*/
18+
@InternalApi
19+
expect class Md5() : Md5Base
20+
21+
/**
22+
* Compute the MD5 hash of the current [ByteArray]
23+
*/
24+
@InternalApi
25+
fun ByteArray.md5(): ByteArray = hash(Md5(), this)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
package aws.smithy.kotlin.runtime.hashing
6+
7+
import aws.smithy.kotlin.runtime.util.InternalApi
8+
9+
@InternalApi
10+
abstract class Sha1Base : HashFunction {
11+
override val blockSizeBytes: Int = 64
12+
override val digestSizeBytes: Int = 20
13+
}
14+
15+
/**
16+
* Implementation of SHA-1 (Secure Hash Algorithm 1) hash function. See: https://csrc.nist.gov/projects/hash-functions
17+
*/
18+
@InternalApi
19+
expect class Sha1() : Sha1Base
20+
21+
/**
22+
* Compute the SHA-1 hash of the current [ByteArray]
23+
*/
24+
@InternalApi
25+
fun ByteArray.sha1(): ByteArray = hash(Sha1(), this)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
package aws.smithy.kotlin.runtime.hashing
6+
7+
import aws.smithy.kotlin.runtime.util.InternalApi
8+
9+
@InternalApi
10+
abstract class Sha256Base : HashFunction {
11+
override val blockSizeBytes: Int = 64
12+
override val digestSizeBytes: Int = 32
13+
}
14+
15+
/**
16+
* Implementation of NIST SHA-256 hash function. See: https://csrc.nist.gov/projects/hash-functions
17+
18+
*/
19+
@InternalApi
20+
expect class Sha256() : Sha256Base
21+
22+
/**
23+
* Compute the SHA-256 hash of the current [ByteArray]
24+
*/
25+
@InternalApi
26+
fun ByteArray.sha256(): ByteArray = hash(Sha256(), this)

runtime/utils/common/test/aws/smithy/kotlin/runtime/util/Crc32Test.kt renamed to runtime/hashing/common/test/aws/smithy/kotlin/runtime/hashing/Crc32Test.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
5-
6-
package aws.smithy.kotlin.runtime.util
5+
package aws.smithy.kotlin.runtime.hashing
76

87
import kotlin.test.Test
98
import kotlin.test.assertEquals

runtime/utils/common/test/aws/smithy/kotlin/runtime/util/MD5Test.kt renamed to runtime/hashing/common/test/aws/smithy/kotlin/runtime/hashing/Md5Test.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,23 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
5+
package aws.smithy.kotlin.runtime.hashing
56

6-
package aws.smithy.kotlin.runtime.util
7-
7+
import aws.smithy.kotlin.runtime.util.encodeToHex
88
import kotlin.test.Test
99
import kotlin.test.assertContentEquals
1010
import kotlin.test.assertEquals
1111

12-
/**
13-
* Test vectors from https://www.ietf.org/rfc/rfc1321.txt
14-
*/
15-
class MD5Test {
12+
class Md5Test {
13+
// Test vectors from https://www.ietf.org/rfc/rfc1321.txt
1614
private val tests = listOf(
1715
"" to "d41d8cd98f00b204e9800998ecf8427e",
1816
"a" to "0cc175b9c0f1b6a831c399e269772661",
1917
"abc" to "900150983cd24fb0d6963f7d28e17f72",
2018
"message digest" to "f96b697d7cb7938d525a2f31aaf161d0",
2119
"abcdefghijklmnopqrstuvwxyz" to "c3fcd3d76192e4007dfb496cca67e13b",
2220
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" to "d174ab98d277d9f5a5611c2c9f419d9f",
23-
"12345678901234567890123456789012345678901234567890123456789012345678901234567890" to "57edf4a22be3c955ac49da2e2107b67a"
21+
"12345678901234567890123456789012345678901234567890123456789012345678901234567890" to "57edf4a22be3c955ac49da2e2107b67a",
2422
)
2523

2624
@Test
@@ -33,7 +31,6 @@ class MD5Test {
3331

3432
@Test
3533
fun testKnownCollision() {
36-
3734
val message1 = intArrayOf(
3835
0xd1, 0x31, 0xdd, 0x02, 0xc5, 0xe6, 0xee, 0xc4, 0x69, 0x3d, 0x9a, 0x06, 0x98, 0xaf, 0xf9, 0x5c,
3936
0x2f, 0xca, 0xb5, 0x87, 0x12, 0x46, 0x7e, 0xab, 0x40, 0x04, 0x58, 0x3e, 0xb8, 0xfb, 0x7f, 0x89,

0 commit comments

Comments
 (0)