-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add (Half)SipHash implementation #43
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a very quick review. A couple of things that stick out:
- Would suggest taking a look at other modules and their implementations. Trying to follow (roughly) how a project has things structured elsewhere is a courtesy which saves people (reviewers) time.
- This implementation does not follow other
Mac
implementations whereby a separate class is utilized for each algorithm. - Tests do not follow structure of other modules which are all verified against Bouncycastle and are designed to properly exercise the implementation's internals.
public sealed class SipHash: Mac {
// ...
}
public class SIPHASH: SipHash {
// ...
}
public class HALF_SIPHASH: SipHash {
// ...
}
EDIT: A good reference to utilize is the kmac
module and how it is structured.
library/siphash/src/commonMain/kotlin/org/kotlincrypto/macs/siphash/SipHash.kt
Outdated
Show resolved
Hide resolved
library/siphash/src/commonMain/kotlin/org/kotlincrypto/macs/siphash/SipHash.kt
Outdated
Show resolved
Hide resolved
this.state = engine.state | ||
this.inputs = engine.inputs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must be copied, otherwise updating old SipHash
will also affect new
private class SipHashEngine : Engine { | ||
|
||
val state: SipHash.State | ||
var inputs: ByteArray |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use val
and an appropriate sized ByteArray
. removal and replacement is an incredible amount of unnecessary overhead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand what appropriately sized ByteArray means in this context. Any ByteArray could be used as an for the algorithm. One of the advantages of SipHash is that it's simpler and faster on short messages, so I expect that we should go for a relatively small ByteArray here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm looking into things further regarding SipHash, and it seems like an array or a list is not even necessary to use.
As per the reference implementation, SipHash
works with 64 bit words (a kotlin.Long
) and HalfSiphHash
algorithms work with 32 bit words (a kotlin.Int
). The rounds then shift bits and update the state locally.
Can see this in BouncyCastle's implementation of SipHash and SipHash128
library/siphash/src/commonMain/kotlin/org/kotlincrypto/macs/siphash/SipHash.kt
Outdated
Show resolved
Hide resolved
library/siphash/src/commonMain/kotlin/org/kotlincrypto/macs/siphash/SipHash.kt
Outdated
Show resolved
Hide resolved
import kotlin.test.* | ||
|
||
@OptIn(ExperimentalUnsignedTypes::class, ExperimentalStdlibApi::class) | ||
class SipHashUnitTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All tests must implement the repository test abstraction. Also, the Jvm implementations are verified against BouncyCastle.
See the other modules' test implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jep, I have one failure on the jvm, which indicates that there is something wrong with my update implementation.
Unfortunately, there is no HalfSipHash implementation on BouncyCastle (that I am aware)
Still need help with the Digest
Thanks! And sorry for not following the existing structure, It was not trivial for me to determine how to structure it. I don't have any background in cryptography. Your comments steered me in the right direction. I still have 1 failing jvm unit test tough, Expected :e635b1b821db25e1 My assumption is that something goes wrong when I update the Engine:
Because these update calls are not used in the provided data set. E.g. the other unit tests, only use I realize that my approach with a |
No checks are necessary with regard to the input. The
Correct, |
Another notable issue here are the naming conventions utilized; unsure how to square this circle. Reference implementation states the following
which would suggest the following class names public sealed class SipHash: Mac {
// ...
}
public class SipHash64: SipHash {
// ...
}
public class SipHash128: SipHash {
// ...
}
public class HalfSipHash64: SipHash {
// ...
}
public class HalfSipHash32: SipHash {
// ...
} Algorithm names would the follow that of the reference implementation based off of My only concern for the I am more inclined to go with algorithm names based off of the actual reference implementation (I think BC has gotten it incorrect). As there is not actual FIPS spec for this, it's sort of up in the air. |
2nd attempt, to provide a (Half)SipHash implementation.
SipHash
implements theMac
interface now.I'm not really happy that the size of the key determines which algorithm is used.
Maybe we can make the distinction more explicit...
Looking forward to feedback/concerns/suggestions