Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ jobs:
strategy:
matrix:
go:
- "1.13"
- "1.14"
- "1.15"
- "1.16"
- "1.17"
- "1.19"
- "1.20"
- "1.21"
- "1.22"
- "1.23"
steps:
- uses: actions/checkout@v2

Expand Down
40 changes: 40 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,32 @@ type SafeFloat = i.SafeFloat
// SafeRune aliases rune. See the explanation for SafeString.
type SafeRune = i.SafeRune

// HashValue is a marker interface to be implemented by types whose
// values should be hashed when redacted, instead of being replaced
// with the redaction marker.
type HashValue = i.HashValue

// HashString represents a string that should be hashed when redacted.
type HashString = i.HashString

// HashInt represents an integer that should be hashed when redacted.
type HashInt = i.HashInt

// HashUint represents an unsigned integer that should be hashed when redacted.
type HashUint = i.HashUint

// HashFloat represents a floating-point value that should be hashed when redacted.
type HashFloat = i.HashFloat

// HashRune represents a rune that should be hashed when redacted.
type HashRune = i.HashRune

// HashByte represents a byte that should be hashed when redacted.
type HashByte = i.HashByte

// HashBytes represents a byte slice that should be hashed when redacted.
type HashBytes = i.HashBytes

// RedactableString is a string that contains a mix of safe and unsafe
// bits of data, but where it is known that unsafe bits are enclosed
// by redaction markers ‹ and ›, and occurrences of the markers
Expand Down Expand Up @@ -173,3 +199,17 @@ type StringBuilder = builder.StringBuilder
func RegisterSafeType(t reflect.Type) {
ifmt.RegisterSafeType(t)
}

// EnableHashing enables hash-based redaction with an optional salt.
// Hash markers (‹†value›) will be replaced with hashes instead of being fully redacted.
// When salt is nil, hash markers use plain SHA-256.
// When salt is provided, hash markers use HMAC-SHA256 for better security.
func EnableHashing(salt []byte) {
m.EnableHashing(salt)
}

// DisableHashing disables hash-based redaction.
// Hash markers will be fully redacted instead of being replaced with hashes.
func DisableHashing() {
m.DisableHashing()
}
34 changes: 34 additions & 0 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,37 @@ func BenchmarkRedact(b *testing.B) {
_ = Sprintf("hello %v %v %v", 123, x, Safe("world"), Unsafe("universe"))
}
}

// BenchmarkRedactCall_PlainMarkers calls .Redact() on a string with only
// regular ‹...› markers (no hash markers). This is the baseline.
func BenchmarkRedactCall_RegularRedaction(b *testing.B) {
s := Sprintf("user=%s action=%s", "alice", Safe("login"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = s.Redact()
}
}

// BenchmarkRedactCall_HashMarkers calls .Redact() on a string with ‹†...›
// hash markers and hashing enabled. This exercises the SHA-256 path.
func BenchmarkRedactCall_HashEnabled(b *testing.B) {
EnableHashing(nil)
defer DisableHashing()
s := Sprintf("user=%s action=%s", HashString("alice"), SafeString("login"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = s.Redact()
}
}

// BenchmarkRedactCall_SingleHashWithSalt — 1 ‹†alice› marker, HMAC-SHA256.
func BenchmarkRedactCall_HashWithSalt(b *testing.B) {
EnableHashing([]byte("my-secret-salt"))
defer DisableHashing()
s := Sprintf("user=%s action=%s", HashString("alice"), Safe("login"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = s.Redact()
}
}

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/cockroachdb/redact

go 1.14
go 1.19
Loading