The output from the password form is filtered through the the_content filter when you call the_content() in your template.
That means it also goes through the wpautop() function that wraps <p></p> around your submit button with this code:
// Rebuild the content as a string, wrapping every bit with a <p>.
foreach ( $pees as $tinkle ) {
$pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
}
You can move your submit button inside your <div></div> part or try to remove the wpautotop filtering only when the password form is displayed.
Another approach would be to remove the <p></p> tags around your input elements:
add_filter( 'the_content', function( $content )
{
// Check if we have an input element in the content
if( false !== strpos( $content, '<input ' ) )
$content = preg_replace('|<p>\s*(<input[^>]+/?>)\s*</p>|', "$1", $content );
return $content;
}, 11 );
where we use a priority later than 10.