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

Drop Digits type #12

Merged
merged 1 commit into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading