Skip to content

Commit

Permalink
first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
Aizen committed Oct 5, 2024
1 parent 5c16201 commit 3abf992
Show file tree
Hide file tree
Showing 8 changed files with 4,409 additions and 4,276 deletions.
39 changes: 34 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import "github.com/francescoalemanno/cryptipass"

### Generate a Passphrase

The primary function of the `cryptipass` package is to generate secure passphrases. You can generate a new passphrase using the `NewPassphrase` function. You can specify how many words you want in the passphrase, and the function returns the passphrase and its total entropy.
The primary function of the `cryptipass` package is to generate secure passphrases. You can generate a new passphrase using the `GenPassphrase` function. You can specify how many words you want in the passphrase, and the function returns the passphrase and its total entropy.

Example:

Expand All @@ -36,11 +36,11 @@ package main

import (
"fmt"
"cryptipass"
"github.com/francescoalemanno/cryptipass"
)

func main() {
passphrase, entropy := cryptipass.NewPassphrase(5)
passphrase, entropy := cryptipass.GenPassphrase(5)
fmt.Printf("Passphrase: %s\n", passphrase)
fmt.Printf("Entropy: %.2f bits\n", entropy)
}
Expand All @@ -53,18 +53,47 @@ Passphrase: jesside.flyperm.aunsis.dertsy
Entropy: 97.63 bits
```

### Generate a Password according to a pattern

You can generate a new password using the `GenFromPattern` function. You can specify how many words you want in the passphrase, and the function returns the passphrase and its total entropy.

Example:

```go
package main

import (
"fmt"
"github.com/francescoalemanno/cryptipass"
)

func main() {
passphrase, entropy := cryptipass.GenFromPattern("W-w.cccc.CCCC(ss)[20dd]")
fmt.Printf("Passphrase: %s\n", passphrase)
fmt.Printf("Entropy: %.2f bits\n", entropy)
}
```

### Example Output:

```
// pattern W - w .cccc.CCCC(ss)[20dd]
Passphrase: Storegu-dedudend.skin.EALR(=*)[2045]
Entropy: 96.41 bits
```

### Word Generation

Internally, the package uses a series of functions to generate words of varying lengths. Each word contributes a certain amount of entropy, calculated during the generation process.

- `GenMixWord()`: Generates a random word of mixed length, returning both the word and its entropy.
- `GenWord(n int)`: Generates a word of exactly `n` characters.
- `PickLength()`: Picks a random length for a word.
- `PickNext()`: Generates the next part of a word based on the current string.
- `PickNext(seed string)`: Generates the next part of a word based on the current string.

## Notes

- The package seeds the random number generator with `crypto/rand`, making it cryptographically secure. In scenarios where cryptographic security is not necessary and faster execution is preferred, the package also provides an alternative (commented out) `PCG` random number generator.
- The package seeds the random number generator with `crypto/rand`, making it cryptographically secure.
- The entropy provided in the output is a measure of how unpredictable the passphrase is. The higher the entropy, the more secure the passphrase is.

## Contributing
Expand Down
86 changes: 59 additions & 27 deletions cmd/genpw/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,29 @@ This will install the `genpw` binary in your `$GOPATH/bin` directory.
Once installed, you can generate passphrases by running `genpw` with the following options:

```
Usage: genpw [flags]
Flags:
-p uint
number of passwords to generate (default 4)
-w uint
number of words per password (default 4)
-c run entropy certification algorithm (for developers)
-c run entropy certification algorithm
users not necessarily need to concern with this detail.
-cd uint
certification effort.
A larger number leads to more accurate results
at the expense of exponentially longer completion times. (default 1)
-n uint
number of passwords to generate (default 6)
-p string
pattern used to generate passphrase e.g. try:
-p WWW20dd
other possible patterns are formed by combining:
- 'W' for uppercase word.
- 'w' lowercase word.
- 's' symbol.
- 'd' digit.
(default "W.w.w")
```

### Example Commands

1. **Generate 4 passphrases with 4 words each** (default):
1. **Generate 6 passphrases with 3 words each** (default):

```bash
genpw
Expand All @@ -47,40 +56,63 @@ genpw
This will output something like:

```
ENTROPY | PASSPHRASE
+++++++++++++++|++++++++++++++++++++++++++++++++
65.57 | ammud.ruffl.ummi.shing
82.76 | epavoi.hakeyer.bles.monfin
82.91 | everap.gighte.clap.baselec
85.93 | stash.laxor.surevida.dexqy
Passphrase Log10(Guesses) EntropyLog2
Joilionel.scric.glicam 20.70 69.76
Haneatri.unfolop.freskl 21.17 71.33
Ricie.enrelerc.morsman 21.90 73.74
Snuterov.possarb.sprive 22.93 77.18
Hartiner.acycata.ovalnegis 23.35 78.57
Grantdoti.irthed.imeatill 23.61 79.45
```

2. **Generate 2 passphrases with 6 words each**:
1. **Generate passphrases with custom pattern**:

```bash
genpw -w 6 -p 2
genpw -p "WW20dds" -n 5
```

The output might look like:

```go
Passphrase Log10(Guesses) EntropyLog2

DofyonLivord2012@ 15.26 51.70
DinkedMankess2026^ 16.09 54.43
BlyestaHameloty2062= 18.02 60.87
ShantlyzSectoo2098= 18.15 61.29
AxoncingTwovernis2056* 19.12 64.52
```
ENTROPY | PASSPHRASE
+++++++++++++++|++++++++++++++++++++++++++++++++
119.97 | tubse.stnew.critedi.priu.bugger.crokess
136.65 | stedin.overjan.gifteto.overepr.comiz.unrupee

or

```bash
genpw -p "w.w.w.w" -n 5
```

The output might look like:

```go
Passphrase Log10(Guesses) EntropyLog2

stritters.candis.frot.unliti 27.06 90.91
treralryi.jangli.stathle.resche 29.22 98.08
andetap.quis.cloashea.firetorki 29.75 99.83
humperes.stacessfi.splan.gidinkl 30.55 102.50
unctirter.arbeday.amersdowf.ovyarvis 33.60 112.62
```

### Entropy Considerations

Each word generated by CryptiPass has on average more than 21 bits of entropy. For example:
- A 4-word passphrase has roughly 84 bits of entropy.
- A 6-word passphrase has approximately 126 bits of entropy.
Each password generated by CryptiPass comes with an exact entropy evaluation . For example:
- A 4-word passphrase has roughly 97 bits of entropy.
- A 6-word passphrase has approximately 146 bits of entropy.

This makes the passphrases highly secure, even against brute-force attacks.
This allows for highly secure passphrases, even against brute-force attacks.

## Certification (Debug/Development Mode)

For debugging or testing purposes, the `certify` function can be used to track the entropy of generated words over large runs, it has to be used if another vocabulary is distilled into random rules for the software.
For debugging or testing purposes, the `certify` function can be used to track the entropy of generated passwords over large runs.

## Contributing

Expand Down
41 changes: 30 additions & 11 deletions cmd/genpw/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,29 @@ type Passphrase struct {
}

func main() {
cert := flag.Bool("c", false, "run entropy certification algorithm (for developers)")
depth := flag.Uint64("cd", 1, "certification depth, larger number -> more accurate results (for developers)")
words := flag.Uint64("w", 3, "number of words per password")
passwords := flag.Uint64("p", 6, "number of passwords to generate")
cert := flag.Bool("c", false, "run entropy certification algorithm\nusers not necessarily need to concern with this detail.")
depth := flag.Uint64("cd", 1, "certification effort.\nA larger number leads to more accurate results\nat the expense of exponentially longer completion times.")
f_pattern := flag.String("p", "W.w.w",
`pattern used to generate passphrase e.g. try:
-p WWW20dd
other possible patterns are formed by combining:
- 'W' for uppercase word.
- 'w' lowercase word.
- 's' symbol.
- 'd' digit.
- 'c' a character.
`)
passwords := flag.Uint64("n", 6, "number of passwords to generate")
flag.Parse()
pattern := *f_pattern
if *cert {
certify(*depth)
certify(pattern, *depth)
}

pws := []Passphrase{}
for range *passwords {
F, H := cp.NewPassphrase(*words)
F, H := cp.GenFromPattern(pattern)
pws = append(pws, Passphrase{F: F, H: H})
}
slices.SortFunc(pws, func(a, b Passphrase) int {
Expand All @@ -38,15 +49,23 @@ func main() {
}
return 0
})
maxlen := 0
for _, v := range pws {
maxlen = max(maxlen, len(v.F))
}
title := "Passphrase"
maxlen = max(maxlen, len(title))

fmt.Printf(" ENTROPY | PASSPHRASE\n")
fmt.Printf("+++++++++++++++|++++++++++++++++++++++++++++++++\n")
pad := 4
padding := strings.Repeat(" ", pad+maxlen-len(title))
fmt.Printf("%s%s%s\n\n", title, padding, "Log10(Guesses) EntropyLog2")
for _, p := range pws {
fmt.Printf("% 13.2f | %s\n", p.H, p.F)
padding := strings.Repeat(" ", pad+maxlen-len(p.F))
fmt.Printf("%s%s%.2f %.2f\n", p.F, padding, (p.H-1)/math.Log2(10), p.H)
}
}

func certify(udepth uint64) {
func certify(pattern string, udepth uint64) {
cnt := make(map[string]int)
iN := 0
Q := 128
Expand All @@ -56,7 +75,7 @@ func certify(udepth uint64) {
for {
Q += Q / 14
for range Q {
w, nh := cp.GenMixWord()
w, nh := cp.GenFromPattern(pattern)
nominal_H += nh
nominal_H2 += nh * nh
cnt_nom_H++
Expand Down
Loading

0 comments on commit 3abf992

Please sign in to comment.