diff --git a/index.html b/index.html
index 6af18a1..429a481 100644
--- a/index.html
+++ b/index.html
@@ -208,6 +208,7 @@
Passphrase and Password Generator
+
diff --git a/js/main.js b/js/main.js
index 6f84ea5..00f7c30 100644
--- a/js/main.js
+++ b/js/main.js
@@ -1048,6 +1048,96 @@ function generateProquints() {
return [pass, pass.length, len * 16]
}
+/**
+ * Generate a Lepron pseudoword password.
+ * @returns {Array} The password string, the length of the password, and the entropy of the password.
+ */
+function generateLepron() {
+ // https://www.cambridgeclarion.org/34.html
+ const start = [
+ ['c','cp'], ['b','bh'], ['p','xm'], ['d','bs'], ['r','ts'], ['s','chl'],
+ ['m','kh'], ['l','dw'], ['t','kl'], ['h','kr'], ['f','chr'], ['g','ps'],
+ ['n','x'], ['w','sch'], ['v','gn'], ['j','gh'], ['pr','spl'], ['st','shr'],
+ ['tr','spr'], ['ch','sk'], ['br','kn'], ['fl','squ'], ['cr','thr'], ['gr','tw'],
+ ['k','rh'], ['sh','scr'], ['qu','sm'], ['fr','ph'], ['bl','wr'], ['sp','str'],
+ ['cl','sn'], ['dr','sw'], ['sl','z'], ['pl','th'], ['y','sc'], ['gl','wh'],
+ ]
+
+ const vowel = [
+ ['a'], ['e'], ['i'], ['o'], ['u', 'oi'], ['ee', 'ea', 'au', 'ua', 'ya', 'y', 'oo', 'ai', 'io']
+ ]
+
+ const middle = [
+ ['t', 'mpl'], ['l', 'nf'], ['r', 'gg'], ['n', 'nv'], ['m', 'lt'], ['v', 'dd'],
+ ['c', 'rb'], ['d', 'bb'], ['s', 'ch'], ['g', 'rl'], ['p', 'pl'], ['b', 'pr'],
+ ['st', 'sp'], ['ll', 'sh'], ['nt', 'bl'], ['nd', 'str'], ['ss', 'rs'], ['rr', 'br'],
+ ['w', 'gn'], ['f', 'rg'], ['mp', 'tr'], ['ct', 'j'], ['rt', 'cr'], ['tt', 'cc'],
+ ['mb', 'y'], ['ff', 'rc'], ['x', 'gr'], ['h', 'rd'], ['th', 'pt'], ['nn', 'nc'],
+ ['qu', 'ph'], ['rm', 'pp'], ['sc', 'k'], ['ns', 'rn'], ['mm', 'ng'], ['z', 'ck'],
+ ]
+
+ const end = [
+ ['r', 'rry'], ['n', 'gh'], ['t', 'wl'], ['l', 'lk'], ['te', 'nge'], ['nt', 'ft'],
+ ['m', 'sk'], ['d', 'wn'], ['s', 'na'], ['re', 'be'], ['ne', 'gy'], ['p', 'rm'],
+ ['st', 'ny'], ['y', 'cs'], ['w', 'sm'], ['se', 'nch'], ['ck', 'f'], ['nd', 'ld'],
+ ['ll', 'dge'], ['ry', 'ght'], ['de', 'rk'], ['ss', 'ze'], ['c', 'th'], ['ve', 'ff'],
+ ['g', 'ch'], ['le', 'ble'], ['nce', 'rn'], ['sh', 'tch'], ['ty', 'mp'], ['ce', 'lt'],
+ ['ge', 'pe'], ['ng', 'nk'], ['ct', 'k'], ['b', 'ke'], ['me', 'rd'], ['rt', 'x'],
+ ]
+
+ const entropy = getEntropy()
+ const minEntropy = Math.log2(36 ** 4 * 6 ** 3)
+ const entropyCheck = document.getElementById('pseudo-entropy-check')
+
+ let useEntropy = false
+
+ if (entropyCheck.checked) {
+ useEntropy = true
+ }
+
+ //
+ const len = Math.ceil(entropy / minEntropy)
+
+ let pass = []
+
+ // There is probably a cleaner way to do this, but at least it's readable.
+ for (let i = 0; i < len; i++) {
+ let idx1 = secRand(start.length, useEntropy)
+ let idx2 = secRand(start[idx1].length, useEntropy)
+ let tmp = start[idx1][idx2]
+
+ idx1 = secRand(vowel.length, useEntropy)
+ idx2 = secRand(vowel[idx1].length, useEntropy)
+ tmp += vowel[idx1][idx2]
+
+ idx1 = secRand(middle.length, useEntropy)
+ idx2 = secRand(middle[idx1].length, useEntropy)
+ tmp += middle[idx1][idx2]
+
+ idx1 = secRand(vowel.length, useEntropy)
+ idx2 = secRand(vowel[idx1].length, useEntropy)
+ tmp += vowel[idx1][idx2]
+
+ idx1 = secRand(middle.length, useEntropy)
+ idx2 = secRand(middle[idx1].length, useEntropy)
+ tmp += middle[idx1][idx2]
+
+ idx1 = secRand(vowel.length, useEntropy)
+ idx2 = secRand(vowel[idx1].length, useEntropy)
+ tmp += vowel[idx1][idx2]
+
+ idx1 = secRand(end.length, useEntropy)
+ idx2 = secRand(end[idx1].length, useEntropy)
+ tmp += end[idx1][idx2]
+
+ pass.push(tmp)
+ }
+
+ pass = pass.join('-')
+
+ return [pass, pass.length, Math.floor(len * minEntropy)]
+}
+
/**
* Generate a Letterblock password. Contains checksum.
* @returns {Array} The password string, the length of the password, and the entropy of the password.
@@ -1416,6 +1506,8 @@ function generatePseudowords() {
displayCheck = true
} else if (pseudo === 'Daefen') {
ret = generateDaefen()
+ } else if (pseudo === 'Lepron') {
+ ret = generateLepron()
} else if (pseudo === 'Letterblock Diceware') {
ret = generateLetterblock()
displayCheck = true