Standarizing V cryptographic hash API #20894
Replies: 4 comments 4 replies
-
First random thoughts... Rename The interface could be named Speaking of |
Beta Was this translation helpful? Give feedback.
-
Renaming
Its doesn't really matter, the main reason for
A good option, this is list common term for that in others language
|
Beta Was this translation helpful? Give feedback.
-
Wait more feedbacks from all v communities, @spytheman, @hungrybluedev, @enghitalo, @danilolekovic, @medvednikov, @joe-conigliaro |
Beta Was this translation helpful? Give feedback.
-
If we can take temporary conclusions, there are at least a few changes that can be proposed interface Hash {
// id returns the identification of this hash algorithm
id() crypto.HashType
// size returns the size of the hash (in bytes) produced by this hash algorithm
size() int
// block_size returns the block size of the underlying hash algorithm
block_size() int
mut:
// write updates to the internal state of this hash algorithm. This satisfies the `io.Writer` interface.
write(b []u8) !int
// hash generates and returns a digest message with the byte length `.size()`
hash() ![]u8 // or maybe hash(mut out)!
// reset returns the internal state to the default state
reset() 3). Adapts the existing hash module to meet the new interface. |
Beta Was this translation helpful? Give feedback.
-
Motivation
As we all know, v has already supports several cryptographic hash modules, such as
sha1
,sha256
,sha512
from theSHA
family or fromblake
family likesblake2b
,blake2s
or evenblake3
modules. However, unfortunately, there are still variations in implementation, and there is still no standard interface that can be used as a reference for this. Golang has acrypto.Hash
interface and some other languages I think have it too, perhaps in different forms. This efforts is a step further to standarize v cryptographic hash API.The discussion about standardizing the hash API has actually happens before this thread, its on the discord channel, see 1, 2 or 3 for more background.
With this in mind and suggestion from @joe-conigliaro, so i pasted here to get more broader scopes, more feedbacks, and more ideas from the V developer, maintainer or all V community.
Ideas
The basic idea is to add more formal API in the sense of standarized interface for V cryptographic hash API. The idea mostly inspired by the go version
crypto.Hash
, so, i'm gone to share my thought on this so we can get lots of input and feedback from the community.For interface name, if we're looking into already defined structs, enum, interface or other object that have been previously defined, the first choice where it similar the go one is
Hash
name, but its already used ascrypto.Hash
enum.The second choices is
Digest
, but its (would) conflict with already defined `Digest struct in scattered hash modules.The third option is
Hasher
orDigester
, its it's closer to the topic and standarized way we're going to create, and its also follows some existing pattern for interface names where its postixed by-er
, think ofio.Reader
,io.Writer
,io.Seeker
and so on.The second thing, where should these interfaces be defined
I think, the best places for this is defined in and lived at
vlib/crypto/crypto.v file
, side by side with theenum Hash
definition but it can be live in separate module, likevlib/crypto/digest
or other alternatives. Please, give an ideaThe third things, are fields or methods for interface.
The standard interface, I think, should at least contains the following methods:
Identity method, calls it
.id()
or other nameIts acts as the identity of these interfaces. I don't have an opinion on what the return value of
id()
should be, but I think it should be an unique value, for example is enumerable value that has been defined, likes thecrypto.Hash
enum, but string or int is also possible.Apart from functioning as an interface identity,
id()
can also act as a comparability identity with other interfaces and can be functioned as a self-check mechanism with other fields/methods from this interface which will be explained later.A method thats return the size of output of the hash/digest bytes produced by the hash algorithm, calls it
.size()
This method dictates the size of the output (in bytes) of the digest produced by this hash algorithm. The others language has this similar one, likes the python
hashlib
, has ahash.digest_size
, java hasMessageDigest.getDigestLength()
. Fortunately, standardsha
Digest has already implementedsize()
part.A method thats return the size of the block of underlying hash algorithm used, maybe calls it
block_size()
methodThis method has been implemented in several existing modules, for example
sha256.Digest.block_size()
and of coursesha512
too. This method specifies the block size of the digest it operates on. But I don't know whether.block_size()
has any meaning and makes sense for those who don't operate on a block basis, think of it like a stream cipher, even though it also uses a block-based strategy internally. Python hashash.block_size
in theirhashlib
, and golang hashcrypto.Hash.block_size()
also.A method for updating internal state of the hash with the bytes of data.
The general pattern for this is
.write(b []u8) !int
even the.update(b []u8)
pattern is also popular among others.The general semantics of
write
follow those already defined in several modules, including the basicio.Writer
interface, This method is used to update the internal state of the digest.A similar method is generally availables in other languages, in python there is
hash.update(data)
from thehashlib
modul.In java there is
MessageDigest.update(bytes[])
with several variant.In my opinion,
write
is the best choice for this purposeA method for obtaining or calculating a digest from this hash algorithm,
There are many pattern for this purpose. At the standard v library, especially the
sh
a family hash, there are already someDigest.checksum
andDigest.sum(b [])
and in theblake
family only implements.checksum
, whereas.sum
is not available.In my thought,
.sum(b []u8)
is little more confusing because its contains two semantics, the first semantic ischecksum
semantic by calling sum with nill bytes, ie,.sum([])
and the second issum
semantic, the sum of bytes message plus current digest, ie,b << current_digest
I think for this purpose, we could follow the python
hashlib
one withhash.digest()
..its exactly produces digest bytes with no other misinterpretation. the.digest()
name also represents what it does. But, as I said before, please give your ideas..reset()
I think the name describes what it is exactly does., but explicitly defines it is more good thing.
Resumed idea
From the several items described above, let's summarize what we have written before,
In minimal form, the hash interface look like this one
That's iit ..
Give your idea
Please, give your idea, feedback and maybe just comments
All of hem are very appreciated.
Thanks ..
Beta Was this translation helpful? Give feedback.
All reactions