Skip to content

Commit

Permalink
Drop Digits type (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
cristaloleg authored Dec 2, 2023
1 parent a21f718 commit 9f2d3d5
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 45 deletions.
4 changes: 2 additions & 2 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func ExampleHOTP() {
hotp, err := otp.NewHOTP(otp.HOTPConfig{
Algo: otp.AlgorithmSHA1,
Digits: otp.Digits(10),
Digits: 10,
Issuer: "cristalhq",
})
checkErr(err)
Expand All @@ -31,7 +31,7 @@ func ExampleHOTP() {
func ExampleTOTP() {
totp, err := otp.NewTOTP(otp.TOTPConfig{
Algo: otp.AlgorithmSHA1,
Digits: otp.Digits(10),
Digits: 10,
Issuer: "cristalhq",
Period: 30,
Skew: 2,
Expand Down
12 changes: 7 additions & 5 deletions hotp.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/hmac"
"crypto/subtle"
"encoding/binary"
"fmt"
"math"
"net/url"
)
Expand All @@ -15,7 +16,7 @@ type HOTP struct {

type HOTPConfig struct {
Algo Algorithm
Digits Digits
Digits uint
Issuer string
}

Expand Down Expand Up @@ -44,7 +45,7 @@ func NewHOTP(cfg HOTPConfig) (*HOTP, error) {
func (h *HOTP) GenerateURL(account string, secret []byte) string {
v := url.Values{}
v.Set("algorithm", h.cfg.Algo.String())
v.Set("digits", h.cfg.Digits.String())
v.Set("digits", atoi(h.cfg.Digits))
v.Set("issuer", h.cfg.Issuer)
v.Set("secret", b32Enc(secret))

Expand Down Expand Up @@ -79,13 +80,14 @@ func (h *HOTP) GenerateCode(counter uint64, secret string) (string, error) {
value |= int64(sum[offset+2]&0xff) << 8
value |= int64(sum[offset+3] & 0xff)

length := int64(math.Pow10(h.cfg.Digits.Length()))
return h.cfg.Digits.Format(int(value % length)), nil
length := int64(math.Pow10(int(h.cfg.Digits)))
code := fmt.Sprintf(fmt.Sprintf("%%0%dd", h.cfg.Digits), value%length)
return code, nil
}

// Validate the given passcode, counter and secret.
func (h *HOTP) Validate(passcode string, counter uint64, secret string) error {
if len(passcode) != h.cfg.Digits.Length() {
if len(passcode) != int(h.cfg.Digits) {
return ErrCodeLengthMismatch
}

Expand Down
18 changes: 9 additions & 9 deletions hotp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestHOTP(t *testing.T) {
for _, tc := range hotpRFCTestCases {
hotp, err := NewHOTP(HOTPConfig{
Algo: tc.algo,
Digits: Digits(6),
Digits: 6,
Issuer: "cristalhq",
})
mustOk(t, err)
Expand All @@ -44,28 +44,28 @@ func TestHOTP(t *testing.T) {
func TestNewHOTP(t *testing.T) {
_, err := NewHOTP(HOTPConfig{
Algo: 0,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
})
mustEqual(t, err, ErrUnsupportedAlgorithm)

_, err = NewHOTP(HOTPConfig{
Algo: 100,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
})
mustEqual(t, err, ErrUnsupportedAlgorithm)

_, err = NewHOTP(HOTPConfig{
Algo: 1,
Digits: Digits(0),
Digits: 0,
Issuer: "cristalhq",
})
mustEqual(t, err, ErrNoDigits)

_, err = NewHOTP(HOTPConfig{
Algo: 1,
Digits: Digits(8),
Digits: 8,
Issuer: "",
})
mustEqual(t, err, ErrEmptyIssuer)
Expand All @@ -74,7 +74,7 @@ func TestNewHOTP(t *testing.T) {
func TestHOTPGenerateURL(t *testing.T) {
hotp, err := NewHOTP(HOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
})
mustOk(t, err)
Expand All @@ -89,7 +89,7 @@ func TestHOTPGenerateURL(t *testing.T) {
func BenchmarkHOTP_GenerateURL(b *testing.B) {
hotp, err := NewHOTP(HOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
})
mustOk(b, err)
Expand All @@ -111,7 +111,7 @@ func BenchmarkHOTP_GenerateURL(b *testing.B) {
func BenchmarkHOTP_GenerateCode(b *testing.B) {
hotp, err := NewHOTP(HOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
})
mustOk(b, err)
Expand All @@ -130,7 +130,7 @@ func BenchmarkHOTP_GenerateCode(b *testing.B) {
func BenchmarkHOTP_Validate(b *testing.B) {
hotp, err := NewHOTP(HOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
})
mustOk(b, err)
Expand Down
17 changes: 4 additions & 13 deletions otp.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,6 @@ func (a Algorithm) Hash() hash.Hash {
}
}

// Digits is the number of digits in the OTP passcode.
type Digits uint

func (d Digits) String() string { return fmt.Sprintf("%d", d) }

// Length of the passcode.
func (d Digits) Length() int { return int(d) }

// Format the number to a digit format (zero-filled upto digits size).
func (d Digits) Format(n int) string {
return fmt.Sprintf(fmt.Sprintf("%%0%dd", d), n)
}

// Key represents an HTOP or TOTP key.
type Key struct {
url *url.URL
Expand Down Expand Up @@ -147,3 +134,7 @@ func b32Dec(s string) ([]byte, error) {
func b32Enc(src []byte) string {
return base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(src)
}

func atoi(v uint) string {
return strconv.FormatUint(uint64(v), 10)
}
9 changes: 4 additions & 5 deletions totp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package otp
import (
"math"
"net/url"
"strconv"
"time"
)

Expand All @@ -15,7 +14,7 @@ type TOTP struct {

type TOTPConfig struct {
Algo Algorithm
Digits Digits
Digits uint
Issuer string
Period uint
Skew uint
Expand Down Expand Up @@ -62,10 +61,10 @@ func NewTOTP(cfg TOTPConfig) (*TOTP, error) {
func (t *TOTP) GenerateURL(account string, secret []byte) string {
v := url.Values{}
v.Set("algorithm", t.cfg.Algo.String())
v.Set("digits", t.cfg.Digits.String())
v.Set("digits", atoi(t.cfg.Digits))
v.Set("issuer", t.cfg.Issuer)
v.Set("secret", b32Enc(secret))
v.Set("period", strconv.FormatUint(uint64(t.cfg.Period), 10))
v.Set("period", atoi(t.cfg.Period))

u := url.URL{
Scheme: "otpauth",
Expand All @@ -88,7 +87,7 @@ func (t *TOTP) GenerateCode(secret string, at time.Time) (string, error) {

// Validate the given passcode, time and secret.
func (t *TOTP) Validate(passcode string, at time.Time, secret string) error {
if len(passcode) != t.cfg.Digits.Length() {
if len(passcode) != int(t.cfg.Digits) {
return ErrCodeLengthMismatch
}

Expand Down
22 changes: 11 additions & 11 deletions totp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestTOTP(t *testing.T) {
for _, tc := range totpRFCTestCases {
totp, err := NewTOTP(TOTPConfig{
Algo: tc.algo,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand All @@ -56,7 +56,7 @@ func TestTOTP(t *testing.T) {
func TestNewTOTP(t *testing.T) {
_, err := NewTOTP(TOTPConfig{
Algo: 0,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand All @@ -65,7 +65,7 @@ func TestNewTOTP(t *testing.T) {

_, err = NewTOTP(TOTPConfig{
Algo: 100,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand All @@ -74,7 +74,7 @@ func TestNewTOTP(t *testing.T) {

_, err = NewTOTP(TOTPConfig{
Algo: 1,
Digits: Digits(0),
Digits: 0,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand All @@ -83,7 +83,7 @@ func TestNewTOTP(t *testing.T) {

_, err = NewTOTP(TOTPConfig{
Algo: 1,
Digits: Digits(8),
Digits: 8,
Issuer: "",
Period: 30,
Skew: 1,
Expand All @@ -92,7 +92,7 @@ func TestNewTOTP(t *testing.T) {

_, err = NewTOTP(TOTPConfig{
Algo: 1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 0,
Skew: 1,
Expand All @@ -101,7 +101,7 @@ func TestNewTOTP(t *testing.T) {

_, err = NewTOTP(TOTPConfig{
Algo: 1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 0,
Expand All @@ -112,7 +112,7 @@ func TestNewTOTP(t *testing.T) {
func TestTOTPGenerateURL(t *testing.T) {
totp, err := NewTOTP(TOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand All @@ -129,7 +129,7 @@ func TestTOTPGenerateURL(t *testing.T) {
func BenchmarkTOTP_GenerateURL(b *testing.B) {
totp, err := NewTOTP(TOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand All @@ -153,7 +153,7 @@ func BenchmarkTOTP_GenerateURL(b *testing.B) {
func BenchmarkTOTP_GenerateCode(b *testing.B) {
totp, err := NewTOTP(TOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand All @@ -176,7 +176,7 @@ func BenchmarkTOTP_GenerateCode(b *testing.B) {
func BenchmarkTOTP_Validate(b *testing.B) {
totp, err := NewTOTP(TOTPConfig{
Algo: AlgorithmSHA1,
Digits: Digits(8),
Digits: 8,
Issuer: "cristalhq",
Period: 30,
Skew: 1,
Expand Down

0 comments on commit 9f2d3d5

Please sign in to comment.