mirror of https://github.com/ginuerzh/gost
6 changed files with 211 additions and 10 deletions
@ -0,0 +1,115 @@ |
|||||
|
package gost |
||||
|
|
||||
|
const delta = 0x9E3779B9 |
||||
|
|
||||
|
func toBytes(v []uint32, includeLength bool) []byte { |
||||
|
length := uint32(len(v)) |
||||
|
n := length << 2 |
||||
|
if includeLength { |
||||
|
m := v[length-1] |
||||
|
n -= 4 |
||||
|
if (m < n-3) || (m > n) { |
||||
|
return nil |
||||
|
} |
||||
|
n = m |
||||
|
} |
||||
|
bytes := make([]byte, n) |
||||
|
for i := uint32(0); i < n; i++ { |
||||
|
bytes[i] = byte(v[i>>2] >> ((i & 3) << 3)) |
||||
|
} |
||||
|
return bytes |
||||
|
} |
||||
|
|
||||
|
func toUint32s(bytes []byte, includeLength bool) (v []uint32) { |
||||
|
length := uint32(len(bytes)) |
||||
|
n := length >> 2 |
||||
|
if length&3 != 0 { |
||||
|
n++ |
||||
|
} |
||||
|
if includeLength { |
||||
|
v = make([]uint32, n+1) |
||||
|
v[n] = length |
||||
|
} else { |
||||
|
v = make([]uint32, n) |
||||
|
} |
||||
|
for i := uint32(0); i < length; i++ { |
||||
|
v[i>>2] |= uint32(bytes[i]) << ((i & 3) << 3) |
||||
|
} |
||||
|
return v |
||||
|
} |
||||
|
|
||||
|
func mx(sum uint32, y uint32, z uint32, p uint32, e uint32, k []uint32) uint32 { |
||||
|
return ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum ^ y) + (k[p&3^e] ^ z)) |
||||
|
} |
||||
|
|
||||
|
func fixk(k []uint32) []uint32 { |
||||
|
if len(k) < 4 { |
||||
|
key := make([]uint32, 4) |
||||
|
copy(key, k) |
||||
|
return key |
||||
|
} |
||||
|
return k |
||||
|
} |
||||
|
|
||||
|
func encrypt(v []uint32, k []uint32) []uint32 { |
||||
|
length := uint32(len(v)) |
||||
|
n := length - 1 |
||||
|
k = fixk(k) |
||||
|
var y, z, sum, e, p, q uint32 |
||||
|
z = v[n] |
||||
|
sum = 0 |
||||
|
for q = 6 + 52/length; q > 0; q-- { |
||||
|
sum += delta |
||||
|
e = sum >> 2 & 3 |
||||
|
for p = 0; p < n; p++ { |
||||
|
y = v[p+1] |
||||
|
v[p] += mx(sum, y, z, p, e, k) |
||||
|
z = v[p] |
||||
|
} |
||||
|
y = v[0] |
||||
|
v[n] += mx(sum, y, z, p, e, k) |
||||
|
z = v[n] |
||||
|
} |
||||
|
return v |
||||
|
} |
||||
|
|
||||
|
func decrypt(v []uint32, k []uint32) []uint32 { |
||||
|
length := uint32(len(v)) |
||||
|
n := length - 1 |
||||
|
k = fixk(k) |
||||
|
var y, z, sum, e, p, q uint32 |
||||
|
y = v[0] |
||||
|
q = 6 + 52/length |
||||
|
for sum = q * delta; sum != 0; sum -= delta { |
||||
|
e = sum >> 2 & 3 |
||||
|
for p = n; p > 0; p-- { |
||||
|
z = v[p-1] |
||||
|
v[p] -= mx(sum, y, z, p, e, k) |
||||
|
y = v[p] |
||||
|
} |
||||
|
z = v[n] |
||||
|
v[0] -= mx(sum, y, z, p, e, k) |
||||
|
y = v[0] |
||||
|
} |
||||
|
return v |
||||
|
} |
||||
|
|
||||
|
// Encrypt the data with key.
|
||||
|
// data is the bytes to be encrypted.
|
||||
|
// key is the encrypt key. It is the same as the decrypt key.
|
||||
|
func Encrypt(data []byte, key []byte) []byte { |
||||
|
if len(data) == 0 { |
||||
|
return data |
||||
|
} |
||||
|
return toBytes(encrypt(toUint32s(data, true), toUint32s(key, false)), false) |
||||
|
} |
||||
|
|
||||
|
// Decrypt the data with key.
|
||||
|
// data is the bytes to be decrypted.
|
||||
|
// key is the decrypted key. It is the same as the encrypt key.
|
||||
|
func Decrypt(data []byte, key []byte) []byte { |
||||
|
if len(data) == 0 { |
||||
|
return data |
||||
|
} |
||||
|
return toBytes(decrypt(toUint32s(data, false), toUint32s(key, false)), true) |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
package gost |
||||
|
|
||||
|
import ( |
||||
|
"testing" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
func TestQiuTea(t *testing.T) { |
||||
|
|
||||
|
var secret = "abcdefg" |
||||
|
|
||||
|
startSec := 0 |
||||
|
passkey := GenerateShortOTP(secret) |
||||
|
println("password:", passkey) |
||||
|
for { |
||||
|
println("password:", passkey) |
||||
|
startSec++ |
||||
|
time.Sleep(1 * time.Second) |
||||
|
|
||||
|
valid := VerifyShortOTP(secret, passkey, 40) |
||||
|
println("times:", startSec) |
||||
|
if !valid { |
||||
|
println(" false") |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func TestQiuTea2(t *testing.T) { |
||||
|
|
||||
|
secret := generateSecret("192.168.1.1", "user") |
||||
|
|
||||
|
for { |
||||
|
passkey := GenerateShortOTP(secret) |
||||
|
|
||||
|
println("secret: ", secret) |
||||
|
println("password:", passkey) |
||||
|
time.Sleep(1 * time.Second) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func TestQiuTea3(t *testing.T) { |
||||
|
|
||||
|
password := "8b0775013ae1e3714914c9e6" |
||||
|
secret := "c00cd5a1f706b614c7e4882ff7ea6d535971e685b8d75741b446f05d28db3447" |
||||
|
startSec := 0 |
||||
|
for { |
||||
|
println("password:", password) |
||||
|
startSec++ |
||||
|
time.Sleep(1 * time.Second) |
||||
|
|
||||
|
valid := VerifyShortOTP(secret, password, 20) |
||||
|
println("times:", startSec) |
||||
|
if !valid { |
||||
|
println(" false") |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue