Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
TenderIronh committed Apr 21, 2023
0 parents commit 0f3320f
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# totp
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/openp2p-cn/totp

go 1.18
41 changes: 41 additions & 0 deletions totp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Time-based One-time Password
package totp

import (
"crypto/hmac"
"crypto/sha256"
"encoding/binary"
)

const RelayTOTPStep = 30
const ForgotPwdTOTPStep = 300

type TOTP struct {
Step int64 // relay 30s; forgot password 300s;
}

func (t *TOTP) Gen(token uint64, ts int64) uint64 {
step := ts / t.Step
tbuff := make([]byte, 8)
binary.LittleEndian.PutUint64(tbuff, token)
mac := hmac.New(sha256.New, tbuff)
b := make([]byte, 8)
binary.LittleEndian.PutUint64(b, uint64(step))
mac.Write(b)
num := binary.LittleEndian.Uint64(mac.Sum(nil)[:8])
// fmt.Printf("%x\n", mac.Sum(nil))
return num
}

func (t *TOTP) Verify(code uint64, token uint64, ts int64) bool {
if code == 0 {
return false
}
if code == token {
return true
}
if code == t.Gen(token, ts) || code == t.Gen(token, ts-t.Step) || code == t.Gen(token, ts+t.Step) {
return true
}
return false
}
37 changes: 37 additions & 0 deletions totp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Time-based One-time Password
package totp

import (
"testing"
"time"
)

func TestTOTP(t *testing.T) {
tt := TOTP{Step: RelayTOTPStep}
for i := 0; i < 20; i++ {
ts := time.Now().Unix()
code := tt.Gen(13666999958022769123, ts)
t.Log(code)
if !tt.Verify(code, 13666999958022769123, ts) {
t.Error("TOTP error")
}
if !tt.Verify(code, 13666999958022769123, ts-10) {
t.Error("TOTP error")
}
if !tt.Verify(code, 13666999958022769123, ts+10) {
t.Error("TOTP error")
}
if tt.Verify(code, 13666999958022769123, ts+60) {
t.Error("TOTP error")
}
if tt.Verify(code, 13666999958022769124, ts+1) {
t.Error("TOTP error")
}
if tt.Verify(code, 13666999958022769125, ts+1) {
t.Error("TOTP error")
}
time.Sleep(time.Second)
t.Log("round", i, " ", ts, " test ok")
}

}

0 comments on commit 0f3320f

Please sign in to comment.