mirror of
https://github.com/luxfi/crypto.git
synced 2026-07-27 01:54:50 +00:00
refactor(hash): remove duplicate hashing package, use hash
- Remove hashing/ directory (duplicate of hash/) - Update imports in cb58, secp256k1 to use crypto/hash - Follows Go stdlib naming convention (hash vs hashing)
This commit is contained in:
+3
-3
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/mr-tron/base58/base58"
|
"github.com/mr-tron/base58/base58"
|
||||||
|
|
||||||
"github.com/luxfi/crypto/hashing"
|
"github.com/luxfi/crypto/hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
const checksumLen = 4
|
const checksumLen = 4
|
||||||
@@ -33,7 +33,7 @@ func Encode(bytes []byte) (string, error) {
|
|||||||
}
|
}
|
||||||
checked := make([]byte, bytesLen+checksumLen)
|
checked := make([]byte, bytesLen+checksumLen)
|
||||||
copy(checked, bytes)
|
copy(checked, bytes)
|
||||||
copy(checked[len(bytes):], hashing.Checksum(bytes, checksumLen))
|
copy(checked[len(bytes):], hash.Checksum(bytes, checksumLen))
|
||||||
return base58.Encode(checked), nil
|
return base58.Encode(checked), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ func Decode(str string) ([]byte, error) {
|
|||||||
// Verify the checksum
|
// Verify the checksum
|
||||||
rawBytes := decodedBytes[:len(decodedBytes)-checksumLen]
|
rawBytes := decodedBytes[:len(decodedBytes)-checksumLen]
|
||||||
checksum := decodedBytes[len(decodedBytes)-checksumLen:]
|
checksum := decodedBytes[len(decodedBytes)-checksumLen:]
|
||||||
if !bytes.Equal(checksum, hashing.Checksum(rawBytes, checksumLen)) {
|
if !bytes.Equal(checksum, hash.Checksum(rawBytes, checksumLen)) {
|
||||||
return nil, ErrBadChecksum
|
return nil, ErrBadChecksum
|
||||||
}
|
}
|
||||||
return rawBytes, nil
|
return rawBytes, nil
|
||||||
|
|||||||
@@ -1,121 +0,0 @@
|
|||||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
|
||||||
// See the file LICENSE for licensing terms.
|
|
||||||
|
|
||||||
// Package blake3 provides Blake3 hash functions for cryptographic operations.
|
|
||||||
// This is extracted from the threshold package to provide a centralized
|
|
||||||
// implementation for all Lux projects.
|
|
||||||
package blake3
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/zeebo/blake3"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DigestLength is the standard output length for Blake3 hashes
|
|
||||||
const DigestLength = 64 // 512 bits
|
|
||||||
|
|
||||||
// Digest represents a Blake3 hash output
|
|
||||||
type Digest [DigestLength]byte
|
|
||||||
|
|
||||||
// Hasher wraps blake3.Hasher to provide a consistent interface
|
|
||||||
type Hasher struct {
|
|
||||||
h *blake3.Hasher
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new Blake3 hasher
|
|
||||||
func New() *Hasher {
|
|
||||||
return &Hasher{h: blake3.New()}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWithDomain creates a new Blake3 hasher with a domain separator
|
|
||||||
func NewWithDomain(domain string) *Hasher {
|
|
||||||
h := &Hasher{h: blake3.New()}
|
|
||||||
h.WriteString(domain)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write adds data to the hash
|
|
||||||
func (h *Hasher) Write(p []byte) (n int, err error) {
|
|
||||||
return h.h.Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteString adds a string to the hash
|
|
||||||
func (h *Hasher) WriteString(s string) (n int, err error) {
|
|
||||||
return h.h.WriteString(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteUint32 adds a uint32 to the hash in big-endian format
|
|
||||||
func (h *Hasher) WriteUint32(v uint32) {
|
|
||||||
var buf [4]byte
|
|
||||||
binary.BigEndian.PutUint32(buf[:], v)
|
|
||||||
h.h.Write(buf[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteUint64 adds a uint64 to the hash in big-endian format
|
|
||||||
func (h *Hasher) WriteUint64(v uint64) {
|
|
||||||
var buf [8]byte
|
|
||||||
binary.BigEndian.PutUint64(buf[:], v)
|
|
||||||
h.h.Write(buf[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteBigInt adds a big.Int to the hash
|
|
||||||
func (h *Hasher) WriteBigInt(n *big.Int) {
|
|
||||||
if n == nil {
|
|
||||||
h.WriteUint32(0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bytes := n.Bytes()
|
|
||||||
h.WriteUint32(uint32(len(bytes)))
|
|
||||||
h.h.Write(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum returns the hash digest
|
|
||||||
func (h *Hasher) Sum(b []byte) []byte {
|
|
||||||
return h.h.Sum(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Digest returns a fixed-size digest
|
|
||||||
func (h *Hasher) Digest() Digest {
|
|
||||||
var d Digest
|
|
||||||
h.h.Digest().Read(d[:])
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reader returns an io.Reader for extended output
|
|
||||||
func (h *Hasher) Reader() io.Reader {
|
|
||||||
return h.h.Digest()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clone creates a copy of the hasher
|
|
||||||
func (h *Hasher) Clone() *Hasher {
|
|
||||||
return &Hasher{h: h.h.Clone()}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset resets the hasher to its initial state
|
|
||||||
func (h *Hasher) Reset() {
|
|
||||||
h.h.Reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
// HashBytes hashes a byte slice and returns a digest
|
|
||||||
func HashBytes(data []byte) Digest {
|
|
||||||
h := New()
|
|
||||||
h.Write(data)
|
|
||||||
return h.Digest()
|
|
||||||
}
|
|
||||||
|
|
||||||
// HashString hashes a string and returns a digest
|
|
||||||
func HashString(s string) Digest {
|
|
||||||
h := New()
|
|
||||||
h.WriteString(s)
|
|
||||||
return h.Digest()
|
|
||||||
}
|
|
||||||
|
|
||||||
// HashWithDomain hashes data with a domain separator
|
|
||||||
func HashWithDomain(domain string, data []byte) Digest {
|
|
||||||
h := NewWithDomain(domain)
|
|
||||||
h.Write(data)
|
|
||||||
return h.Digest()
|
|
||||||
}
|
|
||||||
@@ -1,382 +0,0 @@
|
|||||||
package blake3
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
"math/big"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
|
||||||
h := New()
|
|
||||||
if h == nil {
|
|
||||||
t.Fatal("New() returned nil")
|
|
||||||
}
|
|
||||||
if h.h == nil {
|
|
||||||
t.Fatal("Internal hasher is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewWithDomain(t *testing.T) {
|
|
||||||
domain := "test-domain"
|
|
||||||
h1 := NewWithDomain(domain)
|
|
||||||
h2 := NewWithDomain(domain)
|
|
||||||
|
|
||||||
data := []byte("test data")
|
|
||||||
h1.Write(data)
|
|
||||||
h2.Write(data)
|
|
||||||
|
|
||||||
d1 := h1.Digest()
|
|
||||||
d2 := h2.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d1[:], d2[:]) {
|
|
||||||
t.Error("Same domain should produce same hash")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Different domain should produce different hash
|
|
||||||
h3 := NewWithDomain("different-domain")
|
|
||||||
h3.Write(data)
|
|
||||||
d3 := h3.Digest()
|
|
||||||
|
|
||||||
if bytes.Equal(d1[:], d3[:]) {
|
|
||||||
t.Error("Different domain should produce different hash")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHashBytes(t *testing.T) {
|
|
||||||
// Test with known test vectors
|
|
||||||
testCases := []struct {
|
|
||||||
input []byte
|
|
||||||
expected string // First 64 bytes of hash
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
[]byte(""),
|
|
||||||
"af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262e00f03e7b69af26b7faaf09fcd333050338ddfe085b8cc869ca98b206c08243a",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]byte("hello"),
|
|
||||||
"ea8f163db38682925e4491c5e58d4bb3506ef8c14eb78a86e908c5624a67200fe992405f0d785b599a2e3387f6d34d01faccfeb22fb697ef3fd53541241a338c",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
hash := HashBytes(tc.input)
|
|
||||||
hashStr := hex.EncodeToString(hash[:])
|
|
||||||
if hashStr != tc.expected {
|
|
||||||
t.Errorf("HashBytes(%q) = %s, want %s", tc.input, hashStr, tc.expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test consistency
|
|
||||||
data := []byte("test data")
|
|
||||||
h1 := HashBytes(data)
|
|
||||||
h2 := HashBytes(data)
|
|
||||||
|
|
||||||
if !bytes.Equal(h1[:], h2[:]) {
|
|
||||||
t.Error("Same input should produce same hash")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHashString(t *testing.T) {
|
|
||||||
// Test consistency
|
|
||||||
s := "test string"
|
|
||||||
h1 := HashString(s)
|
|
||||||
h2 := HashString(s)
|
|
||||||
|
|
||||||
if !bytes.Equal(h1[:], h2[:]) {
|
|
||||||
t.Error("Same string should produce same hash")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare with HashBytes
|
|
||||||
h3 := HashBytes([]byte(s))
|
|
||||||
if !bytes.Equal(h1[:], h3[:]) {
|
|
||||||
t.Error("HashString should match HashBytes for same content")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Different strings produce different hashes
|
|
||||||
h4 := HashString("different string")
|
|
||||||
if bytes.Equal(h1[:], h4[:]) {
|
|
||||||
t.Error("Different strings should produce different hashes")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHashWithDomain(t *testing.T) {
|
|
||||||
data := []byte("test data")
|
|
||||||
domain1 := "domain1"
|
|
||||||
domain2 := "domain2"
|
|
||||||
|
|
||||||
h1 := HashWithDomain(domain1, data)
|
|
||||||
h2 := HashWithDomain(domain1, data)
|
|
||||||
h3 := HashWithDomain(domain2, data)
|
|
||||||
|
|
||||||
// Same domain and data should produce same hash
|
|
||||||
if !bytes.Equal(h1[:], h2[:]) {
|
|
||||||
t.Error("Same domain and data should produce same hash")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Different domain should produce different hash
|
|
||||||
if bytes.Equal(h1[:], h3[:]) {
|
|
||||||
t.Error("Different domain should produce different hash")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should differ from hash without domain
|
|
||||||
h4 := HashBytes(data)
|
|
||||||
if bytes.Equal(h1[:], h4[:]) {
|
|
||||||
t.Error("Hash with domain should differ from hash without domain")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriteMethods(t *testing.T) {
|
|
||||||
h := New()
|
|
||||||
|
|
||||||
// Test Write
|
|
||||||
n, err := h.Write([]byte("test"))
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Write error: %v", err)
|
|
||||||
}
|
|
||||||
if n != 4 {
|
|
||||||
t.Errorf("Write returned %d, want 4", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test WriteString
|
|
||||||
n, err = h.WriteString("string")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("WriteString error: %v", err)
|
|
||||||
}
|
|
||||||
if n != 6 {
|
|
||||||
t.Errorf("WriteString returned %d, want 6", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test WriteUint32
|
|
||||||
h.WriteUint32(0x12345678)
|
|
||||||
|
|
||||||
// Test WriteUint64
|
|
||||||
h.WriteUint64(0x123456789ABCDEF0)
|
|
||||||
|
|
||||||
// Test WriteBigInt
|
|
||||||
bigNum := big.NewInt(1234567890)
|
|
||||||
h.WriteBigInt(bigNum)
|
|
||||||
|
|
||||||
// Test WriteBigInt with nil
|
|
||||||
h.WriteBigInt(nil)
|
|
||||||
|
|
||||||
// Get digest to ensure it doesn't panic
|
|
||||||
_ = h.Digest()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriteUint32(t *testing.T) {
|
|
||||||
h1 := New()
|
|
||||||
h1.WriteUint32(0x12345678)
|
|
||||||
d1 := h1.Digest()
|
|
||||||
|
|
||||||
// Should be same as writing the bytes in big-endian
|
|
||||||
h2 := New()
|
|
||||||
h2.Write([]byte{0x12, 0x34, 0x56, 0x78})
|
|
||||||
d2 := h2.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d1[:], d2[:]) {
|
|
||||||
t.Error("WriteUint32 should write in big-endian format")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriteUint64(t *testing.T) {
|
|
||||||
h1 := New()
|
|
||||||
h1.WriteUint64(0x123456789ABCDEF0)
|
|
||||||
d1 := h1.Digest()
|
|
||||||
|
|
||||||
// Should be same as writing the bytes in big-endian
|
|
||||||
h2 := New()
|
|
||||||
h2.Write([]byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0})
|
|
||||||
d2 := h2.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d1[:], d2[:]) {
|
|
||||||
t.Error("WriteUint64 should write in big-endian format")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriteBigInt(t *testing.T) {
|
|
||||||
// Test with normal big int
|
|
||||||
n := big.NewInt(1234567890)
|
|
||||||
h1 := New()
|
|
||||||
h1.WriteBigInt(n)
|
|
||||||
d1 := h1.Digest()
|
|
||||||
|
|
||||||
// Writing same number should produce same hash
|
|
||||||
h2 := New()
|
|
||||||
h2.WriteBigInt(n)
|
|
||||||
d2 := h2.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d1[:], d2[:]) {
|
|
||||||
t.Error("Same big.Int should produce same hash")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with nil
|
|
||||||
h3 := New()
|
|
||||||
h3.WriteBigInt(nil)
|
|
||||||
d3 := h3.Digest()
|
|
||||||
|
|
||||||
// Nil should write a zero length prefix
|
|
||||||
h4 := New()
|
|
||||||
h4.WriteUint32(0)
|
|
||||||
d4 := h4.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d3[:], d4[:]) {
|
|
||||||
t.Error("WriteBigInt(nil) should write zero length")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with zero
|
|
||||||
zero := big.NewInt(0)
|
|
||||||
h5 := New()
|
|
||||||
h5.WriteBigInt(zero)
|
|
||||||
_ = h5.Digest() // Should not panic
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSum(t *testing.T) {
|
|
||||||
h := New()
|
|
||||||
h.WriteString("test")
|
|
||||||
|
|
||||||
// Sum with nil
|
|
||||||
sum1 := h.Sum(nil)
|
|
||||||
if len(sum1) != 32 { // Default blake3 output
|
|
||||||
t.Errorf("Sum(nil) length = %d, want 32", len(sum1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum with existing slice
|
|
||||||
prefix := []byte("prefix")
|
|
||||||
sum2 := h.Sum(prefix)
|
|
||||||
if !bytes.HasPrefix(sum2, prefix) {
|
|
||||||
t.Error("Sum should append to provided slice")
|
|
||||||
}
|
|
||||||
if len(sum2) != len(prefix)+32 {
|
|
||||||
t.Errorf("Sum length = %d, want %d", len(sum2), len(prefix)+32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDigest(t *testing.T) {
|
|
||||||
h := New()
|
|
||||||
h.WriteString("test")
|
|
||||||
d := h.Digest()
|
|
||||||
|
|
||||||
if len(d) != DigestLength {
|
|
||||||
t.Errorf("Digest length = %d, want %d", len(d), DigestLength)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Digest should be consistent
|
|
||||||
h2 := New()
|
|
||||||
h2.WriteString("test")
|
|
||||||
d2 := h2.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d[:], d2[:]) {
|
|
||||||
t.Error("Same input should produce same digest")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReader(t *testing.T) {
|
|
||||||
h := New()
|
|
||||||
h.WriteString("test")
|
|
||||||
|
|
||||||
reader := h.Reader()
|
|
||||||
if reader == nil {
|
|
||||||
t.Fatal("Reader() returned nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read some bytes
|
|
||||||
buf := make([]byte, 100)
|
|
||||||
n, err := reader.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Reader.Read error: %v", err)
|
|
||||||
}
|
|
||||||
if n != 100 {
|
|
||||||
t.Errorf("Reader.Read returned %d, want 100", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClone(t *testing.T) {
|
|
||||||
h1 := New()
|
|
||||||
h1.WriteString("test")
|
|
||||||
|
|
||||||
h2 := h1.Clone()
|
|
||||||
if h2 == nil {
|
|
||||||
t.Fatal("Clone() returned nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Both should produce same digest at this point
|
|
||||||
d1 := h1.Digest()
|
|
||||||
d2 := h2.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d1[:], d2[:]) {
|
|
||||||
t.Error("Clone should produce same digest")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writing to one shouldn't affect the other
|
|
||||||
h1.WriteString("more")
|
|
||||||
d1New := h1.Digest()
|
|
||||||
d2New := h2.Digest()
|
|
||||||
|
|
||||||
if bytes.Equal(d1New[:], d2New[:]) {
|
|
||||||
t.Error("Writing to original should not affect clone")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReset(t *testing.T) {
|
|
||||||
h := New()
|
|
||||||
h.WriteString("test")
|
|
||||||
d1 := h.Digest()
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
h.WriteString("test")
|
|
||||||
d2 := h.Digest()
|
|
||||||
|
|
||||||
if !bytes.Equal(d1[:], d2[:]) {
|
|
||||||
t.Error("Reset should restore initial state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// After reset, different input should produce different hash
|
|
||||||
h.Reset()
|
|
||||||
h.WriteString("different")
|
|
||||||
d3 := h.Digest()
|
|
||||||
|
|
||||||
if bytes.Equal(d1[:], d3[:]) {
|
|
||||||
t.Error("After reset, different input should produce different hash")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDigestLength(t *testing.T) {
|
|
||||||
if DigestLength != 64 {
|
|
||||||
t.Errorf("DigestLength = %d, want 64", DigestLength)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkHashBytes(b *testing.B) {
|
|
||||||
data := make([]byte, 1024)
|
|
||||||
for i := range data {
|
|
||||||
data[i] = byte(i % 256)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = HashBytes(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkHashString(b *testing.B) {
|
|
||||||
data := strings.Repeat("benchmark", 128)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = HashString(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkWriteBigInt(b *testing.B) {
|
|
||||||
n := new(big.Int)
|
|
||||||
n.SetString("123456789012345678901234567890123456789012345678901234567890", 10)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
h := New()
|
|
||||||
h.WriteBigInt(n)
|
|
||||||
_ = h.Digest()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
|
|
||||||
// See the file LICENSE for licensing terms.
|
|
||||||
|
|
||||||
package hashing
|
|
||||||
|
|
||||||
// Hasher is an interface to compute a hash value.
|
|
||||||
type Hasher interface {
|
|
||||||
// Hash takes a string and computes its hash value.
|
|
||||||
// Values must be computed deterministically.
|
|
||||||
Hash([]byte) uint64
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
|
|
||||||
// See the file LICENSE for licensing terms.
|
|
||||||
|
|
||||||
// Package hashing is an alias for hash package for backwards compatibility.
|
|
||||||
// New code should use github.com/luxfi/crypto/hash directly.
|
|
||||||
package hashing
|
|
||||||
|
|
||||||
import "github.com/luxfi/crypto/hash"
|
|
||||||
|
|
||||||
const (
|
|
||||||
HashLen = hash.HashLen
|
|
||||||
AddrLen = hash.AddrLen
|
|
||||||
)
|
|
||||||
|
|
||||||
// Type aliases
|
|
||||||
type Hash256 = hash.Hash256
|
|
||||||
type Hash160 = hash.Hash160
|
|
||||||
|
|
||||||
// Error aliases
|
|
||||||
var ErrInvalidHashLen = hash.ErrInvalidHashLen
|
|
||||||
|
|
||||||
// Function aliases - SHA256 (256-bit)
|
|
||||||
var ComputeHash256Array = hash.ComputeHash256Array
|
|
||||||
var ComputeHash256 = hash.ComputeHash256
|
|
||||||
var ToHash256 = hash.ToHash256
|
|
||||||
|
|
||||||
// Function aliases - RIPEMD160 (160-bit)
|
|
||||||
var ComputeHash160Array = hash.ComputeHash160Array
|
|
||||||
var ComputeHash160 = hash.ComputeHash160
|
|
||||||
var ToHash160 = hash.ToHash160
|
|
||||||
|
|
||||||
// Utility functions
|
|
||||||
var Checksum = hash.Checksum
|
|
||||||
var PubkeyBytesToAddress = hash.PubkeyBytesToAddress
|
|
||||||
@@ -1,299 +0,0 @@
|
|||||||
package hashing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestComputeHash256(t *testing.T) {
|
|
||||||
// Test with known vectors
|
|
||||||
testCases := []struct {
|
|
||||||
name string
|
|
||||||
input []byte
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"empty",
|
|
||||||
[]byte(""),
|
|
||||||
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"abc",
|
|
||||||
[]byte("abc"),
|
|
||||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fox",
|
|
||||||
[]byte("The quick brown fox jumps over the lazy dog"),
|
|
||||||
"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
// Test ComputeHash256
|
|
||||||
hash := ComputeHash256(tc.input)
|
|
||||||
hashStr := hex.EncodeToString(hash)
|
|
||||||
if hashStr != tc.expected {
|
|
||||||
t.Errorf("ComputeHash256(%q) = %s, want %s", tc.input, hashStr, tc.expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test ComputeHash256Array
|
|
||||||
hashArray := ComputeHash256Array(tc.input)
|
|
||||||
hashArrayStr := hex.EncodeToString(hashArray[:])
|
|
||||||
if hashArrayStr != tc.expected {
|
|
||||||
t.Errorf("ComputeHash256Array(%q) = %s, want %s", tc.input, hashArrayStr, tc.expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify slice and array produce same result
|
|
||||||
if !bytes.Equal(hash, hashArray[:]) {
|
|
||||||
t.Error("ComputeHash256 and ComputeHash256Array should produce same result")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestComputeHash160(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
name string
|
|
||||||
input []byte
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"empty",
|
|
||||||
[]byte(""),
|
|
||||||
"9c1185a5c5e9fc54612808977ee8f548b2258d31",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"abc",
|
|
||||||
[]byte("abc"),
|
|
||||||
"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"message digest",
|
|
||||||
[]byte("message digest"),
|
|
||||||
"5d0689ef49d2fae572b881b123a85ffa21595f36",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
// Test ComputeHash160
|
|
||||||
hash := ComputeHash160(tc.input)
|
|
||||||
hashStr := hex.EncodeToString(hash)
|
|
||||||
if hashStr != tc.expected {
|
|
||||||
t.Errorf("ComputeHash160(%q) = %s, want %s", tc.input, hashStr, tc.expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test ComputeHash160Array
|
|
||||||
hashArray := ComputeHash160Array(tc.input)
|
|
||||||
hashArrayStr := hex.EncodeToString(hashArray[:])
|
|
||||||
if hashArrayStr != tc.expected {
|
|
||||||
t.Errorf("ComputeHash160Array(%q) = %s, want %s", tc.input, hashArrayStr, tc.expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify slice and array produce same result
|
|
||||||
if !bytes.Equal(hash, hashArray[:]) {
|
|
||||||
t.Error("ComputeHash160 and ComputeHash160Array should produce same result")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksum(t *testing.T) {
|
|
||||||
input := []byte("test input for checksum")
|
|
||||||
|
|
||||||
// Test various checksum lengths
|
|
||||||
lengths := []int{1, 4, 8, 16, 32}
|
|
||||||
|
|
||||||
for _, length := range lengths {
|
|
||||||
checksum := Checksum(input, length)
|
|
||||||
if len(checksum) != length {
|
|
||||||
t.Errorf("Checksum length should be %d, got %d", length, len(checksum))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify checksum is last 'length' bytes of hash
|
|
||||||
fullHash := ComputeHash256Array(input)
|
|
||||||
expected := fullHash[len(fullHash)-length:]
|
|
||||||
if !bytes.Equal(checksum, expected) {
|
|
||||||
t.Errorf("Checksum should be last %d bytes of hash", length)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that same input produces same checksum
|
|
||||||
checksum1 := Checksum(input, 4)
|
|
||||||
checksum2 := Checksum(input, 4)
|
|
||||||
if !bytes.Equal(checksum1, checksum2) {
|
|
||||||
t.Error("Same input should produce same checksum")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that different input produces different checksum
|
|
||||||
input2 := []byte("different input")
|
|
||||||
checksum3 := Checksum(input2, 4)
|
|
||||||
if bytes.Equal(checksum1, checksum3) {
|
|
||||||
t.Error("Different input should produce different checksum")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToHash256(t *testing.T) {
|
|
||||||
// Test valid conversion
|
|
||||||
validBytes := make([]byte, HashLen)
|
|
||||||
for i := range validBytes {
|
|
||||||
validBytes[i] = byte(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
hash, err := ToHash256(validBytes)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("ToHash256 with valid bytes should not error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(hash[:], validBytes) {
|
|
||||||
t.Error("ToHash256 should copy bytes correctly")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test invalid lengths
|
|
||||||
invalidLengths := []int{0, 1, 31, 33, 100}
|
|
||||||
for _, length := range invalidLengths {
|
|
||||||
invalidBytes := make([]byte, length)
|
|
||||||
_, err := ToHash256(invalidBytes)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("ToHash256 should error with %d bytes", length)
|
|
||||||
}
|
|
||||||
if err != nil && err.Error() != ErrInvalidHashLen.Error() && !bytes.Contains([]byte(err.Error()), []byte("invalid hash length")) {
|
|
||||||
t.Errorf("Expected ErrInvalidHashLen, got: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToHash160(t *testing.T) {
|
|
||||||
// Test valid conversion
|
|
||||||
validBytes := make([]byte, AddrLen)
|
|
||||||
for i := range validBytes {
|
|
||||||
validBytes[i] = byte(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
hash, err := ToHash160(validBytes)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("ToHash160 with valid bytes should not error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(hash[:], validBytes) {
|
|
||||||
t.Error("ToHash160 should copy bytes correctly")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test invalid lengths
|
|
||||||
invalidLengths := []int{0, 1, 19, 21, 100}
|
|
||||||
for _, length := range invalidLengths {
|
|
||||||
invalidBytes := make([]byte, length)
|
|
||||||
_, err := ToHash160(invalidBytes)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("ToHash160 should error with %d bytes", length)
|
|
||||||
}
|
|
||||||
if err != nil && err.Error() != ErrInvalidHashLen.Error() && !bytes.Contains([]byte(err.Error()), []byte("invalid hash length")) {
|
|
||||||
t.Errorf("Expected ErrInvalidHashLen, got: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPubkeyBytesToAddress(t *testing.T) {
|
|
||||||
// Test that address generation is consistent
|
|
||||||
pubkey := []byte("test public key")
|
|
||||||
|
|
||||||
addr1 := PubkeyBytesToAddress(pubkey)
|
|
||||||
addr2 := PubkeyBytesToAddress(pubkey)
|
|
||||||
|
|
||||||
if !bytes.Equal(addr1, addr2) {
|
|
||||||
t.Error("Same pubkey should produce same address")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that different pubkeys produce different addresses
|
|
||||||
pubkey2 := []byte("different public key")
|
|
||||||
addr3 := PubkeyBytesToAddress(pubkey2)
|
|
||||||
|
|
||||||
if bytes.Equal(addr1, addr3) {
|
|
||||||
t.Error("Different pubkeys should produce different addresses")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that address is 20 bytes (ripemd160 size)
|
|
||||||
if len(addr1) != AddrLen {
|
|
||||||
t.Errorf("Address should be %d bytes, got %d", AddrLen, len(addr1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test empty pubkey
|
|
||||||
emptyAddr := PubkeyBytesToAddress([]byte{})
|
|
||||||
if len(emptyAddr) != AddrLen {
|
|
||||||
t.Errorf("Empty pubkey should still produce %d byte address", AddrLen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHashConstants(t *testing.T) {
|
|
||||||
// Verify constants match expected values
|
|
||||||
if HashLen != 32 {
|
|
||||||
t.Errorf("HashLen should be 32, got %d", HashLen)
|
|
||||||
}
|
|
||||||
|
|
||||||
if AddrLen != 20 {
|
|
||||||
t.Errorf("AddrLen should be 20, got %d", AddrLen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkComputeHash256(b *testing.B) {
|
|
||||||
input := make([]byte, 1024)
|
|
||||||
for i := range input {
|
|
||||||
input[i] = byte(i % 256)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = ComputeHash256(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkComputeHash256Array(b *testing.B) {
|
|
||||||
input := make([]byte, 1024)
|
|
||||||
for i := range input {
|
|
||||||
input[i] = byte(i % 256)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = ComputeHash256Array(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkComputeHash160(b *testing.B) {
|
|
||||||
input := make([]byte, 1024)
|
|
||||||
for i := range input {
|
|
||||||
input[i] = byte(i % 256)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = ComputeHash160(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkPubkeyBytesToAddress(b *testing.B) {
|
|
||||||
pubkey := make([]byte, 65) // Typical pubkey size
|
|
||||||
for i := range pubkey {
|
|
||||||
pubkey[i] = byte(i % 256)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = PubkeyBytesToAddress(pubkey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChecksum(b *testing.B) {
|
|
||||||
input := make([]byte, 1024)
|
|
||||||
for i := range input {
|
|
||||||
input[i] = byte(i % 256)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = Checksum(input, 4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-5
@@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/luxfi/cache/lru"
|
"github.com/luxfi/cache/lru"
|
||||||
"github.com/luxfi/crypto/cb58"
|
"github.com/luxfi/crypto/cb58"
|
||||||
"github.com/luxfi/crypto/hashing"
|
"github.com/luxfi/crypto/hash"
|
||||||
"github.com/luxfi/ids"
|
"github.com/luxfi/ids"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ func init() {
|
|||||||
|
|
||||||
// PubkeyBytesToAddress converts public key bytes to an address using SHA256 + RIPEMD160
|
// PubkeyBytesToAddress converts public key bytes to an address using SHA256 + RIPEMD160
|
||||||
func PubkeyBytesToAddress(pubkey []byte) []byte {
|
func PubkeyBytesToAddress(pubkey []byte) []byte {
|
||||||
return hashing.PubkeyBytesToAddress(pubkey)
|
return hash.PubkeyBytesToAddress(pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecoverCache is a cache for recovered public keys
|
// RecoverCache is a cache for recovered public keys
|
||||||
@@ -144,7 +144,7 @@ func (k *PrivateKey) Sign(msg []byte) ([]byte, error) {
|
|||||||
|
|
||||||
// SignArray signs a message and returns a fixed-size array
|
// SignArray signs a message and returns a fixed-size array
|
||||||
func (k *PrivateKey) SignArray(msg []byte) ([SignatureLen]byte, error) {
|
func (k *PrivateKey) SignArray(msg []byte) ([SignatureLen]byte, error) {
|
||||||
return k.SignHashArray(hashing.ComputeHash256(msg))
|
return k.SignHashArray(hash.ComputeHash256(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignHash signs a hash with the private key
|
// SignHash signs a hash with the private key
|
||||||
@@ -246,12 +246,12 @@ func (k *PublicKey) VerifyHash(hash, sig []byte) bool {
|
|||||||
|
|
||||||
// Verify verifies a signature against a message
|
// Verify verifies a signature against a message
|
||||||
func (k *PublicKey) Verify(msg, sig []byte) bool {
|
func (k *PublicKey) Verify(msg, sig []byte) bool {
|
||||||
return k.VerifyHash(hashing.ComputeHash256(msg), sig)
|
return k.VerifyHash(hash.ComputeHash256(msg), sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecoverPublicKey recovers the public key from a message and signature
|
// RecoverPublicKey recovers the public key from a message and signature
|
||||||
func RecoverPublicKey(msg, sig []byte) (*PublicKey, error) {
|
func RecoverPublicKey(msg, sig []byte) (*PublicKey, error) {
|
||||||
return RecoverPublicKeyFromHash(hashing.ComputeHash256(msg), sig)
|
return RecoverPublicKeyFromHash(hash.ComputeHash256(msg), sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecoverPublicKeyFromHash recovers the public key from a hash and signature
|
// RecoverPublicKeyFromHash recovers the public key from a hash and signature
|
||||||
|
|||||||
+10
-10
@@ -9,7 +9,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/luxfi/crypto/hashing"
|
"github.com/luxfi/crypto/hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FuzzSignatureVerification tests signature verification with random inputs
|
// FuzzSignatureVerification tests signature verification with random inputs
|
||||||
@@ -21,7 +21,7 @@ func FuzzSignatureVerification(f *testing.F) {
|
|||||||
// Add a valid signature
|
// Add a valid signature
|
||||||
privKey := make([]byte, 32)
|
privKey := make([]byte, 32)
|
||||||
privKey[31] = 1 // Simple valid private key
|
privKey[31] = 1 // Simple valid private key
|
||||||
msg := hashing.ComputeHash256([]byte("test message"))
|
msg := hash.ComputeHash256([]byte("test message"))
|
||||||
if sig, err := Sign(msg, privKey); err == nil {
|
if sig, err := Sign(msg, privKey); err == nil {
|
||||||
f.Add(msg, sig)
|
f.Add(msg, sig)
|
||||||
}
|
}
|
||||||
@@ -31,10 +31,10 @@ func FuzzSignatureVerification(f *testing.F) {
|
|||||||
copy(validSig[:32], bytes.Repeat([]byte{0xaa}, 32))
|
copy(validSig[:32], bytes.Repeat([]byte{0xaa}, 32))
|
||||||
copy(validSig[32:64], bytes.Repeat([]byte{0xbb}, 32))
|
copy(validSig[32:64], bytes.Repeat([]byte{0xbb}, 32))
|
||||||
validSig[64] = 0
|
validSig[64] = 0
|
||||||
f.Add(hashing.ComputeHash256([]byte("test")), validSig)
|
f.Add(hash.ComputeHash256([]byte("test")), validSig)
|
||||||
|
|
||||||
validSig[64] = 1
|
validSig[64] = 1
|
||||||
f.Add(hashing.ComputeHash256([]byte("test2")), validSig)
|
f.Add(hash.ComputeHash256([]byte("test2")), validSig)
|
||||||
|
|
||||||
f.Fuzz(func(t *testing.T, msg []byte, sig []byte) {
|
f.Fuzz(func(t *testing.T, msg []byte, sig []byte) {
|
||||||
// Ensure msg is 32 bytes (hash size)
|
// Ensure msg is 32 bytes (hash size)
|
||||||
@@ -86,16 +86,16 @@ func FuzzSignatureVerification(f *testing.F) {
|
|||||||
func FuzzSignatureCreation(f *testing.F) {
|
func FuzzSignatureCreation(f *testing.F) {
|
||||||
// Seed corpus
|
// Seed corpus
|
||||||
f.Add(bytes.Repeat([]byte{0x01}, 32), bytes.Repeat([]byte{0x02}, 32))
|
f.Add(bytes.Repeat([]byte{0x01}, 32), bytes.Repeat([]byte{0x02}, 32))
|
||||||
f.Add(bytes.Repeat([]byte{0xff}, 32), hashing.ComputeHash256([]byte("test")))
|
f.Add(bytes.Repeat([]byte{0xff}, 32), hash.ComputeHash256([]byte("test")))
|
||||||
|
|
||||||
// Add some valid private keys
|
// Add some valid private keys
|
||||||
validKey1 := make([]byte, 32)
|
validKey1 := make([]byte, 32)
|
||||||
validKey1[31] = 1
|
validKey1[31] = 1
|
||||||
f.Add(validKey1, hashing.ComputeHash256([]byte("message1")))
|
f.Add(validKey1, hash.ComputeHash256([]byte("message1")))
|
||||||
|
|
||||||
validKey2 := make([]byte, 32)
|
validKey2 := make([]byte, 32)
|
||||||
copy(validKey2, []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef})
|
copy(validKey2, []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef})
|
||||||
f.Add(validKey2, hashing.ComputeHash256([]byte("message2")))
|
f.Add(validKey2, hash.ComputeHash256([]byte("message2")))
|
||||||
|
|
||||||
f.Fuzz(func(t *testing.T, privKey []byte, msg []byte) {
|
f.Fuzz(func(t *testing.T, privKey []byte, msg []byte) {
|
||||||
// Ensure proper sizes
|
// Ensure proper sizes
|
||||||
@@ -158,7 +158,7 @@ func FuzzPublicKeyCompression(f *testing.F) {
|
|||||||
// Generate a valid public key
|
// Generate a valid public key
|
||||||
privKey := make([]byte, 32)
|
privKey := make([]byte, 32)
|
||||||
privKey[31] = 42
|
privKey[31] = 42
|
||||||
msg := hashing.ComputeHash256([]byte("test"))
|
msg := hash.ComputeHash256([]byte("test"))
|
||||||
if sig, err := Sign(msg, privKey); err == nil {
|
if sig, err := Sign(msg, privKey); err == nil {
|
||||||
if pubKey, err := RecoverPubkey(msg, sig); err == nil {
|
if pubKey, err := RecoverPubkey(msg, sig); err == nil {
|
||||||
f.Add(pubKey)
|
f.Add(pubKey)
|
||||||
@@ -267,7 +267,7 @@ func FuzzSignatureMalleability(f *testing.F) {
|
|||||||
sig[64] = v & 1 // Ensure v is 0 or 1
|
sig[64] = v & 1 // Ensure v is 0 or 1
|
||||||
|
|
||||||
// Create a random message
|
// Create a random message
|
||||||
msg := hashing.ComputeHash256(append(r, s...))
|
msg := hash.ComputeHash256(append(r, s...))
|
||||||
|
|
||||||
// Try to verify - should not panic
|
// Try to verify - should not panic
|
||||||
pubKey, err := RecoverPubkey(msg, sig)
|
pubKey, err := RecoverPubkey(msg, sig)
|
||||||
@@ -304,7 +304,7 @@ func FuzzECDSAEdgeCases(f *testing.F) {
|
|||||||
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
|
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
|
||||||
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
|
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
|
||||||
})
|
})
|
||||||
f.Add(nearOrder, hashing.ComputeHash256([]byte("edge")))
|
f.Add(nearOrder, hash.ComputeHash256([]byte("edge")))
|
||||||
|
|
||||||
f.Fuzz(func(t *testing.T, privKey []byte, msg []byte) {
|
f.Fuzz(func(t *testing.T, privKey []byte, msg []byte) {
|
||||||
// Handle nil and empty cases
|
// Handle nil and empty cases
|
||||||
|
|||||||
Reference in New Issue
Block a user