diceware: add passphrase generator

This commit is contained in:
Harsh Shandilya 2021-12-10 13:59:32 +05:30
parent ab8f6a43ee
commit c5436b543d
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
3 changed files with 77 additions and 0 deletions

View file

@ -1,3 +1,9 @@
public final class dev/msfjarvis/aps/passgen/diceware/DicewarePassphraseGenerator {
public static final field DIGITS I
public fun <init> (Ldev/msfjarvis/aps/passgen/diceware/Die;Ljava/io/InputStream;)V
public final fun generatePassphrase (IC)Ljava/lang/String;
}
public final class dev/msfjarvis/aps/passgen/diceware/Die { public final class dev/msfjarvis/aps/passgen/diceware/Die {
public fun <init> (ILdev/msfjarvis/aps/passgen/diceware/RandomIntGenerator;)V public fun <init> (ILdev/msfjarvis/aps/passgen/diceware/RandomIntGenerator;)V
public final fun roll ()I public final fun roll ()I

View file

@ -0,0 +1,42 @@
/*
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
* SPDX-License-Identifier: GPL-3.0-only
*/
package dev.msfjarvis.aps.passgen.diceware
import java.io.InputStream
import javax.inject.Inject
/**
* Password generator implementing the Diceware passphrase generation mechanism. For detailed
* information on how this works, see https://theworld.com/~reinhold/diceware.html.
*/
public class DicewarePassphraseGenerator
@Inject
constructor(
private val die: Die,
wordList: InputStream,
) {
private val wordMap = WordListParser.parse(wordList)
/** Generates a passphrase with [wordCount] words. */
public fun generatePassphrase(wordCount: Int, separator: Char): String {
return StringBuilder()
.apply {
repeat(wordCount) { idx ->
append(wordMap[die.rollMultiple(DIGITS)])
if (idx < wordCount - 1) append(separator)
}
}
.toString()
.trimEnd()
}
private companion object {
/** Number of digits used by indices in the default wordlist. */
const val DIGITS: Int = 5
}
}

View file

@ -0,0 +1,29 @@
/*
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
* SPDX-License-Identifier: GPL-3.0-only
*/
package dev.msfjarvis.aps.passgen.diceware
import kotlin.random.Random
import kotlin.test.assertEquals
import org.junit.Test
class DicewarePassphraseGeneratorTest {
/** Pre-seeded [Random] instance to ensure tests are deterministic. */
private val random = Random(1_00_000)
private val intGenerator = RandomIntGenerator { it.random(random) }
@Test
fun generate_passphrase() {
val die = Die(6, intGenerator)
val generator =
DicewarePassphraseGenerator(
die,
WordListParserTest.getDefaultWordList(),
)
assertEquals("salvation_cozily_croon_trustee_fidgety", generator.generatePassphrase(5, '_'))
}
}