You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Feb 2, 2022. It is now read-only.
Fix for panic in ff1 that occurred when encrypting certain numeric strings (which ones depend on the given tweak). It may also have been an issue for other types of strings, but that has not been checked.
The fix has been verified for all 9-digit numbers (000000001-999999999).
@hakonra The Travis CI builds aren't getting triggered but I ran go test github.com/Videxio/fpe/ff1 and all unit test cases are failing, which does make sense given the change introduced here.
Can you please provide some combinations of inputs/tweaks that reproduce this issue?
You can try to run the program below (it is what I wrote to verify).
It should panic very quickly without the fix, and with the fix I managed to run the entire test without errors. It also verifies that all expected numbers are indeed generated.
package main
import (
"github.com/capitalone/fpe/ff1"
"fmt"
"strconv"
"sync"
"time"
)
const (
MIN = 1
MAX = 999999999
)
func main() {
key := []byte{0x4, 0x8, 0x15, 0x16, 0x23, 0x42, 0x4, 0x8, 0x15, 0x16, 0x23, 0x42, 0x4, 0x8, 0x15, 0x16, 0x23, 0x42, 0x4, 0x8, 0x15, 0x16, 0x23, 0x42}
tweak := []byte{0x42}
bitmapMutex := sync.Mutex{}
bitmapLen := (MAX + 1) / 8
if (MAX+1)%8 > 0 {
bitmapLen++
}
fmt.Printf("[%s] Allocating bitmap of size %d bytes...\n", time.Now().String(), bitmapLen)
bitmap := make([]byte, bitmapLen)
workers := []uint32{250000000, 500000000, 750000000, MAX}
wg := sync.WaitGroup{}
wg.Add(len(workers))
fmt.Printf("[%s] Starting %d workers...\n", time.Now().String(), len(workers))
for gr := 0; gr < len(workers); gr++ {
min := uint32(MIN)
if gr > 0 {
min = workers[gr-1] + 1
}
max := workers[gr]
go func(gr int) {
cipher, err := ff1.NewCipher(10, 8, key, tweak)
if err != nil {
fmt.Printf("[CRITICAL] ff1.NewCipher(): %s\n", err.Error())
return
}
var i uint32
percent := 0
perCalc := float64(max-min+1) / 100.0
for i = min; i <= max; i++ {
if int(float64(i-min)/perCalc) > percent {
percent++
fmt.Printf("[%s -- worker %d] %d%%\n", time.Now().String(), gr, percent)
}
ciphertext, err := cipher.Encrypt(fmt.Sprintf("%09d", i))
if err != nil {
fmt.Println(err.Error())
} else {
c, err := strconv.Atoi(ciphertext)
if err != nil {
fmt.Printf("strconv.Atoi(): %s\n", err.Error())
continue
}
bitmapMutex.Lock()
if get(bitmap, c) {
bitmapMutex.Unlock()
fmt.Printf("[%s -- worker %d] Two equal: %d -> %s == ? -> %s\n", time.Now().String(), gr, i, ciphertext, ciphertext)
} else {
set(bitmap, c)
bitmapMutex.Unlock()
}
}
}
wg.Done()
fmt.Printf("[%s -- worker %d] Finished!\n", time.Now().String(), gr)
}(gr)
}
wg.Wait()
fmt.Printf("\n[%s] main verifying...\n", time.Now().String())
matches := 0
for i := 0; i <= MAX; i++ {
if get(bitmap, int(i)) {
matches++
}
}
total := int(MAX - MIN + 1)
if matches == total {
fmt.Printf("GREAT SUCCESS!\n\n")
} else {
fmt.Printf("Generated %d numbers of %d total :(\n\n", matches, total)
}
}
func get(bitmap []byte, key int) bool {
return (bitmap[key/8]&getMask(key%8) > 0)
}
func set(bitmap []byte, key int) {
bitmap[key/8] |= getMask(key % 8)
}
func getMask(mod int) byte {
switch mod {
case 0:
return 0x01 // 00000001
case 1:
return 0x02 // 00000010
case 2:
return 0x04 // 00000100
case 3:
return 0x08 // 00001000
case 4:
return 0x10 // 00010000
case 5:
return 0x20 // 00100000
case 6:
return 0x40 // 01000000
case 7:
return 0x80 // 10000000
default:
panic(fmt.Sprintf("shit: %d", mod))
}
}
After some investigation, it turns out this is actually an issue with plaintext strings that have enough trailing zeros, such that numB.Bytes() just returns an empty slice.
Will push a fix that doesn't break existing test vectors / unit tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
None yet
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's in this PR?
Fix for panic in ff1 that occurred when encrypting certain numeric strings (which ones depend on the given tweak). It may also have been an issue for other types of strings, but that has not been checked.
The fix has been verified for all 9-digit numbers (000000001-999999999).
Housekeeping Items
I agree.
I agree.