Skip to content

Commit

Permalink
Refactor Digest internal API (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
05nelsonm authored Jan 2, 2025
1 parent fdea6b5 commit abe3af1
Show file tree
Hide file tree
Showing 20 changed files with 630 additions and 373 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package org.kotlincrypto.core.benchmarks

import kotlinx.benchmark.*
import org.kotlincrypto.core.digest.Digest
import org.kotlincrypto.core.digest.internal.DigestState
import kotlin.random.Random

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

private class TestDigest: Digest {
constructor(): super("Benchmark", 32, 32)
private constructor(state: DigestState): super(state)
override fun resetDigest() {}
override fun copy(state: DigestState): Digest = TestDigest(state)
override fun compress(input: ByteArray, offset: Int) {}
override fun digest(bitLength: Long, bufferOffset: Int, buffer: ByteArray): ByteArray = ByteArray(0)
private constructor(state: State): super(state)
override fun resetProtected() {}
override fun copyProtected(state: State): Digest = TestDigest(state)
override fun compressProtected(input: ByteArray, offset: Int) {}
override fun digestProtected(buffer: ByteArray, offset: Int): ByteArray = ByteArray(0)
}

private val digest = TestDigest()
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ POM_DEVELOPER_ID=KotlinCrypto
POM_DEVELOPER_NAME=Kotlin Crypto
POM_DEVELOPER_URL=https://github.com/KotlinCrypto/

VERSION_NAME=0.5.6-SNAPSHOT
VERSION_NAME=1.0.0-SNAPSHOT
# 0.1.0-alpha01 = 00 01 00 11
# 0.1.0-beta01 = 00 01 00 21
# 0.1.0-rc01 = 00 01 00 31
# 0.1.0 = 00 01 00 99
# 1.1.0 = 01 01 00 99
VERSION_CODE=00050699
VERSION_CODE=01000099
40 changes: 40 additions & 0 deletions library/core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,46 @@ public abstract interface class org/kotlincrypto/core/Copyable {
public abstract fun copy ()Ljava/lang/Object;
}

public abstract class org/kotlincrypto/core/Counter {
public final fun equals (Ljava/lang/Object;)Z
public final fun hashCode ()I
protected abstract fun increment ()V
protected abstract fun reset ()V
public final fun toString ()Ljava/lang/String;
}

public abstract class org/kotlincrypto/core/Counter$Bit32 : org/kotlincrypto/core/Counter {
public static final field Companion Lorg/kotlincrypto/core/Counter$Bit32$Companion;
public static final field MAX_INCREMENT I
public final field incrementBy I
public fun <init> (I)V
public fun <init> (III)V
public fun <init> (Lorg/kotlincrypto/core/Counter$Bit32;)V
public final fun hi ()I
protected fun increment ()V
public final fun lo ()I
protected fun reset ()V
}

public final class org/kotlincrypto/core/Counter$Bit32$Companion {
}

public abstract class org/kotlincrypto/core/Counter$Bit64 : org/kotlincrypto/core/Counter {
public static final field Companion Lorg/kotlincrypto/core/Counter$Bit64$Companion;
public static final field MAX_INCREMENT J
public final field incrementBy J
public fun <init> (J)V
public fun <init> (JJJ)V
public fun <init> (Lorg/kotlincrypto/core/Counter$Bit64;)V
public final fun hi ()J
protected fun increment ()V
public final fun lo ()J
protected fun reset ()V
}

public final class org/kotlincrypto/core/Counter$Bit64$Companion {
}

public abstract interface annotation class org/kotlincrypto/core/ExperimentalKotlinCryptoApi : java/lang/annotation/Annotation {
}

Expand Down
52 changes: 52 additions & 0 deletions library/core/api/core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,55 @@ abstract interface org.kotlincrypto.core/Updatable { // org.kotlincrypto.core/Up
abstract fun update(kotlin/ByteArray) // org.kotlincrypto.core/Updatable.update|update(kotlin.ByteArray){}[0]
abstract fun update(kotlin/ByteArray, kotlin/Int, kotlin/Int) // org.kotlincrypto.core/Updatable.update|update(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
}

sealed class org.kotlincrypto.core/Counter { // org.kotlincrypto.core/Counter|null[0]
abstract fun increment() // org.kotlincrypto.core/Counter.increment|increment(){}[0]
abstract fun reset() // org.kotlincrypto.core/Counter.reset|reset(){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // org.kotlincrypto.core/Counter.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // org.kotlincrypto.core/Counter.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // org.kotlincrypto.core/Counter.toString|toString(){}[0]

abstract class Bit32 : org.kotlincrypto.core/Counter { // org.kotlincrypto.core/Counter.Bit32|null[0]
constructor <init>(kotlin/Int) // org.kotlincrypto.core/Counter.Bit32.<init>|<init>(kotlin.Int){}[0]
constructor <init>(kotlin/Int, kotlin/Int, kotlin/Int) // org.kotlincrypto.core/Counter.Bit32.<init>|<init>(kotlin.Int;kotlin.Int;kotlin.Int){}[0]
constructor <init>(org.kotlincrypto.core/Counter.Bit32) // org.kotlincrypto.core/Counter.Bit32.<init>|<init>(org.kotlincrypto.core.Counter.Bit32){}[0]

final val incrementBy // org.kotlincrypto.core/Counter.Bit32.incrementBy|{}incrementBy[0]
final fun <get-incrementBy>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.incrementBy.<get-incrementBy>|<get-incrementBy>(){}[0]

final var hi // org.kotlincrypto.core/Counter.Bit32.hi|{}hi[0]
final fun <get-hi>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.hi.<get-hi>|<get-hi>(){}[0]
final var lo // org.kotlincrypto.core/Counter.Bit32.lo|{}lo[0]
final fun <get-lo>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.lo.<get-lo>|<get-lo>(){}[0]

open fun increment() // org.kotlincrypto.core/Counter.Bit32.increment|increment(){}[0]
open fun reset() // org.kotlincrypto.core/Counter.Bit32.reset|reset(){}[0]

final object Companion { // org.kotlincrypto.core/Counter.Bit32.Companion|null[0]
final const val MAX_INCREMENT // org.kotlincrypto.core/Counter.Bit32.Companion.MAX_INCREMENT|{}MAX_INCREMENT[0]
final fun <get-MAX_INCREMENT>(): kotlin/Int // org.kotlincrypto.core/Counter.Bit32.Companion.MAX_INCREMENT.<get-MAX_INCREMENT>|<get-MAX_INCREMENT>(){}[0]
}
}

abstract class Bit64 : org.kotlincrypto.core/Counter { // org.kotlincrypto.core/Counter.Bit64|null[0]
constructor <init>(kotlin/Long) // org.kotlincrypto.core/Counter.Bit64.<init>|<init>(kotlin.Long){}[0]
constructor <init>(kotlin/Long, kotlin/Long, kotlin/Long) // org.kotlincrypto.core/Counter.Bit64.<init>|<init>(kotlin.Long;kotlin.Long;kotlin.Long){}[0]
constructor <init>(org.kotlincrypto.core/Counter.Bit64) // org.kotlincrypto.core/Counter.Bit64.<init>|<init>(org.kotlincrypto.core.Counter.Bit64){}[0]

final val incrementBy // org.kotlincrypto.core/Counter.Bit64.incrementBy|{}incrementBy[0]
final fun <get-incrementBy>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.incrementBy.<get-incrementBy>|<get-incrementBy>(){}[0]

final var hi // org.kotlincrypto.core/Counter.Bit64.hi|{}hi[0]
final fun <get-hi>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.hi.<get-hi>|<get-hi>(){}[0]
final var lo // org.kotlincrypto.core/Counter.Bit64.lo|{}lo[0]
final fun <get-lo>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.lo.<get-lo>|<get-lo>(){}[0]

open fun increment() // org.kotlincrypto.core/Counter.Bit64.increment|increment(){}[0]
open fun reset() // org.kotlincrypto.core/Counter.Bit64.reset|reset(){}[0]

final object Companion { // org.kotlincrypto.core/Counter.Bit64.Companion|null[0]
final const val MAX_INCREMENT // org.kotlincrypto.core/Counter.Bit64.Companion.MAX_INCREMENT|{}MAX_INCREMENT[0]
final fun <get-MAX_INCREMENT>(): kotlin/Long // org.kotlincrypto.core/Counter.Bit64.Companion.MAX_INCREMENT.<get-MAX_INCREMENT>|<get-MAX_INCREMENT>(){}[0]
}
}
}
212 changes: 212 additions & 0 deletions library/core/src/commonMain/kotlin/org/kotlincrypto/core/Counter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*
* Copyright (c) 2025 Matthew Nelson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.kotlincrypto.core

import org.kotlincrypto.core.Counter.Bit32.Companion.MAX_INCREMENT
import org.kotlincrypto.core.Counter.Bit64.Companion.MAX_INCREMENT
import kotlin.jvm.JvmField
import kotlin.jvm.JvmName

/**
* Utility for counting things.
* */
public sealed class Counter private constructor() {

/**
* A counter that utilizes 32-bit numbers providing a maximum count of 2^64.
* */
public abstract class Bit32: Counter {

public companion object {

/**
* The maximum value for which [Bit32.incrementBy] can be set to.
*
* 1024 * 1024 >> 1048576
* */
public const val MAX_INCREMENT: Int = 1024 * 1024 // Never decrease, only increase.
}

/**
* The value to increment things by
* */
@JvmField
public val incrementBy: Int

/**
* The least significant bits of the number
* */
@get:JvmName("lo")
public var lo: Int
private set

/**
* The most significant bits of the number
* */
@get:JvmName("hi")
public var hi: Int
private set

/**
* Creates a new [Bit32] counter initialized to [lo] and [hi]
*
* @throws [IllegalArgumentException] when:
* - [incrementBy] is less than or equal to 0
* - [incrementBy] is greater than [MAX_INCREMENT]
* - [incrementBy] is not a factor of 8
* - [lo] is not a factor of [incrementBy]
* */
public constructor(lo: Int, hi: Int, incrementBy: Int): super() {
require(incrementBy > 0) { "incrementBy[$incrementBy] must be greater than 0" }
require(incrementBy <= MAX_INCREMENT) { "incrementBy[$incrementBy] must be less than or equal to $MAX_INCREMENT" }
require(incrementBy % 8 == 0) { "incrementBy[$incrementBy] must be a factor of 8" }
require(lo % incrementBy == 0) { "lo must be a factor of incrementBy[$incrementBy]" }

this.incrementBy = incrementBy
this.lo = lo
this.hi = hi
}

/**
* Creates a new [Bit32] counter initialized to 0, 0
*
* @throws [IllegalArgumentException] when [incrementBy] is:
* - Less than or equal to 0
* - Greater than [MAX_INCREMENT]
* - Not a factor of 8
* */
public constructor(incrementBy: Int): this(0, 0, incrementBy)

/**
* Creates a clone of [other]
* */
public constructor(other: Bit32): super() {
this.incrementBy = other.incrementBy
this.lo = other.lo
this.hi = other.hi
}

protected override fun increment() {
lo += incrementBy
if (lo == 0) hi++
}

protected override fun reset() {
lo = 0
hi = 0
}
}

/**
* A counter that utilizes 64-bit numbers providing a maximum count of 2^128.
* */
public abstract class Bit64: Counter {

public companion object {

/**
* The maximum value for which [Bit64.incrementBy] can be set to.
*
* @see [Bit32.MAX_INCREMENT]
* */
public const val MAX_INCREMENT: Long = Bit32.MAX_INCREMENT.toLong()
}

/**
* The value to increment things by
* */
@JvmField
public val incrementBy: Long

/**
* The least significant bits of the number
* */
@get:JvmName("lo")
public var lo: Long
private set

/**
* The most significant bits of the number
* */
@get:JvmName("hi")
public var hi: Long
private set

/**
* Creates a new [Bit64] counter initialized to [lo] and [hi]
*
* @throws [IllegalArgumentException] when:
* - [incrementBy] is less than or equal to 0
* - [incrementBy] is greater than [MAX_INCREMENT]
* - [incrementBy] is not a factor of 8
* - [lo] is not a factor of [incrementBy]
* */
public constructor(lo: Long, hi: Long, incrementBy: Long): super() {
require(incrementBy > 0L) { "incrementBy[$incrementBy] must be greater than 0" }
require(incrementBy <= MAX_INCREMENT) { "incrementBy[$incrementBy] must be less than or equal to $MAX_INCREMENT" }
require(incrementBy % 8 == 0L) { "incrementBy[$incrementBy] must be a factor of 8" }
require(lo % incrementBy == 0L) { "lo must be a factor of incrementBy[$incrementBy]" }

this.incrementBy = incrementBy
this.lo = lo
this.hi = hi
}

/**
* Creates a new [Bit64] counter initialized to 0, 0
*
* @throws [IllegalArgumentException] when [incrementBy] is:
* - Less than or equal to 0
* - Greater than [MAX_INCREMENT]
* - Not a factor of 8
* */
public constructor(incrementBy: Long): this(0, 0, incrementBy)

/**
* Creates a clone of [other]
* */
public constructor(other: Bit64): super() {
this.incrementBy = other.incrementBy
this.lo = other.lo
this.hi = other.hi
}

protected override fun increment() {
lo += incrementBy
if (lo == 0L) hi++
}

protected override fun reset() {
lo = 0L
hi = 0L
}
}

protected abstract fun increment()
protected abstract fun reset()

private val code = Any()

/** @suppress */
public final override fun equals(other: Any?): Boolean = other is Counter && other.hashCode() == hashCode()
/** @suppress */
public final override fun hashCode(): Int = 17 * 31 + code.hashCode()
/** @suppress */
public final override fun toString(): String = when (this) {
is Bit32 -> "Bit32[lo=$lo, hi=$hi, incrementBy=$incrementBy]"
is Bit64 -> "Bit64[lo=$lo, hi=$hi, incrementBy=$incrementBy]"
}.let { value -> "Counter.$value@${hashCode()}" }
}
Loading

0 comments on commit abe3af1

Please sign in to comment.