Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add more compact encoding #72

Closed
wants to merge 2 commits into from

Conversation

funny-falcon
Copy link

Current encoding does Base64 twice against payload because of intermediate
text encoding. And it produces too large mac (256bit) while 128bit is more
than enough.

Add "compact" mode which uses binary encoding for message with single
Base64 pass and 128bit hmac output (at max).

    TestSecureCookie: securecookie_test.go:48: i 0 len 184                                                         
    TestSecureCookie: securecookie_test.go:48: i 1 len 128                                                         
    TestSecureCookie: securecookie_test.go:48: i 2 len 188                                                         
    TestSecureCookie: securecookie_test.go:48: i 3 len 128                                                         
    TestSecureCookie: securecookie_test.go:48: i 4 len 188                                                         
    TestSecureCookie: securecookie_test.go:48: i 5 len 128                                                         
    TestSecureCookie: securecookie_test.go:48: i 6 len 188                                                         
    TestSecureCookie: securecookie_test.go:48: i 7 len 128                                                         
    TestSecureCookie: securecookie_test.go:48: i 8 len 188                                                         
    TestSecureCookie: securecookie_test.go:48: i 9 len 128                                                         

Current encoding does Base64 twice against payload because of intermediate
text encoding. And it produces too large mac (256bit) while 128bit is more
than enough.

Add "compact" mode which uses binary encoding for message with single
Base64 pass and 128bit hmac output (at max).
@elithrar
Copy link
Contributor

elithrar commented Jun 29, 2020 via email

@funny-falcon
Copy link
Author

@elithrar that is why current encoding is preserved and remains to be default.
To migrane smoothly one will have to create couple of SecureCookie, enable Compact(true) on one and use `DecodeMulti

@funny-falcon
Copy link
Author

Probably it will be better to move timestamp backward: currently compact encoded cookie always starts with AAAAA .
Other option could be to use binary.PutVarint.

@funny-falcon
Copy link
Author

Yeah, changed it to varint, and it doesn't even look weird.

@funny-falcon
Copy link
Author

So, will there be consensus about this feature? Close it or merge it?

@funny-falcon
Copy link
Author

Hmm, looks like there is a way to be backward compatible: if I place 0 byte first (before base64 encoding), then there is clear way to distinguish between compact encoding and text based encoding.

I also made such trick to avoid nonce in private repository:
I used mac as nonce for encryption.

mac = Blake2b(14, nil).Sum(version||(namelen,keylen)||name||hashkey||timeMilliSec||message)) // mac is 14 bytes 
cipherText = (timeMilliSec||message) ^ ChaCha20(combine(blockKey,mac[12:14]), mac[:12])
cookie = version||mac||cipherText

where

version - zero byte
timeMilliSec - LittleEndian.PutUint64(time.Now().UnixNano() >> 20) . It plays role of semi-nonce as mac is used for encryption.
(namelen,keylen) - two bytes. I limit name len with 127 bytes to be able in future use varint encoding.
mac is 14 bytes cause I think 112 bits is just enough. Since version bytes goes first, it will be possible to increase it in a future.
hashkey is prepared as Blake2b256(userHashKey)
blockKey is prepared as Blake2b256(userBlockKey, hashKey) (therefore is it 32 bytes, as it is needed for ChaCha20)
combine(blockKey, mac[12:14]) - xors last two blockKey bytes with last two bytes of mac, therefore whole 112bit of mac is used for encryption.

I'd like to change this PR this way if you don't mind.

@funny-falcon
Copy link
Author

funny-falcon commented Jul 8, 2020

comparison of such scheme with current secure cookie using NopEncoder on messages 0-250bytes long:

BenchmarkCompactEncode    914350              1310 ns/op             717 B/op          4 allocs/op
BenchmarkCompactEncode    932637              1315 ns/op             717 B/op          4 allocs/op
BenchmarkSecureEncode     244792              4889 ns/op            3443 B/op         21 allocs/op
BenchmarkSecureEncode     223064              4840 ns/op            3443 B/op         21 allocs/op
BenchmarkCompactDecode    920700              1322 ns/op             494 B/op          4 allocs/op
BenchmarkCompactDecode    920559              1324 ns/op             494 B/op          4 allocs/op
BenchmarkSecureDecode     289554              4057 ns/op            2391 B/op         17 allocs/op
BenchmarkSecureDecode     290959              4062 ns/op            2391 B/op         17 allocs/op

@funny-falcon
Copy link
Author

close in favor of #73

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants