mirror of
https://github.com/rls-moe/nyx
synced 2024-11-14 22:12:24 +00:00
55 lines
1017 B
Go
55 lines
1017 B
Go
|
package nosurf
|
||
|
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
"io"
|
||
|
)
|
||
|
|
||
|
// Masks/unmasks the given data *in place*
|
||
|
// with the given key
|
||
|
// Slices must be of the same length, or oneTimePad will panic
|
||
|
func oneTimePad(data, key []byte) {
|
||
|
n := len(data)
|
||
|
if n != len(key) {
|
||
|
panic("Lengths of slices are not equal")
|
||
|
}
|
||
|
|
||
|
for i := 0; i < n; i++ {
|
||
|
data[i] ^= key[i]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func maskToken(data []byte) []byte {
|
||
|
if len(data) != tokenLength {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// tokenLength*2 == len(enckey + token)
|
||
|
result := make([]byte, 2*tokenLength)
|
||
|
// the first half of the result is the OTP
|
||
|
// the second half is the masked token itself
|
||
|
key := result[:tokenLength]
|
||
|
token := result[tokenLength:]
|
||
|
copy(token, data)
|
||
|
|
||
|
// generate the random token
|
||
|
if _, err := io.ReadFull(rand.Reader, key); err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
oneTimePad(token, key)
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func unmaskToken(data []byte) []byte {
|
||
|
if len(data) != tokenLength*2 {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
key := data[:tokenLength]
|
||
|
token := data[tokenLength:]
|
||
|
oneTimePad(token, key)
|
||
|
|
||
|
return token
|
||
|
}
|