diff --git a/MasterPassword/Java/masterpassword-algorithm/pom.xml b/MasterPassword/Java/masterpassword-algorithm/pom.xml
new file mode 100644
index 00000000..82a1ad0b
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/pom.xml
@@ -0,0 +1,49 @@
+
+
+
+ 4.0.0
+
+
+
+ com.lyndir.lhunath.masterpassword
+ masterpassword
+ GIT-SNAPSHOT
+
+
+ Master Password Algorithm Implementation
+ The implementation of the Master Password algorithm
+
+ com.lyndir.lhunath.masterpassword
+ masterpassword-algorithm
+ jar
+
+
+
+
+
+
+ com.lyndir.lhunath.opal
+ opal-system
+ GIT-SNAPSHOT
+
+
+ com.lyndir.lhunath.opal
+ opal-crypto
+ GIT-SNAPSHOT
+
+
+
+
+ net.sf.plist
+ property-list
+ svn-SNAPSHOT
+
+
+ com.lambdaworks
+ scrypt
+ 1.3.2
+
+
+
+
+
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementFeature.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementFeature.java
new file mode 100644
index 00000000..4261f916
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementFeature.java
@@ -0,0 +1,14 @@
+package com.lyndir.lhunath.masterpassword;
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public enum MPElementFeature {
+
+ /** Export the key-protected content data. */
+ ExportContent,
+ /** Never export content. */
+ DevicePrivate,
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementType.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementType.java
new file mode 100644
index 00000000..0c3fb45b
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementType.java
@@ -0,0 +1,79 @@
+package com.lyndir.lhunath.masterpassword;
+
+import com.google.common.collect.ImmutableSet;
+import com.lyndir.lhunath.opal.system.logging.Logger;
+import java.util.Set;
+
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public enum MPElementType {
+
+ GeneratedMaximum( "Maximum Security Password", "Maximum", "20 characters, contains symbols.", MPElementTypeClass.Generated ),
+ GeneratedLong( "Long Password", "Long", "Copy-friendly, 14 characters, contains symbols.", MPElementTypeClass.Generated ),
+ GeneratedMedium( "Medium Password", "Medium", "Copy-friendly, 8 characters, contains symbols.", MPElementTypeClass.Generated ),
+ GeneratedShort( "Short Password", "Short", "Copy-friendly, 4 characters, no symbols.", MPElementTypeClass.Generated ),
+ GeneratedBasic( "Basic Password", "Basic", "8 characters, no symbols.", MPElementTypeClass.Generated ),
+ GeneratedPIN( "PIN", "PIN", "4 numbers.", MPElementTypeClass.Generated ),
+
+ StoredPersonal( "Personal Password", "Personal", "AES-encrypted, exportable.", MPElementTypeClass.Stored, MPElementFeature.ExportContent ),
+ StoredDevicePrivate( "Device Private Password", "Private", "AES-encrypted, not exported.", MPElementTypeClass.Stored, MPElementFeature.DevicePrivate );
+
+ static final Logger logger = Logger.get( MPElementType.class );
+
+ private final MPElementTypeClass typeClass;
+ private final Set typeFeatures;
+ private final String name;
+ private final String shortName;
+ private final String description;
+
+ MPElementType(final String name, final String shortName, final String description, final MPElementTypeClass typeClass, final MPElementFeature... typeFeatures) {
+
+ this.name = name;
+ this.shortName = shortName;
+ this.typeClass = typeClass;
+ this.description = description;
+
+ ImmutableSet.Builder typeFeaturesBuilder = ImmutableSet.builder();
+ for (final MPElementFeature typeFeature : typeFeatures)
+ typeFeaturesBuilder.add( typeFeature );
+ this.typeFeatures = typeFeaturesBuilder.build();
+ }
+
+ public MPElementTypeClass getTypeClass() {
+
+ return typeClass;
+ }
+
+ public Set getTypeFeatures() {
+
+ return typeFeatures;
+ }
+
+ public String getName() {
+
+ return name;
+ }
+
+ public String getShortName() {
+
+ return shortName;
+ }
+
+ public String getDescription() {
+
+ return description;
+ }
+
+ public static MPElementType forName(final String name) {
+
+ for (final MPElementType type : values())
+ if (type.getName().equals( name ))
+ return type;
+
+ throw logger.bug( "Element type not known: %s", name );
+ }
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementTypeClass.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementTypeClass.java
new file mode 100644
index 00000000..1fbebeea
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPElementTypeClass.java
@@ -0,0 +1,27 @@
+package com.lyndir.lhunath.masterpassword;
+
+import com.lyndir.lhunath.masterpassword.entity.*;
+
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public enum MPElementTypeClass {
+
+ Generated(MPElementGeneratedEntity.class),
+ Stored(MPElementStoredEntity.class);
+
+ private final Class extends MPElementEntity> entityClass;
+
+ MPElementTypeClass(final Class extends MPElementEntity> entityClass) {
+
+ this.entityClass = entityClass;
+ }
+
+ public Class extends MPElementEntity> getEntityClass() {
+
+ return entityClass;
+ }
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplate.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplate.java
new file mode 100644
index 00000000..2027c090
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplate.java
@@ -0,0 +1,41 @@
+package com.lyndir.lhunath.masterpassword;
+
+import com.google.common.collect.ImmutableList;
+import com.lyndir.lhunath.opal.system.util.MetaObject;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public class MPTemplate extends MetaObject {
+
+ private final List template;
+
+ public MPTemplate(final String template, final Map characterClasses) {
+
+ ImmutableList.Builder builder = ImmutableList.builder();
+ for (int i = 0; i < template.length(); ++i)
+ builder.add( characterClasses.get( template.charAt( i ) ) );
+
+ this.template = builder.build();
+ }
+
+ public MPTemplate(final List template) {
+
+ this.template = template;
+ }
+
+ public MPTemplateCharacterClass getCharacterClassAtIndex(final int index) {
+
+ return template.get( index );
+ }
+
+ public int length() {
+
+ return template.size();
+ }
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplateCharacterClass.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplateCharacterClass.java
new file mode 100644
index 00000000..24545e30
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplateCharacterClass.java
@@ -0,0 +1,33 @@
+package com.lyndir.lhunath.masterpassword;
+
+import com.lyndir.lhunath.opal.system.util.MetaObject;
+import com.lyndir.lhunath.opal.system.util.ObjectMeta;
+
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public class MPTemplateCharacterClass extends MetaObject {
+
+ private final char identifier;
+ @ObjectMeta(useFor = { })
+ private final char[] characters;
+
+ public MPTemplateCharacterClass(final char identifier, final char[] characters) {
+
+ this.identifier = identifier;
+ this.characters = characters;
+ }
+
+ public char getIdentifier() {
+
+ return identifier;
+ }
+
+ public char getCharacterAtRollingIndex(final int index) {
+
+ return characters[index % characters.length];
+ }
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplates.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplates.java
new file mode 100644
index 00000000..4986ca4d
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MPTemplates.java
@@ -0,0 +1,103 @@
+package com.lyndir.lhunath.masterpassword;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Closeables;
+import com.lyndir.lhunath.opal.system.logging.Logger;
+import com.lyndir.lhunath.opal.system.util.MetaObject;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+import net.sf.plist.*;
+import net.sf.plist.io.PropertyListException;
+import net.sf.plist.io.PropertyListParser;
+
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public class MPTemplates extends MetaObject {
+
+ static final Logger logger = Logger.get( MPTemplates.class );
+
+ private final Map> templates;
+
+ public MPTemplates(final Map> templates) {
+
+ this.templates = templates;
+ }
+
+ public static MPTemplates loadFromPList(final String templateResource) {
+
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+ InputStream templateStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( templateResource );
+ try {
+ NSObject plistObject = PropertyListParser.parse( templateStream );
+ Preconditions.checkState( NSDictionary.class.isAssignableFrom( plistObject.getClass() ) );
+ NSDictionary plist = (NSDictionary) plistObject;
+
+ NSDictionary characterClassesDict = (NSDictionary) plist.get( "MPCharacterClasses" );
+ NSDictionary templatesDict = (NSDictionary) plist.get( "MPElementGeneratedEntity" );
+
+ ImmutableMap.Builder characterClassesBuilder = ImmutableMap.builder();
+ for (final Map.Entry characterClassEntry : characterClassesDict.entrySet()) {
+ String key = characterClassEntry.getKey();
+ NSObject value = characterClassEntry.getValue();
+ Preconditions.checkState( key.length() == 1 );
+ Preconditions.checkState( NSString.class.isAssignableFrom( value.getClass() ));
+
+ char character = key.charAt( 0 );
+ char[] characterClass = ((NSString)value).getValue().toCharArray();
+ characterClassesBuilder.put( character, new MPTemplateCharacterClass( character, characterClass ) );
+ }
+ ImmutableMap characterClasses = characterClassesBuilder.build();
+
+ ImmutableMap.Builder> templatesBuilder = ImmutableMap.builder();
+ for (final Map.Entry template : templatesDict.entrySet()) {
+ String key = template.getKey();
+ NSObject value = template.getValue();
+ Preconditions.checkState( NSArray.class.isAssignableFrom( value.getClass() ) );
+
+ MPElementType type = MPElementType.forName( key );
+ List templateStrings = ((NSArray) value).getValue();
+
+ ImmutableList.Builder typeTemplatesBuilder = ImmutableList.builder();
+ for (final NSObject templateString : templateStrings)
+ typeTemplatesBuilder.add( new MPTemplate( ((NSString) templateString).getValue(), characterClasses ) );
+
+ templatesBuilder.put( type, typeTemplatesBuilder.build() );
+ }
+ ImmutableMap> templates = templatesBuilder.build();
+
+ return new MPTemplates( templates );
+ }
+ catch (PropertyListException e) {
+ logger.err( e, "Could not parse templates from: %s", templateResource );
+ throw Throwables.propagate( e );
+ }
+ catch (IOException e) {
+ logger.err( e, "Could not read templates from: %s", templateResource );
+ throw Throwables.propagate( e );
+ }
+ finally {
+ Closeables.closeQuietly( templateStream );
+ }
+ }
+
+ public MPTemplate getTemplateForTypeAtRollingIndex(final MPElementType type, final int templateIndex) {
+
+ List typeTemplates = templates.get( type );
+
+ return typeTemplates.get( templateIndex % typeTemplates.size() );
+ }
+
+ public static void main(final String... arguments) {
+
+ loadFromPList( "templates.plist" );
+ }
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MasterPassword.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MasterPassword.java
new file mode 100644
index 00000000..d18bf362
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/MasterPassword.java
@@ -0,0 +1,128 @@
+package com.lyndir.lhunath.masterpassword;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Bytes;
+import com.lambdaworks.crypto.SCrypt;
+import com.lyndir.lhunath.opal.crypto.CryptUtils;
+import com.lyndir.lhunath.opal.system.*;
+import com.lyndir.lhunath.opal.system.logging.Logger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.security.GeneralSecurityException;
+
+
+/**
+ * Implementation of the Master Password algorithm.
+ *
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public abstract class MasterPassword {
+
+ static final Logger logger = Logger.get( MasterPassword.class );
+ private static final int MP_N = 32768;
+ private static final int MP_r = 8;
+ private static final int MP_p = 2;
+ private static final int MP_dkLen = 64;
+ private static final Charset MP_charset = Charsets.UTF_8;
+ private static final ByteOrder MP_byteOrder = ByteOrder.BIG_ENDIAN;
+ private static final MessageDigests MP_hash = MessageDigests.SHA256;
+ private static final MessageAuthenticationDigests MP_mac = MessageAuthenticationDigests.HmacSHA256;
+ private static final MPTemplates templates = MPTemplates.loadFromPList( "templates.plist" );
+
+ public static byte[] keyForPassword(final String password, final String username) {
+
+ long start = System.currentTimeMillis();
+ byte[] nusernameLengthBytes = ByteBuffer.allocate( Integer.SIZE / Byte.SIZE )
+ .order( MP_byteOrder )
+ .putInt( username.length() )
+ .array();
+ byte[] salt = Bytes.concat( "com.lyndir.masterpassword".getBytes( MP_charset ), //
+ nusernameLengthBytes, //
+ username.getBytes( MP_charset ) );
+
+ try {
+ byte[] key = SCrypt.scrypt( password.getBytes( MP_charset ), salt, MP_N, MP_r, MP_p, MP_dkLen );
+ logger.trc( "User: %s, password: %s derives to key ID: %s (took %.2fs)", username, password,
+ CodeUtils.encodeHex( keyIDForKey( key ) ), (double) (System.currentTimeMillis() - start) / 1000 );
+
+ return key;
+ }
+ catch (GeneralSecurityException e) {
+ throw logger.bug( e );
+ }
+ }
+
+ public static byte[] subkeyForKey(final byte[] key, final int subkeyLength) {
+
+ byte[] subkey = new byte[Math.min( subkeyLength, key.length )];
+ System.arraycopy( key, 0, subkey, 0, subkey.length );
+
+ return subkey;
+ }
+
+ public static byte[] keyIDForPassword(final String password, final String username) {
+
+ return keyIDForKey( keyForPassword( password, username ) );
+ }
+
+ public static byte[] keyIDForKey(final byte[] key) {
+
+ return MP_hash.of( key );
+ }
+
+ public static String generateContent(final MPElementType type, final String name, final byte[] key, int counter) {
+
+ Preconditions.checkArgument( type.getTypeClass() == MPElementTypeClass.Generated );
+ Preconditions.checkArgument( !name.isEmpty() );
+ Preconditions.checkArgument( key.length > 0 );
+
+ if (counter == 0)
+ counter = (int) (System.currentTimeMillis() / (300 * 1000)) * 300;
+
+ byte[] nameLengthBytes = ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( MP_byteOrder ).putInt( name.length() ).array();
+ byte[] counterBytes = ByteBuffer.allocate( Integer.SIZE / Byte.SIZE ).order( MP_byteOrder ).putInt( counter ).array();
+ logger.trc( "seed from: hmac-sha256(%s, 'com.lyndir.masterpassword' | %s | %s | %s)", CryptUtils.encodeBase64( key ),
+ CodeUtils.encodeHex( nameLengthBytes ), name, CodeUtils.encodeHex( counterBytes ) );
+ byte[] seed = MP_mac.of( key, Bytes.concat( "com.lyndir.masterpassword".getBytes( MP_charset ), //
+ nameLengthBytes, //
+ name.getBytes( MP_charset ), //
+ counterBytes ) );
+ logger.trc( "seed is: %s", CryptUtils.encodeBase64( seed ) );
+
+ Preconditions.checkState( seed.length > 0 );
+ int templateIndex = seed[0] & 0xFF; // Mask the integer's sign.
+ MPTemplate template = templates.getTemplateForTypeAtRollingIndex( type, templateIndex );
+ logger.trc( "type: %s, template: %s", type, template );
+
+ StringBuilder password = new StringBuilder( template.length() );
+ for (int i = 0; i < template.length(); ++i) {
+ int characterIndex = seed[i + 1] & 0xFF; // Mask the integer's sign.
+ MPTemplateCharacterClass characterClass = template.getCharacterClassAtIndex( i );
+ char passwordCharacter = characterClass.getCharacterAtRollingIndex( characterIndex );
+ logger.trc( "class: %s, index: %d, byte: 0x%02X, chosen password character: %s", characterClass, characterIndex, seed[i + 1],
+ passwordCharacter );
+
+ password.append( passwordCharacter );
+ }
+
+ return password.toString();
+ }
+
+ public static void main(final String... arguments) {
+
+ String masterPassword = "test-mp";
+ String username = "test-user";
+ String siteName = "test-site";
+ MPElementType siteType = MPElementType.GeneratedLong;
+ int siteCounter = 42;
+
+ String sitePassword = generateContent( siteType, siteName, keyForPassword( masterPassword, username ), siteCounter );
+
+ logger.inf( "master password: %s, username: %s\nsite name: %s, site type: %s, site counter: %d\n => site password: %s",
+ masterPassword, username, siteName, siteType, siteCounter, sitePassword );
+ }
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementEntity.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementEntity.java
new file mode 100644
index 00000000..b047bc04
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementEntity.java
@@ -0,0 +1,10 @@
+package com.lyndir.lhunath.masterpassword.entity;
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public class MPElementEntity {
+
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementGeneratedEntity.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementGeneratedEntity.java
new file mode 100644
index 00000000..99d4c43b
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementGeneratedEntity.java
@@ -0,0 +1,10 @@
+package com.lyndir.lhunath.masterpassword.entity;
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public class MPElementGeneratedEntity extends MPElementEntity {
+
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementStoredEntity.java b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementStoredEntity.java
new file mode 100644
index 00000000..0a1e7873
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/java/com/lyndir/lhunath/masterpassword/entity/MPElementStoredEntity.java
@@ -0,0 +1,10 @@
+package com.lyndir.lhunath.masterpassword.entity;
+
+/**
+ * 07 04, 2012
+ *
+ * @author lhunath
+ */
+public class MPElementStoredEntity extends MPElementEntity {
+
+}
diff --git a/MasterPassword/Java/masterpassword-algorithm/src/main/resources/templates.plist b/MasterPassword/Java/masterpassword-algorithm/src/main/resources/templates.plist
new file mode 120000
index 00000000..638eca35
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/src/main/resources/templates.plist
@@ -0,0 +1 @@
+../../../../../../Resources/ciphers.plist
\ No newline at end of file
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementFeature.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementFeature.class
new file mode 100644
index 00000000..2c4251cd
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementFeature.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementType.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementType.class
new file mode 100644
index 00000000..7b5b1a09
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementType.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementTypeClass.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementTypeClass.class
new file mode 100644
index 00000000..86cef427
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPElementTypeClass.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplate.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplate.class
new file mode 100644
index 00000000..74216720
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplate.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplateCharacterClass.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplateCharacterClass.class
new file mode 100644
index 00000000..486312ba
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplateCharacterClass.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplates.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplates.class
new file mode 100644
index 00000000..92a9eb57
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MPTemplates.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MasterPassword.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MasterPassword.class
new file mode 100644
index 00000000..3c44d658
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/MasterPassword.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementEntity.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementEntity.class
new file mode 100644
index 00000000..e7dfd83e
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementEntity.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementGeneratedEntity.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementGeneratedEntity.class
new file mode 100644
index 00000000..292bdded
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementGeneratedEntity.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementStoredEntity.class b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementStoredEntity.class
new file mode 100644
index 00000000..ef61b341
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/classes/com/lyndir/lhunath/masterpassword/entity/MPElementStoredEntity.class differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/classes/templates.plist b/MasterPassword/Java/masterpassword-algorithm/target/classes/templates.plist
new file mode 100644
index 00000000..f8d64d39
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/target/classes/templates.plist
@@ -0,0 +1,78 @@
+
+
+
+
+ MPElementGeneratedEntity
+
+ Maximum Security Password
+
+ anoxxxxxxxxxxxxxxxxx
+ axxxxxxxxxxxxxxxxxno
+
+ Long Password
+
+ CvcvnoCvcvCvcv
+ CvcvCvcvnoCvcv
+ CvcvCvcvCvcvno
+ CvccnoCvcvCvcv
+ CvccCvcvnoCvcv
+ CvccCvcvCvcvno
+ CvcvnoCvccCvcv
+ CvcvCvccnoCvcv
+ CvcvCvccCvcvno
+ CvcvnoCvcvCvcc
+ CvcvCvcvnoCvcc
+ CvcvCvcvCvccno
+ CvccnoCvccCvcv
+ CvccCvccnoCvcv
+ CvccCvccCvcvno
+ CvcvnoCvccCvcc
+ CvcvCvccnoCvcc
+ CvcvCvccCvccno
+ CvccnoCvcvCvcc
+ CvccCvcvnoCvcc
+ CvccCvcvCvccno
+
+ Medium Password
+
+ CvcnoCvc
+ CvcCvcno
+
+ Short Password
+
+ Cvcn
+
+ Basic Password
+
+ aaanaaan
+ aannaaan
+ aaannaaa
+
+ PIN
+
+ nnnn
+
+
+ MPCharacterClasses
+
+ V
+ AEIOU
+ C
+ BCDFGHJKLMNPQRSTVWXYZ
+ v
+ aeiou
+ c
+ bcdfghjklmnpqrstvwxyz
+ A
+ AEIOUBCDFGHJKLMNPQRSTVWXYZ
+ a
+ AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz
+ n
+ 0123456789
+ o
+ @&%?,=[]_:-+*$#!'^~;()/.
+ x
+ AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()
+
+
+
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/masterpassword-algorithm-GIT-SNAPSHOT.jar b/MasterPassword/Java/masterpassword-algorithm/target/masterpassword-algorithm-GIT-SNAPSHOT.jar
new file mode 100644
index 00000000..99e5ca3b
Binary files /dev/null and b/MasterPassword/Java/masterpassword-algorithm/target/masterpassword-algorithm-GIT-SNAPSHOT.jar differ
diff --git a/MasterPassword/Java/masterpassword-algorithm/target/maven-archiver/pom.properties b/MasterPassword/Java/masterpassword-algorithm/target/maven-archiver/pom.properties
new file mode 100644
index 00000000..35d7d212
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-algorithm/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Wed Jul 04 23:49:38 CEST 2012
+version=GIT-SNAPSHOT
+groupId=com.lyndir.lhunath.masterpassword
+artifactId=masterpassword-algorithm
diff --git a/MasterPassword/Java/masterpassword-cli/pom.xml b/MasterPassword/Java/masterpassword-cli/pom.xml
new file mode 100644
index 00000000..86d7bba8
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-cli/pom.xml
@@ -0,0 +1,80 @@
+
+
+
+ 4.0.0
+
+
+
+ com.lyndir.lhunath.masterpassword
+ masterpassword
+ GIT-SNAPSHOT
+
+
+ Master Password CLI
+ A CLI interface to the Master Password algorithm
+
+ com.lyndir.lhunath.masterpassword
+ masterpassword-cli
+ jar
+
+
+
+
+
+ src/main/scripts
+ true
+ ${project.build.directory}
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ com.lyndir.lhunath.masterpassword.CLI
+ true
+ lib/
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.4
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/lib
+
+
+
+
+
+
+
+
+
+
+
+
+ com.lyndir.lhunath.masterpassword
+ masterpassword-algorithm
+ GIT-SNAPSHOT
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+
+
+
diff --git a/MasterPassword/Java/masterpassword-cli/src/main/java/com/lyndir/lhunath/masterpassword/CLI.java b/MasterPassword/Java/masterpassword-cli/src/main/java/com/lyndir/lhunath/masterpassword/CLI.java
new file mode 100644
index 00000000..735692bf
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-cli/src/main/java/com/lyndir/lhunath/masterpassword/CLI.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2008, Maarten Billemont
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.lyndir.lhunath.masterpassword;
+
+import com.google.common.io.LineReader;
+import com.lyndir.lhunath.opal.system.logging.Logger;
+import com.lyndir.lhunath.opal.system.util.ConversionUtils;
+import java.io.*;
+import java.util.Arrays;
+
+
+/**
+ * Jun 10, 2008
+ *
+ * @author mbillemo
+ */
+public class CLI {
+
+ static final Logger logger = Logger.get( CLI.class );
+
+ public static void main(final String[] args)
+ throws IOException {
+
+ InputStream in = System.in;
+
+ /* Arguments. */
+ String userName = null, siteName = null;
+ int counter = 1;
+ MPElementType type = MPElementType.GeneratedLong;
+ boolean typeArg = false, counterArg = false, userNameArg = false;
+ for (final String arg : Arrays.asList( args ))
+ if ("-t".equals( arg ) || "--type".equals( arg ))
+ typeArg = true;
+ else if (typeArg) {
+ if ("list".equalsIgnoreCase( arg )) {
+ System.out.format( "%30s | %s\n", "type", "description" );
+ for (final MPElementType aType : MPElementType.values())
+ System.out.format( "%30s | %s\n", aType.getName(), aType.getDescription() );
+ System.exit( 0 );
+ }
+
+ type = MPElementType.forName( arg );
+ typeArg = false;
+ } else if ("-c".equals( arg ) || "--counter".equals( arg ))
+ counterArg = true;
+ else if (counterArg) {
+ counter = ConversionUtils.toIntegerNN( arg );
+ counterArg = false;
+ } else if ("-u".equals( arg ) || "--username".equals( arg ))
+ userNameArg = true;
+ else if (userNameArg) {
+ userName = arg;
+ userNameArg = false;
+ } else if ("-h".equals( arg ) || "--help".equals( arg )) {
+ System.out.println();
+ System.out.println( "\tMaster Password CLI" );
+ System.out.println( "\t\tLyndir" );
+
+ System.out.println( "[options] [site name]" );
+ System.out.println();
+ System.out.println( "Available options:" );
+ System.out.println( "\t-t | --type [site password type]" );
+ System.out.format( "\t\tDefault: %s. The password type to use for this site.\n", type.getName() );
+ System.out.println( "\t\tUse 'list' to see the available types." );
+
+ System.out.println();
+ System.out.println( "\t-c | --counter [site counter]" );
+ System.out.format( "\t\tDefault: %d. The counter to use for this site.\n", counter );
+ System.out.println( "\t\tIncrement the counter if you need a new password." );
+
+ System.out.println();
+ System.out.println( "\t-u | --username [user's name]" );
+ System.out.println( "\t\tDefault: asked. The name of the current user." );
+
+ System.out.println();
+ return;
+ } else
+ siteName = arg;
+ LineReader lineReader = new LineReader( new InputStreamReader( System.in ) );
+ if (siteName == null) {
+ System.out.print( "Site name: " );
+ siteName = lineReader.readLine();
+ }
+ if (userName == null) {
+ System.out.print( "User's name: " );
+ userName = lineReader.readLine();
+ }
+ System.out.print( "User's master password: " );
+ String masterPassword = lineReader.readLine();
+
+ String sitePassword = MasterPassword.generateContent( type, siteName, MasterPassword.keyForPassword( masterPassword, userName ),
+ counter );
+ System.out.println( sitePassword );
+ }
+}
diff --git a/MasterPassword/Java/masterpassword-cli/src/main/resources/logback.xml b/MasterPassword/Java/masterpassword-cli/src/main/resources/logback.xml
new file mode 100644
index 00000000..199740fd
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-cli/src/main/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ %-8relative %22c{0} [%-5level] %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MasterPassword/Java/masterpassword-cli/src/main/scripts/mpw b/MasterPassword/Java/masterpassword-cli/src/main/scripts/mpw
new file mode 100755
index 00000000..5374b668
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-cli/src/main/scripts/mpw
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+cd "${BASH_SOURCE[0]%/*}"
+java -jar masterpassword-cli-GIT-SNAPSHOT.jar "$@"
diff --git a/MasterPassword/Java/masterpassword-cli/target/classes/com/lyndir/lhunath/masterpassword/CLI.class b/MasterPassword/Java/masterpassword-cli/target/classes/com/lyndir/lhunath/masterpassword/CLI.class
new file mode 100644
index 00000000..cf9ce4d4
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/classes/com/lyndir/lhunath/masterpassword/CLI.class differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/annotations-7.0.2.jar b/MasterPassword/Java/masterpassword-cli/target/lib/annotations-7.0.2.jar
new file mode 100644
index 00000000..7a28646b
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/annotations-7.0.2.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/asm-3.3.1.jar b/MasterPassword/Java/masterpassword-cli/target/lib/asm-3.3.1.jar
new file mode 100644
index 00000000..f50f03f3
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/asm-3.3.1.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/bcpg-jdk16-1.45.jar b/MasterPassword/Java/masterpassword-cli/target/lib/bcpg-jdk16-1.45.jar
new file mode 100644
index 00000000..2393db82
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/bcpg-jdk16-1.45.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/bcprov-jdk16-1.45.jar b/MasterPassword/Java/masterpassword-cli/target/lib/bcprov-jdk16-1.45.jar
new file mode 100644
index 00000000..38685d51
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/bcprov-jdk16-1.45.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/cglib-2.2.2.jar b/MasterPassword/Java/masterpassword-cli/target/lib/cglib-2.2.2.jar
new file mode 100644
index 00000000..564b9f88
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/cglib-2.2.2.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/guava-r09.jar b/MasterPassword/Java/masterpassword-cli/target/lib/guava-r09.jar
new file mode 100644
index 00000000..30dbc569
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/guava-r09.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/joda-time-1.6.jar b/MasterPassword/Java/masterpassword-cli/target/lib/joda-time-1.6.jar
new file mode 100644
index 00000000..68068a4b
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/joda-time-1.6.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/logback-classic-0.9.28.jar b/MasterPassword/Java/masterpassword-cli/target/lib/logback-classic-0.9.28.jar
new file mode 100644
index 00000000..5398d293
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/logback-classic-0.9.28.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/logback-core-0.9.28.jar b/MasterPassword/Java/masterpassword-cli/target/lib/logback-core-0.9.28.jar
new file mode 100644
index 00000000..f88a1d2d
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/logback-core-0.9.28.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/masterpassword-algorithm-GIT-SNAPSHOT.jar b/MasterPassword/Java/masterpassword-cli/target/lib/masterpassword-algorithm-GIT-SNAPSHOT.jar
new file mode 100644
index 00000000..99e5ca3b
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/masterpassword-algorithm-GIT-SNAPSHOT.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/objenesis-1.2.jar b/MasterPassword/Java/masterpassword-cli/target/lib/objenesis-1.2.jar
new file mode 100644
index 00000000..fb04d7fa
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/objenesis-1.2.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/opal-crypto-GIT-SNAPSHOT.jar b/MasterPassword/Java/masterpassword-cli/target/lib/opal-crypto-GIT-SNAPSHOT.jar
new file mode 100644
index 00000000..13faf3d1
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/opal-crypto-GIT-SNAPSHOT.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/opal-system-GIT-SNAPSHOT.jar b/MasterPassword/Java/masterpassword-cli/target/lib/opal-system-GIT-SNAPSHOT.jar
new file mode 100644
index 00000000..ef8e431d
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/opal-system-GIT-SNAPSHOT.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/property-list-svn-SNAPSHOT.jar b/MasterPassword/Java/masterpassword-cli/target/lib/property-list-svn-SNAPSHOT.jar
new file mode 100644
index 00000000..452930e9
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/property-list-svn-SNAPSHOT.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/scrypt-1.3.2.jar b/MasterPassword/Java/masterpassword-cli/target/lib/scrypt-1.3.2.jar
new file mode 100644
index 00000000..98559cd8
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/scrypt-1.3.2.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/lib/slf4j-api-1.6.1.jar b/MasterPassword/Java/masterpassword-cli/target/lib/slf4j-api-1.6.1.jar
new file mode 100644
index 00000000..f1f4fdd2
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/lib/slf4j-api-1.6.1.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/masterpassword-cli-GIT-SNAPSHOT.jar b/MasterPassword/Java/masterpassword-cli/target/masterpassword-cli-GIT-SNAPSHOT.jar
new file mode 100644
index 00000000..d480811d
Binary files /dev/null and b/MasterPassword/Java/masterpassword-cli/target/masterpassword-cli-GIT-SNAPSHOT.jar differ
diff --git a/MasterPassword/Java/masterpassword-cli/target/maven-archiver/pom.properties b/MasterPassword/Java/masterpassword-cli/target/maven-archiver/pom.properties
new file mode 100644
index 00000000..516b7511
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-cli/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Wed Jul 04 23:49:39 CEST 2012
+version=GIT-SNAPSHOT
+groupId=com.lyndir.lhunath.masterpassword
+artifactId=masterpassword-cli
diff --git a/MasterPassword/Java/masterpassword-cli/target/mpw b/MasterPassword/Java/masterpassword-cli/target/mpw
new file mode 100755
index 00000000..5374b668
--- /dev/null
+++ b/MasterPassword/Java/masterpassword-cli/target/mpw
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+cd "${BASH_SOURCE[0]%/*}"
+java -jar masterpassword-cli-GIT-SNAPSHOT.jar "$@"
diff --git a/MasterPassword/Java/pom.xml b/MasterPassword/Java/pom.xml
new file mode 100644
index 00000000..ea98c219
--- /dev/null
+++ b/MasterPassword/Java/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ 4.0.0
+
+
+
+ com.lyndir.lhunath
+ lyndir
+ GIT-SNAPSHOT
+
+
+ Master Password
+ A Java implementation of the Master Password algorithm.
+
+ com.lyndir.lhunath.masterpassword
+ masterpassword
+ GIT-SNAPSHOT
+ pom
+
+
+ masterpassword-algorithm
+ masterpassword-cli
+
+
+