~seirdy/moac

667d3653b9f06d2911c6bdd021186962033eb543 — Rohan Kumar 15 days ago 09d2aeb
Refactor: re-layout and rename project

- Split commandline portion from the rest of the project in a cmd/ dir
- Rename project from moac-pwtools to moac, since this repo will be the
  core libs used by future sibling programs (inc. a GUI)
6 files changed, 38 insertions(+), 36 deletions(-)

M README.md
R main.go => cmd/moac/main.go
A doc.go
M givens.go
M go.mod
M pwgen.go
M README.md => README.md +12 -13
@@ 1,29 1,29 @@
moac-pwtools
moac
============

[![sourcehut](https://img.shields.io/badge/repository-sourcehut-lightgrey.svg?logo=data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjZmZmIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjU2IDhDMTE5IDggOCAxMTkgOCAyNTZzMTExIDI0OCAyNDggMjQ4IDI0OC0xMTEgMjQ4LTI0OFMzOTMgOCAyNTYgOHptMCA0NDhjLTExMC41IDAtMjAwLTg5LjUtMjAwLTIwMFMxNDUuNSA1NiAyNTYgNTZzMjAwIDg5LjUgMjAwIDIwMC04OS41IDIwMC0yMDAgMjAweiIvPjwvc3ZnPg==)](https://sr.ht/~seirdy/moac-pwtools) [![GitLab mirror](https://img.shields.io/badge/mirror-GitLab-orange.svg?logo=gitlab)](https://gitlab.com/Seirdy/moac-pwtools) [![GitHub mirror](https://img.shields.io/badge/mirror-GitHub-black.svg?logo=github)](https://github.com/Seirdy/moac-pwtools)
[![sourcehut](https://img.shields.io/badge/repository-sourcehut-lightgrey.svg?logo=data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjZmZmIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjU2IDhDMTE5IDggOCAxMTkgOCAyNTZzMTExIDI0OCAyNDggMjQ4IDI0OC0xMTEgMjQ4LTI0OFMzOTMgOCAyNTYgOHptMCA0NDhjLTExMC41IDAtMjAwLTg5LjUtMjAwLTIwMFMxNDUuNSA1NiAyNTYgNTZzMjAwIDg5LjUgMjAwIDIwMC04OS41IDIwMC0yMDAgMjAweiIvPjwvc3ZnPg==)](https://sr.ht/~seirdy/MOAC) [![GitLab mirror](https://img.shields.io/badge/mirror-GitLab-orange.svg?logo=gitlab)](https://gitlab.com/Seirdy/moac) [![GitHub mirror](https://img.shields.io/badge/mirror-GitHub-black.svg?logo=github)](https://github.com/Seirdy/moac)

`moac-pwtools` is a tool to analyze password strength given physical limits to computation. It's inspired by a blog post I wrote: [Becoming physically immune to brute-force attacks](https://seirdy.one/2021/01/12/password-strength.html).
`moac` is a tool to analyze password strength given physical limits to computation. It's inspired by a blog post I wrote: [Becoming physically immune to brute-force attacks](https://seirdy.one/2021/01/12/password-strength.html).

Users provide given values like the mass available to attackers, a time limit for the brute-force attack, and the energy available. `moac-pwtools` outputs the likelihood of a successful attack or the minimum password entropy for a possible brute-force failure.
Users provide given values like the mass available to attackers, a time limit for the brute-force attack, and the energy available. `moac` outputs the likelihood of a successful attack or the minimum password entropy for a possible brute-force failure.

`moac-pwtools` uses [zxcvbn-go](https://github.com/nbutton23/zxcvbn-go) to calculate password entropy.
`moac` uses [zxcvbn-go](https://github.com/nbutton23/zxcvbn-go) to calculate password entropy.

Installation
------------

```sh
GO111MODULE=on go install git.sr.ht/~seirdy/moac-pwtools
GO111MODULE=on go install git.sr.ht/~seirdy/moac/cmd/moac
```

Usage
-----

```
moac-pwtools - analyze password strength with physical limits
moac - analyze password strength with physical limits

USAGE:
  moac-pwtools [OPTIONS] [COMMAND]
  moac [OPTIONS] [COMMAND]

OPTIONS:
  -h	Display this help message.


@@ 61,14 61,14 @@ Let's assume this is a maximally efficient quantum computer powered by the Earth
- Mass of the Earth: ~5.97e24 kg

```console
$ moac-pwtools -qm 5.97e24 -t 1.45e17 entropy-limit
$ moac -qm 5.97e24 -t 1.45e17 entropy-limit
427
```

Understanding the answer to Life, the Universe, and Everything requires less than `2^427` computations. If the same computer instead tried to brute-force a password, what kind of password might be out of its reach?

```console
$ moac-pwtools -qm 5.97e24 -t 1.45e17 pwgen lowercase uppercase numbers symbols extendedASCII
$ moac -qm 5.97e24 -t 1.45e17 pwgen lowercase uppercase numbers symbols extendedASCII
v¢JÊÙúQ§4mÀÛªZûYÍé©mËiÐ× "½J6y.ñíí'è¦ïϵ°~
```



@@ 84,16 84,15 @@ Consider this project highly unstable before v0.1.0.
- godocs and manpage
- Better error handling: validate input, etc.
- Write tests.
- Separate command-line package from the rest of the code in a `cmd/` directory.

Roadmap for 0.2.0
-----------------

- Read from a config file.
- Add a command to output requirements for a brute-force attack (time/energy/mass required) with the given constraints.
- zxcvbn-go has a lot of functionality that `moac-pwtools` doesn't need; write an entropy estimator that's a bit simpler but gives similar results, optimized for pseudorandom passwords (no dictionary words, focus on estimating charset size and repetitions/patterns).
- zxcvbn-go has a lot of functionality that `moac` doesn't need; write an entropy estimator that's a bit simpler but gives similar results, optimized for pseudorandom passwords (no dictionary words, focus on estimating charset size and repetitions/patterns).

### Ideas for other programs that can use `moac-pwtools`
### Ideas for other programs that can use `moac`

- A separate program to "benchmark" external password-generation programs/scripts by repeatedly running them and giving measurements of the worst output.
- A GUI

R main.go => cmd/moac/main.go +21 -20
@@ 5,13 5,14 @@ import (
	"os"
	"strconv"

	"git.sr.ht/~seirdy/moac"
	"git.sr.ht/~sircmpwn/getopt"
)

const Usage = `moac-pwtools - analyze password strength with physical limits
const Usage = `moac - analyze password strength with physical limits

USAGE:
  moac-pwtools [OPTIONS] [COMMAND] [ARGS]
  moac [OPTIONS] [COMMAND] [ARGS]

OPTIONS:
  -h	Display this help message.


@@ 33,12 34,12 @@ COMMANDS:

func main() {
	var (
		givens  Givens
		givens  moac.Givens
		quantum bool
	)
	opts, optind, err := getopt.Getopts(os.Args, "hqe:s:m:g:P:t:p:")
	if err != nil {
		fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n%s", err, Usage)
		fmt.Fprintf(os.Stderr, "moac: %v\n%s", err, Usage)
		os.Exit(1)
	}
	for _, opt := range opts {


@@ 51,37 52,37 @@ func main() {
		case 'e':
			givens.Energy, err = strconv.ParseFloat(opt.Value, 64)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n", err)
				fmt.Fprintf(os.Stderr, "moac: %v\n", err)
				os.Exit(1)
			}
		case 's':
			givens.Entropy, err = strconv.ParseFloat(opt.Value, 32)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n%s", err, Usage)
				fmt.Fprintf(os.Stderr, "moac: %v\n%s", err, Usage)
				os.Exit(1)
			}
		case 'm':
			givens.Mass, err = strconv.ParseFloat(opt.Value, 64)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n%s", err, Usage)
				fmt.Fprintf(os.Stderr, "moac: %v\n%s", err, Usage)
				os.Exit(1)
			}
		case 'g':
			givens.EnergyPerGuess, err = strconv.ParseFloat(opt.Value, 64)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n%s", err, Usage)
				fmt.Fprintf(os.Stderr, "moac: %v\n%s", err, Usage)
				os.Exit(1)
			}
		case 'P':
			givens.Power, err = strconv.ParseFloat(opt.Value, 64)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n%s", err, Usage)
				fmt.Fprintf(os.Stderr, "moac: %v\n%s", err, Usage)
				os.Exit(1)
			}
		case 't':
			givens.Time, err = strconv.ParseFloat(opt.Value, 64)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n%s", err, Usage)
				fmt.Fprintf(os.Stderr, "moac: %v\n%s", err, Usage)
				os.Exit(1)
			}
		case 'p':


@@ 93,23 94,23 @@ func main() {
		cmd := args[0]
		switch cmd {
		case "strength":
			likelihood, err := BruteForceability(&givens, quantum)
			likelihood, err := moac.BruteForceability(&givens, quantum)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n", err)
				fmt.Fprintf(os.Stderr, "moac: %v\n", err)
				os.Exit(1)
			}
			fmt.Printf("%.3g\n", likelihood)
		case "entropy-limit":
			entropyLimit, err := MinEntropy(&givens, quantum)
			entropyLimit, err := moac.MinEntropy(&givens, quantum)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n", err)
				fmt.Fprintf(os.Stderr, "moac: %v\n", err)
				os.Exit(1)
			}
			fmt.Printf("%.3g\n", entropyLimit)
		case "pwgen":
			entropyLimit, err := MinEntropy(&givens, quantum)
			entropyLimit, err := moac.MinEntropy(&givens, quantum)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n", err)
				fmt.Fprintf(os.Stderr, "moac: %v\n", err)
				os.Exit(1)
			}
			var charsets []string


@@ 118,9 119,9 @@ func main() {
			} else {
				charsets = []string{"lowercase", "uppercase", "numbers", "symbols", "extendedASCII", " "}
			}
			pw, err := GenPW(charsets, entropyLimit)
			pw, err := moac.GenPW(charsets, entropyLimit)
			if err != nil {
				fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n", err)
				fmt.Fprintf(os.Stderr, "moac: %v\n", err)
				os.Exit(1)
			}
			fmt.Println(pw)


@@ 129,9 130,9 @@ func main() {
			os.Exit(1)
		}
	} else {
		likelihood, err := BruteForceability(&givens, quantum)
		likelihood, err := moac.BruteForceability(&givens, quantum)
		if err != nil {
			fmt.Fprintf(os.Stderr, "moac-pwtools: %v\n", err)
			fmt.Fprintf(os.Stderr, "moac: %v\n", err)
			os.Exit(1)
		}
		fmt.Printf("%.3g\n", likelihood)

A doc.go => doc.go +2 -0
@@ 0,0 1,2 @@
// Package moac provides the utilities to calculate password strength given physical constraints.
package moac

M givens.go => givens.go +1 -1
@@ 1,4 1,4 @@
package main
package moac

import (
	"errors"

M go.mod => go.mod +1 -1
@@ 1,4 1,4 @@
module git.sr.ht/~seirdy/moac-pwtools
module git.sr.ht/~seirdy/moac

go 1.16


M pwgen.go => pwgen.go +1 -1
@@ 1,4 1,4 @@
package main
package moac

import (
	cryptoRand "crypto/rand"