-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5fe638c
Showing
7 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# moths | ||
|
||
> e**mo**ji a**ths** | ||
# what | ||
|
||
Emojies as TOTP | ||
|
||
# why | ||
|
||
Becasue why not? | ||
|
||
# how | ||
|
||
Runnig this is quite easy, just run the command: | ||
|
||
Download the dependencies: | ||
|
||
```sh | ||
go mod download | ||
``` | ||
|
||
Next-up start the program | ||
|
||
```sh | ||
go run . | ||
``` | ||
|
||
As I said, easy-peasy! | ||
|
||
# sample | ||
|
||
A sample out-put might be `😻🙀😺🙀🙀` which would equal the `920811` TOTP-token. Using the super secret secret specified in [`./secret.pem`](./secret.pem) - genereated at `2022/04/28 02:05:42` and a `5`-second interval. | ||
|
||
# shoutout | ||
|
||
I couldn't have done it without the lovely OSS, listed below: | ||
|
||
- https://github.com/aidarkhanov/nanoid | ||
- https://github.com/enescakir/emoji | ||
- https://github.com/tilaklodha/google-authenticator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/binary" | ||
"fmt" | ||
"math" | ||
"math/bits" | ||
"math/rand" | ||
"strings" | ||
) | ||
|
||
// randomBufferFromHOTP generates a random buffer from a HOTP token. | ||
// | ||
// /!\ Modified /!\ | ||
// | ||
// Proudly stolen from https://stackoverflow.com/a/48307199/754471 | ||
func randomBufferFromHOTP(otp string) func(step int) ([]byte, error) { | ||
buf := []byte(fmt.Sprintf("%08s", otp)) | ||
seed := int64(binary.BigEndian.Uint64(buf)) | ||
r := rand.New(rand.NewSource(seed)) | ||
|
||
return func(step int) ([]byte, error) { | ||
buffer := make([]byte, step) | ||
if _, err := r.Read(buffer); err != nil { | ||
return nil, err | ||
} | ||
return buffer, nil | ||
} | ||
} | ||
|
||
// MothsGenerator is essentially the nanoid generator with a few modifications. | ||
// | ||
// /!\ Modified /!\ | ||
// | ||
// https://github.com/aidarkhanov/nanoid/blob/master/nanoid.go | ||
func MothsGenerator(token string, numEmojies int, alphabet ...string) (string, error) { | ||
emojiBytes := 4 | ||
size := emojiBytes * numEmojies | ||
|
||
mask := 2<<uint32(31-bits.LeadingZeros32(uint32(len(alphabet)-1|1))) - 1 | ||
step := int(math.Ceil(1.6 * float64(mask*size) / float64(len(alphabet)))) | ||
|
||
id := new(strings.Builder) | ||
id.Grow(size) | ||
|
||
buffer := randomBufferFromHOTP(token) | ||
for { | ||
randomBuffer, err := buffer(step) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
for i := 0; i < step; i++ { | ||
currentIndex := int(randomBuffer[i]) & mask | ||
|
||
if currentIndex < len(alphabet) { | ||
if _, err := id.WriteString(alphabet[currentIndex]); err != nil { | ||
return "", err | ||
} else if id.Len() == size { | ||
return id.String(), nil | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module moths | ||
|
||
go 1.18 | ||
|
||
require github.com/enescakir/emoji v1.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github.com/enescakir/emoji v1.0.0 h1:W+HsNql8swfCQFtioDGDHCHri8nudlK1n5p2rHCJoog= | ||
github.com/enescakir/emoji v1.0.0/go.mod h1:Bt1EKuLnKDTYpLALApstIkAjdDrS/8IAgTkKp+WKFD0= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"crypto/hmac" | ||
"crypto/sha1" | ||
"encoding/binary" | ||
"fmt" | ||
"log" | ||
"strconv" | ||
) | ||
|
||
// GetHOTPToken returns a HOTP token for the given secret and interval. | ||
// | ||
// /!\ Modified /!\ | ||
// | ||
// https://github.com/tilaklodha/google-authenticator/blob/master/google_authenticator.go | ||
func GetHOTPToken(secret string, interval int64) string { | ||
key := []byte(fmt.Sprintf("%08s", secret)) | ||
|
||
bs := make([]byte, 8) | ||
binary.BigEndian.PutUint64(bs, uint64(interval)) | ||
|
||
// Signing the value using HMAC-SHA1 Algorithm | ||
hash := hmac.New(sha1.New, key) | ||
hash.Write(bs) | ||
h := hash.Sum(nil) | ||
|
||
// We're going to use a subset of the generated hash. | ||
// Using the last nibble (half-byte) to choose the index to start from. | ||
// This number is always appropriate as it's maximum decimal 15, the hash will | ||
// have the maximum index 19 (20 bytes of SHA1) and we need 4 bytes. | ||
o := (h[19] & 15) | ||
|
||
var header uint32 | ||
// Get 32 bit chunk from hash starting at the o | ||
r := bytes.NewReader(h[o : o+4]) | ||
err := binary.Read(r, binary.BigEndian, &header) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
// Ignore most significant bits as per RFC 4226. | ||
// Takes division from one million to generate a remainder less than < 7 digits | ||
h12 := (int(header) & 0x7fffffff) % 1000000 | ||
|
||
// Converts number as a string | ||
otp := strconv.Itoa(int(h12)) | ||
|
||
// Padding with 0s to the left if the OTP is less than 8 digits | ||
return fmt.Sprintf("%06s", otp) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package main | ||
|
||
import ( | ||
"io/ioutil" | ||
"log" | ||
"time" | ||
|
||
"github.com/enescakir/emoji" | ||
) | ||
|
||
func main() { | ||
log.SetFlags(log.Llongfile | log.LstdFlags) | ||
|
||
data, err := ioutil.ReadFile("secret.pem") | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
secret := string(data) | ||
interval := time.Now().Unix() / 5 | ||
|
||
otp := GetHOTPToken(secret, interval) | ||
moth, err := MothsGenerator( | ||
otp, | ||
5, | ||
emoji.GrinningCat.String(), | ||
emoji.GrinningCatWithSmilingEyes.String(), | ||
emoji.CatWithTearsOfJoy.String(), | ||
emoji.SmilingCatWithHeartEyes.String(), | ||
emoji.CatWithWrySmile.String(), | ||
emoji.KissingCat.String(), | ||
emoji.WearyCat.String(), | ||
emoji.CryingCat.String(), | ||
emoji.PoutingCat.String(), | ||
) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
log.Printf("moth-otp: %s => %s\n", moth, otp) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
😻 |