ripemd160
Package ripemd160 provides the local RIPEMD-160 implementation used by the
FrogoDB client for key digest and partition routing support. It exposes a
reusable Digest type, New, and the constants DigestSize (20) and
BlockSize (64).
The implementation is allocation-conscious: callers can reuse a Digest with
Reset, stream bytes with Write or WriteByte, and get a fixed-size
checksum with Checksum.
Strengths
- Provides the deterministic RIPEMD-160 hashing needed by the client for key
digest computation and partition routing compatibility.
- Supports reusable digest state. Keeping a
Digest value per worker and
calling Reset avoids allocating a new digest object on hot paths.
WriteByte handles the key-type byte used by client digest construction
without requiring a one-byte slice allocation.
Checksum returns a fixed [20]byte and leaves the running state unchanged,
so callers can inspect a digest and continue streaming more data.
- The implementation is covered by standard RIPEMD-160 test vectors, including
chunked input and the million-"a" vector.
Weaknesses / Tradeoffs
- This package exists for FrogoDB wire and routing compatibility. It should not
be used for password hashing, message authentication, signatures, or new
security-sensitive designs.
New allocates a Digest; use a value or reuse an existing digest when
allocation behavior matters.
Sum appends to the caller-provided slice, so it may allocate if the slice
capacity is not large enough. Use Checksum when a fixed array result is a
better fit.
- A
Digest is mutable and is not safe for concurrent writes without external
synchronization.
Checksum
package main
import (
"encoding/hex"
"fmt"
"github.com/FrogoAI/fdb-client/pkg/ripemd160"
)
func main() {
d := ripemd160.New()
_, _ = d.Write([]byte("set-name"))
_ = d.WriteByte(0x02)
_, _ = d.Write([]byte("user:1234"))
sum := d.Checksum()
fmt.Println(hex.EncodeToString(sum[:]))
}
Checksum returns a [ripemd160.DigestSize]byte and does not change the
running state, so callers may continue writing after taking a checksum.
Reuse Without Allocating a Digest
For hot paths, keep a Digest value per worker and reset it for each checksum.
type keyHasher struct {
d ripemd160.Digest
}
func (h *keyHasher) checksumKey(set string, key []byte) [ripemd160.DigestSize]byte {
h.d.Reset()
_, _ = h.d.Write([]byte(set))
_ = h.d.WriteByte(0x02) // string key type byte
_, _ = h.d.Write(key)
return h.d.Checksum()
}
Sum is also available when a caller wants to append the current checksum to an
existing byte slice.
d := ripemd160.New()
_, _ = d.Write([]byte("abc"))
out := d.Sum([]byte("prefix"))
fmt.Println(hex.EncodeToString(out))