Skip to content

Commit abe3af1

Browse files
authored
Refactor Digest internal API (#81)
1 parent fdea6b5 commit abe3af1

File tree

20 files changed

+630
-373
lines changed

20 files changed

+630
-373
lines changed

benchmarks/src/commonMain/kotlin/org/kotlincrypto/core/benchmarks/DigestBenchmark.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package org.kotlincrypto.core.benchmarks
1717

1818
import kotlinx.benchmark.*
1919
import org.kotlincrypto.core.digest.Digest
20-
import org.kotlincrypto.core.digest.internal.DigestState
2120
import kotlin.random.Random
2221

2322
@State(Scope.Benchmark)
@@ -29,11 +28,11 @@ open class DigestBenchmark {
2928

3029
private class TestDigest: Digest {
3130
constructor(): super("Benchmark", 32, 32)
32-
private constructor(state: DigestState): super(state)
33-
override fun resetDigest() {}
34-
override fun copy(state: DigestState): Digest = TestDigest(state)
35-
override fun compress(input: ByteArray, offset: Int) {}
36-
override fun digest(bitLength: Long, bufferOffset: Int, buffer: ByteArray): ByteArray = ByteArray(0)
31+
private constructor(state: State): super(state)
32+
override fun resetProtected() {}
33+
override fun copyProtected(state: State): Digest = TestDigest(state)
34+
override fun compressProtected(input: ByteArray, offset: Int) {}
35+
override fun digestProtected(buffer: ByteArray, offset: Int): ByteArray = ByteArray(0)
3736
}
3837

3938
private val digest = TestDigest()

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ POM_DEVELOPER_ID=KotlinCrypto
3030
POM_DEVELOPER_NAME=Kotlin Crypto
3131
POM_DEVELOPER_URL=https://github.com/KotlinCrypto/
3232

33-
VERSION_NAME=0.5.6-SNAPSHOT
33+
VERSION_NAME=1.0.0-SNAPSHOT
3434
# 0.1.0-alpha01 = 00 01 00 11
3535
# 0.1.0-beta01 = 00 01 00 21
3636
# 0.1.0-rc01 = 00 01 00 31
3737
# 0.1.0 = 00 01 00 99
3838
# 1.1.0 = 01 01 00 99
39-
VERSION_CODE=00050699
39+
VERSION_CODE=01000099

library/core/api/core.api

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,46 @@ public abstract interface class org/kotlincrypto/core/Copyable {
66
public abstract fun copy ()Ljava/lang/Object;
77
}
88

9+
public abstract class org/kotlincrypto/core/Counter {
10+
public final fun equals (Ljava/lang/Object;)Z
11+
public final fun hashCode ()I
12+
protected abstract fun increment ()V
13+
protected abstract fun reset ()V
14+
public final fun toString ()Ljava/lang/String;
15+
}
16+
17+
public abstract class org/kotlincrypto/core/Counter$Bit32 : org/kotlincrypto/core/Counter {
18+
public static final field Companion Lorg/kotlincrypto/core/Counter$Bit32$Companion;
19+
public static final field MAX_INCREMENT I
20+
public final field incrementBy I
21+
public fun <init> (I)V
22+
public fun <init> (III)V
23+
public fun <init> (Lorg/kotlincrypto/core/Counter$Bit32;)V
24+
public final fun hi ()I
25+
protected fun increment ()V
26+
public final fun lo ()I
27+
protected fun reset ()V
28+
}
29+
30+
public final class org/kotlincrypto/core/Counter$Bit32$Companion {
31+
}
32+
33+
public abstract class org/kotlincrypto/core/Counter$Bit64 : org/kotlincrypto/core/Counter {
34+
public static final field Companion Lorg/kotlincrypto/core/Counter$Bit64$Companion;
35+
public static final field MAX_INCREMENT J
36+
public final field incrementBy J
37+
public fun <init> (J)V
38+
public fun <init> (JJJ)V
39+
public fun <init> (Lorg/kotlincrypto/core/Counter$Bit64;)V
40+
public final fun hi ()J
41+
protected fun increment ()V
42+
public final fun lo ()J
43+
protected fun reset ()V
44+
}
45+
46+
public final class org/kotlincrypto/core/Counter$Bit64$Companion {
47+
}
48+
949
public abstract interface annotation class org/kotlincrypto/core/ExperimentalKotlinCryptoApi : java/lang/annotation/Annotation {
1050
}
1151

library/core/api/core.klib.api

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,55 @@ abstract interface org.kotlincrypto.core/Updatable { // org.kotlincrypto.core/Up
3131
abstract fun update(kotlin/ByteArray) // org.kotlincrypto.core/Updatable.update|update(kotlin.ByteArray){}[0]
3232
abstract fun update(kotlin/ByteArray, kotlin/Int, kotlin/Int) // org.kotlincrypto.core/Updatable.update|update(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
3333
}
34+
35+
sealed class org.kotlincrypto.core/Counter { // org.kotlincrypto.core/Counter|null[0]
36+
abstract fun increment() // org.kotlincrypto.core/Counter.increment|increment(){}[0]
37+
abstract fun reset() // org.kotlincrypto.core/Counter.reset|reset(){}[0]
38+
final fun equals(kotlin/Any?): kotlin/Boolean // org.kotlincrypto.core/Counter.equals|equals(kotlin.Any?){}[0]
39+
final fun hashCode(): kotlin/Int // org.kotlincrypto.core/Counter.hashCode|hashCode(){}[0]
40+
final fun toString(): kotlin/String // org.kotlincrypto.core/Counter.toString|toString(){}[0]
41+
42+
abstract class Bit32 : org.kotlincrypto.core/Counter { // org.kotlincrypto.core/Counter.Bit32|null[0]
43+
constructor <init>(kotlin/Int) // org.kotlincrypto.core/Counter.Bit32.<init>|<init>(kotlin.Int){}[0]
44+
constructor <init>(kotlin/Int, kotlin/Int, kotlin/Int) // org.kotlincrypto.core/Counter.Bit32.<init>|<init>(kotlin.Int;kotlin.Int;kotlin.Int){}[0]
45+
constructor <init>(org.kotlincrypto.core/Counter.Bit32) // org.kotlincrypto.core/Counter.Bit32.<init>|<init>(org.kotlincrypto.core.Counter.Bit32){}[0]
46+
47+
final val incrementBy // org.kotlincrypto.core/Counter.Bit32.incrementBy|{}incrementBy[0]
48+
final fun <get-incrementBy>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.incrementBy.<get-incrementBy>|<get-incrementBy>(){}[0]
49+
50+
final var hi // org.kotlincrypto.core/Counter.Bit32.hi|{}hi[0]
51+
final fun <get-hi>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.hi.<get-hi>|<get-hi>(){}[0]
52+
final var lo // org.kotlincrypto.core/Counter.Bit32.lo|{}lo[0]
53+
final fun <get-lo>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.lo.<get-lo>|<get-lo>(){}[0]
54+
55+
open fun increment() // org.kotlincrypto.core/Counter.Bit32.increment|increment(){}[0]
56+
open fun reset() // org.kotlincrypto.core/Counter.Bit32.reset|reset(){}[0]
57+
58+
final object Companion { // org.kotlincrypto.core/Counter.Bit32.Companion|null[0]
59+
final const val MAX_INCREMENT // org.kotlincrypto.core/Counter.Bit32.Companion.MAX_INCREMENT|{}MAX_INCREMENT[0]
60+
final fun <get-MAX_INCREMENT>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.Companion.MAX_INCREMENT.<get-MAX_INCREMENT>|<get-MAX_INCREMENT>(){}[0]
61+
}
62+
}
63+
64+
abstract class Bit64 : org.kotlincrypto.core/Counter { // org.kotlincrypto.core/Counter.Bit64|null[0]
65+
constructor <init>(kotlin/Long) // org.kotlincrypto.core/Counter.Bit64.<init>|<init>(kotlin.Long){}[0]
66+
constructor <init>(kotlin/Long, kotlin/Long, kotlin/Long) // org.kotlincrypto.core/Counter.Bit64.<init>|<init>(kotlin.Long;kotlin.Long;kotlin.Long){}[0]
67+
constructor <init>(org.kotlincrypto.core/Counter.Bit64) // org.kotlincrypto.core/Counter.Bit64.<init>|<init>(org.kotlincrypto.core.Counter.Bit64){}[0]
68+
69+
final val incrementBy // org.kotlincrypto.core/Counter.Bit64.incrementBy|{}incrementBy[0]
70+
final fun <get-incrementBy>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.incrementBy.<get-incrementBy>|<get-incrementBy>(){}[0]
71+
72+
final var hi // org.kotlincrypto.core/Counter.Bit64.hi|{}hi[0]
73+
final fun <get-hi>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.hi.<get-hi>|<get-hi>(){}[0]
74+
final var lo // org.kotlincrypto.core/Counter.Bit64.lo|{}lo[0]
75+
final fun <get-lo>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.lo.<get-lo>|<get-lo>(){}[0]
76+
77+
open fun increment() // org.kotlincrypto.core/Counter.Bit64.increment|increment(){}[0]
78+
open fun reset() // org.kotlincrypto.core/Counter.Bit64.reset|reset(){}[0]
79+
80+
final object Companion { // org.kotlincrypto.core/Counter.Bit64.Companion|null[0]
81+
final const val MAX_INCREMENT // org.kotlincrypto.core/Counter.Bit64.Companion.MAX_INCREMENT|{}MAX_INCREMENT[0]
82+
final fun <get-MAX_INCREMENT>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.Companion.MAX_INCREMENT.<get-MAX_INCREMENT>|<get-MAX_INCREMENT>(){}[0]
83+
}
84+
}
85+
}
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* Copyright (c) 2025 Matthew Nelson
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
**/
16+
package org.kotlincrypto.core
17+
18+
import org.kotlincrypto.core.Counter.Bit32.Companion.MAX_INCREMENT
19+
import org.kotlincrypto.core.Counter.Bit64.Companion.MAX_INCREMENT
20+
import kotlin.jvm.JvmField
21+
import kotlin.jvm.JvmName
22+
23+
/**
24+
* Utility for counting things.
25+
* */
26+
public sealed class Counter private constructor() {
27+
28+
/**
29+
* A counter that utilizes 32-bit numbers providing a maximum count of 2^64.
30+
* */
31+
public abstract class Bit32: Counter {
32+
33+
public companion object {
34+
35+
/**
36+
* The maximum value for which [Bit32.incrementBy] can be set to.
37+
*
38+
* 1024 * 1024 >> 1048576
39+
* */
40+
public const val MAX_INCREMENT: Int = 1024 * 1024 // Never decrease, only increase.
41+
}
42+
43+
/**
44+
* The value to increment things by
45+
* */
46+
@JvmField
47+
public val incrementBy: Int
48+
49+
/**
50+
* The least significant bits of the number
51+
* */
52+
@get:JvmName("lo")
53+
public var lo: Int
54+
private set
55+
56+
/**
57+
* The most significant bits of the number
58+
* */
59+
@get:JvmName("hi")
60+
public var hi: Int
61+
private set
62+
63+
/**
64+
* Creates a new [Bit32] counter initialized to [lo] and [hi]
65+
*
66+
* @throws [IllegalArgumentException] when:
67+
* - [incrementBy] is less than or equal to 0
68+
* - [incrementBy] is greater than [MAX_INCREMENT]
69+
* - [incrementBy] is not a factor of 8
70+
* - [lo] is not a factor of [incrementBy]
71+
* */
72+
public constructor(lo: Int, hi: Int, incrementBy: Int): super() {
73+
require(incrementBy > 0) { "incrementBy[$incrementBy] must be greater than 0" }
74+
require(incrementBy <= MAX_INCREMENT) { "incrementBy[$incrementBy] must be less than or equal to $MAX_INCREMENT" }
75+
require(incrementBy % 8 == 0) { "incrementBy[$incrementBy] must be a factor of 8" }
76+
require(lo % incrementBy == 0) { "lo must be a factor of incrementBy[$incrementBy]" }
77+
78+
this.incrementBy = incrementBy
79+
this.lo = lo
80+
this.hi = hi
81+
}
82+
83+
/**
84+
* Creates a new [Bit32] counter initialized to 0, 0
85+
*
86+
* @throws [IllegalArgumentException] when [incrementBy] is:
87+
* - Less than or equal to 0
88+
* - Greater than [MAX_INCREMENT]
89+
* - Not a factor of 8
90+
* */
91+
public constructor(incrementBy: Int): this(0, 0, incrementBy)
92+
93+
/**
94+
* Creates a clone of [other]
95+
* */
96+
public constructor(other: Bit32): super() {
97+
this.incrementBy = other.incrementBy
98+
this.lo = other.lo
99+
this.hi = other.hi
100+
}
101+
102+
protected override fun increment() {
103+
lo += incrementBy
104+
if (lo == 0) hi++
105+
}
106+
107+
protected override fun reset() {
108+
lo = 0
109+
hi = 0
110+
}
111+
}
112+
113+
/**
114+
* A counter that utilizes 64-bit numbers providing a maximum count of 2^128.
115+
* */
116+
public abstract class Bit64: Counter {
117+
118+
public companion object {
119+
120+
/**
121+
* The maximum value for which [Bit64.incrementBy] can be set to.
122+
*
123+
* @see [Bit32.MAX_INCREMENT]
124+
* */
125+
public const val MAX_INCREMENT: Long = Bit32.MAX_INCREMENT.toLong()
126+
}
127+
128+
/**
129+
* The value to increment things by
130+
* */
131+
@JvmField
132+
public val incrementBy: Long
133+
134+
/**
135+
* The least significant bits of the number
136+
* */
137+
@get:JvmName("lo")
138+
public var lo: Long
139+
private set
140+
141+
/**
142+
* The most significant bits of the number
143+
* */
144+
@get:JvmName("hi")
145+
public var hi: Long
146+
private set
147+
148+
/**
149+
* Creates a new [Bit64] counter initialized to [lo] and [hi]
150+
*
151+
* @throws [IllegalArgumentException] when:
152+
* - [incrementBy] is less than or equal to 0
153+
* - [incrementBy] is greater than [MAX_INCREMENT]
154+
* - [incrementBy] is not a factor of 8
155+
* - [lo] is not a factor of [incrementBy]
156+
* */
157+
public constructor(lo: Long, hi: Long, incrementBy: Long): super() {
158+
require(incrementBy > 0L) { "incrementBy[$incrementBy] must be greater than 0" }
159+
require(incrementBy <= MAX_INCREMENT) { "incrementBy[$incrementBy] must be less than or equal to $MAX_INCREMENT" }
160+
require(incrementBy % 8 == 0L) { "incrementBy[$incrementBy] must be a factor of 8" }
161+
require(lo % incrementBy == 0L) { "lo must be a factor of incrementBy[$incrementBy]" }
162+
163+
this.incrementBy = incrementBy
164+
this.lo = lo
165+
this.hi = hi
166+
}
167+
168+
/**
169+
* Creates a new [Bit64] counter initialized to 0, 0
170+
*
171+
* @throws [IllegalArgumentException] when [incrementBy] is:
172+
* - Less than or equal to 0
173+
* - Greater than [MAX_INCREMENT]
174+
* - Not a factor of 8
175+
* */
176+
public constructor(incrementBy: Long): this(0, 0, incrementBy)
177+
178+
/**
179+
* Creates a clone of [other]
180+
* */
181+
public constructor(other: Bit64): super() {
182+
this.incrementBy = other.incrementBy
183+
this.lo = other.lo
184+
this.hi = other.hi
185+
}
186+
187+
protected override fun increment() {
188+
lo += incrementBy
189+
if (lo == 0L) hi++
190+
}
191+
192+
protected override fun reset() {
193+
lo = 0L
194+
hi = 0L
195+
}
196+
}
197+
198+
protected abstract fun increment()
199+
protected abstract fun reset()
200+
201+
private val code = Any()
202+
203+
/** @suppress */
204+
public final override fun equals(other: Any?): Boolean = other is Counter && other.hashCode() == hashCode()
205+
/** @suppress */
206+
public final override fun hashCode(): Int = 17 * 31 + code.hashCode()
207+
/** @suppress */
208+
public final override fun toString(): String = when (this) {
209+
is Bit32 -> "Bit32[lo=$lo, hi=$hi, incrementBy=$incrementBy]"
210+
is Bit64 -> "Bit64[lo=$lo, hi=$hi, incrementBy=$incrementBy]"
211+
}.let { value -> "Counter.$value@${hashCode()}" }
212+
}

0 commit comments

Comments
 (0)