Merge jdk7-b73
authorduke
Wed, 05 Jul 2017 17:01:15 +0200
changeset 3900 ce74bd35ce94
parent 3899 bb6def34ee9a (diff)
parent 3787 d041141e4794 (current diff)
child 3901 a8eba0852ec7
child 3902 e8f92456bc49
child 3903 9decc1272344
child 3922 683ff4d64b7b
child 3934 487e1aa949c4
child 3941 7b53330adf8f
child 3987 2a58cc6c4797
child 3989 73df4e30ad5a
child 3991 4fb4f2670583
child 3993 2438860e7856
child 3998 c66be272f350
Merge
--- a/.hgtags-top-repo	Wed Jul 05 17:00:34 2017 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 17:01:15 2017 +0200
@@ -46,3 +46,4 @@
 82e6c820c51ac27882b77755d42efefdbf1dcda0 jdk7-b69
 175cb3fe615998d1004c6d3fd96e6d2e86b6772d jdk7-b70
 4c36e9853dda27bdac5ef4839a610509fbe31d34 jdk7-b71
+0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72
--- a/README-builds.html	Wed Jul 05 17:00:34 2017 +0200
+++ b/README-builds.html	Wed Jul 05 17:01:15 2017 +0200
@@ -38,12 +38,17 @@
             <ul>
                 <li><a href="#introduction">Introduction</a></li>
                 <li><a href="#MBE">Minimum Build Environments</a></li>
-                <li><a href="#SDBE">Specific Developer Build Environments</a></li>
+                <li><a href="#SDBE">Specific Developer Build Environments</a>
                     <ul>
                         <li><a href="#fedora">Fedora Linux</a> </li>
                         <li><a href="#centos">CentOS Linux</a> </li>
-                        <li><a href="#ubuntu">Ubuntu Linux</a> </li>
+		        <li><a href="#debian">Debian GNU/Linux</a></li>
+			<li><a href="#ubuntu">Ubuntu Linux</a> </li>
+		        <li><a href="#opensuse">OpenSUSE</a></li>
+		        <li><a href="#mandriva">Mandriva</a></li>
+		        <li><a href="#opensolaris">OpenSolaris</a></li>
                     </ul>
+		</li>
                 <li><a href="#directories">Source Directory Structure</a> </li>
                 <li><a href="#building">Build Information</a>
                     <ul>
@@ -209,24 +214,59 @@
             we will try to provide what information we have available to us.
         </blockquote>
         <!-- ------------------------------------------------------ -->
-        <h3><a name="fedora">Fedora 9</a></h3>
+        <h3><a name="fedora">Fedora</a></h3>
         <blockquote>
-            After installing
-            <a href="http://www.fedoraproject.org/">Fedora 9</a>
-            you need to make sure you have
-            the "Software Development" bundle installed, plus the
-            following packages:
-            <blockquote>
-                <ul>
-                    <li>cups devel: Cups Development Package</li>
-                    <li>freetype 2.3+ devel: Freetype 2.3 Development Package</li>
-                    <li>hg: Mercurial, if you need to clone or manage source repositories</li>
-                    <li>ksh: May be needed when using <tt>webrev</tt></li>
-                </ul>
+	  <h4>Fedora 9</h4>
+	  <p>
+	    <blockquote>
+              After installing <a href="http://fedoraproject.org">Fedora</a> 9 
+	      you need to install several build dependencies. The simplest
+	      way to do it is to execute the following commands as user 
+	      <tt>root</tt>:
+	      <p/>
+	      <code>yum-builddep java-openjdk</code>
+	      <p/>
+	      <code>yum install gcc gcc-c++</code>
+	      <p/>
+	      In addition, it's necessary to set a few environment variables for the build:
+
+	      <p/>
+	      <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
             </blockquote>
-            <p>
-            Always a good idea to do a complete Software Update/Refresh
-            after you get all the packages installed.
+	  <h4>Fedora 10</h4>
+	  <p>
+	    <blockquote>
+              After installing <a href="http://fedoraproject.org">Fedora</a> 10 
+	      you need to install several build dependencies. The simplest
+	      way to do it is to execute the following commands as user 
+	      <tt>root</tt>:
+	      <p/>
+	      <code>yum-builddep java-1.6.0-openjdk</code>
+	      <p/>
+	      <code>yum install gcc gcc-c++</code>
+	      <p/>
+	      In addition, it's necessary to set a few environment variables for the build:
+
+	      <p/>
+	      <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
+            </blockquote>
+	  <h4>Fedora 11</h4>
+	  <p>
+	    <blockquote>
+              After installing <a href="http://fedoraproject.org">Fedora</a> 11 
+	      you need to install several build dependencies. The simplest
+	      way to do it is to execute the following commands as user 
+	      <tt>root</tt>:
+	      <p/>
+	      <code>yum-builddep java-1.6.0-openjdk</code>
+	      <p/>
+	      <code>yum install gcc gcc-c++</code>
+	      <p/>
+	      In addition, it's necessary to set a few environment variables for the build:
+
+	      <p/>
+	      <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
+             </blockquote>
         </blockquote>
         <!-- ------------------------------------------------------ -->
         <h3><a name="centos">CentOS 5.2</a></h3>
@@ -269,145 +309,146 @@
             it's needed.
         </blockquote>
         <!-- ------------------------------------------------------ -->
-        <h3><a name="ubuntu">Ubuntu</a></h3>
+        <h3><a name="debian">Debian</a></h3>
+        <blockquote>
+            <h4>Debian 5.0 (Lenny)</h4>
+            <p>
+	      <blockquote>
+		After installing <a href="http://debian.org">Debian</a> 5 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands as user <tt>root</tt>:
+		<p/>
+		<code>aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>aptitude install openjdk-6-jdk libmotif-dev</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+	      </blockquote>
+        </blockquote>
+        <!-- ====================================================== -->
+	<h3><a name="ubuntu">Ubuntu</a></h3>
         <blockquote>
-            In addition to needing the Bootstrap JDK and the Binary Plugs, 
-            when building on Ubuntu you will need to
-            make sure certain packages are installed.
-            In particular, certain X11 packages, make, m4, gawk, gcc 4, 
-            binutils, cups, freetype
-            and alsa.
-            <!-- ------------------------------------------------------ -->
-            <h4>Ubuntu 6.06</h4>
+            <h4>Ubuntu 8.04</h4>
             <p>
-            The following list of packages for Ubuntu 6.06 is a working set that
-            does appear to work. 
+	      <blockquote>
+		After installing <a href="http://ubuntu.org">Ubuntu</a> 8.04 
+		you need to install several build dependencies. 
+		<p/>
+		First, you need to enable the universe repository in the 
+		Software Sources application and reload the repository 
+		information. The Software Sources application is available 
+		under the System/Administration menu. 
+		<p/>
+		The simplest way to install the build dependencies is to 
+		execute the following commands:
+		<p/>
+		<code>sudo aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>sudo aptitude install openjdk-6-jdk</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+              </blockquote>
+           <h4>Ubuntu 8.10</h4>
             <p>
-            <b>Note that it's quite possible that some of these
-                packages are not required, so anyone discovering that some of the
-                packages listed below are NOT required,
-                please let the
-                OpenJDK
-            team know.</b>
+	      <blockquote>
+		After installing <a href="http://ubuntu.org">Ubuntu</a> 8.10 
+		you need to install several build dependencies. The simplest
+		way to do it is to execute the following commands:
+		<p/>
+		<code>sudo aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>sudo aptitude install openjdk-6-jdk</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+             </blockquote>
+           <h4>Ubuntu 9.04</h4>
             <p>
-            All the packages below can be installed with the
-            Synaptic Package manager provided with the base Ubuntu 6.06 release.
-            <blockquote>
-                <ul>
-                    <li>binutils (2.16.1cvs20060117-1ubuntu2.1)</li>
-                    <li>cpp (4:4.0.3-1)</li>
-                    <li>cpp-4.0 (4.0.3-1ubuntu5)</li>
-                    <li>libfreetype6-dev</li>
-                    <li>g++ (4:4.0.3-1)</li>
-                    <li>g++-4.0 (4.0.3-1ubuntu5)</li>
-                    <li>gawk (1:3.1.5-2build1)</li>
-                    <li>gcc (4:4.0.3-1)</li>
-                    <li>gcc-4.0 (4.0.3-1ubuntu5)</li>
-                    <li>libasound2-dev (1.0.10-2ubuntu4)</li>
-                    <li>libc6 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4</li>
-                    <li>libc6-dev (2.3.6-0ubuntu20.4)</li>
-                    <li>libc6-i686 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4</li>
-                    <li>libcupsys2-dev (1.2.2-0ubuntu0.6.06)</li>
-                    <li>libgcrypt11-dev (1.2.2-1)</li>
-                    <li>libgnutls-dev (1.2.9-2ubuntu1.1)</li>
-                    <li>libgnutls12 (1.2.9-2ubuntu1) to 1.2.9-2ubuntu1.1</li>
-                    <li>libgpg-error-dev (1.1-4)</li>
-                    <li>libice-dev (2:1.0.0-0ubuntu2)</li>
-                    <li>liblockfile1 (1.06.1)</li>
-                    <li>libopencdk8-dev (0.5.7-2)</li>
-                    <li>libpopt-dev (1.7-5)</li>
-                    <li>libsm-dev (2:1.0.0-0ubuntu2)</li>
-                    <li>libstdc++6-4.0-dev (4.0.3-1ubuntu5)</li>
-                    <li>libtasn1-2-dev (0.2.17-1ubuntu1)</li>
-                    <li>libx11-dev (2:1.0.0-0ubuntu9)</li>
-                    <li>libxau-dev (1:1.0.0-0ubuntu4)</li>
-                    <li>libxaw-headers (2:1.0.1-0ubuntu3)</li>
-                    <li>libxaw7-dev (2:1.0.1-0ubuntu3)</li>
-                    <li>libxdmcp-dev (1:1.0.0-0ubuntu2)</li>
-                    <li>libxext-dev (2:1.0.0-0ubuntu4)</li>
-                    <li>libxi-dev (2:1.0.0-0ubuntu3) </li>
-                    <li>libxmu-dev (2:1.0.0-0ubuntu3)</li>
-                    <li>libxmu-headers (2:1.0.0-0ubuntu3)</li>
-                    <li>libxmuu-dev (2:1.0.0-0ubuntu3)</li>
-                    <li>libxp-dev (6.8.2-11ubuntu2)</li>
-                    <li>libxpm-dev (1:3.5.4.2-0ubuntu3)</li>
-                    <li>libxrandr-dev (1:1.1.0.2-0ubuntu4)</li>
-                    <li>libxt-dev (1:1.0.0-0ubuntu3)</li>
-                    <li>libxtrap-dev (2:1.0.0-0ubuntu2)</li>
-                    <li>libxtst-dev (2:1.0.1-0ubuntu2)</li>
-                    <li>libxv-dev (2:1.0.1-0ubuntu3)</li>
-                    <li>linux-kernel-headers (2.6.11.2-0ubuntu18)</li>
-                    <li>m4 (1.4.4-1)</li>
-                    <li>make (3.80+3.81.b4-1)</li>
-                    <li>ssl-cert (1.0.13)</li>
-                    <li>x-dev (7.0.4-0ubuntu2)</li>
-                    <li>x11proto-core-dev (7.0.4-0ubuntu2)</li>
-                    <li>x11proto-input-dev (1.3.2-0ubuntu2)</li>
-                    <li>x11proto-kb-dev (1.0.2-0ubuntu2)</li>
-                    <li>x11proto-randr-dev (1.1.2-0ubuntu2)</li>
-                    <li>x11proto-record-dev (1.13.2-0ubuntu2)</li>
-                    <li>x11proto-trap-dev (3.4.3-0ubuntu2)</li>
-                    <li>x11proto-video-dev (2.2.2-0ubuntu2)</li>
-                    <li>x11proto-xext-dev (7.0.2-0ubuntu2)</li>
-                    <li>xlibs-dev (7.0.0-0ubuntu45)</li>
-                    <li>zlib1g-dev (1:1.2.3-6ubuntu4)</li>
-                </ul>
-            </blockquote>
-            <!-- ------------------------------------------------------ -->
-            <h4>Ubuntu 7.04</h4>
+	      <blockquote>
+		After installing <a href="http://ubuntu.org">Ubuntu</a> 9.04 
+		you need to install several build dependencies. The simplest
+		way to do it is to execute the following commands:
+		<p/>
+		<code>sudo aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>sudo aptitude install openjdk-6-jdk</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+             </blockquote>
+        </blockquote>
+        <!-- ====================================================== -->
+        <h3><a name="opensuse">OpenSUSE</a></h3>
+        <blockquote>
+            <h4>OpenSUSE 11.1</h4>
             <p>
-            Using the Synaptic Package Manager, download the following
-            packages (double indented packages are automatically aquired
-            due to package dependencies):
-            <blockquote>
-                <ul>
-                    <li>build-essential</li>
-                    <ul>
-                        <li>dpkg-dev</li>
-                        <li>g++</li>
-                        <li>g++-4.1</li>
-                        <li>libc6-dev</li>
-                        <li>libstdc++6.4.1-dev</li>
-                        <li>linux-libc-dev</li>
-                    </ul>
-                    <li>gawk</li>
-                    <li>m4</li>
-                    <li>libasound2-dev</li>
-                    <li>libcupsys2-dev</li>
-                    <ul>
-                        <li>libgcrypt11-dev</li>
-                        <li>lgnutls-dev</li>
-                        <li>libgpg-error-dev</li>
-                        <li>liblzo-dev</li>
-                        <li>libopencdk8-dev</li>
-                        <li>libpopt-dev</li>
-                        <li>libtasn1-3-dev</li>
-                        <li>zlib1g-dev</li>
-                    </ul>
-                    <li>sun-java6-jdk</li>
-                    <ul>
-                        <li>java-common</li>
-                        <li>libltdl3</li>
-                        <li>odbcinst1debian1</li>
-                        <li>sun-java6-bin</li>
-                        <li>sun-java6-jre</li>
-                        <li>unixodbc</li>
-                    </ul>
-                    <li>xlibs-dev</li>
-                    <ul>
-                        <li>(many)</li>
-                    </ul>
-                    <li>x11proto-print-dev</li>
-                    <li>libxaw7-dev</li>
-                    <ul>
-                        <li>libxaw-headers</li>
-                    </ul>
-                    <li>libxp-dev</li>
-                    <li>libfreetype6-dev</li>
-                </ul>
-            </blockquote>
+	      <blockquote>
+		After installing <a href="http://opensuse.org">OpenSUSE</a> 11.1 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands:
+		<p/>
+		<code>sudo zypper source-install -d java-1_6_0-openjdk</code>
+		<p/>
+		<code>sudo zypper install make</code>
+		<p/>
+		In addition, it is necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
+		<p/>
+		Finally, you need to unset the <code>JAVA_HOME</code> environment variable:
+		<p/>
+		<code>export -n JAVA_HOME</code>
+	      </blockquote>
+	</blockquote>
+        <!-- ====================================================== -->
+        <h3><a name="mandriva">Mandriva</a></h3>
+        <blockquote>
+            <h4>Mandriva Linux One 2009 Spring</h4>
+            <p>
+	      <blockquote>
+		After installing <a href="http://mandriva.org">Mandriva</a> Linux One 2009 Spring 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands as user <tt>root</tt>:
+		<p/>
+		<code>urpmi java-1.6.0-openjdk-devel ant make gcc gcc-c++ freetype-devel zip unzip libcups2-devel libxrender1-devel libalsa2-devel libstc++-static-devel libxtst6-devel libxi-devel</code>
+                <p/>
+		In addition, it is necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
+	      </blockquote>
         </blockquote>
-        <!-- ------------------------------------------------------ -->
+        <!-- ====================================================== -->
+        <h3><a name="opensolaris">OpenSolaris</a></h3>
+        <blockquote>
+            <h4>OpenSolaris 2009.06</h4>
+            <p>
+	      <blockquote>
+		After installing <a href="http://opensolaris.org">OpenSolaris</a> 2009.06 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands:
+		<p/>
+		<code>pfexec pkg install SUNWgmake SUNWj6dev SUNWant sunstudioexpress SUNWcups SUNWzip SUNWunzip SUNWxwhl SUNWxorg-headers SUNWaudh SUNWfreetype2</code>
+                <p/>
+		In addition, it is necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_COMPILER_PATH=/opt/SunStudioExpress/bin/ ALT_CUPS_HEADERS_PATH=/usr/include/</code>
+		<p/>
+		Finally, you need to make sure that the build process can find the Sun Studio compilers:
+		<p/>
+		<code>export PATH=$PATH:/opt/SunStudioExpress/bin/</code>
+	      </blockquote>
+        </blockquote>
+        <!-- ------------------------------------------------------ -->  
         <hr>
         <h2><a name="directories">Source Directory Structure</a></h2>
         <blockquote>
--- a/corba/.hgtags	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/.hgtags	Wed Jul 05 17:01:15 2017 +0200
@@ -46,3 +46,4 @@
 8120d308ec4e805c5588b8d9372844d781c4112d jdk7-b69
 175bd68779546078dbdb6dacd7f0aced79ed22b1 jdk7-b70
 3f1ef7f899ea2aec189c4fb67e5c8fa374437c50 jdk7-b71
+c793a31209263fbb867c23c752599d85c21abb73 jdk7-b72
--- a/corba/make/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -141,12 +141,12 @@
 
 #----- src.zip
 
-SRC_ZIP_FILES = $(shell $(FIND) $(SRC_CLASSES_DIR) \( -name SCCS -o -name \*-template \) -prune -o -type f -print )
+SRC_ZIP_FILES = $(shell $(FIND) $(SRC_CLASSES_DIR) \( -name \*-template \) -prune -o -type f -print )
 
 SRC_ZIP = $(LIB_DIR)/src.zip
 $(SRC_ZIP): $(SRC_ZIP_FILES)
 	abs_src_zip=`cd $(@D) ; pwd`/$(@F) ; \
-	( cd $(SRC_CLASSES_DIR) ; $(FIND) . \( -name SCCS -o -name \*-template \) -prune -o -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ; \
+	( cd $(SRC_CLASSES_DIR) ; $(FIND) . \( -name \*-template \) -prune -o -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ; \
 	( cd $(GENSRC_DIR) ; $(FIND) . -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ;
 
 #----- bin.zip
--- a/corba/make/common/BuildToolJar.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/BuildToolJar.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -24,22 +24,29 @@
 #
 
 # Input: BUILDDIR PACKAGE PKGDIR PROGRAM BUILDTOOL_SOURCE_ROOT BUILDTOOL_MAIN
- 
+
+# All subdirectories under the package root for the tool (max depth 4)
+_WC_DIRS          = * */* */*/* */*/*/*
+
 BUILDTOOL_MAIN_SOURCE_FILE = $(BUILDTOOL_SOURCE_ROOT)/$(BUILDTOOL_MAIN)
 BUILDTOOL_MANIFEST_FILE    = $(BUILDTOOLCLASSDIR)/$(PROGRAM)_manifest.mf
 BUILDTOOL_JAR_FILE         = $(BUILDTOOLJARDIR)/$(PROGRAM).jar
-BUILDTOOL_ALL_FILES       := $(shell $(CD) $(BUILDTOOL_SOURCE_ROOT) \
-    && $(FIND) $(PKGDIR) $(SCM_DIRS_prune) -o -type f -print)
-BUILTTOOL_MAINCLASS = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%))
+BUILTTOOL_MAINCLASS        = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%))
 
-all build: $(BUILDTOOL_JAR_FILE) tool_info
+# Wildcard patterns that find all the sources for this build tool
+BUILDTOOL_WC_PATTERNS      = $(BUILDTOOL_SOURCE_ROOT)/$(PKGDIR)/*.java \
+    $(patsubst %, $(BUILDTOOL_SOURCE_ROOT)/$(PKGDIR)/%/*.java, $(_WC_DIRS))
+
+# Wildcard expansion that finds all the files
+BUILDTOOL_SRC_FILES       := $(wildcard $(BUILDTOOL_WC_PATTERNS))
+
+all build: $(BUILDTOOL_JAR_FILE)
 
 $(BUILDTOOL_MANIFEST_FILE): $(BUILDTOOL_MAIN_SOURCE_FILE)
 	@$(prep-target)
 	$(ECHO) "Main-Class: $(BUILTTOOL_MAINCLASS)" > $@
 
-$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) \
-    $(BUILDTOOL_ALL_FILES:%=$(BUILDTOOL_SOURCE_ROOT)/%)
+$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) $(BUILDTOOL_SRC_FILES)
 	@$(prep-target)
 	@$(MKDIR) -p $(BUILDTOOLCLASSDIR)
 	$(BOOT_JAVAC_CMD) -d $(BUILDTOOLCLASSDIR) \
@@ -49,23 +56,8 @@
 	    $(JAR_JFLAGS) || $(RM) $@
 	@$(java-vm-cleanup)
 
-# Printing out a build tool information line
-define printBuildToolSetting
-if [ "$2" != "" ] ; then $(PRINTF) "%-25s %s\n" "$1:" "$2"; fi
-endef
+clean clobber::
+	$(RM) -r $(BUILDTOOLCLASSDIR)/$(PKGDIR) \
+                 $(BUILDTOOL_MANIFEST_FILE) \
+                 $(BUILDTOOL_JAR_FILE)
 
-# Print out the build tool information
-tool_info:
-	@$(ECHO) "========================================================="
-	@$(call printBuildToolSetting,BUILDTOOL,$(PROGRAM))
-	@$(call printBuildToolSetting,PACKAGE,$(PACKAGE))
-	@$(call printBuildToolSetting,BUILDTOOL_SOURCE_ROOT,$(BUILDTOOL_SOURCE_ROOT))
-	@$(call printBuildToolSetting,BUILTTOOL_MAINCLASS,$(BUILTTOOL_MAINCLASS))
-	@$(call printBuildToolSetting,BUILDTOOL_JAR_FILE,$(BUILDTOOL_JAR_FILE))
-	@$(ECHO) "========================================================="
-
-clean clobber::
-	$(RM) -r $(BUILDTOOLCLASSDIR)/$(PKGDIR)
-	$(RM) $(BUILDTOOL_MANIFEST_FILE)
-	$(RM) $(BUILDTOOL_JAR_FILE)
-
--- a/corba/make/common/CancelImplicits.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/CancelImplicits.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 1998-1999 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -56,11 +56,3 @@
 %: %.sh
 endif
 
-#
-# If you are using RCS, you must set the variable USE_RCS at the make
-# command line. Otherwise we disable RCS.
-#
-ifndef USE_RCS
-%:: %,v
-%:: RCS/%,v
-endif
--- a/corba/make/common/Defs.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/Defs.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -310,125 +310,32 @@
 SUBDIRS_MAKEFLAGS-clobber = INCREMENTAL_BUILD=false
 SUBDIRS_MAKEFLAGS-clean   = INCREMENTAL_BUILD=false
 
-# Current directory
-CURRENT_DIRECTORY := $(shell $(PWD))
-
-# If no timing wanted, we need to define these as empty
-ifdef NO_TIMING
-
-TIMING_ID:=NA
-
-define TIMING_start
-t=0:0:0:0
-endef
-
-define TIMING_end
-time_used=0
-endef
-
-else # NO_TIMING
-
-# Default timing id
-TIMING_ID:=$(shell $(BASENAME) $(CURRENT_DIRECTORY))
-
-# Timing start (must be used in same shell, e.g. same command line)
-#    Defines the shell variable $1 to have the start time.
-define TIMING_start
-$1=`$(DATE) +%j:%H:%M:%S`
-endef
-
-# Timing end (must be used in same shell, e.g. same command line)
-#    Expects shell variable $1 to have been defined as the start time.
-#    Expects shell variable $2 to have timing id string
-#    Sets total_seconds shell variable as the total seconds used.
-#    Sets time_used shell variable to contain format "%dh%dm%ds"
-define TIMING_end
-begTime="$${$1}"; \
-timing_id="$${$2}"; \
-endTime=`$(DATE) +%j:%H:%M:%S`; \
-d1=`$(ECHO) $${begTime} | $(CUT) -d':' -f1 | $(SED) -e 's@^0*@@'`; \
-if [ "$${d1}" = "" ] ; then d1=0; fi; \
-h1=`$(ECHO) $${begTime} | $(CUT) -d':' -f2 | $(SED) -e 's@^0*@@'`; \
-if [ "$${h1}" = "" ] ; then h1=0; fi; \
-m1=`$(ECHO) $${begTime} | $(CUT) -d':' -f3 | $(SED) -e 's@^0*@@'`; \
-if [ "$${m1}" = "" ] ; then m1=0; fi; \
-s1=`$(ECHO) $${begTime} | $(CUT) -d':' -f4 | $(SED) -e 's@^0*@@'`; \
-if [ "$${s1}" = "" ] ; then s1=0; fi; \
-d2=`$(ECHO) $${endTime} | $(CUT) -d':' -f1 | $(SED) -e 's@^0*@@'`; \
-if [ "$${d2}" = "" ] ; then d2=0; fi; \
-h2=`$(ECHO) $${endTime} | $(CUT) -d':' -f2 | $(SED) -e 's@^0*@@'`; \
-if [ "$${h2}" = "" ] ; then h2=0; fi; \
-m2=`$(ECHO) $${endTime} | $(CUT) -d':' -f3 | $(SED) -e 's@^0*@@'`; \
-if [ "$${m2}" = "" ] ; then m2=0; fi; \
-s2=`$(ECHO) $${endTime} | $(CUT) -d':' -f4 | $(SED) -e 's@^0*@@'`; \
-if [ "$${s2}" = "" ] ; then s2=0; fi; \
-t1_secs=`$(EXPR) $${d1} '*' 60 '*' 60 '*' 24 '+' $${h1} '*' 60 '*' 60 \
-		 '+' $${m1} '*' 60 '+' $${s1}`; \
-t2_secs=`$(EXPR) $${d2} '*' 60 '*' 60 '*' 24 '+' $${h2} '*' 60 '*' 60 \
-		 '+' $${m2} '*' 60 '+' $${s2}`; \
-total_seconds=`$(EXPR) $${t2_secs} '-' $${t1_secs}`; \
-if [ "$${total_seconds}" -lt 0 ] ; then total_seconds=0; fi; \
-t_hour=`$(EXPR) $${total_seconds} '/' '(' 60 '*' 60 ')'`h; \
-t_min=`$(EXPR) '(' $${total_seconds} '%' '(' 60 '*' 60 ')' ')' '/' 60`m; \
-t_sec=`$(EXPR) $${total_seconds} '%' 60`s; \
-time_used=$${t_sec}; \
-if [ "$${t_hour}" != "0h" ] ; then \
-time_used=$${t_hour}$${t_min}$${t_sec}; \
-elif [ "$${t_min}" != "0m" ] ; then \
-time_used=$${t_min}$${t_sec}; \
-else \
-time_used=$${t_sec}; \
-fi; \
-$(PRINTF) "  Timing: %05d seconds or %s for %s\n" \
-    $${total_seconds} $${time_used} $${timing_id}
-endef
-
-endif # NO_TIMING
-
 # Given a SUBDIRS list, cd into them and make them
 #   SUBDIRS_MAKEFLAGS      Make settings for a subdir make
 #   SUBDIRS_MAKEFLAGS-$@   Make settings specific to this target
 define SUBDIRS-loop
-@$(ECHO) "Begin Processing SUBDIRS: $(SUBDIRS)"
 @for i in DUMMY $(SUBDIRS) ; do \
   if [ "$$i" != "DUMMY" ] ; then \
-    $(ECHO) ">>>Recursively making "$$i" "$@" @ `$(DATE)` ..."; \
-    timing_id="$(TIMING_ID)-`$(BASENAME) $${i}`"; \
-    $(call TIMING_start,startTime); \
-    curDir=$(CURRENT_DIRECTORY); \
-    $(CD) $$i; $(MAKE) $@ TIMING_ID=$${timing_id} \
-			  $(SUBDIRS_MAKEFLAGS) \
-			  $(SUBDIRS_MAKEFLAGS-$@) \
-			  FULL_VERSION=$(FULL_VERSION) \
-			  RELEASE=$(RELEASE) || exit 1; \
-	       $(CD) $${curDir}; \
-    $(call TIMING_end,startTime,timing_id); \
-    $(ECHO) "<<<Finished Recursively making "$$i" "$@" @ `$(DATE)`." ; \
+    $(MAKE) -C $${i} $@ \
+          $(SUBDIRS_MAKEFLAGS) \
+          $(SUBDIRS_MAKEFLAGS-$@) \
+          FULL_VERSION=$(FULL_VERSION) \
+          RELEASE=$(RELEASE) || exit 1; \
   fi ; \
 done
-@$(ECHO) "Done Processing SUBDIRS: $(SUBDIRS)"
 endef
 
 # Given a OTHERSUBDIRS list, cd into them and make them (extra loop define)
 #   OTHERSUBDIRS_MAKEFLAGS      Make settings for a subdir make
 define OTHERSUBDIRS-loop
-@$(ECHO) "Begin Processing OTHERSUBDIRS: $(OTHERSUBDIRS)"
 @for i in DUMMY $(OTHERSUBDIRS) ; do \
   if [ "$$i" != "DUMMY" ] ; then \
-    $(ECHO) ">>>Recursively making "$$i" "$@" @ `$(DATE)` ..."; \
-    timing_id="$(TIMING_ID)-`$(BASENAME) $${i}`"; \
-    $(call TIMING_start,startTime); \
-    curDir=$(CURRENT_DIRECTORY); \
-    $(CD) $$i; $(MAKE) $@ TIMING_ID=$${timing_id} \
-		          $(OTHERSUBDIRS_MAKEFLAGS) \
-			  FULL_VERSION=$(FULL_VERSION) \
-			  RELEASE=$(RELEASE) || exit 1; \
-	       $(CD) $${curDir}; \
-    $(call TIMING_end,startTime,timing_id); \
-    $(ECHO) "<<<Finished Recursively making "$$i" "$@" @ `$(DATE)`." ; \
+    $(MAKE) -C $${i} $@ \
+          $(OTHERSUBDIRS_MAKEFLAGS) \
+          FULL_VERSION=$(FULL_VERSION) \
+          RELEASE=$(RELEASE) || exit 1; \
   fi ; \
 done
-@$(ECHO) "Done Processing OTHERSUBDIRS: $(OTHERSUBDIRS)"
 endef
 
 #
@@ -460,46 +367,23 @@
   VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
 endif
 
-# Note: As a rule, GNU Make rules should not appear in any of the 
-# Defs*.gmk files. These were added for Kestrel-Solaris and do address
-# a TeamWare bug. They should be moved elsewhere for Merlin.
-# 
-#  Override gnumake built-in rules which do sccs get operations badly.
-#  (They put the checked out code in the current directory, not in the
-#  directory of the original file.) 
-# Since this is a symptom of a teamware failure, complain and die on the spot.
+# Prevent the use of many default suffix rules we do not need
+.SUFFIXES:
+.SUFFIXES: .c .o .h .obj .cpp .hpp .java .class
 
-# This message immediately goes to stdout and the build terminates.
-define SCCS-trouble
-$(error  \
-"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
- is out of date with respect to its SCCS file $<. \
- This can happen from an unresolved Teamware conflict, a file movement, or \
- a failure in which SCCS files are updated but the 'sccs get' was not done. \
- You should double check for other out of date files in your workspace. \
- Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
-endef
-
-%:: s.%
-	@$(SCCS-trouble)
-%:: SCCS/s.%
-	@$(SCCS-trouble)
-	@$(ECHO) "         is out of date with respect to its SCCS file." >> $(WARNING_FILE)
-	@$(ECHO) "         This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
-	@$(ECHO) "         This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
-	@$(ECHO) "         in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
-	@$(ECHO) "         Check for other out of date files in your workspace." >> $(WARNING_FILE)
-	@$(ECHO) "" >> $(WARNING_FILE)
-	@#exit 666
-
+# Make sure we are all insane
 ifdef INSANE
   export INSANE
 endif
 
-ifdef ALT_COPYRIGHT_YEAR
-  COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR)
-else
-  COPYRIGHT_YEAR = $(shell $(DATE) '+%Y')
+# Make sure we have the current year
+ifndef COPYRIGHT_YEAR
+  ifdef ALT_COPYRIGHT_YEAR
+    COPYRIGHT_YEAR := $(ALT_COPYRIGHT_YEAR)
+  else
+    COPYRIGHT_YEAR := $(shell $(DATE) '+%Y')
+  endif
+  export COPYRIGHT_YEAR
 endif
 
 # Install of imported file (JDK_IMPORT_PATH, or some other external location)
--- a/corba/make/common/Rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/Rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -27,17 +27,6 @@
 #
 # Rules shared by all Java makefiles.
 #
-# Used to apply to source file $<, checks code conventions, issues warnings.
-define check-conventions
-  if [ "$(CONVENTION_WATCH)" = "true" ] ; then \
-    if [ "`$(CAT) -n -v -t $< | $(EGREP) -v '\@\(\#\)' | $(EGREP) '\^[MLI]'`" != "" ] ; then \
-      $(ECHO) "WARNING: File contains tabs, ^M, or ^L characters: $<"; \
-      if [ "$(CONVENTION_DETAILS)" = "true" ] ; then \
-        $(CAT) -n -v -t $< | $(EGREP) -v '\@\(\#\)' | $(EGREP) '\^[MLI]' ; \
-      fi; \
-    fi; \
-  fi
-endef
 
 # Make sure the default rule is all
 rules_default_rule: all
@@ -162,7 +151,6 @@
 # Add a java source to the list
 define add-java-file
 $(ECHO) "$?" >> $(JAVA_SOURCE_LIST)
-$(check-conventions)
 endef
 
 $(CLASSDESTDIR)/%.class: $(GENSRCDIR)/%.java
@@ -197,11 +185,8 @@
 
 .compile.classlist : $(JAVA_SOURCE_LIST)
 	@$(MKDIR) -p $(CLASSDESTDIR)
-	@if [ `$(CAT) $(JAVA_SOURCE_LIST) | $(WC) -l` -ge 1 ] ; then \
-	  $(ECHO) "# Java sources to be compiled: (listed in file $(JAVA_SOURCE_LIST))"; \
+	if [ -s $(JAVA_SOURCE_LIST) ] ; then \
 	  $(CAT) $(JAVA_SOURCE_LIST); \
-	  $(ECHO) "# Running javac:"; \
-	  $(ECHO) $(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
 	  $(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
 	fi
 	@$(java-vm-cleanup)
@@ -220,10 +205,7 @@
 packages.clean:
 ifeq ($(DONT_CLOBBER_CLASSES),false)
   ifdef AUTO_FILES_JAVA_DIRS
-	@for sdir in $(AUTO_FILES_JAVA_DIRS); do \
-	  $(ECHO) "$(RM) -r $(CLASSDESTDIR)/$$sdir"; \
-	  $(RM) -r $(CLASSDESTDIR)/$$sdir; \
-        done
+	$(RM) -r $(patsubst %, $(CLASSDESTDIR)/%, $(AUTO_FILES_JAVA_DIRS))
   else
 	$(RM) -r $(CLASSDESTDIR)/$(PKGDIR)
   endif
@@ -259,15 +241,13 @@
 
 $(CLASSHDR_DOTFILE): $(CLASSES_export)
 	$(prep-target)
-	@$(ECHO) "# Running javah:"
 	$(JAVAH_CMD) -d $(CLASSHDRDIR)/ \
 		$(CLASSES.export) $(subst $$,\$$,$(EXPORTED_inner))
 	@$(java-vm-cleanup)
 	@$(TOUCH) $@
 
 classheaders.clean:
-	$(RM) $(CLASSHDR_DOTFILE)
-	$(RM) -r $(CLASSHDRDIR)
+	$(RM) -r $(CLASSHDRDIR) $(CLASSHDR_DOTFILE)
 
 else # FILES_export
 
--- a/corba/make/common/shared/Compiler-msvc.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/shared/Compiler-msvc.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -48,11 +48,17 @@
   NMAKE          = MFLAGS= MAKEFLAGS= $(COMPILER_PATH)nmake -nologo
 
   # Compiler version and type (Always get word after "Version")
-  CC_VER  := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}')
-  
+  ifndef CC_VER
+    CC_VER  := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}')
+    export CC_VER
+  endif
+
   # SDK-64 and MSVC6 put REBASE.EXE in a different places - go figure...
   ifeq ($(ARCH_DATA_MODEL), 32)
-    LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+    ifndef LINK_VER
+      LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+      export LINK_VER
+    endif
     CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
     ifeq ($(CC_MAJORVER), 13)
       # This should be: CC_VER=13.10.3077 LINK_VER=7.10.3077
@@ -93,7 +99,10 @@
     endif
   else
     # else ARCH_DATA_MODEL is 64
-    LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+    ifndef LINK_VER
+      LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+      export LINK_VER
+    endif
     CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
     CC_MINORVER :=$(call MinorVersion,$(CC_VER))
     CC_MICROVER :=$(call MicroVersion,$(CC_VER))
--- a/corba/make/common/shared/Defs-utils.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/shared/Defs-utils.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -116,7 +116,6 @@
 RMDIR          = $(UTILS_COMMAND_PATH)rmdir
 RPM            = $(UTILS_COMMAND_PATH)rpm
 RPMBUILD       = $(UTILS_COMMAND_PATH)rpmbuild
-SCCS           = $(UTILS_CCS_BIN_PATH)sccs
 SED            = $(UTILS_COMMAND_PATH)sed
 SH             = $(UTILS_COMMAND_PATH)sh
 SHOWREV        = $(UTILS_USR_BIN_PATH)showrev
--- a/corba/make/common/shared/Defs-windows.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/shared/Defs-windows.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -113,32 +113,38 @@
 
 # UNIXCOMMAND_PATH: path to where the most common Unix commands are.
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_UNIXCOMMAND_PATH
-  xALT_UNIXCOMMAND_PATH  :="$(subst \,/,$(ALT_UNIXCOMMAND_PATH))"
-  fxALT_UNIXCOMMAND_PATH :=$(call FullPath,$(xALT_UNIXCOMMAND_PATH))
-  UNIXCOMMAND_PATH       :=$(call PrefixPath,$(fxALT_UNIXCOMMAND_PATH))
-else
-  ifdef USING_CYGWIN
-    UNIXCOMMAND_PATH :=$(call PrefixPath,/usr/bin)
+ifndef UNIXCOMMAND_PATH
+  ifdef ALT_UNIXCOMMAND_PATH
+    xALT_UNIXCOMMAND_PATH  :="$(subst \,/,$(ALT_UNIXCOMMAND_PATH))"
+    fxALT_UNIXCOMMAND_PATH :=$(call FullPath,$(xALT_UNIXCOMMAND_PATH))
+    UNIXCOMMAND_PATH       :=$(call PrefixPath,$(fxALT_UNIXCOMMAND_PATH))
   else
-    ifdef ROOTDIR
-      xROOTDIR :="$(subst \,/,$(ROOTDIR))"
-      _rootdir :=$(call FullPath,$(xROOTDIR))
+    ifdef USING_CYGWIN
+      UNIXCOMMAND_PATH :=$(call PrefixPath,/usr/bin)
     else
-      xROOTDIR :="$(_system_drive)/mksnt"
-      _rootdir :=$(call FullPath,$(xROOTDIR))
-    endif
-    ifneq ($(_rootdir),)
-      UNIXCOMMAND_PATH :=$(call PrefixPath,$(_rootdir)/mksnt)
+      ifdef ROOTDIR
+        xROOTDIR :="$(subst \,/,$(ROOTDIR))"
+        _rootdir :=$(call FullPath,$(xROOTDIR))
+      else
+        xROOTDIR :="$(_system_drive)/mksnt"
+        _rootdir :=$(call FullPath,$(xROOTDIR))
+      endif
+      ifneq ($(_rootdir),)
+        UNIXCOMMAND_PATH :=$(call PrefixPath,$(_rootdir)/mksnt)
+      endif
     endif
   endif
+  UNIXCOMMAND_PATH:=$(call AltCheckSpaces,UNIXCOMMAND_PATH)
+  export UNIXCOMMAND_PATH
 endif
-UNIXCOMMAND_PATH:=$(call AltCheckSpaces,UNIXCOMMAND_PATH)
 
 # Get version of MKS or CYGWIN
 ifdef USING_CYGWIN
-_CYGWIN_VER :=$(shell $(UNAME))
-CYGWIN_VER  :=$(call GetVersion,$(_CYGWIN_VER))
+  ifndef CYGWIN_VER
+    _CYGWIN_VER :=$(shell $(UNAME))
+    CYGWIN_VER  :=$(call GetVersion,$(_CYGWIN_VER))
+    export CYGWIN_VER
+  endif
 else # MKS
 _MKS_VER :=$(shell $(MKSINFO) 2>&1 | $(GREP) Release | $(TAIL) -1 | $(SED) -e 's@.*\(Release.*\)@\1@')
 MKS_VER  :=$(call GetVersion,$(_MKS_VER))
@@ -168,235 +174,234 @@
 
 # Process Windows values into FullPath values, these paths may have \ chars
 
-# System root
-ifdef SYSTEMROOT
-  xSYSTEMROOT  :="$(subst \,/,$(SYSTEMROOT))"
-  _system_root :=$(call FullPath,$(xSYSTEMROOT))
-else
-  ifdef SystemRoot
-     xSYSTEMROOT :="$(subst \,/,$(SystemRoot))"
-    _system_root :=$(call FullPath,$(xSYSTEMROOT))
+# Program Files directory
+ifndef SHORTPROGRAMFILES
+  ifdef PROGRAMFILES
+    xPROGRAMFILES      :="$(subst \,/,$(PROGRAMFILES))"
   else
-    ifdef WINDIR
-      xWINDIR      :="$(subst \,/,$(WINDIR))"
-      _system_root :=$(call FullPath,$(xWINDIR))
+    ifeq ($(ARCH_DATA_MODEL), 32)
+      xPROGRAMFILES    :="$(_system_drive)/Program Files"
     else
-      ifdef windir
-        xWINDIR      :="$(subst \,/,$(windir))"
-        _system_root :=$(call FullPath,$(xWINDIR))
-      endif
+      xPROGRAMFILES    :="$(_system_drive)/Program Files (x86)"
     endif
   endif
-endif
-_system_root:=$(call CheckValue,_system_root,$(_system_drive)/WINNT)
-
-# Program Files directory
-ifdef PROGRAMFILES
-  xPROGRAMFILES      :="$(subst \,/,$(PROGRAMFILES))"
-else
   ifeq ($(ARCH_DATA_MODEL), 32)
-    xPROGRAMFILES    :="$(_system_drive)/Program Files"
+    SHORTPROGRAMFILES  :=$(call FullPath,$(xPROGRAMFILES))
   else
-    xPROGRAMFILES    :="$(_system_drive)/Program Files (x86)"
+    ifdef PROGRAMW6432
+      xPROGRAMW6432    :="$(subst \,/,$(PROGRAMW6432))"
+    else
+      xPROGRAMW6432    :="$(_system_drive)/Program Files"
+    endif
+    SHORTPROGRAMFILES  :=$(call FullPath,$(xPROGRAMW6432))
   endif
-endif
-ifeq ($(ARCH_DATA_MODEL), 32)
-  _program_files     :=$(call FullPath,$(xPROGRAMFILES))
-else
-  ifdef PROGRAMW6432
-    xPROGRAMW6432    :="$(subst \,/,$(PROGRAMW6432))"
-  else
-    xPROGRAMW6432    :="$(_system_drive)/Program Files"
+  ifneq ($(word 1,$(SHORTPROGRAMFILES)),$(SHORTPROGRAMFILES))
+    SHORTPROGRAMFILES  :=
   endif
-  _program_files     :=$(call FullPath,$(xPROGRAMW6432))
-  _program_files32   :=$(call FullPath,$(xPROGRAMFILES))
-  ifneq ($(word 1,$(_program_files32)),$(_program_files32))
-    _program_files32:=
-  endif
-endif
-ifneq ($(word 1,$(_program_files)),$(_program_files))
-  _program_files:=
+  export SHORTPROGRAMFILES
 endif
 
 # Compilers, SDK, and Visual Studio (MSDEV) [32bit is different from 64bit]
 ifeq ($(ARCH_DATA_MODEL), 32)
-  # Try looking in MSVCDIR or MSVCDir area first (set by vcvars32.bat)
-  ifdef MSVCDIR
-    xMSVCDIR  :="$(subst \,/,$(MSVCDIR))"
-    _msvc_dir :=$(call FullPath,$(xMSVCDIR))
-  else
-    ifdef MSVCDir
-      xMSVCDIR  :="$(subst \,/,$(MSVCDir))"
-      _msvc_dir :=$(call FullPath,$(xMSVCDIR))
+  ifndef SHORTMSVCDIR
+    # Try looking in MSVCDIR or MSVCDir area first (set by vcvars32.bat)
+    ifdef MSVCDIR
+      xMSVCDIR         :="$(subst \,/,$(MSVCDIR))"
+      SHORTMSVCDIR     :=$(call FullPath,$(xMSVCDIR))
     else
-      ifneq ($(_program_files),)
-        xMSVCDIR  :="$(_program_files)/Microsoft Visual Studio .NET 2003/Vc7"
-        _msvc_dir :=$(call FullPath,$(xMSVCDIR))
+      ifdef MSVCDir
+        xMSVCDIR       :="$(subst \,/,$(MSVCDir))"
+        SHORTMSVCDIR   :=$(call FullPath,$(xMSVCDIR))
+      else
+        ifneq ($(SHORTPROGRAMFILES),)
+          xMSVCDIR     :="$(SHORTPROGRAMFILES)/Microsoft Visual Studio .NET 2003/Vc7"
+          SHORTMSVCDIR :=$(call FullPath,$(xMSVCDIR))
+        endif
       endif
     endif
-  endif
-  ifneq ($(subst MSDev98,OLDOLDOLD,$(_msvc_dir)),$(_msvc_dir))
-    _msvc_dir :=
+    ifneq ($(subst MSDev98,OLDOLDOLD,$(SHORTMSVCDIR)),$(SHORTMSVCDIR))
+      SHORTMSVCDIR     :=
+    endif
+    # If we still don't have it, look for VS71COMNTOOLS, setup by installer?
+    ifeq ($(SHORTMSVCDIR),)
+      ifdef VS71COMNTOOLS  # /Common/Tools directory, use ../../Vc7
+        xVS71COMNTOOLS :="$(subst \,/,$(VS71COMNTOOLS))"
+        _vs71tools     :=$(call FullPath,$(xVS71COMNTOOLS))
+      endif
+      ifneq ($(_vs71tools),)
+        SHORTMSVCDIR   :=$(_vs71tools)/../../Vc7
+      endif
+    endif
+    export SHORTMSVCDIR
   endif
-  # If we still don't have it, look for VS71COMNTOOLS, setup by installer?
-  ifeq ($(_msvc_dir),)
-    ifdef VS71COMNTOOLS  # /Common/Tools directory, use ../../Vc7
-      xVS71COMNTOOLS :="$(subst \,/,$(VS71COMNTOOLS))"
-      _vs71tools     :=$(call FullPath,$(xVS71COMNTOOLS))
-    endif
-    ifneq ($(_vs71tools),)
-      _msvc_dir :=$(_vs71tools)/../../Vc7
-    endif
-  endif
-  ifneq ($(_msvc_dir),)
-    _compiler_bin :=$(_msvc_dir)/Bin
-    _redist_sdk   :=$(_msvc_dir)/../SDK/v1.1/Bin
-    _ms_sdk       :=$(_msvc_dir)/PlatformSDK
+  ifneq ($(SHORTMSVCDIR),)
+    SHORTCOMPILERBIN   :=$(SHORTMSVCDIR)/Bin
+    SHORTPSDK          :=$(SHORTMSVCDIR)/PlatformSDK
+    export SHORTCOMPILERBIN
+    export SHORTPSDK
   endif
 endif
 
 # The Microsoft Platform SDK installed by itself
-ifneq ($(_program_files),)
-  xPSDK  :="$(_program_files)/Microsoft Platform SDK"
-  _psdk  :=$(call FullPath,$(xPSDK))
-  ifeq ($(_psdk),)
-    xPSDK  :="$(_program_files)/Microsoft SDK"
-    _psdk :=$(call FullPath,$(xMSSDK))
+ifneq ($(SHORTPROGRAMFILES),)
+  ifndef SHORTPSDK
+    xPSDK       :="$(SHORTPROGRAMFILES)/Microsoft Platform SDK"
+    SHORTPSDK   :=$(call FullPath,$(xPSDK))
+    ifeq ($(SHORTPSDK),)
+      xPSDK     :="$(SHORTPROGRAMFILES)/Microsoft SDK"
+      SHORTPSDK :=$(call FullPath,$(xMSSDK))
+    endif
+    export SHORTPSDK
   endif
 endif
 
 # If no SDK found yet, look in other places
-ifeq ($(_ms_sdk),)
+ifndef SHORTPSDK
   ifdef MSSDK
-    xMSSDK  :="$(subst \,/,$(MSSDK))"
-    _ms_sdk :=$(call FullPath,$(xMSSDK))
+    xMSSDK      :="$(subst \,/,$(MSSDK))"
+    SHORTPSDK   :=$(call FullPath,$(xMSSDK))
   else
     ifdef MSSdk
-      xMSSDK  :="$(subst \,/,$(MSSdk))"
-      _ms_sdk :=$(call FullPath,$(xMSSDK))
-    else
-      _ms_sdk :=$(_psdk)
+      xMSSDK    :="$(subst \,/,$(MSSdk))"
+      SHORTPSDK :=$(call FullPath,$(xMSSDK))
     endif
   endif
+  export SHORTPSDK
 endif
 
 # Compilers for 64bit are from SDK
 ifeq ($(ARCH_DATA_MODEL), 64)
-  xMSSDK61 :="C:/Program Files/Microsoft SDKs/Windows/v6.1/"
-  MSSDK61 :=$(call FullPath,$(xMSSDK61))
-  xVS2008 :="C:/Program Files (x86)/Microsoft Visual Studio 9.0/"
-  _vs2008 :=$(call FullPath,$(xVS2008))
-  ifneq ($(_vs2008),)
-    ifeq ($(ARCH), ia64)
-      _compiler_bin :=$(_vs2008)/VC/Bin/x86_ia64
-    endif
-    ifeq ($(ARCH), amd64)
-      _compiler_bin :=$(_vs2008)/VC/Bin/$(ARCH)
-      _redist_sdk   :=$(MSSDK61)/VC/redist
-    endif
-  else
-    ifneq ($(_ms_sdk),)
+  ifndef SHORTCOMPILERBIN
+    xMSSDK61 :="C:/Program Files/Microsoft SDKs/Windows/v6.1/"
+    MSSDK61 :=$(call FullPath,$(xMSSDK61))
+    xVS2008 :="C:/Program Files (x86)/Microsoft Visual Studio 9.0/"
+    _vs2008 :=$(call FullPath,$(xVS2008))
+    ifneq ($(_vs2008),)
       ifeq ($(ARCH), ia64)
-        _compiler_bin :=$(_ms_sdk)/Bin/Win64
+        SHORTCOMPILERBIN :=$(_vs2008)/VC/Bin/x86_ia64
       endif
       ifeq ($(ARCH), amd64)
-        _compiler_bin :=$(_ms_sdk)/Bin/Win64/x86/$(ARCH)
-        _redist_sdk   :=$(_ms_sdk)/redist/win64/AMD64
+        SHORTCOMPILERBIN :=$(_vs2008)/VC/Bin/$(ARCH)
+      endif
+    else
+      ifneq ($(SHORTPSDK),)
+        ifeq ($(ARCH), ia64)
+          SHORTCOMPILERBIN :=$(SHORTPSDK)/Bin/Win64
+        endif
+        ifeq ($(ARCH), amd64)
+          SHORTCOMPILERBIN :=$(SHORTPSDK)/Bin/Win64/x86/$(ARCH)
+        endif
       endif
     endif
+    export SHORTCOMPILERBIN
   endif
 endif
 
 # Location on system where jdk installs might be
-ifneq ($(_program_files),)
-  USRJDKINSTANCES_PATH =$(_program_files)/Java
+ifneq ($(SHORTPROGRAMFILES),)
+  USRJDKINSTANCES_PATH =$(SHORTPROGRAMFILES)/Java
 else
   USRJDKINSTANCES_PATH =$(_system_drive)/
 endif
 
 # SLASH_JAVA: location of all network accessable files
-ifdef ALT_SLASH_JAVA
-  xALT_SLASH_JAVA :="$(subst \,/,$(ALT_SLASH_JAVA))"
-  SLASH_JAVA      :=$(call FullPath,$(xALT_SLASH_JAVA))
-else
-  ifdef ALT_JDK_JAVA_DRIVE
-    SLASH_JAVA  =$(JDK_JAVA_DRIVE)
+ifndef SLASH_JAVA
+  ifdef ALT_SLASH_JAVA
+    xALT_SLASH_JAVA :="$(subst \,/,$(ALT_SLASH_JAVA))"
+    SLASH_JAVA      :=$(call FullPath,$(xALT_SLASH_JAVA))
   else
-    SLASH_JAVA  =J:
+    ifdef ALT_JDK_JAVA_DRIVE
+      SLASH_JAVA  =$(JDK_JAVA_DRIVE)
+    else
+      SLASH_JAVA  =J:
+    endif
   endif
+  SLASH_JAVA:=$(call AltCheckSpaces,SLASH_JAVA)
+  SLASH_JAVA:=$(call AltCheckValue,SLASH_JAVA)
+  export SLASH_JAVA
 endif
-SLASH_JAVA:=$(call AltCheckSpaces,SLASH_JAVA)
-SLASH_JAVA:=$(call AltCheckValue,SLASH_JAVA)
 
 # JDK_DEVTOOLS_DIR: common path for all the java devtools
-ifdef ALT_JDK_DEVTOOLS_DIR
-  xALT_JDK_DEVTOOLS_DIR :="$(subst \,/,$(ALT_JDK_DEVTOOLS_DIR))"
-  JDK_DEVTOOLS_DIR      :=$(call FullPath,$(xALT_JDK_DEVTOOLS_DIR))
-else
-  JDK_DEVTOOLS_DIR =$(SLASH_JAVA)/devtools
+ifndef JDK_DEVTOOLS_DIR
+  ifdef ALT_JDK_DEVTOOLS_DIR
+    xALT_JDK_DEVTOOLS_DIR :="$(subst \,/,$(ALT_JDK_DEVTOOLS_DIR))"
+    JDK_DEVTOOLS_DIR      :=$(call FullPath,$(xALT_JDK_DEVTOOLS_DIR))
+  else
+    JDK_DEVTOOLS_DIR =$(SLASH_JAVA)/devtools
+  endif
+  JDK_DEVTOOLS_DIR:=$(call AltCheckSpaces,JDK_DEVTOOLS_DIR)
+  JDK_DEVTOOLS_DIR:=$(call AltCheckValue,JDK_DEVTOOLS_DIR)
+  export JDK_DEVTOOLS_DIR
 endif
-JDK_DEVTOOLS_DIR:=$(call AltCheckSpaces,JDK_DEVTOOLS_DIR)
-JDK_DEVTOOLS_DIR:=$(call AltCheckValue,JDK_DEVTOOLS_DIR)
 
 # COMPILER_PATH: path to where the compiler and tools are installed.
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_COMPILER_PATH
-  xALT_COMPILER_PATH  :="$(subst \,/,$(ALT_COMPILER_PATH))"
-  fxALT_COMPILER_PATH :=$(call FullPath,$(xALT_COMPILER_PATH))
-  COMPILER_PATH       :=$(call PrefixPath,$(fxALT_COMPILER_PATH))
-else
-  COMPILER_PATH :=$(call PrefixPath,$(_compiler_bin))
+ifndef COMPILER_PATH
+  ifdef ALT_COMPILER_PATH
+    xALT_COMPILER_PATH  :="$(subst \,/,$(ALT_COMPILER_PATH))"
+    fxALT_COMPILER_PATH :=$(call FullPath,$(xALT_COMPILER_PATH))
+    COMPILER_PATH       :=$(call PrefixPath,$(fxALT_COMPILER_PATH))
+  else
+    COMPILER_PATH :=$(call PrefixPath,$(SHORTCOMPILERBIN))
+  endif
+  COMPILER_PATH :=$(call AltCheckSpaces,COMPILER_PATH)
+  export COMPILER_PATH
 endif
-COMPILER_PATH :=$(call AltCheckSpaces,COMPILER_PATH)
 
 # MSDEVTOOLS_PATH: path to where the additional MS Compiler tools are.
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_MSDEVTOOLS_PATH
-  xALT_MSDEVTOOLS_PATH  :="$(subst \,/,$(ALT_MSDEVTOOLS_PATH))"
-  fxALT_MSDEVTOOLS_PATH :=$(call FullPath,$(xALT_MSDEVTOOLS_PATH))
-  MSDEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_MSDEVTOOLS_PATH))
-else
-  ifeq ($(ARCH_DATA_MODEL), 64)
-    ifdef MSTOOLS
-      xMSTOOLS  :="$(subst \,/,$(MSTOOLS))"
-      _ms_tools :=$(call FullPath,$(xMSTOOLS))
-    else
-      ifdef Mstools
-        xMSTOOLS  :="$(subst \,/,$(Mstools))"
+ifndef MSDEVTOOLS_PATH
+  ifdef ALT_MSDEVTOOLS_PATH
+    xALT_MSDEVTOOLS_PATH  :="$(subst \,/,$(ALT_MSDEVTOOLS_PATH))"
+    fxALT_MSDEVTOOLS_PATH :=$(call FullPath,$(xALT_MSDEVTOOLS_PATH))
+    MSDEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_MSDEVTOOLS_PATH))
+  else
+    ifeq ($(ARCH_DATA_MODEL), 64)
+      ifdef MSTOOLS
+        xMSTOOLS  :="$(subst \,/,$(MSTOOLS))"
         _ms_tools :=$(call FullPath,$(xMSTOOLS))
       else
-        _ms_tools :=
+        ifdef Mstools
+          xMSTOOLS  :="$(subst \,/,$(Mstools))"
+          _ms_tools :=$(call FullPath,$(xMSTOOLS))
+        else
+          _ms_tools :=
+        endif
       endif
-    endif
-    ifneq ($(_ms_tools),)
-      _ms_tools_bin :=$(_ms_tools)/Bin
+      ifneq ($(_ms_tools),)
+        _ms_tools_bin :=$(_ms_tools)/Bin
+      else
+        # Assumes compiler bin is .../Bin/win64/x86/AMD64, rc.exe is 3 levels up
+        _ms_tools_bin :=$(SHORTCOMPILERBIN)/../../..
+      endif
     else
-      # Assumes compiler bin is .../Bin/win64/x86/AMD64, rc.exe is 3 levels up
-      _ms_tools_bin :=$(_compiler_bin)/../../..
+      _ms_tools_bin :=$(SHORTCOMPILERBIN)
     endif
-  else
-    _ms_tools_bin :=$(_compiler_bin)
+    MSDEVTOOLS_PATH :=$(call PrefixPath,$(_ms_tools_bin))
   endif
-  MSDEVTOOLS_PATH :=$(call PrefixPath,$(_ms_tools_bin))
+  MSDEVTOOLS_PATH:=$(call AltCheckSpaces,MSDEVTOOLS_PATH)
+  export MSDEVTOOLS_PATH
 endif
-MSDEVTOOLS_PATH:=$(call AltCheckSpaces,MSDEVTOOLS_PATH)
 
 # DEVTOOLS_PATH: for other tools required for building (such as zip, etc.)
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_DEVTOOLS_PATH
-  xALT_DEVTOOLS_PATH  :="$(subst \,/,$(ALT_DEVTOOLS_PATH))"
-  fxALT_DEVTOOLS_PATH :=$(call FullPath,$(xALT_DEVTOOLS_PATH))
-  DEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_DEVTOOLS_PATH))
-else
-  ifdef USING_CYGWIN
-    DEVTOOLS_PATH :=$(UNIXCOMMAND_PATH)
+ifndef DEVTOOLS_PATH
+  ifdef ALT_DEVTOOLS_PATH
+    xALT_DEVTOOLS_PATH  :="$(subst \,/,$(ALT_DEVTOOLS_PATH))"
+    fxALT_DEVTOOLS_PATH :=$(call FullPath,$(xALT_DEVTOOLS_PATH))
+    DEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_DEVTOOLS_PATH))
   else
-    xDEVTOOLS_PATH  :="$(_system_drive)/utils"
-    fxDEVTOOLS_PATH :=$(call FullPath,$(xDEVTOOLS_PATH))
-    DEVTOOLS_PATH  :=$(call PrefixPath,$(fxDEVTOOLS_PATH))
+    ifdef USING_CYGWIN
+      DEVTOOLS_PATH :=$(UNIXCOMMAND_PATH)
+    else
+      xDEVTOOLS_PATH  :="$(_system_drive)/utils"
+      fxDEVTOOLS_PATH :=$(call FullPath,$(xDEVTOOLS_PATH))
+      DEVTOOLS_PATH  :=$(call PrefixPath,$(fxDEVTOOLS_PATH))
+    endif
   endif
+  DEVTOOLS_PATH:=$(call AltCheckSpaces,DEVTOOLS_PATH)
+  export DEVTOOLS_PATH
 endif
-DEVTOOLS_PATH:=$(call AltCheckSpaces,DEVTOOLS_PATH)
 
 # _BOOTDIR1: First choice for a Bootstrap JDK, previous released JDK.
 # _BOOTDIR2: Second choice
@@ -410,20 +415,26 @@
 
 # BUILD_JDK_IMPORT_PATH: location of JDK install trees to import for
 #   multiple platforms, e.g. windows-i586, solaris-sparc, linux-586, etc.
-ifdef ALT_BUILD_JDK_IMPORT_PATH
-  BUILD_JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_BUILD_JDK_IMPORT_PATH))
-else
-  BUILD_JDK_IMPORT_PATH   = $(PROMOTED_BUILD_BINARIES)
+ifndef BUILD_JDK_IMPORT_PATH
+  ifdef ALT_BUILD_JDK_IMPORT_PATH
+    BUILD_JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_BUILD_JDK_IMPORT_PATH))
+  else
+    BUILD_JDK_IMPORT_PATH   = $(PROMOTED_BUILD_BINARIES)
+  endif
+  BUILD_JDK_IMPORT_PATH:=$(call AltCheckSpaces,BUILD_JDK_IMPORT_PATH)
+  BUILD_JDK_IMPORT_PATH:=$(call AltCheckValue,BUILD_JDK_IMPORT_PATH)
+  export BUILD_JDK_IMPORT_PATH
 endif
-BUILD_JDK_IMPORT_PATH:=$(call AltCheckSpaces,BUILD_JDK_IMPORT_PATH)
-BUILD_JDK_IMPORT_PATH:=$(call AltCheckValue,BUILD_JDK_IMPORT_PATH)
 
 # JDK_IMPORT_PATH: location of previously built JDK (this version) to import
-ifdef ALT_JDK_IMPORT_PATH
-  JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_JDK_IMPORT_PATH))
-else
-  JDK_IMPORT_PATH   = $(BUILD_JDK_IMPORT_PATH)/$(PLATFORM)-$(ARCH)$(_JDK_IMPORT_VARIANT)
+ifndef JDK_IMPORT_PATH
+  ifdef ALT_JDK_IMPORT_PATH
+    JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_JDK_IMPORT_PATH))
+  else
+    JDK_IMPORT_PATH   = $(BUILD_JDK_IMPORT_PATH)/$(PLATFORM)-$(ARCH)$(_JDK_IMPORT_VARIANT)
+  endif
+  JDK_IMPORT_PATH:=$(call AltCheckSpaces,JDK_IMPORT_PATH)
+  JDK_IMPORT_PATH:=$(call AltCheckValue,JDK_IMPORT_PATH)
+  export JDK_IMPORT_PATH
 endif
-JDK_IMPORT_PATH:=$(call AltCheckSpaces,JDK_IMPORT_PATH)
-JDK_IMPORT_PATH:=$(call AltCheckValue,JDK_IMPORT_PATH)
 
--- a/corba/make/common/shared/Defs.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/shared/Defs.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -228,12 +228,15 @@
 endif
 
 # FULL_VERSION is RELEASE and -BUILD_NUMBER if BUILD_NUMBER is set
-ifdef BUILD_NUMBER
-  FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER)
-else
-  BUILD_NUMBER = b00
-  USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`)
-  FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER)
+ifndef FULL_VERSION
+  ifdef BUILD_NUMBER
+    FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER)
+  else
+    BUILD_NUMBER = b00
+    USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`)
+    FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER)
+  endif
+  export FULL_VERSION
 endif
 
 # Promoted build location
--- a/corba/make/common/shared/Platform.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/common/shared/Platform.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -84,21 +84,14 @@
 #     REQUIRED_LINUX_VER          linux only: required version of linux
 #     REQUIRED_LINUX_FULLVER      linux only: required full version of linux
 
-SYSTEM_UNAME := $(shell uname)
+ifndef SYSTEM_UNAME
+  SYSTEM_UNAME := $(shell uname)
+  export SYSTEM_UNAME
+endif
 
 # Normal boot jdk is previous release, but a hard requirement is a 1.5 boot
 REQUIRED_BOOT_VER = 1.5
 
-#
-# Prune out all known SCM (Source Code Management) directories
-# so they will not be included when copying directory trees
-# or packaging up .jar files, etc.  This applies to all workspaces.
-#
-SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files
-# When changing SCM_DIRs also change SCM_DIRS_rexp and SCM_DIRS_prune:
-SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files"
-SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files \) -prune
-
 # Don't define this unless it's not defined
 ifndef VARIANT
   VARIANT=OPT
@@ -372,14 +365,17 @@
   REQUIRED_FREE_SPACE=500000
   OS_VENDOR = Microsoft
   # How much RAM does this machine have:
-  MB_OF_MEMORY := $(shell \
-    if [ -f "C:/cygwin/bin/free.exe" ] ; then \
-      ( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
-	grep Mem: | \
-	sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
-    else \
-      echo "512"; \
-    fi)
+  ifndef MB_OF_MEMORY
+    MB_OF_MEMORY := $(shell \
+      if [ -f "C:/cygwin/bin/free.exe" ] ; then \
+        ( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
+	  grep Mem: | \
+	  sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
+      else \
+        echo "512"; \
+      fi)
+    export MB_OF_MEMORY
+  endif
 endif
 
 # Machines with 512Mb or less of real memory are considered low memory
@@ -387,30 +383,36 @@
 #    system swapping during the build.
 #    If we don't know, assume 512. Subtract 128 from MB for VM MAX.
 #    Don't set VM max over 1024-128=896.
-ifneq ($(MB_OF_MEMORY),)
-  LOW_MEMORY_MACHINE := $(shell \
-    if [ $(MB_OF_MEMORY) -le 512 ] ; then \
-      echo "true"; \
-    else \
-      echo "false"; \
-    fi)
-  MAX_VM_MEMORY := $(shell \
-    if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
-      expr $(MB_OF_MEMORY) '-' 128 ; \
-    else \
-      echo "896"; \
-    fi)
-  MIN_VM_MEMORY := $(shell \
-    if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
-      expr $(MAX_VM_MEMORY) '-' 8 ; \
-    else \
-      echo "128"; \
-    fi)
-else
-  MB_OF_MEMORY       := unknown
-  LOW_MEMORY_MACHINE := true
-  MAX_VM_MEMORY      := 384
-  MIN_VM_MEMORY      := 128
+ifndef MAX_VM_MEMORY
+  ifneq ($(MB_OF_MEMORY),)
+    LOW_MEMORY_MACHINE := $(shell \
+      if [ $(MB_OF_MEMORY) -le 512 ] ; then \
+        echo "true"; \
+      else \
+        echo "false"; \
+      fi)
+    MAX_VM_MEMORY := $(shell \
+      if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
+        expr $(MB_OF_MEMORY) '-' 128 ; \
+      else \
+        echo "896"; \
+      fi)
+    MIN_VM_MEMORY := $(shell \
+      if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
+        expr $(MAX_VM_MEMORY) '-' 8 ; \
+      else \
+        echo "128"; \
+      fi)
+  else
+    MB_OF_MEMORY       := unknown
+    LOW_MEMORY_MACHINE := true
+    MAX_VM_MEMORY      := 384
+    MIN_VM_MEMORY      := 128
+  endif
+  export MAX_VM_MEMORY
+  export MIN_VM_MEMORY
+  export LOW_MEMORY_MACHINE
+  export MAX_VM_MEMORY
 endif
 
 REQUIRED_ZIP_VER = 2.2
--- a/corba/make/jprt.properties	Wed Jul 05 17:00:34 2017 +0200
+++ b/corba/make/jprt.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -34,8 +34,8 @@
 solaris_x64_5.10,\
 linux_i586_2.6,\
 linux_x64_2.6,\
-windows_i586,\
-windows_x64
+windows_i586_5.0,\
+windows_x64_5.2
 
 # The different build flavors we want
 jprt.build.flavors=product,fastdebug
--- a/hotspot/.hgtags	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 17:01:15 2017 +0200
@@ -46,3 +46,4 @@
 54fd4d9232969ea6cd3d236e5ad276183bb0d423 jdk7-b69
 0632c3e615a315ff11e2ab1d64f4d82ff9853461 jdk7-b70
 50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71
+a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
--- a/hotspot/agent/make/saenv.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/agent/make/saenv.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/make/saenv64.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/agent/make/saenv64.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/os/solaris/proc/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/agent/src/os/solaris/proc/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/os/solaris/proc/mapfile	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/agent/src/os/solaris/proc/mapfile	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #
 
 #
-# Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/make/hotspot_version	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/hotspot_version	Wed Jul 05 17:01:15 2017 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=17
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=01
+HS_BUILD_NUMBER=02
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/make/linux/makefiles/jvmti.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/linux/makefiles/jvmti.make	Wed Jul 05 17:01:15 2017 +0200
@@ -70,10 +70,10 @@
 both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
 
 $(JvmtiGenClass): $(JvmtiGenSource)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
 
 $(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
 
 $(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
 	@echo Generating $@
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug	Wed Jul 05 17:01:15 2017 +0200
@@ -74,6 +74,7 @@
                 JVM_CurrentTimeMillis;
                 JVM_DefineClass;
                 JVM_DefineClassWithSource;
+                JVM_DefineClassWithSourceCond;
                 JVM_DesiredAssertionStatus;
                 JVM_DisableCompiler;
                 JVM_DoPrivileged;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product	Wed Jul 05 17:01:15 2017 +0200
@@ -74,6 +74,7 @@
                 JVM_CurrentTimeMillis;
                 JVM_DefineClass;
                 JVM_DefineClassWithSource;
+                JVM_DefineClassWithSourceCond;
                 JVM_DesiredAssertionStatus;
                 JVM_DisableCompiler;
                 JVM_DoPrivileged;
--- a/hotspot/make/linux/makefiles/rules.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/linux/makefiles/rules.make	Wed Jul 05 17:01:15 2017 +0200
@@ -122,12 +122,20 @@
 endif
 endif
 
+COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
+
 SUM = /usr/bin/sum
 
 # 'gmake MAKE_VERBOSE=y' gives all the gory details.
 QUIETLY$(MAKE_VERBOSE)  = @
 RUN.JAR$(MAKE_VERBOSE) += >/dev/null
 
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION = 6
+BOOT_TARGET_CLASS_VERSION = 6
+JAVAC_FLAGS = -g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
 # With parallel makes, print a message at the end of compilation.
 ifeq    ($(findstring j,$(MFLAGS)),j)
 COMPILE_DONE    = && { echo Done with $<; }
--- a/hotspot/make/linux/makefiles/sa.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/linux/makefiles/sa.make	Wed Jul 05 17:01:15 2017 +0200
@@ -74,8 +74,8 @@
 	  mkdir -p $(SA_CLASSDIR);        \
 	fi
 
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
 
 	$(QUIETLY) $(REMOTE) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
--- a/hotspot/make/linux/makefiles/top.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/linux/makefiles/top.make	Wed Jul 05 17:01:15 2017 +0200
@@ -24,7 +24,7 @@
 
 # top.make is included in the Makefile in the build directories.
 # It DOES NOT include the vm dependency info in order to be faster.
-# It's main job is to implement the incremental form of make lists.
+# Its main job is to implement the incremental form of make lists.
 # It also:
 #   -builds and runs adlc via adlc.make
 #   -generates JVMTI source and docs via jvmti.make (JSR-163)
@@ -114,7 +114,7 @@
 # make makeDeps: (and zap the cached db files to force a nonincremental run)
 
 $(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
-	@$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
+	@$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
 	@echo Removing $(Incremental_Lists) to force regeneration.
 	@rm -f $(Incremental_Lists)
 	@$(CDG) echo >$(Cached_plat)
--- a/hotspot/make/solaris/makefiles/jvmti.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/solaris/makefiles/jvmti.make	Wed Jul 05 17:01:15 2017 +0200
@@ -69,10 +69,10 @@
 both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
 
 $(JvmtiGenClass): $(JvmtiGenSource)
-	$(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+	$(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
 
 $(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
-	$(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+	$(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
 
 $(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
 	@echo Generating $@
--- a/hotspot/make/solaris/makefiles/mapfile-vers	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/solaris/makefiles/mapfile-vers	Wed Jul 05 17:01:15 2017 +0200
@@ -74,6 +74,7 @@
 		JVM_CurrentTimeMillis;
 		JVM_DefineClass;
 		JVM_DefineClassWithSource;
+		JVM_DefineClassWithSourceCond;
 		JVM_DesiredAssertionStatus;
 		JVM_DisableCompiler;
 		JVM_DoPrivileged;
--- a/hotspot/make/solaris/makefiles/rules.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/solaris/makefiles/rules.make	Wed Jul 05 17:01:15 2017 +0200
@@ -122,12 +122,20 @@
 endif
 endif
 
+COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
+
 SUM = /usr/bin/sum
 
 # 'gmake MAKE_VERBOSE=y' gives all the gory details.
 QUIETLY$(MAKE_VERBOSE)  = @
 RUN.JAR$(MAKE_VERBOSE) += >/dev/null
 
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION = 6
+BOOT_TARGET_CLASS_VERSION = 6
+JAVAC_FLAGS = -g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
 # With parallel makes, print a message at the end of compilation.
 ifeq    ($(findstring j,$(MFLAGS)),j)
 COMPILE_DONE    = && { echo Done with $<; }
--- a/hotspot/make/solaris/makefiles/sa.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/solaris/makefiles/sa.make	Wed Jul 05 17:01:15 2017 +0200
@@ -67,8 +67,8 @@
 	$(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \
 	  mkdir -p $(SA_CLASSDIR);        \
 	fi
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
+	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
+	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
 	
 	$(QUIETLY) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
--- a/hotspot/make/solaris/makefiles/top.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/solaris/makefiles/top.make	Wed Jul 05 17:01:15 2017 +0200
@@ -24,7 +24,7 @@
 
 # top.make is included in the Makefile in the build directories.
 # It DOES NOT include the vm dependency info in order to be faster.
-# It's main job is to implement the incremental form of make lists.
+# Its main job is to implement the incremental form of make lists.
 # It also:
 #   -builds and runs adlc via adlc.make
 #   -generates JVMTI source and docs via jvmti.make (JSR-163)
@@ -112,7 +112,7 @@
 # make makeDeps: (and zap the cached db files to force a nonincremental run)
 
 $(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
-	@$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
+	@$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
 	@echo Removing $(Incremental_Lists) to force regeneration.
 	@rm -f $(Incremental_Lists)
 	@$(CDG) echo >$(Cached_plat)
--- a/hotspot/make/windows/makefiles/generated.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/windows/makefiles/generated.make	Wed Jul 05 17:01:15 2017 +0200
@@ -91,7 +91,7 @@
 classes/MakeDeps.class: $(MakeDepsSources)
 	if exist classes rmdir /s /q classes
 	mkdir classes
-	$(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -g -d classes $(MakeDepsSources)
+	$(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -d classes $(MakeDepsSources)
 
 !if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
 
--- a/hotspot/make/windows/makefiles/jvmti.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/windows/makefiles/jvmti.make	Wed Jul 05 17:01:15 2017 +0200
@@ -68,10 +68,10 @@
         @if not exist $(JvmtiOutDir) mkdir $(JvmtiOutDir)
 
 $(JvmtiGenClass): $(JvmtiGenSource)
-	$(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+	$(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
 
 $(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
-	@$(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+	@$(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
 
 $(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
 	@echo Generating $@
--- a/hotspot/make/windows/makefiles/rules.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/windows/makefiles/rules.make	Wed Jul 05 17:01:15 2017 +0200
@@ -29,7 +29,7 @@
 RUN_JAVAP=$(BootStrapDir)\bin\javap
 RUN_JAVAH=$(BootStrapDir)\bin\javah
 RUN_JAR=$(BootStrapDir)\bin\jar
-COMPILE_JAVAC=$(BootStrapDir)\bin\javac
+COMPILE_JAVAC=$(BootStrapDir)\bin\javac $(BOOTSTRAP_JAVAC_FLAGS)
 COMPILE_RMIC=$(BootStrapDir)\bin\rmic
 BOOT_JAVA_HOME=$(BootStrapDir)
 !else
@@ -37,11 +37,17 @@
 RUN_JAVAP=javap
 RUN_JAVAH=javah
 RUN_JAR=jar
-COMPILE_JAVAC=javac
+COMPILE_JAVAC=javac $(BOOTSTRAP_JAVAC_FLAGS)
 COMPILE_RMIC=rmic
 BOOT_JAVA_HOME=
 !endif
 
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION=6
+BOOT_TARGET_CLASS_VERSION=6
+JAVAC_FLAGS=-g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
 ProjectFile=vm.vcproj
 
 !if "$(MSC_VER)" == "1200"
--- a/hotspot/make/windows/makefiles/sa.make	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/windows/makefiles/sa.make	Wed Jul 05 17:01:15 2017 +0200
@@ -55,9 +55,9 @@
 $(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
 	@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
 	@echo ...Building sa-jdi.jar
-	@echo ...$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) ....
-	@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
-	@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
+	@echo ...$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
+	@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
+	@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
 	$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
 	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
--- a/hotspot/make/windows/projectfiles/common/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/make/windows/projectfiles/common/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -179,6 +179,6 @@
 $(HOTSPOTBUILDSPACE)/classes/MakeDeps.class: $(MakeDepsSources)
 	@if exist $(HOTSPOTBUILDSPACE)\classes rmdir /s /q $(HOTSPOTBUILDSPACE)\classes
 	@mkdir $(HOTSPOTBUILDSPACE)\classes
-	@$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -g -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
+	@$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
 
 FORCE:
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1696,6 +1696,9 @@
 void InterpreterMacroAssembler::record_klass_in_profile_helper(
                                         Register receiver, Register scratch,
                                         int start_row, Label& done) {
+  if (TypeProfileWidth == 0)
+    return;
+
   int last_row = VirtualCallData::row_limit() - 1;
   assert(start_row <= last_row, "must be work left to do");
   // Test this row for both the receiver and for null.
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 17:01:15 2017 +0200
@@ -5707,7 +5707,7 @@
   effect(TEMP dst, TEMP tmp);
   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 
-  size(3*4);
+  size((3+1)*4);  // set may use two instructions.
   format %{ "LDUH   $mem,$dst\t! ushort/char & 16-bit mask -> long\n\t"
             "SET    $mask,$tmp\n\t"
             "AND    $dst,$tmp,$dst" %}
@@ -5851,7 +5851,7 @@
   effect(TEMP dst, TEMP tmp);
   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 
-  size(3*4);
+  size((3+1)*4);  // set may use two instructions.
   format %{ "LDUW   $mem,$dst\t! int & 32-bit mask -> long\n\t"
             "SET    $mask,$tmp\n\t"
             "AND    $dst,$tmp,$dst" %}
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -827,8 +827,8 @@
     case vmIntrinsics::_dsin:   __ sin  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dcos:   __ cos  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dtan:   __ tan  (calc_input, calc_result, tmp1, tmp2);              break;
-    case vmIntrinsics::_dlog:   __ log  (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
-    case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, LIR_OprFact::illegalOpr); break;
+    case vmIntrinsics::_dlog:   __ log  (calc_input, calc_result, tmp1);                    break;
+    case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1);                    break;
     default:                    ShouldNotReachHere();
   }
 
--- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -764,8 +764,6 @@
       break;
     }
 
-    case lir_log:
-    case lir_log10:
     case lir_abs:
     case lir_sqrt: {
       // Right argument appears to be unused
@@ -785,6 +783,30 @@
       break;
     }
 
+    case lir_log:
+    case lir_log10: {
+      // log and log10 needs one temporary fpu stack slot, so there is ontemporary
+      // registers stored in temp of the operation.
+      // the stack allocator must guarantee that the stack slots are really free,
+      // otherwise there might be a stack overflow.
+      assert(right->is_illegal(), "must be");
+      assert(left->is_fpu_register(), "must be");
+      assert(res->is_fpu_register(), "must be");
+      assert(op2->tmp_opr()->is_fpu_register(), "must be");
+
+      insert_free_if_dead(op2->tmp_opr());
+      insert_free_if_dead(res, left);
+      insert_exchange(left);
+      do_rename(left, res);
+
+      new_left = to_fpu_stack_top(res);
+      new_res = new_left;
+
+      op2->set_fpu_stack_size(sim()->stack_size());
+      assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
+      break;
+    }
+
 
     case lir_tan:
     case lir_sin:
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1262,6 +1262,9 @@
                                         Register receiver, Register mdp,
                                         Register reg2,
                                         int start_row, Label& done) {
+  if (TypeProfileWidth == 0)
+    return;
+
   int last_row = VirtualCallData::row_limit() - 1;
   assert(start_row <= last_row, "must be work left to do");
   // Test this row for both the receiver and for null.
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1272,6 +1272,9 @@
                                         Register receiver, Register mdp,
                                         Register reg2,
                                         int start_row, Label& done) {
+  if (TypeProfileWidth == 0)
+    return;
+
   int last_row = VirtualCallData::row_limit() - 1;
   assert(start_row <= last_row, "must be work left to do");
   // Test this row for both the receiver and for null.
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1526,7 +1526,8 @@
     case 5000: st->print(" Windows 2000"); break;
     case 5001: st->print(" Windows XP"); break;
     case 5002:
-    case 6000: {
+    case 6000:
+    case 6001: {
       // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
       // find out whether we are running on 64 bit processor or not.
       SYSTEM_INFO si;
@@ -1549,13 +1550,27 @@
           st->print(" Windows XP x64 Edition");
         else
             st->print(" Windows Server 2003 family");
-      } else { // os_vers == 6000
+      } else if (os_vers == 6000) {
         if (osvi.wProductType == VER_NT_WORKSTATION)
             st->print(" Windows Vista");
         else
             st->print(" Windows Server 2008");
         if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
             st->print(" , 64 bit");
+      } else if (os_vers == 6001) {
+        if (osvi.wProductType == VER_NT_WORKSTATION) {
+            st->print(" Windows 7");
+        } else {
+            // Unrecognized windows, print out its major and minor versions
+            st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+        }
+        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+            st->print(" , 64 bit");
+      } else { // future os
+        // Unrecognized windows, print out its major and minor versions
+        st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+            st->print(" , 64 bit");
       }
       break;
     }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/adlc/archDesc.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1031,7 +1031,8 @@
 //---------------------------addSUNcopyright-------------------------------
 // output SUN copyright info
 void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
-  fwrite(legal, size, 1, fp);
+  size_t count = fwrite(legal, 1, size, fp);
+  assert(count == (size_t) size, "copyright info truncated");
   fprintf(fp,"\n");
   fprintf(fp,"// Machine Generated File.  Do Not Edit!\n");
   fprintf(fp,"\n");
--- a/hotspot/src/share/vm/c1/c1_IR.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/c1/c1_IR.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_IR.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -567,8 +567,6 @@
     case lir_rem:
     case lir_sqrt:
     case lir_abs:
-    case lir_log:
-    case lir_log10:
     case lir_logic_and:
     case lir_logic_or:
     case lir_logic_xor:
@@ -644,13 +642,16 @@
 
     case lir_tan:
     case lir_sin:
-    case lir_cos: {
+    case lir_cos:
+    case lir_log:
+    case lir_log10: {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
 
-      // sin and cos need two temporary fpu stack slots, so register
-      // two temp operands.  Register input operand as temp to
-      // guarantee that they do not overlap
+      // On x86 tan/sin/cos need two temporary fpu stack slots and
+      // log/log10 need one so handle opr2 and tmp as temp inputs.
+      // Register input operand as temp to guarantee that it doesn't
+      // overlap with the input.
       assert(op2->_info == NULL, "not used");
       assert(op2->_opr1->is_valid(), "used");
       do_input(op2->_opr1); do_temp(op2->_opr1);
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1840,8 +1840,8 @@
 
   void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_abs , from, tmp, to)); }
   void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_sqrt, from, tmp, to)); }
-  void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_log,  from, tmp, to)); }
-  void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)              { append(new LIR_Op2(lir_log10, from, tmp, to)); }
+  void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_log,  from, LIR_OprFact::illegalOpr, to, tmp)); }
+  void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)              { append(new LIR_Op2(lir_log10, from, LIR_OprFact::illegalOpr, to, tmp)); }
   void sin (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_sin , from, tmp1, to, tmp2)); }
   void cos (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_cos , from, tmp1, to, tmp2)); }
   void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -2547,6 +2547,7 @@
                                                     KlassHandle host_klass,
                                                     GrowableArray<Handle>* cp_patches,
                                                     symbolHandle& parsed_name,
+                                                    bool verify,
                                                     TRAPS) {
   // So that JVMTI can cache class file in the state before retransformable agents
   // have modified it
@@ -2591,7 +2592,7 @@
   instanceKlassHandle nullHandle;
 
   // Figure out whether we can skip format checking (matching classic VM behavior)
-  _need_verify = Verifier::should_verify_for(class_loader());
+  _need_verify = Verifier::should_verify_for(class_loader(), verify);
 
   // Set the verify flag in stream
   cfs->set_verify(_need_verify);
@@ -3210,6 +3211,7 @@
 
     // Fill in information already parsed
     this_klass->set_access_flags(access_flags);
+    this_klass->set_should_verify_class(verify);
     jint lh = Klass::instance_layout_helper(instance_size, false);
     this_klass->set_layout_helper(lh);
     assert(this_klass->oop_is_instance(), "layout is correct");
@@ -3229,6 +3231,12 @@
       this_klass->set_has_final_method();
     }
     this_klass->set_method_ordering(method_ordering());
+    // The instanceKlass::_methods_jmethod_ids cache and the
+    // instanceKlass::_methods_cached_itable_indices cache are
+    // both managed on the assumption that the initial cache
+    // size is equal to the number of methods in the class. If
+    // that changes, then instanceKlass::idnum_can_increment()
+    // has to be changed accordingly.
     this_klass->set_initial_method_idnum(methods->length());
     this_klass->set_name(cp->klass_name_at(this_class_index));
     if (LinkWellKnownClasses || is_anonymous())  // I am well known to myself
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -260,9 +260,10 @@
                                      Handle class_loader,
                                      Handle protection_domain,
                                      symbolHandle& parsed_name,
+                                     bool verify,
                                      TRAPS) {
     KlassHandle no_host_klass;
-    return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, THREAD);
+    return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);
   }
   instanceKlassHandle parseClassFile(symbolHandle name,
                                      Handle class_loader,
@@ -270,6 +271,7 @@
                                      KlassHandle host_klass,
                                      GrowableArray<Handle>* cp_patches,
                                      symbolHandle& parsed_name,
+                                     bool verify,
                                      TRAPS);
 
   // Verifier checks
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -874,6 +874,7 @@
                                                        class_loader,
                                                        protection_domain,
                                                        parsed_name,
+                                                       false,
                                                        CHECK_(h));
 
     // add to package table
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -252,7 +252,7 @@
   typeArrayOop value  = java_lang_String::value(obj);
   int          offset = java_lang_String::offset(obj);
   int          length = java_lang_String::length(obj);
-  jchar* base = value->char_at_addr(offset);
+  jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
   symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD);
   return symbolHandle(THREAD, sym);
 }
@@ -261,7 +261,7 @@
   typeArrayOop value  = java_lang_String::value(java_string);
   int          offset = java_lang_String::offset(java_string);
   int          length = java_lang_String::length(java_string);
-  jchar* base = value->char_at_addr(offset);
+  jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
   return SymbolTable::probe_unicode(base, length);
 }
 
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -970,6 +970,7 @@
                                                              host_klass,
                                                              cp_patches,
                                                              parsed_name,
+                                                             true,
                                                              THREAD);
 
 
@@ -1025,6 +1026,7 @@
                                                Handle class_loader,
                                                Handle protection_domain,
                                                ClassFileStream* st,
+                                               bool verify,
                                                TRAPS) {
 
   // Classloaders that support parallelism, e.g. bootstrap classloader,
@@ -1055,6 +1057,7 @@
                                                              class_loader,
                                                              protection_domain,
                                                              parsed_name,
+                                                             verify,
                                                              THREAD);
 
   const char* pkg = "java/";
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -259,7 +259,9 @@
                                TRAPS);
 
   // Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
-  static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, TRAPS);
+  static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader,
+                                      Handle protection_domain,
+                                      ClassFileStream* st, bool verify, TRAPS);
 
   // Lookup an already loaded class. If not found NULL is returned.
   static klassOop find(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS);
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -53,8 +53,8 @@
 
 // Methods in Verifier
 
-bool Verifier::should_verify_for(oop class_loader) {
-  return class_loader == NULL ?
+bool Verifier::should_verify_for(oop class_loader, bool should_verify_class) {
+  return (class_loader == NULL || !should_verify_class) ?
     BytecodeVerificationLocal : BytecodeVerificationRemote;
 }
 
@@ -68,7 +68,7 @@
   return !need_verify;
 }
 
-bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, TRAPS) {
+bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) {
   ResourceMark rm(THREAD);
   HandleMark hm;
 
@@ -81,7 +81,7 @@
   // If the class should be verified, first see if we can use the split
   // verifier.  If not, or if verification fails and FailOverToOldVerifier
   // is set, then call the inference verifier.
-  if (is_eligible_for_verification(klass)) {
+  if (is_eligible_for_verification(klass, should_verify_class)) {
     if (TraceClassInitialization) {
       tty->print_cr("Start class verification for: %s", klassName);
     }
@@ -141,12 +141,13 @@
   }
 }
 
-bool Verifier::is_eligible_for_verification(instanceKlassHandle klass) {
+bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) {
   symbolOop name = klass->name();
   klassOop refl_magic_klass = SystemDictionary::reflect_magic_klass();
 
-  return (should_verify_for(klass->class_loader()) &&
+  return (should_verify_for(klass->class_loader(), should_verify_class) &&
     // return if the class is a bootstrapping class
+    // or defineClass specified not to verify by default (flags override passed arg)
     // We need to skip the following four for bootstraping
     name != vmSymbols::java_lang_Object() &&
     name != vmSymbols::java_lang_Class() &&
--- a/hotspot/src/share/vm/classfile/verifier.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/classfile/verifier.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -34,16 +34,18 @@
    * Otherwise, no exception is thrown and the return indicates the
    * error.
    */
-  static bool verify(instanceKlassHandle klass, Mode mode, TRAPS);
+  static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, TRAPS);
 
-  // Return false if the class is loaded by the bootstrap loader.
-  static bool should_verify_for(oop class_loader);
+  // Return false if the class is loaded by the bootstrap loader,
+  // or if defineClass was called requesting skipping verification
+  // -Xverify:all/none override this value
+  static bool should_verify_for(oop class_loader, bool should_verify_class);
 
   // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2.
   static bool relax_verify_for(oop class_loader);
 
  private:
-  static bool is_eligible_for_verification(instanceKlassHandle klass);
+  static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
   static symbolHandle inference_verify(
     instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
 };
--- a/hotspot/src/share/vm/code/debugInfoRec.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/code/debugInfoRec.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/code/nmethod.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/compiler/oopMap.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/compiler/oopMap.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/compiler/oopMap.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -302,9 +302,9 @@
     if (cur->isHumongous()) {
       return MemRegion(last_start, end);
     }
-    cur->reset_zero_fill();
     assert(cur == _regions.top(), "Should be top");
     if (!cur->is_empty()) break;
+    cur->reset_zero_fill();
     shrink_bytes -= cur->capacity();
     num_regions_deleted++;
     _regions.pop();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -2752,7 +2752,6 @@
   cm->revisit_klass_stack()->push(k);
 }
 
-#if ( defined(COMPILER1) || defined(COMPILER2) )
 void PSParallelCompact::revisit_mdo(ParCompactionManager* cm, DataLayout* p) {
   cm->revisit_mdo_stack()->push(p);
 }
@@ -2778,7 +2777,6 @@
     follow_stack(cm);
   }
 }
-#endif //  ( COMPILER1 || COMPILER2 )
 
 
 #ifdef VALIDATE_MARK_SWEEP
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,6 @@
   follow_stack();
 }
 
-#if ( defined(COMPILER1) || defined(COMPILER2) )
 void MarkSweep::revisit_mdo(DataLayout* p) {
   _revisit_mdo_stack->push(p);
 }
@@ -92,7 +91,6 @@
   }
   follow_stack();
 }
-#endif //  ( COMPILER1 || COMPILER2 )
 
 MarkSweep::FollowRootClosure  MarkSweep::follow_root_closure;
 
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/memory/iterator.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/memory/iterator.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2001 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/memory/iterator.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/memory/iterator.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/memory/serialize.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/memory/serialize.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -110,7 +110,7 @@
   // 1) Verify the bytecodes
   Verifier::Mode mode =
     throw_verifyerror ? Verifier::ThrowException : Verifier::NoException;
-  return Verifier::verify(this_oop, mode, CHECK_false);
+  return Verifier::verify(this_oop, mode, this_oop->should_verify_class(), CHECK_false);
 }
 
 
@@ -967,33 +967,78 @@
 
 
 // Lookup or create a jmethodID.
-// This code can be called by the VM thread.  For this reason it is critical that
-// there are no blocking operations (safepoints) while the lock is held -- or a
-// deadlock can occur.
-jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h) {
+// This code is called by the VMThread and JavaThreads so the
+// locking has to be done very carefully to avoid deadlocks
+// and/or other cache consistency problems.
+//
+jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, methodHandle method_h) {
   size_t idnum = (size_t)method_h->method_idnum();
   jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
   size_t length = 0;
   jmethodID id = NULL;
-  // array length stored in first element, other elements offset by one
-  if (jmeths == NULL ||                         // If there is no jmethodID array,
-      (length = (size_t)jmeths[0]) <= idnum ||  // or if it is too short,
-      (id = jmeths[idnum+1]) == NULL) {         // or if this jmethodID isn't allocated
+
+  // We use a double-check locking idiom here because this cache is
+  // performance sensitive. In the normal system, this cache only
+  // transitions from NULL to non-NULL which is safe because we use
+  // release_set_methods_jmethod_ids() to advertise the new cache.
+  // A partially constructed cache should never be seen by a racing
+  // thread. We also use release_store_ptr() to save a new jmethodID
+  // in the cache so a partially constructed jmethodID should never be
+  // seen either. Cache reads of existing jmethodIDs proceed without a
+  // lock, but cache writes of a new jmethodID requires uniqueness and
+  // creation of the cache itself requires no leaks so a lock is
+  // generally acquired in those two cases.
+  //
+  // If the RedefineClasses() API has been used, then this cache can
+  // grow and we'll have transitions from non-NULL to bigger non-NULL.
+  // Cache creation requires no leaks and we require safety between all
+  // cache accesses and freeing of the old cache so a lock is generally
+  // acquired when the RedefineClasses() API has been used.
 
-    // Do all the safepointing things (allocations) before grabbing the lock.
-    // These allocations will have to be freed if they are unused.
+  if (jmeths != NULL) {
+    // the cache already exists
+    if (!ik_h->idnum_can_increment()) {
+      // the cache can't grow so we can just get the current values
+      get_jmethod_id_length_value(jmeths, idnum, &length, &id);
+    } else {
+      // cache can grow so we have to be more careful
+      if (Threads::number_of_threads() == 0 ||
+          SafepointSynchronize::is_at_safepoint()) {
+        // we're single threaded or at a safepoint - no locking needed
+        get_jmethod_id_length_value(jmeths, idnum, &length, &id);
+      } else {
+        MutexLocker ml(JmethodIdCreation_lock);
+        get_jmethod_id_length_value(jmeths, idnum, &length, &id);
+      }
+    }
+  }
+  // implied else:
+  // we need to allocate a cache so default length and id values are good
 
-    // Allocate a new array of methods.
+  if (jmeths == NULL ||   // no cache yet
+      length <= idnum ||  // cache is too short
+      id == NULL) {       // cache doesn't contain entry
+
+    // This function can be called by the VMThread so we have to do all
+    // things that might block on a safepoint before grabbing the lock.
+    // Otherwise, we can deadlock with the VMThread or have a cache
+    // consistency issue. These vars keep track of what we might have
+    // to free after the lock is dropped.
+    jmethodID  to_dealloc_id     = NULL;
+    jmethodID* to_dealloc_jmeths = NULL;
+
+    // may not allocate new_jmeths or use it if we allocate it
     jmethodID* new_jmeths = NULL;
     if (length <= idnum) {
-      // A new array will be needed (unless some other thread beats us to it)
+      // allocate a new cache that might be used
       size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count());
       new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1);
       memset(new_jmeths, 0, (size+1)*sizeof(jmethodID));
-      new_jmeths[0] =(jmethodID)size;  // array size held in the first element
+      // cache size is stored in element[0], other elements offset by one
+      new_jmeths[0] = (jmethodID)size;
     }
 
-    // Allocate a new method ID.
+    // allocate a new jmethodID that might be used
     jmethodID new_id = NULL;
     if (method_h->is_old() && !method_h->is_obsolete()) {
       // The method passed in is old (but not obsolete), we need to use the current version
@@ -1007,63 +1052,111 @@
       new_id = JNIHandles::make_jmethod_id(method_h);
     }
 
-    if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
-      // No need and unsafe to lock the JmethodIdCreation_lock at safepoint.
-      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
+    if (Threads::number_of_threads() == 0 ||
+        SafepointSynchronize::is_at_safepoint()) {
+      // we're single threaded or at a safepoint - no locking needed
+      id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths,
+                                          &to_dealloc_id, &to_dealloc_jmeths);
     } else {
       MutexLocker ml(JmethodIdCreation_lock);
-      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
+      id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths,
+                                          &to_dealloc_id, &to_dealloc_jmeths);
+    }
+
+    // The lock has been dropped so we can free resources.
+    // Free up either the old cache or the new cache if we allocated one.
+    if (to_dealloc_jmeths != NULL) {
+      FreeHeap(to_dealloc_jmeths);
+    }
+    // free up the new ID since it wasn't needed
+    if (to_dealloc_id != NULL) {
+      JNIHandles::destroy_jmethod_id(to_dealloc_id);
     }
   }
   return id;
 }
 
 
-jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
-                                        jmethodID new_id, jmethodID* new_jmeths) {
-  // Retry lookup after we got the lock or ensured we are at safepoint
+// Common code to fetch the jmethodID from the cache or update the
+// cache with the new jmethodID. This function should never do anything
+// that causes the caller to go to a safepoint or we can deadlock with
+// the VMThread or have cache consistency issues.
+//
+jmethodID instanceKlass::get_jmethod_id_fetch_or_update(
+            instanceKlassHandle ik_h, size_t idnum, jmethodID new_id,
+            jmethodID* new_jmeths, jmethodID* to_dealloc_id_p,
+            jmethodID** to_dealloc_jmeths_p) {
+  assert(new_id != NULL, "sanity check");
+  assert(to_dealloc_id_p != NULL, "sanity check");
+  assert(to_dealloc_jmeths_p != NULL, "sanity check");
+  assert(Threads::number_of_threads() == 0 ||
+         SafepointSynchronize::is_at_safepoint() ||
+         JmethodIdCreation_lock->owned_by_self(), "sanity check");
+
+  // reacquire the cache - we are locked, single threaded or at a safepoint
   jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
-  jmethodID  id                = NULL;
-  jmethodID  to_dealloc_id     = NULL;
-  jmethodID* to_dealloc_jmeths = NULL;
-  size_t     length;
+  jmethodID  id     = NULL;
+  size_t     length = 0;
 
-  if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
+  if (jmeths == NULL ||                         // no cache yet
+      (length = (size_t)jmeths[0]) <= idnum) {  // cache is too short
     if (jmeths != NULL) {
-      // We have grown the array: copy the existing entries, and delete the old array
+      // copy any existing entries from the old cache
       for (size_t index = 0; index < length; index++) {
         new_jmeths[index+1] = jmeths[index+1];
       }
-      to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
+      *to_dealloc_jmeths_p = jmeths;  // save old cache for later delete
     }
     ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
   } else {
+    // fetch jmethodID (if any) from the existing cache
     id = jmeths[idnum+1];
-    to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
+    *to_dealloc_jmeths_p = new_jmeths;  // save new cache for later delete
   }
   if (id == NULL) {
+    // No matching jmethodID in the existing cache or we have a new
+    // cache or we just grew the cache. This cache write is done here
+    // by the first thread to win the foot race because a jmethodID
+    // needs to be unique once it is generally available.
     id = new_id;
-    jmeths[idnum+1] = id;  // install the new method ID
+
+    // The jmethodID cache can be read while unlocked so we have to
+    // make sure the new jmethodID is complete before installing it
+    // in the cache.
+    OrderAccess::release_store_ptr(&jmeths[idnum+1], id);
   } else {
-    to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
-  }
-
-  // Free up unneeded or no longer needed resources
-  FreeHeap(to_dealloc_jmeths);
-  if (to_dealloc_id != NULL) {
-    JNIHandles::destroy_jmethod_id(to_dealloc_id);
+    *to_dealloc_id_p = new_id; // save new id for later delete
   }
   return id;
 }
 
 
+// Common code to get the jmethodID cache length and the jmethodID
+// value at index idnum if there is one.
+//
+void instanceKlass::get_jmethod_id_length_value(jmethodID* cache,
+       size_t idnum, size_t *length_p, jmethodID* id_p) {
+  assert(cache != NULL, "sanity check");
+  assert(length_p != NULL, "sanity check");
+  assert(id_p != NULL, "sanity check");
+
+  // cache size is stored in element[0], other elements offset by one
+  *length_p = (size_t)cache[0];
+  if (*length_p <= idnum) {  // cache is too short
+    *id_p = NULL;
+  } else {
+    *id_p = cache[idnum+1];  // fetch jmethodID (if any)
+  }
+}
+
+
 // Lookup a jmethodID, NULL if not found.  Do no blocking, no allocations, no handles
 jmethodID instanceKlass::jmethod_id_or_null(methodOop method) {
   size_t idnum = (size_t)method->method_idnum();
   jmethodID* jmeths = methods_jmethod_ids_acquire();
   size_t length;                                // length assigned as debugging crumb
   jmethodID id = NULL;
-  if (jmeths != NULL &&                         // If there is a jmethodID array,
+  if (jmeths != NULL &&                         // If there is a cache
       (length = (size_t)jmeths[0]) > idnum) {   // and if it is long enough,
     id = jmeths[idnum+1];                       // Look up the id (may be NULL)
   }
@@ -1074,18 +1167,35 @@
 // Cache an itable index
 void instanceKlass::set_cached_itable_index(size_t idnum, int index) {
   int* indices = methods_cached_itable_indices_acquire();
-  if (indices == NULL ||                         // If there is no index array,
-      ((size_t)indices[0]) <= idnum) {           // or if it is too short
-    // Lock before we allocate the array so we don't leak
+  int* to_dealloc_indices = NULL;
+
+  // We use a double-check locking idiom here because this cache is
+  // performance sensitive. In the normal system, this cache only
+  // transitions from NULL to non-NULL which is safe because we use
+  // release_set_methods_cached_itable_indices() to advertise the
+  // new cache. A partially constructed cache should never be seen
+  // by a racing thread. Cache reads and writes proceed without a
+  // lock, but creation of the cache itself requires no leaks so a
+  // lock is generally acquired in that case.
+  //
+  // If the RedefineClasses() API has been used, then this cache can
+  // grow and we'll have transitions from non-NULL to bigger non-NULL.
+  // Cache creation requires no leaks and we require safety between all
+  // cache accesses and freeing of the old cache so a lock is generally
+  // acquired when the RedefineClasses() API has been used.
+
+  if (indices == NULL || idnum_can_increment()) {
+    // we need a cache or the cache can grow
     MutexLocker ml(JNICachedItableIndex_lock);
-    // Retry lookup after we got the lock
+    // reacquire the cache to see if another thread already did the work
     indices = methods_cached_itable_indices_acquire();
     size_t length = 0;
-    // array length stored in first element, other elements offset by one
+    // cache size is stored in element[0], other elements offset by one
     if (indices == NULL || (length = (size_t)indices[0]) <= idnum) {
       size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count());
       int* new_indices = NEW_C_HEAP_ARRAY(int, size+1);
-      // Copy the existing entries, if any
+      new_indices[0] = (int)size;
+      // copy any existing entries
       size_t i;
       for (i = 0; i < length; i++) {
         new_indices[i+1] = indices[i+1];
@@ -1095,15 +1205,32 @@
         new_indices[i+1] = -1;
       }
       if (indices != NULL) {
-        FreeHeap(indices);  // delete any old indices
+        // We have an old cache to delete so save it for after we
+        // drop the lock.
+        to_dealloc_indices = indices;
       }
       release_set_methods_cached_itable_indices(indices = new_indices);
     }
+
+    if (idnum_can_increment()) {
+      // this cache can grow so we have to write to it safely
+      indices[idnum+1] = index;
+    }
   } else {
     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
   }
-  // This is a cache, if there is a race to set it, it doesn't matter
-  indices[idnum+1] = index;
+
+  if (!idnum_can_increment()) {
+    // The cache cannot grow and this JNI itable index value does not
+    // have to be unique like a jmethodID. If there is a race to set it,
+    // it doesn't matter.
+    indices[idnum+1] = index;
+  }
+
+  if (to_dealloc_indices != NULL) {
+    // we allocated a new cache so free the old one
+    FreeHeap(to_dealloc_indices);
+  }
 }
 
 
@@ -2299,6 +2426,11 @@
 
 // Add an information node that contains weak references to the
 // interesting parts of the previous version of the_class.
+// This is also where we clean out any unused weak references.
+// Note that while we delete nodes from the _previous_versions
+// array, we never delete the array itself until the klass is
+// unloaded. The has_been_redefined() query depends on that fact.
+//
 void instanceKlass::add_previous_version(instanceKlassHandle ikh,
        BitMap* emcp_methods, int emcp_method_count) {
   assert(Thread::current()->is_VM_thread(),
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -217,6 +217,7 @@
   bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
   bool            _rewritten;            // methods rewritten.
   bool            _has_nonstatic_fields; // for sizing with UseCompressedOops
+  bool            _should_verify_class;  // allow caching of preverification
   u2              _minor_version;        // minor version number of class file
   u2              _major_version;        // major version number of class file
   ClassState      _init_state;           // state of class
@@ -362,6 +363,10 @@
   int  get_init_state()                    { return _init_state; } // Useful for debugging
   bool is_rewritten() const                { return _rewritten; }
 
+  // defineClass specified verification
+  bool should_verify_class() const         { return _should_verify_class; }
+  void set_should_verify_class(bool value) { _should_verify_class = value; }
+
   // marking
   bool is_marked_dependent() const         { return _is_marked_dependent; }
   void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
@@ -460,6 +465,10 @@
   // RedefineClasses() support for previous versions:
   void add_previous_version(instanceKlassHandle ikh, BitMap *emcp_methods,
          int emcp_method_count);
+  // If the _previous_versions array is non-NULL, then this klass
+  // has been redefined at least once even if we aren't currently
+  // tracking a previous version.
+  bool has_been_redefined() const { return _previous_versions != NULL; }
   bool has_previous_version() const;
   void init_previous_versions() {
     _previous_versions = NULL;
@@ -501,9 +510,14 @@
   void set_bootstrap_method(oop mh)                   { oop_store(&_bootstrap_method, mh); }
 
   // jmethodID support
-  static jmethodID get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
-                                  jmethodID new_id, jmethodID* new_jmeths);
-  static jmethodID jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h);
+  static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
+                     methodHandle method_h);
+  static jmethodID get_jmethod_id_fetch_or_update(instanceKlassHandle ik_h,
+                     size_t idnum, jmethodID new_id, jmethodID* new_jmeths,
+                     jmethodID* to_dealloc_id_p,
+                     jmethodID** to_dealloc_jmeths_p);
+  static void get_jmethod_id_length_value(jmethodID* cache, size_t idnum,
+                size_t *length_p, jmethodID* id_p);
   jmethodID jmethod_id_or_null(methodOop method);
 
   // cached itable index support
@@ -749,6 +763,11 @@
   void set_init_thread(Thread *thread)  { _init_thread = thread; }
 
   u2 idnum_allocated_count() const      { return _idnum_allocated_count; }
+  // The RedefineClasses() API can cause new method idnums to be needed
+  // which will cause the caches to grow. Safety requires different
+  // cache management logic if the caches can grow instead of just
+  // going from NULL to non-NULL.
+  bool idnum_can_increment() const      { return has_been_redefined(); }
   jmethodID* methods_jmethod_ids_acquire() const
          { return (jmethodID*)OrderAccess::load_ptr_acquire(&_methods_jmethod_ids); }
   void release_set_methods_jmethod_ids(jmethodID* jmeths)
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/oops/methodDataOop.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/methodDataOop.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/oops/methodOop.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/methodOop.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -555,7 +555,7 @@
 
   // Get this method's jmethodID -- allocate if it doesn't exist
   jmethodID jmethod_id()                            { methodHandle this_h(this);
-                                                      return instanceKlass::jmethod_id_for_impl(method_holder(), this_h); }
+                                                      return instanceKlass::get_jmethod_id(method_holder(), this_h); }
 
   // Lookup the jmethodID for this method.  Return NULL if not found.
   // NOTE that this function can be called from a signal handler
--- a/hotspot/src/share/vm/oops/objArrayOop.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/oops/objArrayOop.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/compile.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -439,6 +439,11 @@
   Node *base = addp->in(AddPNode::Base)->uncast();
   if (base->is_top()) { // The AddP case #3 and #6.
     base = addp->in(AddPNode::Address)->uncast();
+    while (base->is_AddP()) {
+      // Case #6 (unsafe access) may have several chained AddP nodes.
+      assert(base->in(AddPNode::Base)->is_top(), "expected unsafe access address only");
+      base = base->in(AddPNode::Address)->uncast();
+    }
     assert(base->Opcode() == Op_ConP || base->Opcode() == Op_ThreadLocal ||
            base->Opcode() == Op_CastX2P || base->is_DecodeN() ||
            (base->is_Mem() && base->bottom_type() == TypeRawPtr::NOTNULL) ||
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -622,11 +622,13 @@
 
 //---------------------------PreserveReexecuteState----------------------------
 PreserveReexecuteState::PreserveReexecuteState(GraphKit* kit) {
+  assert(!kit->stopped(), "must call stopped() before");
   _kit    =    kit;
   _sp     =    kit->sp();
   _reexecute = kit->jvms()->_reexecute;
 }
 PreserveReexecuteState::~PreserveReexecuteState() {
+  if (_kit->stopped()) return;
   _kit->jvms()->_reexecute = _reexecute;
   _kit->set_sp(_sp);
 }
@@ -1086,7 +1088,7 @@
     alen = _gvn.transform( new (C, 3) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS));
   } else {
     alen = alloc->Ideal_length();
-    Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_aryptr(), &_gvn);
+    Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn);
     if (ccast != alen) {
       alen = _gvn.transform(ccast);
     }
@@ -1123,8 +1125,8 @@
     case T_OBJECT : {
       const Type *t = _gvn.type( value );
 
-      const TypeInstPtr* tp = t->isa_instptr();
-      if (tp != NULL && !tp->klass()->is_loaded()
+      const TypeOopPtr* tp = t->isa_oopptr();
+      if (tp != NULL && tp->klass() != NULL && !tp->klass()->is_loaded()
           // Only for do_null_check, not any of its siblings:
           && !assert_null && null_control == NULL) {
         // Usually, any field access or invocation on an unloaded oop type
--- a/hotspot/src/share/vm/opto/idealKit.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/idealKit.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/idealKit.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/idealKit.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/ifnode.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/ifnode.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -3903,19 +3903,10 @@
     guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), "");
   }
 
-  // Cast to Object for arraycopy.
-  // We can't use the original CheckCastPP since it should be moved
-  // after the arraycopy to prevent stores flowing above it.
-  Node* new_obj = new(C, 2) CheckCastPPNode(alloc_obj->in(0), raw_obj,
-                                            TypeInstPtr::NOTNULL);
-  new_obj = _gvn.transform(new_obj);
-  // Substitute in the locally valid dest_oop.
-  replace_in_map(alloc_obj, new_obj);
-
   // Copy the fastest available way.
   // TODO: generate fields copies for small objects instead.
   Node* src  = obj;
-  Node* dest = new_obj;
+  Node* dest = alloc_obj;
   Node* size = _gvn.transform(obj_size);
 
   // Exclude the header but include array length to copy by 8 bytes words.
@@ -3961,7 +3952,7 @@
     int raw_adr_idx = Compile::AliasIdxRaw;
     post_barrier(control(),
                  memory(raw_adr_type),
-                 new_obj,
+                 alloc_obj,
                  no_particular_field,
                  raw_adr_idx,
                  no_particular_value,
@@ -3969,16 +3960,8 @@
                  false);
   }
 
-  // Move the original CheckCastPP after arraycopy.
-  _gvn.hash_delete(alloc_obj);
-  alloc_obj->set_req(0, control());
-  // Replace raw memory edge with new CheckCastPP to have a live oop
-  // at safepoints instead of raw value.
-  assert(new_obj->is_CheckCastPP() && new_obj->in(1) == alloc_obj->in(1), "sanity");
-  alloc_obj->set_req(1, new_obj);    // cast to the original type
-  _gvn.hash_find_insert(alloc_obj);  // put back into GVN table
-  // Restore in the locally valid dest_oop.
-  replace_in_map(new_obj, alloc_obj);
+  // Do not let reads from the cloned object float above the arraycopy.
+  insert_mem_bar(Op_MemBarCPUOrder);
 }
 
 //------------------------inline_native_clone----------------------------
@@ -4448,15 +4431,6 @@
     assert(init->is_complete(), "we just did this");
     assert(dest->is_CheckCastPP(), "sanity");
     assert(dest->in(0)->in(0) == init, "dest pinned");
-
-    // Cast to Object for arraycopy.
-    // We can't use the original CheckCastPP since it should be moved
-    // after the arraycopy to prevent stores flowing above it.
-    Node* new_obj = new(C, 2) CheckCastPPNode(dest->in(0), dest->in(1),
-                                              TypeInstPtr::NOTNULL);
-    dest = _gvn.transform(new_obj);
-    // Substitute in the locally valid dest_oop.
-    replace_in_map(original_dest, dest);
     adr_type = TypeRawPtr::BOTTOM;  // all initializations are into raw memory
     // From this point on, every exit path is responsible for
     // initializing any non-copied parts of the object to zero.
@@ -4786,18 +4760,6 @@
   set_i_o(     _gvn.transform(result_i_o)    );
   set_memory(  _gvn.transform(result_memory), adr_type );
 
-  if (dest != original_dest) {
-    // Pin the "finished" array node after the arraycopy/zeroing operations.
-    _gvn.hash_delete(original_dest);
-    original_dest->set_req(0, control());
-    // Replace raw memory edge with new CheckCastPP to have a live oop
-    // at safepoints instead of raw value.
-    assert(dest->is_CheckCastPP() && dest->in(1) == original_dest->in(1), "sanity");
-    original_dest->set_req(1, dest);       // cast to the original type
-    _gvn.hash_find_insert(original_dest);  // put back into GVN table
-    // Restore in the locally valid dest_oop.
-    replace_in_map(dest, original_dest);
-  }
   // The memory edges above are precise in order to model effects around
   // array copies accurately to allow value numbering of field loads around
   // arraycopy.  Such field loads, both before and after, are common in Java
@@ -4808,7 +4770,9 @@
   // The next memory barrier is added to avoid it. If the arraycopy can be
   // optimized away (which it can, sometimes) then we can manually remove
   // the membar also.
-  if (InsertMemBarAfterArraycopy)
+  //
+  // Do not let reads from the cloned object float above the arraycopy.
+  if (InsertMemBarAfterArraycopy || alloc != NULL)
     insert_mem_bar(Op_MemBarCPUOrder);
 }
 
--- a/hotspot/src/share/vm/opto/phaseX.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/phaseX.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/phaseX.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/phaseX.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/postaloc.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/postaloc.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -990,8 +990,8 @@
 // (5) We know there is no dependence cycle, so there in no other case;
 // (6) Finally, all memory ops in another single pack should be moved in the same direction.
 //
-// To schedule a load pack: the memory edge of every loads in the pack must be
-// the same as the memory edge of the last executed load in the pack
+// To schedule a load pack, we use the memory state of either the first or the last load in
+// the pack, based on the dependence constraint.
 void SuperWord::co_locate_pack(Node_List* pk) {
   if (pk->at(0)->is_Store()) {
     MemNode* first     = executed_first(pk)->as_Mem();
@@ -1076,15 +1076,32 @@
       current = my_mem->as_Mem();
     } // end while
   } else if (pk->at(0)->is_Load()) { //load
-    // all use the memory state that the last executed load uses
-    LoadNode* last_load  = executed_last(pk)->as_Load();
-    Node* last_mem       = last_load->in(MemNode::Memory);
-    _igvn.hash_delete(last_mem);
-    // Give each load same memory state as last
+    // all loads in the pack should have the same memory state. By default,
+    // we use the memory state of the last load. However, if any load could
+    // not be moved down due to the dependence constraint, we use the memory
+    // state of the first load.
+    Node* last_mem  = executed_last(pk)->in(MemNode::Memory);
+    Node* first_mem = executed_first(pk)->in(MemNode::Memory);
+    bool schedule_last = true;
+    for (uint i = 0; i < pk->size(); i++) {
+      Node* ld = pk->at(i);
+      for (Node* current = last_mem; current != ld->in(MemNode::Memory);
+           current=current->in(MemNode::Memory)) {
+        assert(current != first_mem, "corrupted memory graph");
+        if(current->is_Mem() && !independent(current, ld)){
+          schedule_last = false; // a later store depends on this load
+          break;
+        }
+      }
+    }
+
+    Node* mem_input = schedule_last ? last_mem : first_mem;
+    _igvn.hash_delete(mem_input);
+    // Give each load the same memory state
     for (uint i = 0; i < pk->size(); i++) {
       LoadNode* ld = pk->at(i)->as_Load();
       _igvn.hash_delete(ld);
-      ld->set_req(MemNode::Memory, last_mem);
+      ld->set_req(MemNode::Memory, mem_input);
       _igvn._worklist.push(ld);
     }
   }
--- a/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -2236,12 +2236,12 @@
 
 //------------------------------make-------------------------------------------
 const TypeOopPtr *TypeOopPtr::make(PTR ptr,
-                                   int offset) {
+                                   int offset, int instance_id) {
   assert(ptr != Constant, "no constant generic pointers");
   ciKlass*  k = ciKlassKlass::make();
   bool      xk = false;
   ciObject* o = NULL;
-  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, InstanceBot))->hashcons();
+  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id))->hashcons();
 }
 
 
@@ -2330,7 +2330,8 @@
 
   case OopPtr: {                 // Meeting to other OopPtrs
     const TypeOopPtr *tp = t->is_oopptr();
-    return make( meet_ptr(tp->ptr()), meet_offset(tp->offset()) );
+    int instance_id = meet_instance_id(tp->instance_id());
+    return make( meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id );
   }
 
   case InstPtr:                  // For these, flip the call around to cut down
@@ -2801,7 +2802,7 @@
 
   case OopPtr: {                // Meeting to OopPtrs
     // Found a OopPtr type vs self-InstPtr type
-    const TypePtr *tp = t->is_oopptr();
+    const TypeOopPtr *tp = t->is_oopptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
     switch (tp->ptr()) {
@@ -2812,8 +2813,10 @@
                   (ptr == Constant ? const_oop() : NULL), offset, instance_id);
     }
     case NotNull:
-    case BotPTR:
-      return TypeOopPtr::make(ptr, offset);
+    case BotPTR: {
+      int instance_id = meet_instance_id(tp->instance_id());
+      return TypeOopPtr::make(ptr, offset, instance_id);
+    }
     default: typerr(t);
     }
   }
@@ -3259,7 +3262,7 @@
 
   case OopPtr: {                // Meeting to OopPtrs
     // Found a OopPtr type vs self-AryPtr type
-    const TypePtr *tp = t->is_oopptr();
+    const TypeOopPtr *tp = t->is_oopptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
     switch (tp->ptr()) {
@@ -3270,8 +3273,10 @@
                   _ary, _klass, _klass_is_exact, offset, instance_id);
     }
     case BotPTR:
-    case NotNull:
-      return TypeOopPtr::make(ptr, offset);
+    case NotNull: {
+      int instance_id = meet_instance_id(tp->instance_id());
+      return TypeOopPtr::make(ptr, offset, instance_id);
+    }
     default: ShouldNotReachHere();
     }
   }
--- a/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -714,7 +714,7 @@
   static const TypeOopPtr* make_from_constant(ciObject* o);
 
   // Make a generic (unclassed) pointer to an oop.
-  static const TypeOopPtr* make(PTR ptr, int offset);
+  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id = InstanceBot);
 
   ciObject* const_oop()    const { return _const_oop; }
   virtual ciKlass* klass() const { return _klass;     }
--- a/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -299,7 +299,8 @@
     }
   }
   klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader,
-                                                     Handle(), &st, CHECK_NULL);
+                                                     Handle(), &st, true,
+                                                     CHECK_NULL);
 
   if (TraceClassResolution && k != NULL) {
     trace_class_resolution(k);
--- a/hotspot/src/share/vm/prims/jvm.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -762,7 +762,11 @@
 }
 
 // common code for JVM_DefineClass() and JVM_DefineClassWithSource()
-static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
+// and JVM_DefineClassWithSourceCond()
+static jclass jvm_define_class_common(JNIEnv *env, const char *name,
+                                      jobject loader, const jbyte *buf,
+                                      jsize len, jobject pd, const char *source,
+                                      jboolean verify, TRAPS) {
   if (source == NULL)  source = "__JVM_DefineClass__";
 
   assert(THREAD->is_Java_thread(), "must be a JavaThread");
@@ -803,6 +807,7 @@
   Handle protection_domain (THREAD, JNIHandles::resolve(pd));
   klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader,
                                                      protection_domain, &st,
+                                                     verify != 0,
                                                      CHECK_NULL);
 
   if (TraceClassResolution && k != NULL) {
@@ -816,16 +821,24 @@
 JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
   JVMWrapper2("JVM_DefineClass %s", name);
 
-  return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
+  return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, true, THREAD);
 JVM_END
 
 
 JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
   JVMWrapper2("JVM_DefineClassWithSource %s", name);
 
-  return jvm_define_class_common(env, name, loader, buf, len, pd, source, THREAD);
-JVM_END
-
+  return jvm_define_class_common(env, name, loader, buf, len, pd, source, true, THREAD);
+JVM_END
+
+JVM_ENTRY(jclass, JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name,
+                                                jobject loader, const jbyte *buf,
+                                                jsize len, jobject pd,
+                                                const char *source, jboolean verify))
+  JVMWrapper2("JVM_DefineClassWithSourceCond %s", name);
+
+  return jvm_define_class_common(env, name, loader, buf, len, pd, source, verify, THREAD);
+JVM_END
 
 JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))
   JVMWrapper("JVM_FindLoadedClass");
--- a/hotspot/src/share/vm/prims/jvm.h	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvm.h	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -417,6 +417,17 @@
                           const jbyte *buf, jsize len, jobject pd,
                           const char *source);
 
+/* Define a class with a source with conditional verification (added HSX 14)
+ * -Xverify:all will verify anyway, -Xverify:none will not verify,
+ * -Xverify:remote (default) will obey this conditional
+ * i.e. true = should_verify_class
+ */
+JNIEXPORT jclass JNICALL
+JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name,
+                              jobject loader, const jbyte *buf,
+                              jsize len, jobject pd, const char *source,
+                              jboolean verify);
+
 /* Define a class with a source (MLVM) */
 JNIEXPORT jclass JNICALL
 JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -933,7 +933,7 @@
       // description.
       RedefineVerifyMark rvm(&the_class, &scratch_class, state);
       Verifier::verify(
-        scratch_class, Verifier::ThrowException, THREAD);
+        scratch_class, Verifier::ThrowException, true, THREAD);
     }
 
     if (HAS_PENDING_EXCEPTION) {
@@ -959,7 +959,7 @@
       // verify what we have done during constant pool merging
       {
         RedefineVerifyMark rvm(&the_class, &scratch_class, state);
-        Verifier::verify(scratch_class, Verifier::ThrowException, THREAD);
+        Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD);
       }
 
       if (HAS_PENDING_EXCEPTION) {
--- a/hotspot/src/share/vm/runtime/atomic.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/atomic.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/runtime/perfData.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/perfData.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -769,9 +769,23 @@
   // to grab the Threads_lock which we own here, so a thread cannot be
   // resumed during safepoint synchronization.
 
-  // We check with locking because another thread that has not yet
-  // synchronized may be trying to suspend this one.
-  bool is_suspended = _thread->is_any_suspended_with_lock();
+  // We check to see if this thread is suspended without locking to
+  // avoid deadlocking with a third thread that is waiting for this
+  // thread to be suspended. The third thread can notice the safepoint
+  // that we're trying to start at the beginning of its SR_lock->wait()
+  // call. If that happens, then the third thread will block on the
+  // safepoint while still holding the underlying SR_lock. We won't be
+  // able to get the SR_lock and we'll deadlock.
+  //
+  // We don't need to grab the SR_lock here for two reasons:
+  // 1) The suspend flags are both volatile and are set with an
+  //    Atomic::cmpxchg() call so we should see the suspended
+  //    state right away.
+  // 2) We're being called from the safepoint polling loop; if
+  //    we don't see the suspended state on this iteration, then
+  //    we'll come around again.
+  //
+  bool is_suspended = _thread->is_ext_suspended();
   if (is_suspended) {
     roll_forward(_at_safepoint);
     return;
--- a/hotspot/src/share/vm/runtime/sweeper.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1942,7 +1942,7 @@
 
   MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
 
-  assert(!this->is_any_suspended(),
+  assert(!this->is_ext_suspended(),
     "a thread trying to self-suspend should not already be suspended");
 
   if (this->is_suspend_equivalent()) {
--- a/hotspot/src/share/vm/runtime/thread.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -967,11 +967,6 @@
     return (_suspend_flags & _ext_suspended) != 0;
   }
 
-  // legacy method that checked for either external suspension or vm suspension
-  bool is_any_suspended() const {
-    return is_ext_suspended();
-  }
-
   bool is_external_suspend_with_lock() const {
     MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
     return is_external_suspend();
@@ -997,10 +992,6 @@
     return ret;
   }
 
-  bool is_any_suspended_with_lock() const {
-    MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
-    return is_any_suspended();
-  }
   // utility methods to see if we are doing some kind of suspension
   bool is_being_ext_suspended() const            {
     MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
--- a/hotspot/src/share/vm/runtime/vframeArray.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vframeArray.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/runtime/vframe_hp.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vframe_hp.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/services/threadService.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/services/threadService.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/services/threadService.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/src/share/vm/services/threadService.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/test/compiler/6636138/Test1.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/test/compiler/6636138/Test1.java	Wed Jul 05 17:01:15 2017 +0200
@@ -45,7 +45,7 @@
         for (int i = 0; i < src.length; i++) {
             if (src[i] != ref[i]) {
                 System.out.println("Error: src and ref don't match at " + i);
-                System.exit(-1);
+                System.exit(97);
             }
         }
     }
--- a/hotspot/test/compiler/6636138/Test2.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/test/compiler/6636138/Test2.java	Wed Jul 05 17:01:15 2017 +0200
@@ -51,7 +51,7 @@
             int value = (i-1 + src.length)%src.length; // correct value after shifting
                 if (src[i] != value) {
                     System.out.println("Error: src["+i+"] should be "+ value + " instead of " + src[i]);
-                    System.exit(-1);
+                    System.exit(97);
                 }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6855215/Test6855215.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6855215
+ * @summary Calculation error (NaN) after about 1500 calculations
+ *
+ * @run main/othervm -Xbatch -XX:UseSSE=0 Test6855215
+ */
+
+public class Test6855215 {
+    private double m;
+    private double b;
+
+    public static double log10(double x) {
+        return Math.log(x) / Math.log(10);
+    }
+
+    void calcMapping(double xmin, double xmax, double ymin, double ymax) {
+        m = (ymax - ymin) / (log10(xmax) - log10(xmin));
+        b = (log10(xmin) * ymax - log10(xmax) * ymin);
+    }
+
+    public static void main(String[] args) {
+        Test6855215 c = new Test6855215();
+        for (int i = 0; i < 30000; i++) {
+            c.calcMapping(91, 121, 177, 34);
+            if (c.m != c.m) {
+                throw new InternalError();
+            }
+        }
+    }
+}
--- a/hotspot/test/compiler/6865031/Test.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/hotspot/test/compiler/6865031/Test.java	Wed Jul 05 17:01:15 2017 +0200
@@ -26,7 +26,7 @@
  * @test
  * @bug 6865031
  * @summary Application gives bad result (throws bad exception) with compressed oops
- * @run main/othervm -XX:+UseCompressedOops -XX:HeapBaseMinAddress=32g -XX:-LoopUnswitching -XX:CompileCommand=inline,AbstractMemoryEfficientList.equals Test hello goodbye
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:HeapBaseMinAddress=32g -XX:-LoopUnswitching -XX:CompileCommand=inline,AbstractMemoryEfficientList.equals Test hello goodbye
  */
 
 import java.lang.ref.ReferenceQueue;
--- a/jaxp/.hgignore	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxp/.hgignore	Wed Jul 05 17:01:15 2017 +0200
@@ -1,4 +1,5 @@
 ^build/
 ^dist/
+^drop/
 ^webrev/
 ^nbproject/private/
--- a/jaxp/.hgtags	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 17:01:15 2017 +0200
@@ -46,3 +46,4 @@
 a4ab0d6ded63bed0fd1e5be55d38090e0ee5efb7 jdk7-b69
 c83f0106b78a85c7e614d27a328675460b2081cf jdk7-b70
 ff94d8ce0daded647bb326630e643d010357afce jdk7-b71
+37c805b6156fd492c12301688b54a6bcca39e729 jdk7-b72
--- a/jaxp/README	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxp/README	Wed Jul 05 17:01:15 2017 +0200
@@ -1,14 +1,25 @@
 README:
-  This file should be located at the top of the jaxp Mercurial repository.
+  
+  This file should be located at the top of the Mercurial repository.
 
   See http://openjdk.java.net/ for more information about the OpenJDK.
 
   See ../README-builds.html for complete details on build machine requirements.
 
 Simple Build Instructions:
-
+  This repository can be loaded as a NetBeans project, built with ant, or
+  built with GNU make, e.g.
+    ant
+       -OR-
     cd make && gnumake
      
-  The files that will be imported into the jdk build will be in the "dist"
-  directory.
+  The built files that will be imported into the jdk build will be in the 
+  "dist" directory.
+  Help information is available by running "ant -projecthelp" or "make help".
 
+Drop Repository:
+  This repository builds sources from a created "drop" source directory.
+  These files will normally be copied from a shared directory area or
+  downloaded from a public website.
+  See the ant build script (build.xml) for more details.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/build-defs.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Sun designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Sun in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ CA 95054 USA or visit www.sun.com if you need additional information or
+ have any questions.
+-->
+
+<project name="jaxp_defs" default="all" basedir=".">
+
+    <!-- Specific build properties. -->
+    <property file="jaxp.properties"/>
+
+    <!-- Where generated xml files will stay. -->
+    <property name="xml.gen.dir" value="${build.dir}/xml_generated"/>
+    <property name="xml.template" value="build-drop-template.xml"/>
+
+    <!--  ############### -->
+    <!--  Begin Macrodefs -->
+
+    <!-- Copies template file, replaces @DROP@ pattern, and imports it. -->
+    <macrodef name="drop-import">
+        <attribute name="name"/>
+        <sequential>
+            <property name="xml.gen.@{name}" value="${xml.gen.dir}/build-drop-@{name}.xml"/>
+            <mkdir dir="${xml.gen.dir}"/>
+            <copy file="${xml.template}" tofile="${xml.gen.@{name}}"/>
+            <replace file="${xml.gen.@{name}}" token="@DROP@" value="@{name}"/>
+            <import file="${xml.gen.@{name}}"/>
+        </sequential>
+    </macrodef>
+
+    <!--  End of Macrodefs -->
+    <!--  ############### -->
+
+    <!-- Create xml file and import it for these drops. -->
+    <drop-import name="jaxp_src"/>
+    <!-- <drop-import name="jaxp_tests"/> -->
+
+
+    <!-- Special build area preparation. -->
+    <target name="-drop-build-prep" depends="init, -init-src-dirs">
+        <mkdir dir="${build.classes.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${primary.src.dir}"
+                     includes="**/*.properties"/>
+        </copy>
+        <replaceregexp match="#(.*)$" replace="#" flags="gm">
+            <fileset dir="${build.classes.dir}" includes="**/*.properties"/>
+        </replaceregexp>
+    </target>
+
+    <!-- Try to get drop sources, set property use.orig.src.dir if no drops. -->
+    <target name="-set-props"
+	    depends="init,
+                     jaxp_src-update">
+        <condition property="use.orig.src.dir">
+            <and>
+                <available file="${orig.src.dir}" type="dir"/>
+                <not>
+                    <and>
+                        <available file="${jaxp_src.src.dir}" type="dir"/>
+                    </and>
+                </not>
+            </and>
+        </condition>
+    </target>
+
+    <!-- Set up source to use orig.src.dir, if use.orig.src.dir defined. -->
+    <target name="-use-orig" depends="-set-props" if="use.orig.src.dir">
+        <property name="primary.src.dir" value="${orig.src.dir}"/>
+        <path id="src.dir.id">
+            <pathelement path="${primary.src.dir}"/>
+        </path>
+    </target>
+
+    <!-- Set up source to use drop.dir, if use.orig.src.dir not defined. -->
+    <target name="-use-drop" depends="-set-props" unless="use.orig.src.dir">
+        <property name="primary.src.dir" value="${jaxp_src.src.dir}"/>
+        <path id="src.dir.id">
+            <pathelement path="${primary.src.dir}"/>
+        </path>
+    </target>
+
+    <!-- Source directory selection. -->
+    <target name="-init-src-dirs"
+	    depends="init, -use-orig, -use-drop">
+        <echo message="Using primary.src.dir=${primary.src.dir}"/>
+        <pathconvert property="src.list.id" refid="src.dir.id"/>
+        <echo message="Using src.dir.id=${src.list.id}"/>
+    </target>
+
+    <!-- Create orig src.zip. -->
+    <target name="-orig-src-zip" depends="init, -set-props" if="use.orig.src.dir">
+        <zip file="${dist.src.zip}" basedir="${primary.src.dir}"/>
+    </target>
+
+    <!-- Create drop src.zip. -->
+    <target name="-drop-src-zip" depends="init, -set-props" unless="use.orig.src.dir">
+        <zip file="${dist.src.zip}" basedir="${primary.src.dir}"/>
+    </target>
+
+    <!-- Create src.zip. -->
+    <target name="-dist-src-zip" depends="init, -orig-src-zip, -drop-src-zip">
+    </target>
+    
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/build-drop-template.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Sun designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Sun in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ CA 95054 USA or visit www.sun.com if you need additional information or
+ have any questions.
+-->
+
+<project name="@DROP@-drop" default="all" basedir=".">
+
+    <!-- Locations of master drop bundles. -->
+    <property name="@DROP@.master.bundle.copy"
+              value="${@DROP@.master.bundle.dir}/${@DROP@.bundle.name}"/>
+    <property name="@DROP@.master.bundle.url"
+              value="${@DROP@.master.bundle.url.base}/${@DROP@.bundle.name}"/>
+
+    <!-- Location where the copied bundle lands. -->
+    <property name="@DROP@.bundle.copy"
+              value="${drop.dir}/bundles/${@DROP@.bundle.name}"/>
+
+    <!-- Root of exploded area. -->
+    <property name="@DROP@.root.dir" value="${drop.dir}/@DROP@"/>
+    <property name="@DROP@.src.dir" value="${@DROP@.root.dir}/src"/>
+
+    <!-- To see if the drop areas are ready. (ignoring bundles) -->
+    <target name="-@DROP@-ready">
+        <condition property="@DROP@.ready">
+            <and>
+                <available file="${@DROP@.root.dir}" type="dir"/>
+                <available file="${@DROP@.root.dir}/PATCHED" type="file"/>
+            </and>
+        </condition>
+    </target>
+
+    <!-- Copy over bundles from some shared master area. -->
+    <condition property="@DROP@.master.bundle.copy.exists">
+        <available file="${@DROP@.master.bundle.copy}" type="file"/>
+    </condition>
+    <target name="-@DROP@-copy-bundle"
+	    depends="init, -@DROP@-ready"
+            if="@DROP@.master.bundle.copy.exists"
+            unless="@DROP@.ready">
+        <echo message="Copying from ${@DROP@.master.bundle.copy}"/>
+        <dirname property="@DROP@.bundle.dirname" file="${@DROP@.bundle.copy}"/>
+        <mkdir dir="${@DROP@.bundle.dirname}"/>
+        <delete file="${@DROP@.bundle.copy}.temp"/>
+        <delete file="${@DROP@.bundle.copy}"/>
+        <copy file="${@DROP@.master.bundle.copy}" tofile="${@DROP@.bundle.copy}.temp"/>
+        <move file="${@DROP@.bundle.copy}.temp" tofile="${@DROP@.bundle.copy}"/>
+        <property name="@DROP@.master.bundle.found" value="true"/>
+    </target>
+
+    <!-- Determine if the master url download should be used. -->
+    <target name="-@DROP@-url-should-be-used" unless="@DROP@.url.should.be.used">
+        <condition property="@DROP@.url.should.be.used">
+            <and>
+                <http url="${@DROP@.master.bundle.url.base}"/>
+                <not>
+                    <isset property="@DROP@.master.bundle.copy.exists"/>
+                </not>
+            </and>
+        </condition>
+    </target>
+
+    <!-- Download bundles from a url. -->
+    <target name="-@DROP@-url-bundle"
+	    depends="init, -@DROP@-ready, -@DROP@-url-should-be-used"
+            if="@DROP@.url.should.be.used"
+            unless="@DROP@.ready">
+        <echo message="Downloading from ${@DROP@.master.bundle.url}"/>
+        <dirname property="@DROP@.bundle.dirname" file="${@DROP@.bundle.copy}"/>
+        <mkdir dir="${@DROP@.bundle.dirname}"/>
+        <delete file="${@DROP@.bundle.copy}.temp"/>
+        <delete file="${@DROP@.bundle.copy}"/>
+        <get src="${@DROP@.master.bundle.url}" dest="${@DROP@.bundle.copy}.temp"/>
+        <move file="${@DROP@.bundle.copy}.temp" tofile="${@DROP@.bundle.copy}"/>
+        <property name="@DROP@.master.bundle.found" value="true"/>
+    </target>
+    
+    <!-- Fill in the drop zones, but just when needed. -->
+    <target name="@DROP@-update"
+            depends="init, 
+		     -@DROP@-copy-bundle,
+		     -@DROP@-url-bundle,
+                     -@DROP@-ready"
+            if="@DROP@.master.bundle.found"
+            unless="@DROP@.ready">
+        <delete dir="${@DROP@.root.dir}"/>
+        <delete dir="${@DROP@.root.dir}-temp"/>
+        <mkdir dir="${@DROP@.root.dir}-temp"/>
+        <unzip src="${@DROP@.bundle.copy}" dest="${@DROP@.root.dir}-temp"/>
+        <move file="${@DROP@.root.dir}-temp" tofile="${@DROP@.root.dir}"/>
+        <touch>
+            <fileset dir="${@DROP@.root.dir}"/>
+        </touch>
+        <condition property="patch.utility" value="gpatch" else="patch">
+            <os name="SunOS"/>
+        </condition>
+        <apply executable="${patch.utility}"
+		   dir="${@DROP@.root.dir}"
+	           parallel="false"
+	           failonerror="true"
+	           verbose="true">
+            <arg value="-l"/>
+            <arg value="-p0"/>
+            <arg value="-i"/>
+            <filelist dir="${patches.dir}/@DROP@" files="${@DROP@.patch.list}"/>
+        </apply>
+        <echo file="${@DROP@.root.dir}/PATCHED"
+	      message="Patches have been applied."/>
+    </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/build.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,103 @@
+#
+# Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# Base locations where bundles are located
+slashjava=/java
+devtools=${slashjava}/devtools
+
+# This is the JDK used to build and run the bootstrap version of javac.
+# The bootstrap javac is used to compile both boostrap versions of the
+# other tools, and product versions of all the tools.
+# Override this path as needed, either on the command line or in 
+# one of the standard user build.properties files (see build.xml)
+javac.jar=${bootstrap.dir}/lib/javac.jar
+
+# options for the <javac> tasks used to compile the tools
+javac.source = 7
+javac.target = 7
+javac.debug = true
+javac.no.jdk.warnings = -XDignore.symbol.file=true
+# set the following to -version to verify the versions of javac being used
+javac.version.opt = 
+# in time, there should be no exceptions to -Xlint:all
+#javac.lint.opts = -Xlint:all,-unchecked,-deprecation,-fallthrough,-cast,-serial
+javac.lint.opts=
+
+# JVM memory size
+javac.memoryInitialSize = 256m
+javac.memoryMaximumSize = 512m
+
+#------------------------------------------------------------
+
+# Root of output directories
+output.dir=.
+
+# Built files
+build.dir=${output.dir}/build
+build.classes.dir=${build.dir}/classes
+
+# Distributed results
+dist.dir=${output.dir}/dist
+dist.lib.dir=${dist.dir}/lib
+dist.classes.jar=${dist.lib.dir}/classes.jar
+dist.src.zip=${dist.lib.dir}/src.zip
+
+# Where all drop sources live
+drop.dir=./drop
+
+# Where patches to drop bundle sources live
+patches.dir=patches
+
+# Original source area
+orig.dir=src
+orig.src.dir=${orig.dir}/share/classes
+
+# Sanity information
+sanity.info= Sanity Settings:${line.separator}\
+  ant.home=${ant.home}${line.separator}\
+  ant.version=${ant.version}${line.separator}\
+  ant.java.version=${ant.java.version}${line.separator}\
+  java.home=${java.home}${line.separator}\
+  java.version=${java.version}${line.separator}\
+  os.name=${os.name}${line.separator}\
+  os.arch=${os.arch}${line.separator}\
+  os.version=${os.version}${line.separator}\
+  bootstrap.dir=${bootstrap.dir}${line.separator}\
+  javac.jar=${javac.jar}${line.separator}\
+  javac.memoryInitialSize=${javac.memoryInitialSize}${line.separator}\
+  javac.memoryMaximumSize=${javac.memoryMaximumSize}${line.separator}\
+  javac.source=${javac.source}${line.separator}\
+  javac.debug=${javac.debug}${line.separator}\
+  javac.target=${javac.target}${line.separator}\
+  javac.version.opt=${javac.version.opt}${line.separator}\
+  javac.lint.opts=${javac.lint.opts}${line.separator}\
+  javac.no.jdk.warnings=${javac.no.jdk.warnings}${line.separator}\
+  output.dir=${output.dir}${line.separator}\
+  build.dir=${build.dir}${line.separator}\
+  dist.dir=${dist.dir}${line.separator}\
+  drop.dir=${drop.dir}${line.separator}\
+${line.separator}
+
+#------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/build.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Sun designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Sun in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ CA 95054 USA or visit www.sun.com if you need additional information or
+ have any questions.
+-->
+
+<project name="jaxp" default="all" basedir=".">
+   
+    <!-- For 'ant -p' or 'ant -projecthelp' -->
+    
+    <description>
+    Ant build script for the ${ant.project.name} part of the jdk.
+
+    Input Properties: (see build.properties for the ant defaults)
+      bootstrap.dir        - dir with lib/javac.jar, added to javac bootclasspath
+      javac.debug          - true or false for debug classfiles
+      javac.target         - classfile version target
+      javac.source         - source version
+    </description>
+
+    <!-- Mac is special, need to downgrade these before build.properties. -->
+    <condition property="javac.source" value="1.5">
+        <os family="mac"/>
+    </condition>
+    <condition property="javac.target" value="1.5">
+        <os family="mac"/>
+    </condition>
+
+    <!-- Project build properties. -->
+    <property file="build.properties"/>
+
+    <!-- Get shared targets. -->
+    <import file="build-defs.xml"/>
+
+    <!-- Initialization of directories needed for build. -->
+    <target name="init">
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${build.classes.dir}"/>
+        <mkdir dir="${dist.dir}"/>
+        <mkdir dir="${dist.lib.dir}"/>
+    </target>
+    
+    <!-- Sanity checks and settings -->
+    <target name="sanity"
+	    depends="-javac-jar-exists"
+            description="Display settings of configuration values">
+        <echo message="${sanity.info}"/>
+    </target>
+
+     <!-- Check for bootstrap javac.jar file, warn if missing. -->
+    <condition property="javac.jar.exists">
+        <available file="${javac.jar}" type="file"/>
+    </condition>
+    <target name="-javac-jar-exists"
+            unless="javac.jar.exists">
+        <echo message="WARNING: Cannot find ${javac.jar}"/>
+    </target>
+
+    <!-- Creation of distribution files to jdk build process. -->
+    <target name="dist"
+	    depends="init, -init-src-dirs, build, -dist-classes-jar, -dist-src-zip"
+            description="Create all built distribution files.">
+    </target>
+    <target name="-dist-classes-jar-uptodate"
+	    depends="init, -init-src-dirs">
+        <condition property="dist.classes.jar.uptodate">
+            <and>
+                <available file="${dist.classes.jar}" type="file"/>
+                <uptodate targetfile="${dist.classes.jar}">
+                    <srcfiles dir="${build.classes.dir}" includes="**"/>
+                </uptodate>
+            </and>
+        </condition>
+    </target>
+    <target name="-dist-classes-jar"
+	    depends="init, -init-src-dirs, -dist-classes-jar-uptodate"
+            unless="dist.classes.jar.uptodate">
+        <delete file="${dist.classes.jar}"/>
+        <jar file="${dist.classes.jar}" basedir="${build.classes.dir}"/>
+    </target>
+
+    <target name="-build-prep"
+	    depends="init, -init-src-dirs, -drop-build-prep">
+    </target>
+
+    <!-- Build (compilation) of sources to class files. -->
+    <target name="build"
+	    depends="init, -init-src-dirs, -build-prep">
+        <javac fork="true"
+             destdir="${build.classes.dir}"
+             memoryInitialSize="${javac.memoryInitialSize}"
+             memoryMaximumSize="${javac.memoryMaximumSize}"
+             source="${javac.source}"
+	     debug="${javac.debug}"
+             target="${javac.target}">
+            <compilerarg value="-J-Xbootclasspath/p:${javac.jar}"/>
+            <compilerarg line="${javac.version.opt} ${javac.lint.opts} ${javac.no.jdk.warnings}"/>
+            <src refid="src.dir.id"/>
+        </javac>
+    </target>
+
+    <!-- Test. (FIXME: Need to know how to run tests.) -->
+    <target name="test"
+	    depends="init, -init-src-dirs, dist">
+        <echo message="FIXME: How do you run the tests"/>
+    </target>
+    
+    <!-- Populate source area if needed. -->
+    <target name="source"
+            depends="init, -init-src-dirs"
+            description="Populate all source file directories">
+    </target>
+
+    <!-- Clean up compiled files. -->
+    <target name="clean"
+            description="Delete all generated files">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dist.dir}"/>
+    </target>
+
+    <!-- Clean up compiled files and all imported source files. -->
+    <target name="clobber"
+	    depends="clean"
+            description="Delete all generated files, including imported sources">
+        <delete dir="${drop.dir}"/>
+    </target>
+
+    <target name="-banner">
+        <echo message="+---------------------------------------+"/>
+        <echo message="+ Starting ant project ${ant.project.name} +"/>
+        <echo message="+---------------------------------------+"/>
+    </target>
+   
+    <!-- Do everything but test. -->
+    <target name="all"
+	    depends="-banner, sanity, dist"
+            description="Build everything.">
+        <echo message="+---------------------------------------+"/>
+        <echo message="+ Finishing ant project ${ant.project.name}"/>
+        <echo message="+---------------------------------------+"/>
+    </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/jaxp.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+drops.master.copy.base=${devtools}/share/jdk7-drops
+drops.master.url.base=http://kenai.com/projects/jdk7-drops/downloads/download
+
+jaxp_src.bundle.name=jdk7-jaxp-2009_09_28.zip
+jaxp_src.master.bundle.dir=${drops.master.copy.base}
+#jaxp_src.bundle.url.base=https://jaxp.dev.java.net/files/documents/913/142147
+jaxp_src.master.bundle.url.base=${drops.master.url.base}
+
+jaxp_tests.bundle.name=jdk7-jaxp-tests-2009_08_28.zip
+jaxp_tests.master.bundle.dir=${drops.master.copy.base}
+jaxp_tests.master.bundle.url.base=${drops.master.url.base}
--- a/jaxp/make/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxp/make/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -23,7 +23,7 @@
 # have any questions.
 #
 
-# Makefile for jaxp: wrapper around Ant build.xml file
+# Makefile wrapper around Ant build.xml file
 
 #
 # On Solaris, the 'make' utility from Sun will not work with these makefiles.
@@ -41,38 +41,12 @@
   ANT_OPTIONS += -verbose
 endif
 
-ifdef JDK_VERSION
-  ANT_OPTIONS += -Djdk.version=$(JDK_VERSION)
-endif 
-
-ifdef FULL_VERSION
-  ANT_OPTIONS += -Dfull.version='$(FULL_VERSION)' # will contain spaces
-endif 
-
-ifdef MILESTONE
-  ANT_OPTIONS += -Dmilestone=$(MILESTONE)
-endif
-
-ifdef BUILD_NUMBER
-  ANT_OPTIONS += -Dbuild.number=$(BUILD_NUMBER)
-else
-  ifdef JDK_BUILD_NUMBER
-    ANT_OPTIONS += -Dbuild.number=$(JDK_BUILD_NUMBER)
-  endif
-endif
-
-ifeq ($(VARIANT), DBG)
-  ANT_OPTIONS += -Djavac.debug=true
-else
-  ifeq ($(VARIANT), OPT)
+ifeq ($(VARIANT), OPT)
+  ifneq ($(DEBUG_CLASSFILES), true)
     ANT_OPTIONS += -Djavac.debug=false
   endif
 endif
 
-ifeq ($(DEBUG_CLASSFILES), true)
-  ANT_OPTIONS += -Djavac.debug=true
-endif
-
 # Note: jdk/make/common/Defs.gmk uses LANGUAGE_VERSION (-source NN)
 # and the somewhat misnamed CLASS_VERSION (-target NN)
 ifdef TARGET_CLASS_VERSION
@@ -81,7 +55,7 @@
   ifdef JAVAC_TARGET_ARG
     ANT_OPTIONS += -Djavac.target=$(JAVAC_TARGET_ARG)
   endif
-endif 
+endif
 
 ifdef SOURCE_LANGUAGE_VERSION
   ANT_OPTIONS += -Djavac.source=$(SOURCE_LANGUAGE_VERSION)
@@ -91,24 +65,53 @@
   endif
 endif 
 
-ifdef ALT_BOOTDIR
-  ANT_JAVA_HOME = JAVA_HOME=$(ALT_BOOTDIR)
+# Figure out the platform we are using
+_SYSTEM_UNAME := $(shell uname)
+_PLATFORM_KIND = unix
+ifeq ($(_SYSTEM_UNAME), Windows_NT)
+  _PLATFORM_KIND = windows
+endif
+ifneq (,$(findstring CYGWIN,$(_SYSTEM_UNAME)))
+  _PLATFORM_KIND = windows
 endif
 
+# Where is /java in case we need it
+ifdef ALT_SLASH_JAVA
+  _SLASHJAVA = $(ALT_SLASH_JAVA)
+else
+  ifeq ($(_PLATFORM_KIND), windows)
+    _SLASHJAVA=J:/
+  else
+    _SLASHJAVA=/java
+  endif
+endif
+
+# Where is /java/devtools in case we need it
+ifdef ALT_JDK_DEVTOOLS_DIR
+  _DEVTOOLS = $(ALT_JDK_DEVTOOLS_DIR)
+else
+  _DEVTOOLS = $(_SLASHJAVA)/devtools
+endif
+
+# Add in path to devtools
+ANT_OPTIONS += -Ddevtools=$(_DEVTOOLS)
+
 ifdef ALT_OUTPUTDIR
   OUTPUTDIR = $(ALT_OUTPUTDIR)
-  ANT_OPTIONS += -Dbuild.dir=$(ALT_OUTPUTDIR)/build
-  ANT_OPTIONS += -Ddist.dir=$(ALT_OUTPUTDIR)/dist
+  ANT_OPTIONS += -Doutput.dir=$(ALT_OUTPUTDIR)
 else
   OUTPUTDIR = ..
 endif
 
 ifdef ALT_LANGTOOLS_DIST
+  ifdef ALT_BOOTDIR
+    ANT_JAVA_HOME = JAVA_HOME=$(ALT_BOOTDIR)
+  endif
   ANT_OPTIONS += -Dbootstrap.dir=$(ALT_LANGTOOLS_DIST)/bootstrap
-endif
-
-ifdef FINDBUGS_HOME
-  ANT_OPTIONS += -Dfindbugs.home=$(FINDBUGS_HOME)
+else
+  ifdef ALT_JDK_IMPORT_PATH
+    ANT_JAVA_HOME = JAVA_HOME=$(ALT_JDK_IMPORT_PATH)
+  endif
 endif
 
 ifdef ANT_HOME
@@ -124,26 +127,67 @@
 endif
 
 # Default target and expected 'do everything' target
-all: build
-
-# Standard make clobber target
-clobber: clean
+default: all
 
 # All ant targets of interest
-ANT_TARGETS = build clean sanity # for now
+ANT_TARGETS = all source build dist clobber clean sanity
 
 # Create a make target for each
 $(ANT_TARGETS):
-	$(ANT_JAVA_HOME) $(ANT) -version
-	$(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@
+	cd .. && $(ANT_JAVA_HOME) $(ANT) -version
+	cd .. && $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@
+
+# Help target
+define helpenvline
+@echo "    $1";echo "        $2"
+endef
+help:
+	@echo "----------------------------------------------------------"
+	@echo " "
+	@echo "Help information for this Makefile:"
+	@echo " "
+	@echo "  Targets (see ant project information for descriptions):"
+	@echo "    $(ANT_TARGETS)"
+	@echo " "
+	@echo "  Environment or command line variables (all optional):"
+	$(call helpenvline, ALT_BOOTDIR,\
+	       "JAVA_HOME to use when running ant")
+	$(call helpenvline, ALT_LANGTOOLS_DIST,\
+	       "path to langtools repository dist directory")
+	$(call helpenvline, ALT_OUTPUTDIR,\
+	       "path to root of output")
+	$(call helpenvline, DEBUG_CLASSFILES,\
+	       "if set makes sure ant property javac.debug is true")
+	$(call helpenvline, JAVAC_SOURCE_ARG,\
+	       "if SOURCE_LANGUAGE_VERSION not set uses this to set ant property javac.source")
+	$(call helpenvline, JAVAC_TARGET_ARG,\
+	       "if TARGET_CLASS_VERSION not set uses this to set ant property javac.target")
+	$(call helpenvline, SOURCE_LANGUAGE_VERSION,\
+	       "if set uses this to set ant property javac.source")
+	$(call helpenvline, QUIET,\
+	       "if set will pass -quiet to ant")
+	$(call helpenvline, TARGET_CLASS_VERSION,\
+	       "JAVA_HOME to use when running ant")
+	$(call helpenvline, VARIANT,\
+	       "if set to OPT means optimized build will set javac.debug to false")
+	$(call helpenvline, VERBOSE,\
+	       "if set will pass -verbose to ant")
+	@echo " "
+	@echo "----------------------------------------------------------"
+	@echo " "
+	@echo "Ant project file help information:"
+	@echo " "
+	@$(ANT_JAVA_HOME) cd .. && $(ANT) $(ANT_OPTIONS) -p
+	@echo " "
+	@echo "----------------------------------------------------------"
 
 # Targets for Sun's internal JPRT build system
 JPRT_ARCHIVE_BUNDLE=$(OUTPUTDIR)/jprt.zip
 jprt_build_product jprt_build_debug jprt_build_fastdebug: all
 	$(RM) $(JPRT_ARCHIVE_BUNDLE)
 	( cd $(OUTPUTDIR)/dist && \
-	  zip -q -r $(JPRT_ARCHIVE_BUNDLE) . )
+	   zip -q -r $(JPRT_ARCHIVE_BUNDLE) . )
 
 # Declare these phony (not filenames)
-.PHONY: $(ANT_TARGETS) all clobber \
+.PHONY: $(ANT_TARGETS) \
 	jprt_build_product jprt_build_debug jprt_build_fastdebug
--- a/jaxp/make/build.properties	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-# This is the JDK used to build and run the bootstrap version of javac.
-# The bootstrap javac is used to compile both boostrap versions of the
-# other tools, and product versions of all the tools.
-# Override this path as needed, either on the command line or in 
-# one of the standard user build.properties files (see build.xml)
-
-# options for the <javac> tasks used to compile the tools
-javac.source = 7
-javac.target = 7
-javac.debug = true
-javac.no.jdk.warnings = -XDignore.symbol.file=true
-# set the following to -version to verify the versions of javac being used
-javac.version.opt = 
-# in time, there should be no exceptions to -Xlint:all
-javac.lint.opts = -Xlint:all,-unchecked,-deprecation,-fallthrough,-cast,-serial -Werror
-
-# JVM memory size
-javac.memoryInitialSize = 128m
-javac.memoryMaximumSize = 256m
-
-#------------------------------------------------------------
--- a/jaxp/make/build.xml	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.  Sun designates this
- particular file as subject to the "Classpath" exception as provided
- by Sun in the LICENSE file that accompanied this code.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- CA 95054 USA or visit www.sun.com if you need additional information or
- have any questions.
--->
-
-<!--
- This is the main build file for the complete jaxp workspace.
- -->
-
-<project name="jaxp" default="all" basedir=".">
-
-    <!-- Convenient shorthands for standard locations within the workspace. -->
-    <property file="build.properties"/>
-    <property name="topdir" value=".."/>
-    <property name="build.dir" location="${topdir}/build"/>
-    <property name="build.classes.dir" location="${build.dir}/classes"/>
-    <property name="build.gensrc.dir" location="${build.dir}/gensrc"/>
-    <property name="build.toolclasses.dir" location="${build.dir}/toolclasses"/>
-    <property name="dist.dir" location="${topdir}/dist"/>
-    <property name="dist.lib.dir" location="${dist.dir}/lib"/>
-    <property name="make.dir" location="${topdir}/make"/>
-    <property name="make.tools.dir" location="${make.dir}/tools"/>
-    <property name="src.dir" location="${topdir}/src"/>
-    <property name="src.classes.dir" location="${src.dir}/share/classes"/>
-    <property environment="env"/>
-
-    <target name="build" depends="banner, build-classes, build-tools">
-	<mkdir dir="${dist.lib.dir}"/>
-	<jar file="${dist.lib.dir}/classes.jar" basedir="${build.classes.dir}"/>
-	<zip file="${dist.lib.dir}/src.zip" basedir="${src.classes.dir}"/>
-    </target>
-
-    <!-- Debug information -->
-    <target name="sanity"
-        description="display settings of configuration values">
-	<echo level="info">ant.home = ${ant.home}</echo>
-	<echo level="info">java.home = ${env.JAVA_HOME}</echo>
-	<echo level="info">bootstrap.dir = ${bootstrap.dir}</echo>
-    </target>
-
-    <target name="build-tools" depends="-defs-pstrip">
-        <mkdir dir="${build.dir}"/>
-        <mkdir dir="${build.classes.dir}"/>
-	    <pstrip srcdir="${src.classes.dir}"
-                    destdir="${build.classes.dir}"
-		    includes="**/*.properties"/>
-    </target>
-
-    <target name="-defs-pstrip">
-      <mkdir dir="${build.toolclasses.dir}"/>
-      <javac srcdir="${make.tools.dir}/StripProperties"
-		destdir="${build.toolclasses.dir}/"
-		classpath="${ant.home}/lib/ant.jar"/>
-      <taskdef name="pstrip"
-		 classname="StripPropertiesTask"
-		 classpath="${build.toolclasses.dir}/"/>
-    </target>
-
-    <target name="build-classes" depends="sanity">
-      <mkdir dir="${build.dir}"/>
-      <mkdir dir="${build.classes.dir}"/>
-      <javac fork="true"
-             srcdir="${src.classes.dir}"
-             destdir="${build.classes.dir}"
-             memoryInitialSize="${javac.memoryInitialSize}"
-             memoryMaximumSize="${javac.memoryMaximumSize}"
-	     source="${javac.source}"
-	     debug="${javac.debug}"
-             target="${javac.target}">
-         <compilerarg value="-J-Xbootclasspath/p:${bootstrap.dir}/lib/javac.jar"/>
-         <compilerarg line="${javac.version.opt}"/>
-      </javac>
-    </target>
-
-    <target name="clean" description="Delete all generated files">
-	<delete dir="${build.dir}"/>
-	<delete dir="${dist.dir}"/>
-    </target>
-
-    <target name="banner">
-      <echo>+---------------------------------------+</echo>
-      <echo>+    Building JAXP Component            +</echo>
-      <echo>+---------------------------------------+</echo>
-    </target>
-
-</project>
--- a/jaxp/make/jprt.properties	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxp/make/jprt.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -34,8 +34,8 @@
 solaris_x64_5.10,\
 linux_i586_2.6,\
 linux_x64_2.6,\
-windows_i586,\
-windows_x64
+windows_i586_5.0,\
+windows_x64_5.2
 
 # The different build flavors we want
 jprt.build.flavors=product,fastdebug
@@ -49,7 +49,6 @@
 # Standard list of jprt test targets for this workspace
 jprt.test.targets=
 
-# Directories needed to build
-jprt.bundle.src.dirs=make src
+# Directories needing to exclude from source bundles
 jprt.bundle.exclude.src.dirs=build dist
 
--- a/jaxp/make/tools/StripProperties/StripProperties.java	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +0,0 @@
-/*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-import java.io.BufferedInputStream;
-import java.io.BufferedWriter;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * Reads a properties file from standard input and writes an equivalent
- * properties file without comments to standard output.
- */
-public class StripProperties {
-
-    public static void main(String[] args) {
-        StripProperties sp = new StripProperties();
-        boolean ok = sp.run(args);
-        if ( !ok ) {
-            System.exit(1);
-        }
-    }
-
-    static interface Log {
-        void info(String msg);
-        void verbose(String msg);
-        void error(String msg, Exception e);
-    }
-
-    private String propfiles[];
-    private String outfiles[] ;
-    private int stripCount = 0;
-    private boolean quiet = false;
-    private Log log;
-
-    public void setLog(Log log) {
-        this.log = log;
-    }
-
-    private boolean parseOptions(String args[]) {
-        boolean ok = true;
-        if ( stripCount > 0 ) {
-            String new_propfiles[] = new String[stripCount + args.length];
-            String new_outfiles[]  = new String[stripCount + args.length];
-            System.arraycopy(propfiles, 0, new_propfiles, 0, stripCount);
-            System.arraycopy(outfiles, 0, new_outfiles, 0, stripCount);
-            propfiles = new_propfiles;
-            outfiles  = new_outfiles;
-        } else {
-            propfiles = new String[args.length];
-            outfiles  = new String[args.length];
-        }
-
-        for ( int i = 0; i < args.length ; i++ ) {
-            if ( "-strip".equals(args[i]) && i+2 < args.length ) {
-                propfiles[stripCount] = args[++i];
-                outfiles[stripCount]    = args[++i];
-                stripCount++;
-            } else if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) {
-                String filename = args[++i];
-                FileInputStream finput = null;
-                byte contents[] = null;
-                try {
-                    finput = new FileInputStream(filename);
-                    int byteCount = finput.available();
-                    if ( byteCount <= 0 ) {
-                        log.error("The -optionsfile file is empty", null);
-                        ok = false;
-                    } else {
-                        contents = new byte[byteCount];
-                        int bytesRead = finput.read(contents);
-                        if ( byteCount != bytesRead ) {
-                            log.error("Cannot read all of -optionsfile file", null);
-                            ok = false;
-                        }
-                    }
-                } catch ( IOException e ) {
-                    log.error("cannot open " + filename, e);
-                    ok = false;
-                }
-                if ( finput != null ) {
-                    try {
-                        finput.close();
-                    } catch ( IOException e ) {
-                        ok = false;
-                        log.error("cannot close " + filename, e);
-                    }
-                }
-                if ( ok = true && contents != null ) {
-                    String tokens[] = (new String(contents)).split("\\s+");
-                    if ( tokens.length > 0 ) {
-                        ok = parseOptions(tokens);
-                    }
-                }
-                if ( !ok ) {
-                    break;
-                }
-        } else if ( "-quiet".equals(args[i]) ) {
-                quiet = true;
-        } else {
-                log.error("argument error", null);
-                ok = false;
-        }
-        }
-        return ok;
-    }
-
-    private boolean stripFiles(String propertiesPath, String outputPath) {
-        boolean ok = true;
-        Properties prop = new Properties();
-        InputStream in = null;
-        try {
-                in = new BufferedInputStream(new FileInputStream(propertiesPath));
-                prop.load(in);
-        } catch ( FileNotFoundException e ) {
-                log.error("Cannot access file " + propertiesPath, e);
-                ok = false;
-        } catch ( IOException e ) {
-                log.error("IO exception processing file " + propertiesPath, e);
-                ok = false;
-        }
-        if ( in != null ) {
-                try {
-                    in.close();
-                } catch ( IOException e ) {
-                    log.error("IO exception closing file " + propertiesPath, e);
-                    ok = false;
-                }
-        }
-
-        OutputStream out = null;
-        try {
-                out = new FileOutputStream(outputPath);
-                storeProperties(prop, out);
-                out.flush();
-        } catch ( IOException e ) {
-                log.error("IO exception processing file " + outputPath, e);
-                e.printStackTrace();
-                ok = false;
-        }
-        if ( out != null ) {
-           try {
-                    out.close();
-           } catch ( IOException e ) {
-                    log.error("IO exception closing file " + outputPath, e);
-                    ok = false;
-           }
-        }
-        return ok;
-    }
-
-    /**
-     * Strip the properties filenames supplied, replacing their contents.
-     * @param args Names of properties files to process and replace contents
-     */
-    public boolean run(String args[]) {
-        if (log == null) {
-            log = new Log() {
-                public void error(String msg, Exception e) {
-                    System.err.println("ERROR: StripProperties: " + msg);
-                    if ( e != null ) {
-                        System.err.println("EXCEPTION: " + e.toString());
-                        e.printStackTrace();
-                    }
-                }
-                public void info(String msg) {
-                    System.out.println(msg);
-                }
-                public void verbose(String msg) {
-                    if (!quiet)
-                        System.out.println(msg);
-                }
-            };
-        }
-
-        boolean ok = true;
-        ok = parseOptions(args);
-        if ( ok && stripCount == 0 ) {
-                log.error("options parsed but no files to compile", null);
-                ok = false;
-        }
-        /* Need at least one file. */
-        if ( !ok ) {
-            //usage(log);
-        } else {
-            /* Process files */
-            for ( int i = 0; i < stripCount && ok ; i++ ) {
-                    ok = stripFiles(propfiles[i], outfiles[i]);
-            }
-        }
-        return ok;
-    }
-
-    // --- code below here is adapted from java.util.Properties ---
-
-    private static final String specialSaveChars = "=: \t\r\n\f#!";
-
-    /*
-     * Converts unicodes to encoded &#92;uxxxx
-     * and writes out any of the characters in specialSaveChars
-     * with a preceding slash
-     */
-    private static String saveConvert(String theString, boolean escapeSpace) {
-        int len = theString.length();
-        StringBuffer outBuffer = new StringBuffer(len*2);
-
-        for(int x=0; x<len; x++) {
-            char aChar = theString.charAt(x);
-            switch(aChar) {
-                case ' ':
-                    if (x == 0 || escapeSpace) {
-                        outBuffer.append('\\');
-                    }
-                    outBuffer.append(' ');
-                    break;
-                case '\\':
-                    outBuffer.append('\\');
-                    outBuffer.append('\\');
-                    break;
-                case '\t':
-                    outBuffer.append('\\');
-                    outBuffer.append('t');
-                    break;
-                case '\n':
-                    outBuffer.append('\\');
-                    outBuffer.append('n');
-                    break;
-                case '\r':
-                    outBuffer.append('\\');
-                    outBuffer.append('r');
-                    break;
-                case '\f':
-                    outBuffer.append('\\');
-                    outBuffer.append('f');
-                    break;
-                default:
-                    if ((aChar < 0x0020) || (aChar == 0x007e) || (aChar > 0x00ff)) {
-                        outBuffer.append('\\');
-                        outBuffer.append('u');
-                        outBuffer.append(toHex((aChar >> 12) & 0xF));
-                        outBuffer.append(toHex((aChar >>  8) & 0xF));
-                        outBuffer.append(toHex((aChar >>  4) & 0xF));
-                        outBuffer.append(toHex( aChar        & 0xF));
-                    } else {
-                        if (specialSaveChars.indexOf(aChar) != -1) {
-                            outBuffer.append('\\');
-                        }
-                        outBuffer.append(aChar);
-                    }
-            }
-        }
-        return outBuffer.toString();
-    }
-
-    /**
-     * Writes the content of <code>properties</code> to <code>out</code>.
-     * The format is that of Properties.store with the following modifications:
-     * <ul>
-     * <li>No header or date is written
-     * <li>Latin-1 characters are written as single bytes, not escape sequences
-     * <li>Line breaks are indicated by a single \n independent of platform
-     * <ul>
-     */
-    private static void storeProperties(Properties properties, OutputStream out)
-    throws IOException {
-        BufferedWriter awriter;
-        awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
-        for (Enumeration e = properties.keys(); e.hasMoreElements();) {
-            String key = (String)e.nextElement();
-            String val = (String)properties.get(key);
-            key = saveConvert(key, true);
-
-            /* No need to escape embedded and trailing spaces for value, hence
-             * pass false to flag.
-             */
-            val = saveConvert(val, false);
-            writeln(awriter, key + "=" + val);
-        }
-        awriter.flush();
-    }
-
-    private static void writeln(BufferedWriter bw, String s) throws IOException {
-        bw.write(s);
-        bw.write("\n");
-    }
-
-    /**
-     * Convert a nibble to a hex character
-     * @param   nibble  the nibble to convert.
-     */
-    private static char toHex(int nibble) {
-        return hexDigit[(nibble & 0xF)];
-    }
-
-    /** A table of hex digits */
-    private static final char[] hexDigit = {
-        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-    };
-}
--- a/jaxp/make/tools/StripProperties/StripPropertiesTask.java	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-
-public class StripPropertiesTask extends MatchingTask {
-    public void setSrcDir(File srcDir) {
-        this.srcDir = srcDir;
-    }
-
-    public void setDestDir(File destDir) {
-        this.destDir = destDir;
-    }
-
-    public void execute() {
-        StripProperties.Log log = new StripProperties.Log() {
-            public void error(String msg, Exception e) {
-                log(msg, Project.MSG_ERR);
-            }
-            public void info(String msg) {
-                log(msg, Project.MSG_INFO);
-            }
-            public void verbose(String msg) {
-                log(msg, Project.MSG_VERBOSE);
-            }
-        };
-        List<String> mainOpts = new ArrayList<String>();
-        int count = 0;
-        DirectoryScanner s = getDirectoryScanner(srcDir);
-        for (String path: s.getIncludedFiles()) {
-            if (path.endsWith(".properties")) {
-                File srcFile = new File(srcDir, path);
-                File destFile = new File(destDir, path);
-                // Arguably, the comparison in the next line should be ">", not ">="
-                // but that assumes the resolution of the last modified time is fine
-                // grained enough; in practice, it is better to use ">=".
-                if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified())
-                    continue;
-                destFile.getParentFile().mkdirs();
-                mainOpts.add("-strip");
-                mainOpts.add(srcFile.getPath());
-                mainOpts.add(destFile.getPath());
-                count++;
-            }
-        }
-        if (mainOpts.size() > 0) {
-            log("Generating " + count + " resource files to " + destDir, Project.MSG_INFO);
-            StripProperties sp = new StripProperties();
-            sp.setLog(log);
-            boolean ok = sp.run((String[])mainOpts.toArray(new String[mainOpts.size()]));
-            if (!ok)
-                throw new BuildException("StripProperties failed.");
-        }
-    }
-
-    private File srcDir;
-    private File destDir;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/nbproject/findbugs.settings	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,72 @@
+#FindBugs User Preferences
+#Tue Jun 30 18:33:11 PDT 2009
+detectorAbnormalFinallyBlockReturn=AbnormalFinallyBlockReturn|false
+detectorAbstractClassEmptyMethods=AbstractClassEmptyMethods|false
+detectorAbstractOverriddenMethod=AbstractOverriddenMethod|false
+detectorArrayBasedCollections=ArrayBasedCollections|false
+detectorArrayWrappedCallByReference=ArrayWrappedCallByReference|false
+detectorBloatedAssignmentScope=BloatedAssignmentScope|false
+detectorBloatedSynchronizedBlock=BloatedSynchronizedBlock|false
+detectorClassEnvy=ClassEnvy|false
+detectorCollectStatistics=CollectStatistics|false
+detectorConfusingAutoboxedOverloading=ConfusingAutoboxedOverloading|false
+detectorConstantListIndex=ConstantListIndex|false
+detectorCopiedOverriddenMethod=CopiedOverriddenMethod|false
+detectorCustomBuiltXML=CustomBuiltXML|false
+detectorCyclomaticComplexity=CyclomaticComplexity|false
+detectorDateComparison=DateComparison|false
+detectorDeclaredRuntimeException=DeclaredRuntimeException|false
+detectorDeletingWhileIterating=DeletingWhileIterating|false
+detectorDubiousListCollection=DubiousListCollection|false
+detectorFieldCouldBeLocal=FieldCouldBeLocal|false
+detectorFinalParameters=FinalParameters|false
+detectorFloatingPointLoops=FloatingPointLoops|false
+detectorInefficientStringBuffering=InefficientStringBuffering|false
+detectorInheritanceTypeChecking=InheritanceTypeChecking|false
+detectorJDBCVendorReliance=JDBCVendorReliance|false
+detectorListIndexedIterating=ListIndexedIterating|false
+detectorLiteralStringComparison=LiteralStringComparison|false
+detectorLocalSynchronizedCollection=LocalSynchronizedCollection|false
+detectorLostExceptionStackTrace=LostExceptionStackTrace|false
+detectorManualArrayCopy=ManualArrayCopy|false
+detectorMethodReturnsConstant=MethodReturnsConstant|false
+detectorNeedlessAutoboxing=NeedlessAutoboxing|false
+detectorNeedlessCustomSerialization=NeedlessCustomSerialization|false
+detectorNeedlessInstanceRetrieval=NeedlessInstanceRetrieval|false
+detectorNeedlessMemberCollectionSynchronization=NeedlessMemberCollectionSynchronization|false
+detectorNonCollectionMethodUse=NonCollectionMethodUse|false
+detectorNonOwnedSynchronization=NonOwnedSynchronization|false
+detectorNonRecycleableTaglibs=NonRecycleableTaglibs|false
+detectorOrphanedDOMNode=OrphanedDOMNode|false
+detectorOverlyConcreteParameter=OverlyConcreteParameter|false
+detectorParallelLists=ParallelLists|false
+detectorPartiallyConstructedObjectAccess=PartiallyConstructedObjectAccess|false
+detectorPossibleIncompleteSerialization=PossibleIncompleteSerialization|false
+detectorPossibleMemoryBloat=PossibleMemoryBloat|false
+detectorPossiblyRedundantMethodCalls=PossiblyRedundantMethodCalls|false
+detectorSQLInLoop=SQLInLoop|false
+detectorSection508Compliance=Section508Compliance|false
+detectorSillynessPotPourri=SillynessPotPourri|false
+detectorSloppyClassReflection=SloppyClassReflection|false
+detectorSluggishGui=SluggishGui|false
+detectorSpoiledChildInterfaceImplementor=SpoiledChildInterfaceImplementor|false
+detectorSpuriousThreadStates=SpuriousThreadStates|false
+detectorStaticArrayCreatedInMethod=StaticArrayCreatedInMethod|false
+detectorStaticMethodInstanceInvocation=StaticMethodInstanceInvocation|false
+detectorSuspiciousComparatorReturnValues=SuspiciousComparatorReturnValues|false
+detectorSuspiciousJDKVersionUse=SuspiciousJDKVersionUse|false
+detectorSuspiciousWaitOnConcurrentObject=SuspiciousWaitOnConcurrentObject|false
+detectorSyncCollectionIterators=SyncCollectionIterators|false
+detectorTailRecursion=TailRecursion|false
+detectorUnnecessaryStoreBeforeReturn=UnnecessaryStoreBeforeReturn|false
+detectorUnrelatedCollectionContents=UnrelatedCollectionContents|false
+detectorUnrelatedReturnValues=UnrelatedReturnValues|false
+detectorUseAddAll=UseAddAll|false
+detectorUseCharacterParameterizedMethod=UseCharacterParameterizedMethod|false
+detectorUseEnumCollections=UseEnumCollections|false
+detectorUseSplit=UseSplit|false
+detectorUseToArray=UseToArray|false
+detector_threshold=2
+effort=default
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,I18N,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false
+filter_settings_neg=|
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/nbproject/project.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.ant.freeform</type>
+    <configuration>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+            <name>jaxp</name>
+        </general-data>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
+            <!-- Do not use Project Properties customizer when editing this file manually. -->
+            <name>jaxp</name>
+            <properties/>
+            <folders>
+                <source-folder>
+                    <label>jaxp</label>
+                    <location>.</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+            </folders>
+            <ide-actions>
+                <action name="build">
+                    <target>build</target>
+                </action>
+                <action name="clean">
+                    <target>clean</target>
+                </action>
+                <action name="rebuild">
+                    <target>clean</target>
+                    <target>build</target>
+                </action>
+            </ide-actions>
+            <view>
+                <items>
+                    <source-file>
+                        <location>build.xml</location>
+                    </source-file>
+                </items>
+                <context-menu>
+                    <ide-action name="build"/>
+                    <ide-action name="rebuild"/>
+                    <ide-action name="clean"/>
+                </context-menu>
+            </view>
+            <subprojects/>
+        </general-data>
+        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+        <preferences xmlns="http://www.netbeans.org/ns/auxiliary-configuration-preferences/1">
+            <module name="org-netbeans-modules-editor-indent"/>
+        </preferences>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/nbproject/sqe.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,2 @@
+#Path to FindbugsSettingsFile (relative)
+findbugs.settings.file=findbugs.settings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/patches/jaxp_src/README	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,5 @@
+
+This directory will hold any patches that need to be applied to the drop files.
+
+The patch order is defined in the ant build script properties.
+
--- a/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Portions Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Portions Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  */
 
 /*
--- a/jaxws/.hgignore	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxws/.hgignore	Wed Jul 05 17:01:15 2017 +0200
@@ -1,3 +1,5 @@
 ^build/
 ^dist/
+^drop/
+^webrev/
 ^nbproject/private/
--- a/jaxws/.hgtags	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 17:01:15 2017 +0200
@@ -46,3 +46,4 @@
 3e64fdfb92910e164d1f4b21b147719d5c674254 jdk7-b69
 dd3c5f3ec28d5d5e5c0dc3229fdd52d85d04274d jdk7-b70
 03314cf56a7212bbb6c186dbc9f15aca988a48ec jdk7-b71
+4c990aa99bc037fd81dd1b1b269690e9bea8a0b4 jdk7-b72
--- a/jaxws/README	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxws/README	Wed Jul 05 17:01:15 2017 +0200
@@ -1,14 +1,25 @@
 README:
-  This file should be located at the top of the jaxws Mercurial repository.
+  
+  This file should be located at the top of the Mercurial repository.
 
   See http://openjdk.java.net/ for more information about the OpenJDK.
 
   See ../README-builds.html for complete details on build machine requirements.
 
 Simple Build Instructions:
-
+  This repository can be loaded as a NetBeans project, built with ant, or
+  built with GNU make, e.g.
+    ant
+       -OR-
     cd make && gnumake
      
-  The files that will be imported into the jdk build will be in the "dist"
-  directory.
+  The built files that will be imported into the jdk build will be in the 
+  "dist" directory.
+  Help information is available by running "ant -projecthelp" or "make help".
 
+Drop Repository:
+  This repository builds sources from a created "drop" source directory.
+  These files will normally be copied from a shared directory area or
+  downloaded from a public website.
+  See the ant build script (build.xml) for more details.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/build-defs.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Sun designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Sun in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ CA 95054 USA or visit www.sun.com if you need additional information or
+ have any questions.
+-->
+
+<project name="jaxws_defs" default="all" basedir=".">
+     
+    <!-- Specific build properties. -->
+    <property file="jaxws.properties"/>
+
+    <!-- Where generated xml files will stay. -->
+    <property name="xml.gen.dir" value="${build.dir}/xml_generated"/>
+    <property name="xml.template" value="build-drop-template.xml"/>
+
+    <!--  ############### -->
+    <!--  Begin Macrodefs -->
+
+    <!-- Copies template file, replaces @DROP@ pattern, and imports it. -->
+    <macrodef name="drop-import">
+        <attribute name="name"/>
+        <sequential>
+            <property name="xml.gen.@{name}" value="${xml.gen.dir}/build-drop-@{name}.xml"/>
+            <mkdir dir="${xml.gen.dir}"/>
+            <copy file="${xml.template}" tofile="${xml.gen.@{name}}"/>
+            <replace file="${xml.gen.@{name}}" token="@DROP@" value="@{name}"/>
+            <import file="${xml.gen.@{name}}"/>
+        </sequential>
+    </macrodef>
+
+    <!--  End of Macrodefs -->
+    <!--  ############### -->
+
+    <!-- Create xml file and import it for these drops. -->
+    <drop-import name="jaxws_src"/>
+    <drop-import name="jaf_src"/>
+    <!-- <drop-import name="jaxws_tests"/> -->
+
+    <!-- Special build area preparation. -->
+    <target name="-drop-build-prep" depends="init, -init-src-dirs">
+        <mkdir dir="${build.classes.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${primary.src.dir}"
+                     includes="**/*.xsd, **/*.default, **/*.properties"
+                     excludes="**/*.java, **/*.package.html"/>
+        </copy>
+        <replaceregexp match="#(.*)$" replace="#" flags="gm">
+            <fileset dir="${build.classes.dir}" includes="**/*.properties"/>
+        </replaceregexp>
+
+        <mkdir dir="${build.classes.dir}/META-INF/services"/>
+        <copy todir="${build.classes.dir}/META-INF/services"
+              file="${primary.src.dir}/com/sun/tools/etc/META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory"/>
+        <copy todir="${build.classes.dir}/META-INF/services"
+              file="${primary.src.dir}/com/sun/tools/etc/META-INF/services/com.sun.tools.internal.xjc.Plugin"/>
+        <mkdir dir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime"/>
+        <copy todir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime">
+            <fileset dir="${primary.src.dir}/com/sun/tools/internal/xjc/runtime"
+                     includes="**/*.java"
+                     excludes="**/*.package.html"/>
+        </copy>
+    </target>
+
+    <!-- Try to get drop sources, set property use.orig.src.dir if no drops. -->
+    <target name="-set-props"
+	    depends="init,
+                     jaxws_src-update,
+                     jaf_src-update">
+        <condition property="use.orig.src.dir">
+            <and>
+                <available file="${orig.src.dir}" type="dir"/>
+                <not>
+                    <and>
+                        <available file="${jaxws_src.src.dir}" type="dir"/>
+                        <available file="${jaf_src.src.dir}"   type="dir"/>
+                    </and>
+                </not>
+            </and>
+        </condition>
+    </target>
+
+    <!-- Set up source to use orig.src.dir, if use.orig.src.dir defined. -->
+    <target name="-use-orig" depends="-set-props" if="use.orig.src.dir">
+        <property name="primary.src.dir" value="${orig.src.dir}"/>
+        <path id="src.dir.id">
+            <pathelement path="${primary.src.dir}"/>
+        </path>
+    </target>
+
+    <!-- Set up source to use drop.dir, if use.orig.src.dir not defined. -->
+    <target name="-use-drop" depends="-set-props" unless="use.orig.src.dir">
+        <property name="primary.src.dir" value="${jaxws_src.src.dir}"/>
+        <path id="src.dir.id">
+            <pathelement path="${primary.src.dir}"/>
+            <pathelement path="${jaf_src.src.dir}"/>
+        </path>
+    </target>
+
+    <!-- Source directory selection. -->
+    <target name="-init-src-dirs"
+	    depends="init, -use-orig, -use-drop">
+        <echo message="Using primary.src.dir=${primary.src.dir}"/>
+        <pathconvert property="src.list.id" refid="src.dir.id"/>
+        <echo message="Using src.dir.id=${src.list.id}"/>
+    </target>
+
+    <!-- Create orig src.zip. -->
+    <target name="-orig-src-zip" depends="init, -set-props" if="use.orig.src.dir">
+        <zip file="${dist.src.zip}" basedir="${primary.src.dir}"/>
+    </target>
+
+    <!-- Create drop src.zip. -->
+    <target name="-drop-src-zip" depends="init, -set-props" unless="use.orig.src.dir">
+        <zip file="${dist.src.zip}" basedir="${primary.src.dir}"/>
+        <zip file="${dist.src.zip}" basedir="${jaf_src.src.dir}" update="true"/>
+    </target>
+
+    <!-- Create src.zip. -->
+    <target name="-dist-src-zip" depends="init, -orig-src-zip, -drop-src-zip">
+    </target>
+    
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/build-drop-template.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Sun designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Sun in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ CA 95054 USA or visit www.sun.com if you need additional information or
+ have any questions.
+-->
+
+<project name="@DROP@-drop" default="all" basedir=".">
+
+    <!-- Locations of master drop bundles. -->
+    <property name="@DROP@.master.bundle.copy"
+              value="${@DROP@.master.bundle.dir}/${@DROP@.bundle.name}"/>
+    <property name="@DROP@.master.bundle.url"
+              value="${@DROP@.master.bundle.url.base}/${@DROP@.bundle.name}"/>
+
+    <!-- Location where the copied bundle lands. -->
+    <property name="@DROP@.bundle.copy"
+              value="${drop.dir}/bundles/${@DROP@.bundle.name}"/>
+
+    <!-- Root of exploded area. -->
+    <property name="@DROP@.root.dir" value="${drop.dir}/@DROP@"/>
+    <property name="@DROP@.src.dir" value="${@DROP@.root.dir}/src"/>
+
+    <!-- To see if the drop areas are ready. (ignoring bundles) -->
+    <target name="-@DROP@-ready">
+        <condition property="@DROP@.ready">
+            <and>
+                <available file="${@DROP@.root.dir}" type="dir"/>
+                <available file="${@DROP@.root.dir}/PATCHED" type="file"/>
+            </and>
+        </condition>
+    </target>
+
+    <!-- Copy over bundles from some shared master area. -->
+    <condition property="@DROP@.master.bundle.copy.exists">
+        <available file="${@DROP@.master.bundle.copy}" type="file"/>
+    </condition>
+    <target name="-@DROP@-copy-bundle"
+	    depends="init, -@DROP@-ready"
+            if="@DROP@.master.bundle.copy.exists"
+            unless="@DROP@.ready">
+        <echo message="Copying from ${@DROP@.master.bundle.copy}"/>
+        <dirname property="@DROP@.bundle.dirname" file="${@DROP@.bundle.copy}"/>
+        <mkdir dir="${@DROP@.bundle.dirname}"/>
+        <delete file="${@DROP@.bundle.copy}.temp"/>
+        <delete file="${@DROP@.bundle.copy}"/>
+        <copy file="${@DROP@.master.bundle.copy}" tofile="${@DROP@.bundle.copy}.temp"/>
+        <move file="${@DROP@.bundle.copy}.temp" tofile="${@DROP@.bundle.copy}"/>
+        <property name="@DROP@.master.bundle.found" value="true"/>
+    </target>
+
+    <!-- Determine if the master url download should be used. -->
+    <target name="-@DROP@-url-should-be-used" unless="@DROP@.url.should.be.used">
+        <condition property="@DROP@.url.should.be.used">
+            <and>
+                <http url="${@DROP@.master.bundle.url.base}"/>
+                <not>
+                    <isset property="@DROP@.master.bundle.copy.exists"/>
+                </not>
+            </and>
+        </condition>
+    </target>
+
+    <!-- Download bundles from a url. -->
+    <target name="-@DROP@-url-bundle"
+	    depends="init, -@DROP@-ready, -@DROP@-url-should-be-used"
+            if="@DROP@.url.should.be.used"
+            unless="@DROP@.ready">
+        <echo message="Downloading from ${@DROP@.master.bundle.url}"/>
+        <dirname property="@DROP@.bundle.dirname" file="${@DROP@.bundle.copy}"/>
+        <mkdir dir="${@DROP@.bundle.dirname}"/>
+        <delete file="${@DROP@.bundle.copy}.temp"/>
+        <delete file="${@DROP@.bundle.copy}"/>
+        <get src="${@DROP@.master.bundle.url}" dest="${@DROP@.bundle.copy}.temp"/>
+        <move file="${@DROP@.bundle.copy}.temp" tofile="${@DROP@.bundle.copy}"/>
+        <property name="@DROP@.master.bundle.found" value="true"/>
+    </target>
+    
+    <!-- Fill in the drop zones, but just when needed. -->
+    <target name="@DROP@-update"
+            depends="init, 
+		     -@DROP@-copy-bundle,
+		     -@DROP@-url-bundle,
+                     -@DROP@-ready"
+            if="@DROP@.master.bundle.found"
+            unless="@DROP@.ready">
+        <delete dir="${@DROP@.root.dir}"/>
+        <delete dir="${@DROP@.root.dir}-temp"/>
+        <mkdir dir="${@DROP@.root.dir}-temp"/>
+        <unzip src="${@DROP@.bundle.copy}" dest="${@DROP@.root.dir}-temp"/>
+        <move file="${@DROP@.root.dir}-temp" tofile="${@DROP@.root.dir}"/>
+        <touch>
+            <fileset dir="${@DROP@.root.dir}"/>
+        </touch>
+        <condition property="patch.utility" value="gpatch" else="patch">
+            <os name="SunOS"/>
+        </condition>
+        <apply executable="${patch.utility}"
+		   dir="${@DROP@.root.dir}"
+	           parallel="false"
+	           failonerror="true"
+	           verbose="true">
+            <arg value="-l"/>
+            <arg value="-p0"/>
+            <arg value="-i"/>
+            <filelist dir="${patches.dir}/@DROP@" files="${@DROP@.patch.list}"/>
+        </apply>
+        <echo file="${@DROP@.root.dir}/PATCHED"
+	      message="Patches have been applied."/>
+    </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/build.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,103 @@
+#
+# Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# Base locations where bundles are located
+slashjava=/java
+devtools=${slashjava}/devtools
+
+# This is the JDK used to build and run the bootstrap version of javac.
+# The bootstrap javac is used to compile both boostrap versions of the
+# other tools, and product versions of all the tools.
+# Override this path as needed, either on the command line or in 
+# one of the standard user build.properties files (see build.xml)
+javac.jar=${bootstrap.dir}/lib/javac.jar
+
+# options for the <javac> tasks used to compile the tools
+javac.source = 7
+javac.target = 7
+javac.debug = true
+javac.no.jdk.warnings = -XDignore.symbol.file=true
+# set the following to -version to verify the versions of javac being used
+javac.version.opt = 
+# in time, there should be no exceptions to -Xlint:all
+#javac.lint.opts = -Xlint:all,-unchecked,-deprecation,-fallthrough,-cast,-serial
+javac.lint.opts=
+
+# JVM memory size
+javac.memoryInitialSize = 256m
+javac.memoryMaximumSize = 512m
+
+#------------------------------------------------------------
+
+# Root of output directories
+output.dir=.
+
+# Built files
+build.dir=${output.dir}/build
+build.classes.dir=${build.dir}/classes
+
+# Distributed results
+dist.dir=${output.dir}/dist
+dist.lib.dir=${dist.dir}/lib
+dist.classes.jar=${dist.lib.dir}/classes.jar
+dist.src.zip=${dist.lib.dir}/src.zip
+
+# Where all drop sources live
+drop.dir=./drop
+
+# Where patches to drop bundle sources live
+patches.dir=patches
+
+# Original source area
+orig.dir=src
+orig.src.dir=${orig.dir}/share/classes
+
+# Sanity information
+sanity.info= Sanity Settings:${line.separator}\
+  ant.home=${ant.home}${line.separator}\
+  ant.version=${ant.version}${line.separator}\
+  ant.java.version=${ant.java.version}${line.separator}\
+  java.home=${java.home}${line.separator}\
+  java.version=${java.version}${line.separator}\
+  os.name=${os.name}${line.separator}\
+  os.arch=${os.arch}${line.separator}\
+  os.version=${os.version}${line.separator}\
+  bootstrap.dir=${bootstrap.dir}${line.separator}\
+  javac.jar=${javac.jar}${line.separator}\
+  javac.memoryInitialSize=${javac.memoryInitialSize}${line.separator}\
+  javac.memoryMaximumSize=${javac.memoryMaximumSize}${line.separator}\
+  javac.source=${javac.source}${line.separator}\
+  javac.debug=${javac.debug}${line.separator}\
+  javac.target=${javac.target}${line.separator}\
+  javac.version.opt=${javac.version.opt}${line.separator}\
+  javac.lint.opts=${javac.lint.opts}${line.separator}\
+  javac.no.jdk.warnings=${javac.no.jdk.warnings}${line.separator}\
+  output.dir=${output.dir}${line.separator}\
+  build.dir=${build.dir}${line.separator}\
+  dist.dir=${dist.dir}${line.separator}\
+  drop.dir=${drop.dir}${line.separator}\
+${line.separator}
+
+#------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/build.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Sun designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Sun in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ CA 95054 USA or visit www.sun.com if you need additional information or
+ have any questions.
+-->
+
+<project name="jaxws" default="all" basedir=".">
+   
+    <!-- For 'ant -p' or 'ant -projecthelp' -->
+    
+    <description>
+    Ant build script for the ${ant.project.name} part of the jdk.
+
+    Input Properties: (see build.properties for the ant defaults)
+      bootstrap.dir        - dir with lib/javac.jar, added to javac bootclasspath
+      javac.debug          - true or false for debug classfiles
+      javac.target         - classfile version target
+      javac.source         - source version
+    </description>
+
+    <!-- Mac is special, need to downgrade these before build.properties. -->
+    <condition property="javac.source" value="1.5">
+        <os family="mac"/>
+    </condition>
+    <condition property="javac.target" value="1.5">
+        <os family="mac"/>
+    </condition>
+
+    <!-- Project build properties. -->
+    <property file="build.properties"/>
+
+    <!-- Get shared targets. -->
+    <import file="build-defs.xml"/>
+
+    <!-- Initialization of directories needed for build. -->
+    <target name="init">
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${build.classes.dir}"/>
+        <mkdir dir="${dist.dir}"/>
+        <mkdir dir="${dist.lib.dir}"/>
+    </target>
+    
+    <!-- Sanity checks and settings -->
+    <target name="sanity"
+	    depends="-javac-jar-exists"
+            description="Display settings of configuration values">
+        <echo message="${sanity.info}"/>
+    </target>
+
+     <!-- Check for bootstrap javac.jar file, warn if missing. -->
+    <condition property="javac.jar.exists">
+        <available file="${javac.jar}" type="file"/>
+    </condition>
+    <target name="-javac-jar-exists"
+            unless="javac.jar.exists">
+        <echo message="WARNING: Cannot find ${javac.jar}"/>
+    </target>
+
+    <!-- Creation of distribution files to jdk build process. -->
+    <target name="dist"
+	    depends="init, -init-src-dirs, build, -dist-classes-jar, -dist-src-zip"
+            description="Create all built distribution files.">
+    </target>
+    <target name="-dist-classes-jar-uptodate"
+	    depends="init, -init-src-dirs">
+        <condition property="dist.classes.jar.uptodate">
+            <and>
+                <available file="${dist.classes.jar}" type="file"/>
+                <uptodate targetfile="${dist.classes.jar}">
+                    <srcfiles dir="${build.classes.dir}" includes="**"/>
+                </uptodate>
+            </and>
+        </condition>
+    </target>
+    <target name="-dist-classes-jar"
+	    depends="init, -init-src-dirs, -dist-classes-jar-uptodate"
+            unless="dist.classes.jar.uptodate">
+        <delete file="${dist.classes.jar}"/>
+        <jar file="${dist.classes.jar}" basedir="${build.classes.dir}"/>
+    </target>
+
+    <target name="-build-prep"
+	    depends="init, -init-src-dirs, -drop-build-prep">
+    </target>
+
+    <!-- Build (compilation) of sources to class files. -->
+    <target name="build"
+	    depends="init, -init-src-dirs, -build-prep">
+        <javac fork="true"
+             destdir="${build.classes.dir}"
+             memoryInitialSize="${javac.memoryInitialSize}"
+             memoryMaximumSize="${javac.memoryMaximumSize}"
+             source="${javac.source}"
+	     debug="${javac.debug}"
+             target="${javac.target}">
+            <compilerarg value="-J-Xbootclasspath/p:${javac.jar}"/>
+            <compilerarg line="${javac.version.opt} ${javac.lint.opts} ${javac.no.jdk.warnings}"/>
+            <src refid="src.dir.id"/>
+        </javac>
+    </target>
+
+    <!-- Test. (FIXME: Need to know how to run tests.) -->
+    <target name="test"
+	    depends="init, -init-src-dirs, dist">
+        <echo message="FIXME: How do you run the tests"/>
+    </target>
+    
+    <!-- Populate source area if needed. -->
+    <target name="source"
+            depends="init, -init-src-dirs"
+            description="Populate all source file directories">
+    </target>
+
+    <!-- Clean up compiled files. -->
+    <target name="clean"
+            description="Delete all generated files">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dist.dir}"/>
+    </target>
+
+    <!-- Clean up compiled files and all imported source files. -->
+    <target name="clobber"
+	    depends="clean"
+            description="Delete all generated files, including imported sources">
+        <delete dir="${drop.dir}"/>
+    </target>
+
+    <target name="-banner">
+        <echo message="+---------------------------------------+"/>
+        <echo message="+ Starting ant project ${ant.project.name} +"/>
+        <echo message="+---------------------------------------+"/>
+    </target>
+   
+    <!-- Do everything but test. -->
+    <target name="all"
+	    depends="-banner, sanity, dist"
+            description="Build everything.">
+        <echo message="+---------------------------------------+"/>
+        <echo message="+ Finishing ant project ${ant.project.name}"/>
+        <echo message="+---------------------------------------+"/>
+    </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/jaxws.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,40 @@
+#
+# Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+drops.master.copy.base=${devtools}/share/jdk7-drops
+drops.master.url.base=http://kenai.com/projects/jdk7-drops/downloads/download
+
+jaxws_src.bundle.name=jdk7-jaxws-2009_09_28.zip
+jaxws_src.master.bundle.dir=${drops.master.copy.base}
+#jaxws_src.bundle.url.base=https://jaxws.dev.java.net/files/documents/913/142147
+jaxws_src.master.bundle.url.base=${drops.master.url.base}
+
+jaf_src.bundle.name=jdk7-jaf-2009_08_28.zip
+jaf_src.master.bundle.dir=${drops.master.copy.base}
+jaf_src.master.bundle.url.base=${drops.master.url.base}
+
+jaxws_tests.bundle.name=jdk7-jaxws-tests-2009_08_28.zip
+jaxws_tests.master.bundle.dir=${drops.master.copy.base}
+jaxws_tests.master.bundle.url.base=${drops.master.url.base}
--- a/jaxws/make/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxws/make/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -23,7 +23,7 @@
 # have any questions.
 #
 
-# Makefile for jaxws: wrapper around Ant build.xml file
+# Makefile wrapper around Ant build.xml file
 
 #
 # On Solaris, the 'make' utility from Sun will not work with these makefiles.
@@ -41,38 +41,12 @@
   ANT_OPTIONS += -verbose
 endif
 
-ifdef JDK_VERSION
-  ANT_OPTIONS += -Djdk.version=$(JDK_VERSION)
-endif 
-
-ifdef FULL_VERSION
-  ANT_OPTIONS += -Dfull.version='$(FULL_VERSION)' # will contain spaces
-endif 
-
-ifdef MILESTONE
-  ANT_OPTIONS += -Dmilestone=$(MILESTONE)
-endif
-
-ifdef BUILD_NUMBER
-  ANT_OPTIONS += -Dbuild.number=$(BUILD_NUMBER)
-else
-  ifdef JDK_BUILD_NUMBER
-    ANT_OPTIONS += -Dbuild.number=$(JDK_BUILD_NUMBER)
-  endif
-endif
-
-ifeq ($(VARIANT), DBG)
-  ANT_OPTIONS += -Djavac.debug=true
-else
-  ifeq ($(VARIANT), OPT)
+ifeq ($(VARIANT), OPT)
+  ifneq ($(DEBUG_CLASSFILES), true)
     ANT_OPTIONS += -Djavac.debug=false
   endif
 endif
 
-ifeq ($(DEBUG_CLASSFILES), true)
-  ANT_OPTIONS += -Djavac.debug=true
-endif
-
 # Note: jdk/make/common/Defs.gmk uses LANGUAGE_VERSION (-source NN)
 # and the somewhat misnamed CLASS_VERSION (-target NN)
 ifdef TARGET_CLASS_VERSION
@@ -91,24 +65,53 @@
   endif
 endif 
 
-ifdef ALT_BOOTDIR
-  ANT_JAVA_HOME = JAVA_HOME=$(ALT_BOOTDIR)
+# Figure out the platform we are using
+_SYSTEM_UNAME := $(shell uname)
+_PLATFORM_KIND = unix
+ifeq ($(_SYSTEM_UNAME), Windows_NT)
+  _PLATFORM_KIND = windows
+endif
+ifneq (,$(findstring CYGWIN,$(_SYSTEM_UNAME)))
+  _PLATFORM_KIND = windows
 endif
 
+# Where is /java in case we need it
+ifdef ALT_SLASH_JAVA
+  _SLASHJAVA = $(ALT_SLASH_JAVA)
+else
+  ifeq ($(_PLATFORM_KIND), windows)
+    _SLASHJAVA=J:/
+  else
+    _SLASHJAVA=/java
+  endif
+endif
+
+# Where is /java/devtools in case we need it
+ifdef ALT_JDK_DEVTOOLS_DIR
+  _DEVTOOLS = $(ALT_JDK_DEVTOOLS_DIR)
+else
+  _DEVTOOLS = $(_SLASHJAVA)/devtools
+endif
+
+# Add in path to devtools
+ANT_OPTIONS += -Ddevtools=$(_DEVTOOLS)
+
 ifdef ALT_OUTPUTDIR
   OUTPUTDIR = $(ALT_OUTPUTDIR)
-  ANT_OPTIONS += -Dbuild.dir=$(ALT_OUTPUTDIR)/build
-  ANT_OPTIONS += -Ddist.dir=$(ALT_OUTPUTDIR)/dist
+  ANT_OPTIONS += -Doutput.dir=$(ALT_OUTPUTDIR)
 else
   OUTPUTDIR = ..
 endif
 
 ifdef ALT_LANGTOOLS_DIST
+  ifdef ALT_BOOTDIR
+    ANT_JAVA_HOME = JAVA_HOME=$(ALT_BOOTDIR)
+  endif
   ANT_OPTIONS += -Dbootstrap.dir=$(ALT_LANGTOOLS_DIST)/bootstrap
-endif
-
-ifdef FINDBUGS_HOME
-  ANT_OPTIONS += -Dfindbugs.home=$(FINDBUGS_HOME)
+else
+  ifdef ALT_JDK_IMPORT_PATH
+    ANT_JAVA_HOME = JAVA_HOME=$(ALT_JDK_IMPORT_PATH)
+  endif
 endif
 
 ifdef ANT_HOME
@@ -124,18 +127,59 @@
 endif
 
 # Default target and expected 'do everything' target
-all: build
-
-# Standard make clobber target
-clobber: clean
+default: all
 
 # All ant targets of interest
-ANT_TARGETS = build clean sanity # for now
+ANT_TARGETS = all source build dist clobber clean sanity
 
 # Create a make target for each
 $(ANT_TARGETS):
-	$(ANT_JAVA_HOME) $(ANT) -version
-	$(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@
+	cd .. && $(ANT_JAVA_HOME) $(ANT) -version
+	cd .. && $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@
+
+# Help target
+define helpenvline
+@echo "    $1";echo "        $2"
+endef
+help:
+	@echo "----------------------------------------------------------"
+	@echo " "
+	@echo "Help information for this Makefile:"
+	@echo " "
+	@echo "  Targets (see ant project information for descriptions):"
+	@echo "    $(ANT_TARGETS)"
+	@echo " "
+	@echo "  Environment or command line variables (all optional):"
+	$(call helpenvline, ALT_BOOTDIR,\
+	       "JAVA_HOME to use when running ant")
+	$(call helpenvline, ALT_LANGTOOLS_DIST,\
+	       "path to langtools repository dist directory")
+	$(call helpenvline, ALT_OUTPUTDIR,\
+	       "path to root of output")
+	$(call helpenvline, DEBUG_CLASSFILES,\
+	       "if set makes sure ant property javac.debug is true")
+	$(call helpenvline, JAVAC_SOURCE_ARG,\
+	       "if SOURCE_LANGUAGE_VERSION not set uses this to set ant property javac.source")
+	$(call helpenvline, JAVAC_TARGET_ARG,\
+	       "if TARGET_CLASS_VERSION not set uses this to set ant property javac.target")
+	$(call helpenvline, SOURCE_LANGUAGE_VERSION,\
+	       "if set uses this to set ant property javac.source")
+	$(call helpenvline, QUIET,\
+	       "if set will pass -quiet to ant")
+	$(call helpenvline, TARGET_CLASS_VERSION,\
+	       "JAVA_HOME to use when running ant")
+	$(call helpenvline, VARIANT,\
+	       "if set to OPT means optimized build will set javac.debug to false")
+	$(call helpenvline, VERBOSE,\
+	       "if set will pass -verbose to ant")
+	@echo " "
+	@echo "----------------------------------------------------------"
+	@echo " "
+	@echo "Ant project file help information:"
+	@echo " "
+	@$(ANT_JAVA_HOME) cd .. && $(ANT) $(ANT_OPTIONS) -p
+	@echo " "
+	@echo "----------------------------------------------------------"
 
 # Targets for Sun's internal JPRT build system
 JPRT_ARCHIVE_BUNDLE=$(OUTPUTDIR)/jprt.zip
@@ -145,5 +189,5 @@
 	   zip -q -r $(JPRT_ARCHIVE_BUNDLE) . )
 
 # Declare these phony (not filenames)
-.PHONY: $(ANT_TARGETS) all clobber \
+.PHONY: $(ANT_TARGETS) \
 	jprt_build_product jprt_build_debug jprt_build_fastdebug
--- a/jaxws/make/build.properties	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-# This is the JDK used to build and run the bootstrap version of javac.
-# The bootstrap javac is used to compile both boostrap versions of the
-# other tools, and product versions of all the tools.
-# Override this path as needed, either on the command line or in 
-# one of the standard user build.properties files (see build.xml)
-
-# options for the <javac> tasks used to compile the tools
-javac.source = 7
-javac.target = 7
-javac.debug = true
-javac.no.jdk.warnings = -XDignore.symbol.file=true
-# set the following to -version to verify the versions of javac being used
-javac.version.opt = 
-# in time, there should be no exceptions to -Xlint:all
-javac.lint.opts = -Xlint:all,-unchecked,-deprecation,-fallthrough,-cast,-serial -Werror
-
-# JVM memory size
-javac.memoryInitialSize = 128m
-javac.memoryMaximumSize = 256m
-
-#------------------------------------------------------------
--- a/jaxws/make/build.xml	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.  Sun designates this
- particular file as subject to the "Classpath" exception as provided
- by Sun in the LICENSE file that accompanied this code.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- CA 95054 USA or visit www.sun.com if you need additional information or
- have any questions.
--->
-
-<!--
- This is the main build file for the jaxws workspace.
- -->
-
-<project name="jaxws" default="all" basedir=".">
-
-    <!-- Convenient shorthands for standard locations within the workspace. -->
-    <property file="build.properties"/>
-    <property name="topdir" value=".."/>
-    <property name="build.dir" location="${topdir}/build"/>
-    <property name="build.classes.dir" location="${build.dir}/classes"/>
-    <property name="build.gensrc.dir" location="${build.dir}/gensrc"/>
-    <property name="build.toolclasses.dir" location="${build.dir}/toolclasses"/>
-    <property name="dist.dir" location="${topdir}/dist"/>
-    <property name="dist.lib.dir" location="${dist.dir}/lib"/>
-    <property name="make.dir" location="${topdir}/make"/>
-    <property name="make.tools.dir" location="${make.dir}/tools"/>
-    <property name="src.dir" location="${topdir}/src"/>
-    <property name="src.classes.dir" location="${src.dir}/share/classes"/>
-    <property environment="env"/>
-
-    <target name="build" depends="banner, build-classes, build-tools, build-binaries">
-	<mkdir dir="${dist.lib.dir}"/>
-	<jar file="${dist.lib.dir}/classes.jar" basedir="${build.classes.dir}"/>
-	<zip file="${dist.lib.dir}/src.zip" basedir="${src.classes.dir}"/>
-    </target>
-
-    <!-- Debug information -->
-    <target name="sanity"
-        description="display settings of configuration values">
-        <echo level="info">ant.home = ${ant.home}</echo>
-        <echo level="info">java.home = ${env.JAVA_HOME}</echo>
-        <echo level="info">bootstrap.dir = ${bootstrap.dir}</echo>
-    </target>
-
-    <target name="build-tools" depends="-defs-pstrip">
-        <mkdir dir="${build.dir}"/>
-        <mkdir dir="${build.classes.dir}"/>
-	    <pstrip srcdir="${src.classes.dir}"
-                    destdir="${build.classes.dir}"
-		    includes="**/*.properties"/>
-    </target>
-
-    <target name="build-binaries">
-        <mkdir dir="${build.dir}"/>
-        <mkdir dir="${build.classes.dir}"/>
-            <copy todir="${build.classes.dir}">
-                 <fileset dir="${src.classes.dir}"
-                     includes="**/*.xsd, **/*.default"
-                     excludes="**/*.java, **/*.package.html, **/*.properties"/>
-            </copy>
-        <mkdir dir="${build.classes.dir}/META-INF/services"/>
-            <copy todir="${build.classes.dir}/META-INF/services"
-                  file="${src.classes.dir}/com/sun/tools/etc/META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory"/>
-            <copy todir="${build.classes.dir}/META-INF/services"
-                  file="${src.classes.dir}/com/sun/tools/etc/META-INF/services/com.sun.tools.internal.xjc.Plugin"/>
- 	    <!-- copy jaxb sources files required for jaxb tool time -->	
-           <mkdir dir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime"/>
-            <copy todir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime">
-                 <fileset dir="${src.classes.dir}/com/sun/tools/internal/xjc/runtime"
-                     includes="**/*.java"
-                     excludes="**/*.package.html"/>
-            </copy>
-    </target>
-
-    <target name="-defs-pstrip">
-      <mkdir dir="${build.toolclasses.dir}"/>
-      <javac srcdir="${make.tools.dir}/StripProperties"
-		destdir="${build.toolclasses.dir}/"
-		classpath="${ant.home}/lib/ant.jar"/>
-      <taskdef name="pstrip"
-		 classname="StripPropertiesTask"
-		 classpath="${build.toolclasses.dir}/"/>
-    </target>
-
-    <target name="build-classes" depends="sanity">
-      <mkdir dir="${build.dir}"/>
-      <mkdir dir="${build.classes.dir}"/>
-      <javac fork="true"
-             srcdir="${src.classes.dir}"
-             destdir="${build.classes.dir}"
-             memoryInitialSize="${javac.memoryInitialSize}"
-             memoryMaximumSize="${javac.memoryMaximumSize}"
-             source="${javac.source}"
-	     debug="${javac.debug}"
-             target="${javac.target}"
-             excludes="com/sun/tools/internal/txw2/**">
-         <compilerarg value="-J-Xbootclasspath/p:${bootstrap.dir}/lib/javac.jar"/>
-         <compilerarg line="${javac.version.opt}"/>
-         <compilerarg line="${javac.no.jdk.warnings}"/>
-      </javac>
-    </target>
-
-    <target name="clean" description="Delete all generated files">
-	<delete dir="${build.dir}"/>
-	<delete dir="${dist.dir}"/>
-    </target>
-
-    <target name="banner">
-      <echo>+---------------------------------------+</echo>
-      <echo>+    Building JAX-WS Component          +</echo>
-      <echo>+---------------------------------------+</echo>
-    </target>
-
-</project>
--- a/jaxws/make/jprt.properties	Wed Jul 05 17:00:34 2017 +0200
+++ b/jaxws/make/jprt.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2006-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -34,8 +34,8 @@
 solaris_x64_5.10,\
 linux_i586_2.6,\
 linux_x64_2.6,\
-windows_i586,\
-windows_x64
+windows_i586_5.0,\
+windows_x64_5.2
 
 # The different build flavors we want
 jprt.build.flavors=product,fastdebug
@@ -49,7 +49,6 @@
 # Standard list of jprt test targets for this workspace
 jprt.test.targets=
 
-# Directories needed to build
-jprt.bundle.src.dirs=make src
+# Directories needing to exclude from source bundles
 jprt.bundle.exclude.src.dirs=build dist
 
--- a/jaxws/make/tools/StripProperties/StripProperties.java	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +0,0 @@
-/*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-import java.io.BufferedInputStream;
-import java.io.BufferedWriter;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * Reads a properties file from standard input and writes an equivalent
- * properties file without comments to standard output.
- */
-public class StripProperties {
-
-    public static void main(String[] args) {
-        StripProperties sp = new StripProperties();
-        boolean ok = sp.run(args);
-        if ( !ok ) {
-            System.exit(1);
-        }
-    }
-
-    static interface Log {
-        void info(String msg);
-        void verbose(String msg);
-        void error(String msg, Exception e);
-    }
-
-    private String propfiles[];
-    private String outfiles[] ;
-    private int stripCount = 0;
-    private boolean quiet = false;
-    private Log log;
-
-    public void setLog(Log log) {
-        this.log = log;
-    }
-
-    private boolean parseOptions(String args[]) {
-        boolean ok = true;
-        if ( stripCount > 0 ) {
-            String new_propfiles[] = new String[stripCount + args.length];
-            String new_outfiles[]  = new String[stripCount + args.length];
-            System.arraycopy(propfiles, 0, new_propfiles, 0, stripCount);
-            System.arraycopy(outfiles, 0, new_outfiles, 0, stripCount);
-            propfiles = new_propfiles;
-            outfiles  = new_outfiles;
-        } else {
-            propfiles = new String[args.length];
-            outfiles  = new String[args.length];
-        }
-
-        for ( int i = 0; i < args.length ; i++ ) {
-            if ( "-strip".equals(args[i]) && i+2 < args.length ) {
-                propfiles[stripCount] = args[++i];
-                outfiles[stripCount]    = args[++i];
-                stripCount++;
-            } else if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) {
-                String filename = args[++i];
-                FileInputStream finput = null;
-                byte contents[] = null;
-                try {
-                    finput = new FileInputStream(filename);
-                    int byteCount = finput.available();
-                    if ( byteCount <= 0 ) {
-                        log.error("The -optionsfile file is empty", null);
-                        ok = false;
-                    } else {
-                        contents = new byte[byteCount];
-                        int bytesRead = finput.read(contents);
-                        if ( byteCount != bytesRead ) {
-                            log.error("Cannot read all of -optionsfile file", null);
-                            ok = false;
-                        }
-                    }
-                } catch ( IOException e ) {
-                    log.error("cannot open " + filename, e);
-                    ok = false;
-                }
-                if ( finput != null ) {
-                    try {
-                        finput.close();
-                    } catch ( IOException e ) {
-                        ok = false;
-                        log.error("cannot close " + filename, e);
-                    }
-                }
-                if ( ok = true && contents != null ) {
-                    String tokens[] = (new String(contents)).split("\\s+");
-                    if ( tokens.length > 0 ) {
-                        ok = parseOptions(tokens);
-                    }
-                }
-                if ( !ok ) {
-                    break;
-                }
-        } else if ( "-quiet".equals(args[i]) ) {
-                quiet = true;
-        } else {
-                log.error("argument error", null);
-                ok = false;
-        }
-        }
-        return ok;
-    }
-
-    private boolean stripFiles(String propertiesPath, String outputPath) {
-        boolean ok = true;
-        Properties prop = new Properties();
-        InputStream in = null;
-        try {
-                in = new BufferedInputStream(new FileInputStream(propertiesPath));
-                prop.load(in);
-        } catch ( FileNotFoundException e ) {
-                log.error("Cannot access file " + propertiesPath, e);
-                ok = false;
-        } catch ( IOException e ) {
-                log.error("IO exception processing file " + propertiesPath, e);
-                ok = false;
-        }
-        if ( in != null ) {
-                try {
-                    in.close();
-                } catch ( IOException e ) {
-                    log.error("IO exception closing file " + propertiesPath, e);
-                    ok = false;
-                }
-        }
-
-        OutputStream out = null;
-        try {
-                out = new FileOutputStream(outputPath);
-                storeProperties(prop, out);
-                out.flush();
-        } catch ( IOException e ) {
-                log.error("IO exception processing file " + outputPath, e);
-                e.printStackTrace();
-                ok = false;
-        }
-        if ( out != null ) {
-           try {
-                    out.close();
-           } catch ( IOException e ) {
-                    log.error("IO exception closing file " + outputPath, e);
-                    ok = false;
-           }
-        }
-        return ok;
-    }
-
-    /**
-     * Strip the properties filenames supplied, replacing their contents.
-     * @param args Names of properties files to process and replace contents
-     */
-    public boolean run(String args[]) {
-        if (log == null) {
-            log = new Log() {
-                public void error(String msg, Exception e) {
-                    System.err.println("ERROR: StripProperties: " + msg);
-                    if ( e != null ) {
-                        System.err.println("EXCEPTION: " + e.toString());
-                        e.printStackTrace();
-                    }
-                }
-                public void info(String msg) {
-                    System.out.println(msg);
-                }
-                public void verbose(String msg) {
-                    if (!quiet)
-                        System.out.println(msg);
-                }
-            };
-        }
-
-        boolean ok = true;
-        ok = parseOptions(args);
-        if ( ok && stripCount == 0 ) {
-                log.error("options parsed but no files to compile", null);
-                ok = false;
-        }
-        /* Need at least one file. */
-        if ( !ok ) {
-            //usage(log);
-        } else {
-            /* Process files */
-            for ( int i = 0; i < stripCount && ok ; i++ ) {
-                    ok = stripFiles(propfiles[i], outfiles[i]);
-            }
-        }
-        return ok;
-    }
-
-    // --- code below here is adapted from java.util.Properties ---
-
-    private static final String specialSaveChars = "=: \t\r\n\f#!";
-
-    /*
-     * Converts unicodes to encoded &#92;uxxxx
-     * and writes out any of the characters in specialSaveChars
-     * with a preceding slash
-     */
-    private static String saveConvert(String theString, boolean escapeSpace) {
-        int len = theString.length();
-        StringBuffer outBuffer = new StringBuffer(len*2);
-
-        for(int x=0; x<len; x++) {
-            char aChar = theString.charAt(x);
-            switch(aChar) {
-                case ' ':
-                    if (x == 0 || escapeSpace) {
-                        outBuffer.append('\\');
-                    }
-                    outBuffer.append(' ');
-                    break;
-                case '\\':
-                    outBuffer.append('\\');
-                    outBuffer.append('\\');
-                    break;
-                case '\t':
-                    outBuffer.append('\\');
-                    outBuffer.append('t');
-                    break;
-                case '\n':
-                    outBuffer.append('\\');
-                    outBuffer.append('n');
-                    break;
-                case '\r':
-                    outBuffer.append('\\');
-                    outBuffer.append('r');
-                    break;
-                case '\f':
-                    outBuffer.append('\\');
-                    outBuffer.append('f');
-                    break;
-                default:
-                    if ((aChar < 0x0020) || (aChar == 0x007e) || (aChar > 0x00ff)) {
-                        outBuffer.append('\\');
-                        outBuffer.append('u');
-                        outBuffer.append(toHex((aChar >> 12) & 0xF));
-                        outBuffer.append(toHex((aChar >>  8) & 0xF));
-                        outBuffer.append(toHex((aChar >>  4) & 0xF));
-                        outBuffer.append(toHex( aChar        & 0xF));
-                    } else {
-                        if (specialSaveChars.indexOf(aChar) != -1) {
-                            outBuffer.append('\\');
-                        }
-                        outBuffer.append(aChar);
-                    }
-            }
-        }
-        return outBuffer.toString();
-    }
-
-    /**
-     * Writes the content of <code>properties</code> to <code>out</code>.
-     * The format is that of Properties.store with the following modifications:
-     * <ul>
-     * <li>No header or date is written
-     * <li>Latin-1 characters are written as single bytes, not escape sequences
-     * <li>Line breaks are indicated by a single \n independent of platform
-     * <ul>
-     */
-    private static void storeProperties(Properties properties, OutputStream out)
-    throws IOException {
-        BufferedWriter awriter;
-        awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
-        for (Enumeration e = properties.keys(); e.hasMoreElements();) {
-            String key = (String)e.nextElement();
-            String val = (String)properties.get(key);
-            key = saveConvert(key, true);
-
-            /* No need to escape embedded and trailing spaces for value, hence
-             * pass false to flag.
-             */
-            val = saveConvert(val, false);
-            writeln(awriter, key + "=" + val);
-        }
-        awriter.flush();
-    }
-
-    private static void writeln(BufferedWriter bw, String s) throws IOException {
-        bw.write(s);
-        bw.write("\n");
-    }
-
-    /**
-     * Convert a nibble to a hex character
-     * @param   nibble  the nibble to convert.
-     */
-    private static char toHex(int nibble) {
-        return hexDigit[(nibble & 0xF)];
-    }
-
-    /** A table of hex digits */
-    private static final char[] hexDigit = {
-        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-    };
-}
--- a/jaxws/make/tools/StripProperties/StripPropertiesTask.java	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-
-public class StripPropertiesTask extends MatchingTask {
-    public void setSrcDir(File srcDir) {
-        this.srcDir = srcDir;
-    }
-
-    public void setDestDir(File destDir) {
-        this.destDir = destDir;
-    }
-
-    public void execute() {
-        StripProperties.Log log = new StripProperties.Log() {
-            public void error(String msg, Exception e) {
-                log(msg, Project.MSG_ERR);
-            }
-            public void info(String msg) {
-                log(msg, Project.MSG_INFO);
-            }
-            public void verbose(String msg) {
-                log(msg, Project.MSG_VERBOSE);
-            }
-        };
-        List<String> mainOpts = new ArrayList<String>();
-        int count = 0;
-        DirectoryScanner s = getDirectoryScanner(srcDir);
-        for (String path: s.getIncludedFiles()) {
-            if (path.endsWith(".properties")) {
-                File srcFile = new File(srcDir, path);
-                File destFile = new File(destDir, path);
-                // Arguably, the comparison in the next line should be ">", not ">="
-                // but that assumes the resolution of the last modified time is fine
-                // grained enough; in practice, it is better to use ">=".
-                if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified())
-                    continue;
-                destFile.getParentFile().mkdirs();
-                mainOpts.add("-strip");
-                mainOpts.add(srcFile.getPath());
-                mainOpts.add(destFile.getPath());
-                count++;
-            }
-        }
-        if (mainOpts.size() > 0) {
-            log("Generating " + count + " resource files to " + destDir, Project.MSG_INFO);
-            StripProperties sp = new StripProperties();
-            sp.setLog(log);
-            boolean ok = sp.run((String[])mainOpts.toArray(new String[mainOpts.size()]));
-            if (!ok)
-                throw new BuildException("StripProperties failed.");
-        }
-    }
-
-    private File srcDir;
-    private File destDir;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/nbproject/findbugs.settings	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,72 @@
+#FindBugs User Preferences
+#Tue Jun 30 18:33:11 PDT 2009
+detectorAbnormalFinallyBlockReturn=AbnormalFinallyBlockReturn|false
+detectorAbstractClassEmptyMethods=AbstractClassEmptyMethods|false
+detectorAbstractOverriddenMethod=AbstractOverriddenMethod|false
+detectorArrayBasedCollections=ArrayBasedCollections|false
+detectorArrayWrappedCallByReference=ArrayWrappedCallByReference|false
+detectorBloatedAssignmentScope=BloatedAssignmentScope|false
+detectorBloatedSynchronizedBlock=BloatedSynchronizedBlock|false
+detectorClassEnvy=ClassEnvy|false
+detectorCollectStatistics=CollectStatistics|false
+detectorConfusingAutoboxedOverloading=ConfusingAutoboxedOverloading|false
+detectorConstantListIndex=ConstantListIndex|false
+detectorCopiedOverriddenMethod=CopiedOverriddenMethod|false
+detectorCustomBuiltXML=CustomBuiltXML|false
+detectorCyclomaticComplexity=CyclomaticComplexity|false
+detectorDateComparison=DateComparison|false
+detectorDeclaredRuntimeException=DeclaredRuntimeException|false
+detectorDeletingWhileIterating=DeletingWhileIterating|false
+detectorDubiousListCollection=DubiousListCollection|false
+detectorFieldCouldBeLocal=FieldCouldBeLocal|false
+detectorFinalParameters=FinalParameters|false
+detectorFloatingPointLoops=FloatingPointLoops|false
+detectorInefficientStringBuffering=InefficientStringBuffering|false
+detectorInheritanceTypeChecking=InheritanceTypeChecking|false
+detectorJDBCVendorReliance=JDBCVendorReliance|false
+detectorListIndexedIterating=ListIndexedIterating|false
+detectorLiteralStringComparison=LiteralStringComparison|false
+detectorLocalSynchronizedCollection=LocalSynchronizedCollection|false
+detectorLostExceptionStackTrace=LostExceptionStackTrace|false
+detectorManualArrayCopy=ManualArrayCopy|false
+detectorMethodReturnsConstant=MethodReturnsConstant|false
+detectorNeedlessAutoboxing=NeedlessAutoboxing|false
+detectorNeedlessCustomSerialization=NeedlessCustomSerialization|false
+detectorNeedlessInstanceRetrieval=NeedlessInstanceRetrieval|false
+detectorNeedlessMemberCollectionSynchronization=NeedlessMemberCollectionSynchronization|false
+detectorNonCollectionMethodUse=NonCollectionMethodUse|false
+detectorNonOwnedSynchronization=NonOwnedSynchronization|false
+detectorNonRecycleableTaglibs=NonRecycleableTaglibs|false
+detectorOrphanedDOMNode=OrphanedDOMNode|false
+detectorOverlyConcreteParameter=OverlyConcreteParameter|false
+detectorParallelLists=ParallelLists|false
+detectorPartiallyConstructedObjectAccess=PartiallyConstructedObjectAccess|false
+detectorPossibleIncompleteSerialization=PossibleIncompleteSerialization|false
+detectorPossibleMemoryBloat=PossibleMemoryBloat|false
+detectorPossiblyRedundantMethodCalls=PossiblyRedundantMethodCalls|false
+detectorSQLInLoop=SQLInLoop|false
+detectorSection508Compliance=Section508Compliance|false
+detectorSillynessPotPourri=SillynessPotPourri|false
+detectorSloppyClassReflection=SloppyClassReflection|false
+detectorSluggishGui=SluggishGui|false
+detectorSpoiledChildInterfaceImplementor=SpoiledChildInterfaceImplementor|false
+detectorSpuriousThreadStates=SpuriousThreadStates|false
+detectorStaticArrayCreatedInMethod=StaticArrayCreatedInMethod|false
+detectorStaticMethodInstanceInvocation=StaticMethodInstanceInvocation|false
+detectorSuspiciousComparatorReturnValues=SuspiciousComparatorReturnValues|false
+detectorSuspiciousJDKVersionUse=SuspiciousJDKVersionUse|false
+detectorSuspiciousWaitOnConcurrentObject=SuspiciousWaitOnConcurrentObject|false
+detectorSyncCollectionIterators=SyncCollectionIterators|false
+detectorTailRecursion=TailRecursion|false
+detectorUnnecessaryStoreBeforeReturn=UnnecessaryStoreBeforeReturn|false
+detectorUnrelatedCollectionContents=UnrelatedCollectionContents|false
+detectorUnrelatedReturnValues=UnrelatedReturnValues|false
+detectorUseAddAll=UseAddAll|false
+detectorUseCharacterParameterizedMethod=UseCharacterParameterizedMethod|false
+detectorUseEnumCollections=UseEnumCollections|false
+detectorUseSplit=UseSplit|false
+detectorUseToArray=UseToArray|false
+detector_threshold=2
+effort=default
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,I18N,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false
+filter_settings_neg=|
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/nbproject/project.xml	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.ant.freeform</type>
+    <configuration>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+            <name>jaxws</name>
+        </general-data>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
+            <!-- Do not use Project Properties customizer when editing this file manually. -->
+            <name>jaxws</name>
+            <properties/>
+            <folders>
+                <source-folder>
+                    <label>jaxws</label>
+                    <location>.</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+            </folders>
+            <ide-actions>
+                <action name="build">
+                    <target>build</target>
+                </action>
+                <action name="clean">
+                    <target>clean</target>
+                </action>
+                <action name="rebuild">
+                    <target>clean</target>
+                    <target>build</target>
+                </action>
+            </ide-actions>
+            <view>
+                <items>
+                    <source-file>
+                        <location>build.xml</location>
+                    </source-file>
+                </items>
+                <context-menu>
+                    <ide-action name="build"/>
+                    <ide-action name="rebuild"/>
+                    <ide-action name="clean"/>
+                </context-menu>
+            </view>
+            <subprojects/>
+        </general-data>
+        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+        <preferences xmlns="http://www.netbeans.org/ns/auxiliary-configuration-preferences/1">
+            <module name="org-netbeans-modules-editor-indent"/>
+        </preferences>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/nbproject/sqe.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,2 @@
+#Path to FindbugsSettingsFile (relative)
+findbugs.settings.file=findbugs.settings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/patches/jaxws_src/README	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,5 @@
+
+This directory will hold any patches that need to be applied to the drop files.
+
+The patch order is defined in the ant build script properties.
+
--- a/jdk/.hgtags	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/.hgtags	Wed Jul 05 17:01:15 2017 +0200
@@ -46,3 +46,4 @@
 226b20019b1f020c09ea97d137d98e011ce65d76 jdk7-b69
 893bcca951b747ddcf6986362b877f0e1dbb835b jdk7-b70
 b3f3240135f0c10b9f2481c174b81b7fcf0daa60 jdk7-b71
+460639b036f327282832a4fe52b7aa45688afd50 jdk7-b72
--- a/jdk/make/java/java/FILES_java.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/make/java/java/FILES_java.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -454,6 +454,8 @@
     sun/misc/JavaLangAccess.java \
     sun/misc/JavaIOAccess.java \
     sun/misc/JavaIOFileDescriptorAccess.java \
-    sun/misc/JavaNioAccess.java
+    sun/misc/JavaNioAccess.java \
+    sun/misc/Perf.java \
+    sun/misc/PerfCounter.java
 
 FILES_java = $(JAVA_JAVA_java)
--- a/jdk/make/java/logging/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/make/java/logging/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -31,7 +31,7 @@
 #
 # Files to compile.
 #
-AUTO_FILES_JAVA_DIRS = java/util/logging
+AUTO_FILES_JAVA_DIRS = java/util/logging sun/util/logging
 
 #
 # Resources
@@ -46,7 +46,6 @@
 include $(BUILDDIR)/common/Classes.gmk
 
 properties: $(LIBDIR)/logging.properties
-
 $(LIBDIR)/logging.properties: $(SHARE_SRC)/lib/logging.properties
 	$(install-file)
 
--- a/jdk/make/sun/net/FILES_java.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/make/sun/net/FILES_java.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -86,9 +86,11 @@
 	sun/net/www/protocol/http/AuthCache.java \
 	sun/net/www/protocol/http/AuthCacheImpl.java \
 	sun/net/www/protocol/http/AuthCacheValue.java \
+	sun/net/www/protocol/http/AuthScheme.java \
 	sun/net/www/protocol/http/BasicAuthentication.java \
 	sun/net/www/protocol/http/DigestAuthentication.java \
 	sun/net/www/protocol/http/NTLMAuthentication.java \
+	sun/net/www/protocol/http/NTLMAuthenticationProxy.java \
 	sun/net/www/protocol/http/NegotiateAuthentication.java \
 	sun/net/www/protocol/http/NegotiatorImpl.java \
 	sun/net/www/protocol/http/NegotiateCallbackHandler.java \
@@ -123,8 +125,7 @@
 	sun/net/idn/UCharacterEnums.java \
 	sun/net/idn/UCharacterDirection.java \
 	sun/net/idn/StringPrepDataReader.java \
-	sun/net/idn/StringPrep.java \
-	sun/net/www/protocol/http/InMemoryCookieStore.java
+	sun/net/idn/StringPrep.java
 
 ifeq ($(PLATFORM), windows)
     FILES_java += sun/net/www/protocol/http/NTLMAuthSequence.java 
--- a/jdk/make/sun/security/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/make/sun/security/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -60,8 +60,15 @@
   endif
 endif
 
-SUBDIRS = ec other action util tools jgss krb5 smartcardio $(PKCS11) \
-          $(JGSS_WRAPPER) $(MSCAPI)
+# Build in-tree elliptic curve crypto provider only when
+# DISABLE_INTREE_EC is not set
+INTREE_EC = ec
+ifdef DISABLE_INTREE_EC
+  INTREE_EC =
+endif
+
+SUBDIRS = $(INTREE_EC) other action util tools jgss krb5 smartcardio \
+	  $(PKCS11) $(JGSS_WRAPPER) $(MSCAPI)
 
 all build clean clobber::
 	$(SUBDIRS-loop)
--- a/jdk/make/sun/security/ec/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/make/sun/security/ec/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -24,7 +24,7 @@
 #
 
 #
-# Makefile for building sunec.jar and sunecc native library.
+# Makefile for building sunec.jar and sunec native library.
 #
 # This file was derived from make/com/sun/crypto/provider/Makefile.
 #
@@ -121,7 +121,15 @@
 #
 AUTO_FILES_JAVA_DIRS = $(PKGDIR)
 
-include $(BUILDDIR)/common/Classes.gmk
+#
+# Exclude the sources that get built by ../other/Makefile
+#
+AUTO_JAVA_PRUNE = \
+    ECKeyFactory.java \
+    ECParameters.java \
+    ECPrivateKeyImpl.java \
+    ECPublicKeyImpl.java \
+    NamedCurve.java
 
 #
 # Some licensees do not get the native ECC sources, but we still need to
@@ -130,7 +138,7 @@
 #
 
 NATIVE_ECC_AVAILABLE := $(shell \
-    if [ -d $(SHARE_SRC)/native/$(PKGDIR) ] ; then \
+    if [ -d $(SHARE_SRC)/native/$(PKGDIR)/impl ] ; then \
 	$(ECHO) true; \
     else \
 	$(ECHO) false; \
@@ -138,7 +146,7 @@
 
 ifeq ($(NATIVE_ECC_AVAILABLE), true)
 
-  LIBRARY = sunecc
+  LIBRARY = sunec
 
   #
   # Java files that define native methods
@@ -166,12 +174,12 @@
   #
   vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)
 
-  vpath %.c $(SHARE_SRC)/native/$(PKGDIR)
+  vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/impl
 
   #
   # Find include files
   #
-  OTHER_INCLUDES += -I$(SHARE_SRC)/native/$(PKGDIR)
+  OTHER_INCLUDES += -I$(SHARE_SRC)/native/$(PKGDIR)/impl
 
   #
   # Compiler flags
@@ -191,6 +199,10 @@
 
   include $(BUILDDIR)/common/Library.gmk
 
+else # NATIVE_ECC_AVAILABLE
+
+  include $(BUILDDIR)/common/Classes.gmk
+
 endif # NATIVE_ECC_AVAILABLE
 
 #
--- a/jdk/make/sun/security/other/Makefile	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/make/sun/security/other/Makefile	Wed Jul 05 17:01:15 2017 +0200
@@ -45,6 +45,16 @@
     com/sun/net/ssl/internal/ssl
 
 #
+# EC classes used by the packages above
+#
+FILES_java += \
+    sun/security/ec/ECKeyFactory.java \
+    sun/security/ec/ECParameters.java \
+    sun/security/ec/ECPrivateKeyImpl.java \
+    sun/security/ec/ECPublicKeyImpl.java \
+    sun/security/ec/NamedCurve.java
+
+#
 # Rules
 #
 include $(BUILDDIR)/common/Classes.gmk
--- a/jdk/src/share/bin/java.h	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/bin/java.h	Wed Jul 05 17:01:15 2017 +0200
@@ -187,9 +187,6 @@
  *
  */
 typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
-                                                const char *name,
-                                                jboolean init,
-                                                jobject loader,
-                                                jboolean throwError));
+                                                  const char *name));
 jclass FindBootStrapClass(JNIEnv *env, const char *classname);
 #endif /* _JAVA_H_ */
--- a/jdk/src/share/bin/parse_manifest.c	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/bin/parse_manifest.c	Wed Jul 05 17:01:15 2017 +0200
@@ -59,7 +59,7 @@
     char        *out;
     z_stream    zs;
 
-    if (entry->csize == 0xffffffff || entry->isize == 0xffffffff)
+    if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 )
         return (NULL);
     if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0)
         return (NULL);
--- a/jdk/src/share/classes/com/sun/rowset/JdbcRowSetResourceBundle.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/JdbcRowSetResourceBundle.java	Wed Jul 05 17:01:15 2017 +0200
@@ -133,7 +133,7 @@
      * This method returns an enumerated handle of the keys
      * which correspond to values translated to various locales.
      *
-     * @returns an enumerated keys which have messages tranlated to
+     * @return an enumeration of keys which have messages tranlated to
      * corresponding locales.
      */
     public Enumeration getKeys() {
@@ -146,7 +146,7 @@
      * returns the corresponding value reading it
      * from the Resource Bundle loaded earlier.
      *
-     * @returns value in locale specific language
+     * @return value in locale specific language
      * according to the key passed.
      */
     public Object handleGetObject(String key) {
--- a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Wed Jul 05 17:01:15 2017 +0200
@@ -3737,7 +3737,6 @@
     * Returns a result set containing the original value of the current
     * row only.
     *
-    * @return the original result set of the row
     * @throws SQLException if there is no current row
     * @see #setOriginalRow
     */
--- a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlReader.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlReader.java	Wed Jul 05 17:01:15 2017 +0200
@@ -46,6 +46,17 @@
  */
 public class WebRowSetXmlReader implements XmlReader, Serializable {
 
+
+    private JdbcRowSetResourceBundle resBundle;
+
+    public WebRowSetXmlReader(){
+        try {
+           resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
+        } catch(IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+
     /**
      * Parses the given <code>WebRowSet</code> object, getting its input from
      * the given <code>java.io.Reader</code> object.  The parser will send
@@ -69,17 +80,6 @@
      *            reader for the given rowset
      * @see XmlReaderContentHandler
      */
-
-    private JdbcRowSetResourceBundle resBundle;
-
-    public WebRowSetXmlReader(){
-        try {
-           resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
-        } catch(IOException ioe) {
-            throw new RuntimeException(ioe);
-        }
-    }
-
     public void readXML(WebRowSet caller, java.io.Reader reader) throws SQLException {
         try {
             // Crimson Parser(as in J2SE 1.4.1 is NOT able to handle
--- a/jdk/src/share/classes/java/lang/Class.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/lang/Class.java	Wed Jul 05 17:01:15 2017 +0200
@@ -565,8 +565,9 @@
      *          represented by this object.
      */
     public String getName() {
+        String name = this.name;
         if (name == null)
-            name = getName0();
+            this.name = name = getName0();
         return name;
     }
 
--- a/jdk/src/share/classes/java/lang/ClassLoader.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java	Wed Jul 05 17:01:15 2017 +0200
@@ -380,16 +380,28 @@
             // First, check if the class has already been loaded
             Class c = findLoadedClass(name);
             if (c == null) {
+                long t0 = System.nanoTime();
                 try {
                     if (parent != null) {
                         c = parent.loadClass(name, false);
                     } else {
-                        c = findBootstrapClass0(name);
+                        c = findBootstrapClassOrNull(name);
                     }
                 } catch (ClassNotFoundException e) {
+                    // ClassNotFoundException thrown if class not found
+                    // from the non-null parent class loader
+                }
+
+                if (c == null) {
                     // If still not found, then invoke findClass in order
                     // to find the class.
+                    long t1 = System.nanoTime();
                     c = findClass(name);
+
+                    // this is the defining class loader; record the stats
+                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
+                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
+                    sun.misc.PerfCounter.getFindClasses().increment();
                 }
             }
             if (resolve) {
@@ -1008,22 +1020,29 @@
         if (system == null) {
             if (!checkName(name))
                 throw new ClassNotFoundException(name);
-            return findBootstrapClass(name);
+            Class cls = findBootstrapClass(name);
+            if (cls == null) {
+                throw new ClassNotFoundException(name);
+            }
+            return cls;
         }
         return system.loadClass(name);
     }
 
-    private Class findBootstrapClass0(String name)
-        throws ClassNotFoundException
+    /**
+     * Returns a class loaded by the bootstrap class loader;
+     * or return null if not found.
+     */
+    private Class findBootstrapClassOrNull(String name)
     {
         check();
-        if (!checkName(name))
-            throw new ClassNotFoundException(name);
+        if (!checkName(name)) return null;
+
         return findBootstrapClass(name);
     }
 
-    private native Class findBootstrapClass(String name)
-        throws ClassNotFoundException;
+    // return null if not found
+    private native Class findBootstrapClass(String name);
 
     // Check to make sure the class loader has been initialized.
     private void check() {
--- a/jdk/src/share/classes/java/net/CookieManager.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/net/CookieManager.java	Wed Jul 05 17:01:15 2017 +0200
@@ -157,7 +157,7 @@
 
         // if not specify CookieStore to use, use default one
         if (store == null) {
-            cookieJar = new sun.net.www.protocol.http.InMemoryCookieStore();
+            cookieJar = new InMemoryCookieStore();
         } else {
             cookieJar = store;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/net/InMemoryCookieStore.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,393 @@
+/*
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+import java.net.URI;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * A simple in-memory java.net.CookieStore implementation
+ *
+ * @author Edward Wang
+ * @since 1.6
+ */
+class InMemoryCookieStore implements CookieStore {
+    // the in-memory representation of cookies
+    private List<HttpCookie> cookieJar = null;
+
+    // the cookies are indexed by its domain and associated uri (if present)
+    // CAUTION: when a cookie removed from main data structure (i.e. cookieJar),
+    //          it won't be cleared in domainIndex & uriIndex. Double-check the
+    //          presence of cookie when retrieve one form index store.
+    private Map<String, List<HttpCookie>> domainIndex = null;
+    private Map<URI, List<HttpCookie>> uriIndex = null;
+
+    // use ReentrantLock instead of syncronized for scalability
+    private ReentrantLock lock = null;
+
+
+    /**
+     * The default ctor
+     */
+    public InMemoryCookieStore() {
+        cookieJar = new ArrayList<HttpCookie>();
+        domainIndex = new HashMap<String, List<HttpCookie>>();
+        uriIndex = new HashMap<URI, List<HttpCookie>>();
+
+        lock = new ReentrantLock(false);
+    }
+
+    /**
+     * Add one cookie into cookie store.
+     */
+    public void add(URI uri, HttpCookie cookie) {
+        // pre-condition : argument can't be null
+        if (cookie == null) {
+            throw new NullPointerException("cookie is null");
+        }
+
+
+        lock.lock();
+        try {
+            // remove the ole cookie if there has had one
+            cookieJar.remove(cookie);
+
+            // add new cookie if it has a non-zero max-age
+            if (cookie.getMaxAge() != 0) {
+                cookieJar.add(cookie);
+                // and add it to domain index
+                if (cookie.getDomain() != null) {
+                    addIndex(domainIndex, cookie.getDomain(), cookie);
+                }
+                // add it to uri index, too
+                addIndex(uriIndex, getEffectiveURI(uri), cookie);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+
+    /**
+     * Get all cookies, which:
+     *  1) given uri domain-matches with, or, associated with
+     *     given uri when added to the cookie store.
+     *  3) not expired.
+     * See RFC 2965 sec. 3.3.4 for more detail.
+     */
+    public List<HttpCookie> get(URI uri) {
+        // argument can't be null
+        if (uri == null) {
+            throw new NullPointerException("uri is null");
+        }
+
+        List<HttpCookie> cookies = new ArrayList<HttpCookie>();
+        boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
+        lock.lock();
+        try {
+            // check domainIndex first
+            getInternal1(cookies, domainIndex, uri.getHost(), secureLink);
+            // check uriIndex then
+            getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink);
+        } finally {
+            lock.unlock();
+        }
+
+        return cookies;
+    }
+
+    /**
+     * Get all cookies in cookie store, except those have expired
+     */
+    public List<HttpCookie> getCookies() {
+        List<HttpCookie> rt;
+
+        lock.lock();
+        try {
+            Iterator<HttpCookie> it = cookieJar.iterator();
+            while (it.hasNext()) {
+                if (it.next().hasExpired()) {
+                    it.remove();
+                }
+            }
+        } finally {
+            rt = Collections.unmodifiableList(cookieJar);
+            lock.unlock();
+        }
+
+        return rt;
+    }
+
+    /**
+     * Get all URIs, which are associated with at least one cookie
+     * of this cookie store.
+     */
+    public List<URI> getURIs() {
+        List<URI> uris = new ArrayList<URI>();
+
+        lock.lock();
+        try {
+            Iterator<URI> it = uriIndex.keySet().iterator();
+            while (it.hasNext()) {
+                URI uri = it.next();
+                List<HttpCookie> cookies = uriIndex.get(uri);
+                if (cookies == null || cookies.size() == 0) {
+                    // no cookies list or an empty list associated with
+                    // this uri entry, delete it
+                    it.remove();
+                }
+            }
+        } finally {
+            uris.addAll(uriIndex.keySet());
+            lock.unlock();
+        }
+
+        return uris;
+    }
+
+
+    /**
+     * Remove a cookie from store
+     */
+    public boolean remove(URI uri, HttpCookie ck) {
+        // argument can't be null
+        if (ck == null) {
+            throw new NullPointerException("cookie is null");
+        }
+
+        boolean modified = false;
+        lock.lock();
+        try {
+            modified = cookieJar.remove(ck);
+        } finally {
+            lock.unlock();
+        }
+
+        return modified;
+    }
+
+
+    /**
+     * Remove all cookies in this cookie store.
+     */
+    public boolean removeAll() {
+        lock.lock();
+        try {
+            cookieJar.clear();
+            domainIndex.clear();
+            uriIndex.clear();
+        } finally {
+            lock.unlock();
+        }
+
+        return true;
+    }
+
+
+    /* ---------------- Private operations -------------- */
+
+
+    /*
+     * This is almost the same as HttpCookie.domainMatches except for
+     * one difference: It won't reject cookies when the 'H' part of the
+     * domain contains a dot ('.').
+     * I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com
+     * and the cookie domain is .domain.com, then it should be rejected.
+     * However that's not how the real world works. Browsers don't reject and
+     * some sites, like yahoo.com do actually expect these cookies to be
+     * passed along.
+     * And should be used for 'old' style cookies (aka Netscape type of cookies)
+     */
+    private boolean netscapeDomainMatches(String domain, String host)
+    {
+        if (domain == null || host == null) {
+            return false;
+        }
+
+        // if there's no embedded dot in domain and domain is not .local
+        boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
+        int embeddedDotInDomain = domain.indexOf('.');
+        if (embeddedDotInDomain == 0) {
+            embeddedDotInDomain = domain.indexOf('.', 1);
+        }
+        if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) {
+            return false;
+        }
+
+        // if the host name contains no dot and the domain name is .local
+        int firstDotInHost = host.indexOf('.');
+        if (firstDotInHost == -1 && isLocalDomain) {
+            return true;
+        }
+
+        int domainLength = domain.length();
+        int lengthDiff = host.length() - domainLength;
+        if (lengthDiff == 0) {
+            // if the host name and the domain name are just string-compare euqal
+            return host.equalsIgnoreCase(domain);
+        } else if (lengthDiff > 0) {
+            // need to check H & D component
+            String H = host.substring(0, lengthDiff);
+            String D = host.substring(lengthDiff);
+
+            return (D.equalsIgnoreCase(domain));
+        } else if (lengthDiff == -1) {
+            // if domain is actually .host
+            return (domain.charAt(0) == '.' &&
+                    host.equalsIgnoreCase(domain.substring(1)));
+        }
+
+        return false;
+    }
+
+    private void getInternal1(List<HttpCookie> cookies, Map<String, List<HttpCookie>> cookieIndex,
+            String host, boolean secureLink) {
+        // Use a separate list to handle cookies that need to be removed so
+        // that there is no conflict with iterators.
+        ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>();
+        for (Map.Entry<String, List<HttpCookie>> entry : cookieIndex.entrySet()) {
+            String domain = entry.getKey();
+            List<HttpCookie> lst = entry.getValue();
+            for (HttpCookie c : lst) {
+                if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) ||
+                        (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) {
+                    if ((cookieJar.indexOf(c) != -1)) {
+                        // the cookie still in main cookie store
+                        if (!c.hasExpired()) {
+                            // don't add twice and make sure it's the proper
+                            // security level
+                            if ((secureLink || !c.getSecure()) &&
+                                    !cookies.contains(c)) {
+                                cookies.add(c);
+                            }
+                        } else {
+                            toRemove.add(c);
+                        }
+                    } else {
+                        // the cookie has beed removed from main store,
+                        // so also remove it from domain indexed store
+                        toRemove.add(c);
+                    }
+                }
+            }
+            // Clear up the cookies that need to be removed
+            for (HttpCookie c : toRemove) {
+                lst.remove(c);
+                cookieJar.remove(c);
+
+            }
+            toRemove.clear();
+        }
+    }
+
+    // @param cookies           [OUT] contains the found cookies
+    // @param cookieIndex       the index
+    // @param comparator        the prediction to decide whether or not
+    //                          a cookie in index should be returned
+    private <T> void getInternal2(List<HttpCookie> cookies,
+                                Map<T, List<HttpCookie>> cookieIndex,
+                                Comparable<T> comparator, boolean secureLink)
+    {
+        for (T index : cookieIndex.keySet()) {
+            if (comparator.compareTo(index) == 0) {
+                List<HttpCookie> indexedCookies = cookieIndex.get(index);
+                // check the list of cookies associated with this domain
+                if (indexedCookies != null) {
+                    Iterator<HttpCookie> it = indexedCookies.iterator();
+                    while (it.hasNext()) {
+                        HttpCookie ck = it.next();
+                        if (cookieJar.indexOf(ck) != -1) {
+                            // the cookie still in main cookie store
+                            if (!ck.hasExpired()) {
+                                // don't add twice
+                                if ((secureLink || !ck.getSecure()) &&
+                                        !cookies.contains(ck))
+                                    cookies.add(ck);
+                            } else {
+                                it.remove();
+                                cookieJar.remove(ck);
+                            }
+                        } else {
+                            // the cookie has beed removed from main store,
+                            // so also remove it from domain indexed store
+                            it.remove();
+                        }
+                    }
+                } // end of indexedCookies != null
+            } // end of comparator.compareTo(index) == 0
+        } // end of cookieIndex iteration
+    }
+
+    // add 'cookie' indexed by 'index' into 'indexStore'
+    private <T> void addIndex(Map<T, List<HttpCookie>> indexStore,
+                              T index,
+                              HttpCookie cookie)
+    {
+        if (index != null) {
+            List<HttpCookie> cookies = indexStore.get(index);
+            if (cookies != null) {
+                // there may already have the same cookie, so remove it first
+                cookies.remove(cookie);
+
+                cookies.add(cookie);
+            } else {
+                cookies = new ArrayList<HttpCookie>();
+                cookies.add(cookie);
+                indexStore.put(index, cookies);
+            }
+        }
+    }
+
+
+    //
+    // for cookie purpose, the effective uri should only be http://host
+    // the path will be taken into account when path-match algorithm applied
+    //
+    private URI getEffectiveURI(URI uri) {
+        URI effectiveURI = null;
+        try {
+            effectiveURI = new URI("http",
+                                   uri.getHost(),
+                                   null,  // path component
+                                   null,  // query component
+                                   null   // fragment component
+                                  );
+        } catch (URISyntaxException ignored) {
+            effectiveURI = uri;
+        }
+
+        return effectiveURI;
+    }
+}
--- a/jdk/src/share/classes/java/net/URLClassLoader.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/net/URLClassLoader.java	Wed Jul 05 17:01:15 2017 +0200
@@ -340,6 +340,7 @@
      * used.
      */
     private Class defineClass(String name, Resource res) throws IOException {
+        long t0 = System.nanoTime();
         int i = name.lastIndexOf('.');
         URL url = res.getCodeSourceURL();
         if (i != -1) {
@@ -370,12 +371,14 @@
             // Use (direct) ByteBuffer:
             CodeSigner[] signers = res.getCodeSigners();
             CodeSource cs = new CodeSource(url, signers);
+            sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
             return defineClass(name, bb, cs);
         } else {
             byte[] b = res.getBytes();
             // must read certificates AFTER reading bytes.
             CodeSigner[] signers = res.getCodeSigners();
             CodeSource cs = new CodeSource(url, signers);
+            sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
             return defineClass(name, b, 0, b.length, cs);
         }
     }
--- a/jdk/src/share/classes/java/net/doc-files/net-properties.html	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/net/doc-files/net-properties.html	Wed Jul 05 17:01:15 2017 +0200
@@ -71,12 +71,12 @@
 	<LI><P>HTTP</P>
 	<P>The following proxy settings are used by the HTTP protocol handler.</P>
 	<UL>
-		<LI><P><B>http.proxyHost</FONT></B> (default: &lt;none&gt;)<BR>
+		<LI><P><B>http.proxyHost</B> (default: &lt;none&gt;)<BR>
 	        The hostname, or address, of the proxy server 
 		</P>
 		<LI><P><B>http.proxyPort</B> (default: 80)<BR>
 	        The port number of the proxy server.</P>
-		<LI><P><B>http.nonProxyHosts</B> (default: &lt;none&gt;)<BR>
+		<LI><P><B>http.nonProxyHosts</B> (default:  localhost|127.*|[::1])<BR>
 	        Indicates the hosts that should be accessed without going
 	        through the proxy. Typically this defines internal hosts.
 	        The value of this property is a list of hosts,
@@ -86,7 +86,8 @@
 		will indicate that every hosts in the foo.com domain and the
 		localhost should be accessed directly even if a proxy server is
 		specified.</P>
-	</UL>
+                <P>The default value excludes all common variations of the loopback address.</P>
+        </UL>
 	<LI><P>HTTPS<BR>This is HTTP over SSL, a secure version of HTTP
 	mainly used when confidentiality (like on payment sites) is needed.</P>
 	<P>The following proxy settings are used by the HTTPS protocol handler.</P>
@@ -107,7 +108,7 @@
 		</P>
 		<LI><P><B>ftp.proxyPort</B> (default: 80)<BR>
 	        The port number of the proxy server.</P>
-		<LI><P><B>ftp.nonProxyHosts</B> (default: &lt;none&gt;)<BR>
+		<LI><P><B>ftp.nonProxyHosts</B> (default: localhost|127.*|[::1])<BR>
 	        Indicates the hosts that should be accessed without going
 	        through the proxy. Typically this defines internal hosts.
 	        The value of this property is a list of hosts, separated by
@@ -117,6 +118,7 @@
 		will indicate that every hosts in the foo.com domain and the
 		localhost should be accessed directly even if a proxy server is
 		specified.</P>
+                <P>The default value excludes all common variations of the loopback address.</P>
 	</UL>
 	<LI><P>SOCKS<BR>This is another type of proxy. It allows for lower
 	level type of tunneling since it works at the TCP level. In effect,
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Wed Jul 05 17:01:15 2017 +0200
@@ -41,8 +41,12 @@
     private final boolean detectCycles;
     private final LinkOption[] linkOptions;
     private final FileVisitor<? super Path> visitor;
+    private final int maxDepth;
 
-    FileTreeWalker(Set<FileVisitOption> options, FileVisitor<? super Path> visitor) {
+    FileTreeWalker(Set<FileVisitOption> options,
+                   FileVisitor<? super Path> visitor,
+                   int maxDepth)
+    {
         boolean fl = false;
         boolean dc = false;
         for (FileVisitOption option: options) {
@@ -58,18 +62,15 @@
         this.linkOptions = (fl) ? new LinkOption[0] :
             new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
         this.visitor = visitor;
+        this.maxDepth = maxDepth;
     }
 
     /**
      * Walk file tree starting at the given file
      */
-    void walk(Path start, int maxDepth) {
-        // don't use attributes of starting file as they may be stale
-        if (start instanceof BasicFileAttributesHolder) {
-            ((BasicFileAttributesHolder)start).invalidate();
-        }
+    void walk(Path start) {
         FileVisitResult result = walk(start,
-                                      maxDepth,
+                                      0,
                                       new ArrayList<AncestorDirectory>());
         if (result == null) {
             throw new NullPointerException("Visitor returned 'null'");
@@ -89,12 +90,15 @@
                                  List<AncestorDirectory> ancestors)
     {
         // depth check
-        if (depth-- < 0)
+        if (depth > maxDepth)
             return FileVisitResult.CONTINUE;
 
         // if attributes are cached then use them if possible
         BasicFileAttributes attrs = null;
-        if (file instanceof BasicFileAttributesHolder) {
+        if ((depth > 0) &&
+            (file instanceof BasicFileAttributesHolder) &&
+            (System.getSecurityManager() == null))
+        {
             BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
             if (!followLinks || !cached.isSymbolicLink())
                 attrs = cached;
@@ -120,6 +124,10 @@
                     }
                 }
             } catch (SecurityException x) {
+                // If access to starting file is denied then SecurityException
+                // is thrown, otherwise the file is ignored.
+                if (depth == 0)
+                    throw x;
                 return FileVisitResult.CONTINUE;
             }
         }
@@ -196,7 +204,7 @@
                 try {
                     for (Path entry: stream) {
                         inAction = true;
-                        result = walk(entry, depth, ancestors);
+                        result = walk(entry, depth+1, ancestors);
                         inAction = false;
 
                         // returning null will cause NPE to be thrown
--- a/jdk/src/share/classes/java/nio/file/Files.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/Files.java	Wed Jul 05 17:01:15 2017 +0200
@@ -223,7 +223,7 @@
     {
         if (maxDepth < 0)
             throw new IllegalArgumentException("'maxDepth' is negative");
-        new FileTreeWalker(options, visitor).walk(start, maxDepth);
+        new FileTreeWalker(options, visitor, maxDepth).walk(start);
     }
 
     /**
--- a/jdk/src/share/classes/java/util/Currency.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/Currency.java	Wed Jul 05 17:01:15 2017 +0200
@@ -35,12 +35,12 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.logging.Level;
-import java.util.logging.Logger;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 import java.util.spi.CurrencyNameProvider;
 import java.util.spi.LocaleServiceProvider;
 import sun.util.LocaleServiceProviderPool;
+import sun.util.logging.PlatformLogger;
 import sun.util.resources.LocaleData;
 import sun.util.resources.OpenListResourceBundle;
 
@@ -244,7 +244,7 @@
                         }
                     }
                 } catch (IOException e) {
-                    log(Level.INFO, "currency.properties is ignored because of an IOException", e);
+                    info("currency.properties is ignored because of an IOException", e);
                 }
                 return null;
             }
@@ -686,7 +686,7 @@
                 .append("The entry in currency.properties for ")
                 .append(ctry).append(" is ignored because of the invalid country code.")
                 .toString();
-            log(Level.INFO, message, null);
+            info(message, null);
             return;
         }
 
@@ -698,7 +698,7 @@
                 .append(ctry)
                 .append(" is ignored because the value format is not recognized.")
                 .toString();
-            log(Level.INFO, message, null);
+            info(message, null);
             return;
         }
 
@@ -726,13 +726,13 @@
         setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry);
     }
 
-    private static void log(Level level, String message, Throwable t) {
-        Logger logger = Logger.getLogger("java.util.Currency");
-        if (logger.isLoggable(level)) {
+    private static void info(String message, Throwable t) {
+        PlatformLogger logger = PlatformLogger.getLogger("java.util.Currency");
+        if (logger.isLoggable(PlatformLogger.INFO)) {
             if (t != null) {
-                logger.log(level, message, t);
+                logger.info(message, t);
             } else {
-                logger.log(level, message);
+                logger.info(message);
             }
         }
     }
--- a/jdk/src/share/classes/java/util/jar/Attributes.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/jar/Attributes.java	Wed Jul 05 17:01:15 2017 +0200
@@ -34,7 +34,7 @@
 import java.util.Collection;
 import java.util.AbstractSet;
 import java.util.Iterator;
-import java.util.logging.Logger;
+import sun.util.logging.PlatformLogger;
 import java.util.Comparator;
 import sun.misc.ASCIICaseInsensitiveComparator;
 
@@ -419,7 +419,7 @@
             }
             try {
                 if ((putValue(name, value) != null) && (!lineContinued)) {
-                    Logger.getLogger("java.util.jar").warning(
+                    PlatformLogger.getLogger("java.util.jar").warning(
                                      "Duplicate name in Manifest: " + name
                                      + ".\n"
                                      + "Ensure that the manifest does not "
--- a/jdk/src/share/classes/java/util/logging/ErrorManager.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/ErrorManager.java	Wed Jul 05 17:01:15 2017 +0200
@@ -28,7 +28,7 @@
 
 /**
  * ErrorManager objects can be attached to Handlers to process
- * any error that occur on a Handler during Logging.
+ * any error that occurs on a Handler during Logging.
  * <p>
  * When processing logging output, if a Handler encounters problems
  * then rather than throwing an Exception back to the issuer of
@@ -72,7 +72,7 @@
     /**
      * The error method is called when a Handler failure occurs.
      * <p>
-     * This method may be overriden in subclasses.  The default
+     * This method may be overridden in subclasses.  The default
      * behavior in this base class is that the first call is
      * reported to System.err, and subsequent calls are ignored.
      *
--- a/jdk/src/share/classes/java/util/logging/FileHandler.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/FileHandler.java	Wed Jul 05 17:01:15 2017 +0200
@@ -39,7 +39,7 @@
  * For a rotating set of files, as each file reaches a given size
  * limit, it is closed, rotated out, and a new file opened.
  * Successively older files are named by adding "0", "1", "2",
- * etc into the base filename.
+ * etc. into the base filename.
  * <p>
  * By default buffering is enabled in the IO libraries but each log
  * record is flushed out when it is complete.
@@ -391,7 +391,7 @@
             // Generate a lock file name from the "unique" int.
             lockFileName = generate(pattern, 0, unique).toString() + ".lck";
             // Now try to lock that filename.
-            // Because some systems (e.g. Solaris) can only do file locks
+            // Because some systems (e.g., Solaris) can only do file locks
             // between processes (and not within a process), we first check
             // if we ourself already have the file locked.
             synchronized(locks) {
--- a/jdk/src/share/classes/java/util/logging/Formatter.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Formatter.java	Wed Jul 05 17:01:15 2017 +0200
@@ -52,7 +52,7 @@
      * Format the given log record and return the formatted string.
      * <p>
      * The resulting formatted String will normally include a
-     * localized and formated version of the LogRecord's message field.
+     * localized and formatted version of the LogRecord's message field.
      * It is recommended to use the {@link Formatter#formatMessage}
      * convenience method to localize and format the message field.
      *
@@ -66,7 +66,7 @@
      * Return the header string for a set of formatted records.
      * <p>
      * This base class returns an empty string, but this may be
-     * overriden by subclasses.
+     * overridden by subclasses.
      *
      * @param   h  The target handler (can be null)
      * @return  header string
@@ -79,7 +79,7 @@
      * Return the tail string for a set of formatted records.
      * <p>
      * This base class returns an empty string, but this may be
-     * overriden by subclasses.
+     * overridden by subclasses.
      *
      * @param   h  The target handler (can be null)
      * @return  tail string
--- a/jdk/src/share/classes/java/util/logging/Handler.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Handler.java	Wed Jul 05 17:01:15 2017 +0200
@@ -274,7 +274,7 @@
      * <tt>Level</tt> and  whether it satisfies any <tt>Filter</tt>.  It also
      * may make other <tt>Handler</tt> specific checks that might prevent a
      * handler from logging the <tt>LogRecord</tt>. It will return false if
-     * the <tt>LogRecord</tt> is Null.
+     * the <tt>LogRecord</tt> is null.
      * <p>
      * @param record  a <tt>LogRecord</tt>
      * @return true if the <tt>LogRecord</tt> would be logged.
--- a/jdk/src/share/classes/java/util/logging/Level.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Level.java	Wed Jul 05 17:01:15 2017 +0200
@@ -110,7 +110,7 @@
      * Typically INFO messages will be written to the console
      * or its equivalent.  So the INFO level should only be
      * used for reasonably significant messages that will
-     * make sense to end users and system admins.
+     * make sense to end users and system administrators.
      * This level is initialized to <CODE>800</CODE>.
      */
     public static final Level INFO = new Level("INFO", 800, defaultBundle);
@@ -245,6 +245,8 @@
     }
 
     /**
+     * Returns a string representation of this Level.
+     *
      * @return the non-localized name of the Level, for example "INFO".
      */
     public final String toString() {
@@ -299,14 +301,14 @@
      * @throws IllegalArgumentException if the value is not valid.
      * Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
      * and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
-     * Known names are the levels defined by this class (i.e. <CODE>FINE</CODE>,
+     * Known names are the levels defined by this class (e.g., <CODE>FINE</CODE>,
      * <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
      * appropriate package access, or new levels defined or created
      * by subclasses.
      *
      * @return The parsed value. Passing an integer that corresponds to a known name
-     * (eg 700) will return the associated name (eg <CODE>CONFIG</CODE>).
-     * Passing an integer that does not (eg 1) will return a new level name
+     * (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>).
+     * Passing an integer that does not (e.g., 1) will return a new level name
      * initialized to that value.
      */
     public static synchronized Level parse(String name) throws IllegalArgumentException {
--- a/jdk/src/share/classes/java/util/logging/LogManager.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java	Wed Jul 05 17:01:15 2017 +0200
@@ -283,6 +283,10 @@
                         AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                                 public Object run() throws Exception {
                                     readConfiguration();
+
+                                    // Platform loggers begin to delegate to java.util.logging.Logger
+                                    sun.util.logging.PlatformLogger.redirectPlatformLoggers();
+
                                     return null;
                                 }
                             });
--- a/jdk/src/share/classes/java/util/logging/LogRecord.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LogRecord.java	Wed Jul 05 17:01:15 2017 +0200
@@ -188,7 +188,7 @@
    }
 
     /**
-     * Get the source Logger name's
+     * Get the source Logger's name.
      *
      * @return source logger name (may be null)
      */
@@ -197,7 +197,7 @@
     }
 
     /**
-     * Set the source Logger name.
+     * Set the source Logger's name.
      *
      * @param name   the source logger name (may be null)
      */
@@ -530,6 +530,7 @@
         int depth = access.getStackTraceDepth(throwable);
 
         String logClassName = "java.util.logging.Logger";
+        String plogClassName = "sun.util.logging.PlatformLogger";
         boolean lookingForLogger = true;
         for (int ix = 0; ix < depth; ix++) {
             // Calling getStackTraceElement directly prevents the VM
@@ -539,15 +540,18 @@
             String cname = frame.getClassName();
             if (lookingForLogger) {
                 // Skip all frames until we have found the first logger frame.
-                if (cname.equals(logClassName)) {
+                if (cname.equals(logClassName) || cname.startsWith(plogClassName)) {
                     lookingForLogger = false;
                 }
             } else {
-                if (!cname.equals(logClassName)) {
-                    // We've found the relevant frame.
-                    setSourceClassName(cname);
-                    setSourceMethodName(frame.getMethodName());
-                    return;
+                if (!cname.equals(logClassName) && !cname.startsWith(plogClassName)) {
+                    // skip reflection call
+                    if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
+                       // We've found the relevant frame.
+                       setSourceClassName(cname);
+                       setSourceMethodName(frame.getMethodName());
+                       return;
+                    }
                 }
             }
         }
--- a/jdk/src/share/classes/java/util/logging/Logger.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Logger.java	Wed Jul 05 17:01:15 2017 +0200
@@ -66,7 +66,7 @@
  * effective level from its parent.
  * <p>
  * On each logging call the Logger initially performs a cheap
- * check of the request level (e.g. SEVERE or FINE) against the
+ * check of the request level (e.g., SEVERE or FINE) against the
  * effective log level of the logger.  If the request level is
  * lower than the log level, the logging call returns immediately.
  * <p>
@@ -230,7 +230,7 @@
      * Protected method to construct a logger for a named subsystem.
      * <p>
      * The logger will be initially configured with a null Level
-     * and with useParentHandlers true.
+     * and with useParentHandlers set to true.
      *
      * @param   name    A name for the logger.  This should
      *                          be a dot-separated name and should normally
@@ -240,7 +240,7 @@
      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
      *                          messages for this logger.  May be null if none
      *                          of the messages require localization.
-     * @throws MissingResourceException if the ResourceBundleName is non-null and
+     * @throws MissingResourceException if the resourceBundleName is non-null and
      *             no corresponding resource can be found.
      */
     protected Logger(String name, String resourceBundleName) {
@@ -285,7 +285,7 @@
      * <p>
      * If a new logger is created its log level will be configured
      * based on the LogManager configuration and it will configured
-     * to also send logging output to its parent's handlers.  It will
+     * to also send logging output to its parent's Handlers.  It will
      * be registered in the LogManager global namespace.
      *
      * @param   name            A name for the logger.  This should
@@ -308,7 +308,7 @@
      * <p>
      * If a new logger is created its log level will be configured
      * based on the LogManager and it will configured to also send logging
-     * output to its parent loggers Handlers.  It will be registered in
+     * output to its parent's Handlers.  It will be registered in
      * the LogManager global namespace.
      * <p>
      * If the named Logger already exists and does not yet have a
@@ -326,7 +326,8 @@
      *                          messages for this logger. May be <CODE>null</CODE> if none of
      *                          the messages require localization.
      * @return a suitable Logger
-     * @throws MissingResourceException if the named ResourceBundle cannot be found.
+     * @throws MissingResourceException if the resourceBundleName is non-null and
+     *             no corresponding resource can be found.
      * @throws IllegalArgumentException if the Logger already exists and uses
      *             a different resource bundle name.
      * @throws NullPointerException if the name is null.
@@ -395,7 +396,8 @@
      *                          messages for this logger.
      *          May be null if none of the messages require localization.
      * @return a newly created private Logger
-     * @throws MissingResourceException if the named ResourceBundle cannot be found.
+     * @throws MissingResourceException if the resourceBundleName is non-null and
+     *             no corresponding resource can be found.
      */
     public static synchronized Logger getAnonymousLogger(String resourceBundleName) {
         LogManager manager = LogManager.getLogManager();
@@ -514,7 +516,7 @@
      * level then the given message is forwarded to all the
      * registered output Handler objects.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   msg     The string message (or a key in the message catalog)
      */
     public void log(Level level, String msg) {
@@ -532,7 +534,7 @@
      * level then a corresponding LogRecord is created and forwarded
      * to all the registered output Handler objects.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   msg     The string message (or a key in the message catalog)
      * @param   param1  parameter to the message
      */
@@ -553,7 +555,7 @@
      * level then a corresponding LogRecord is created and forwarded
      * to all the registered output Handler objects.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   msg     The string message (or a key in the message catalog)
      * @param   params  array of parameters to the message
      */
@@ -578,7 +580,7 @@
      * processed specially by output Formatters and is not treated
      * as a formatting parameter to the LogRecord message property.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   msg     The string message (or a key in the message catalog)
      * @param   thrown  Throwable associated with log message.
      */
@@ -603,7 +605,7 @@
      * level then the given message is forwarded to all the
      * registered output Handler objects.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   msg     The string message (or a key in the message catalog)
@@ -626,7 +628,7 @@
      * level then a corresponding LogRecord is created and forwarded
      * to all the registered output Handler objects.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   msg      The string message (or a key in the message catalog)
@@ -653,7 +655,7 @@
      * level then a corresponding LogRecord is created and forwarded
      * to all the registered output Handler objects.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   msg     The string message (or a key in the message catalog)
@@ -684,7 +686,7 @@
      * processed specially by output Formatters and is not treated
      * as a formatting parameter to the LogRecord message property.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   msg     The string message (or a key in the message catalog)
@@ -731,7 +733,7 @@
      * resource bundle name is null, or an empty String or invalid
      * then the msg string is not localized.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   bundleName     name of resource bundle to localize msg,
@@ -762,7 +764,7 @@
      * resource bundle name is null, or an empty String or invalid
      * then the msg string is not localized.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   bundleName     name of resource bundle to localize msg,
@@ -795,7 +797,7 @@
      * resource bundle name is null, or an empty String or invalid
      * then the msg string is not localized.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   bundleName     name of resource bundle to localize msg,
@@ -832,7 +834,7 @@
      * processed specially by output Formatters and is not treated
      * as a formatting parameter to the LogRecord message property.
      * <p>
-     * @param   level   One of the message level identifiers, e.g. SEVERE
+     * @param   level   One of the message level identifiers, e.g., SEVERE
      * @param   sourceClass    name of class that issued the logging request
      * @param   sourceMethod   name of method that issued the logging request
      * @param   bundleName     name of resource bundle to localize msg,
@@ -1214,7 +1216,7 @@
 
     /**
      * Specify whether or not this logger should send its output
-     * to it's parent Logger.  This means that any LogRecords will
+     * to its parent Logger.  This means that any LogRecords will
      * also be written to the parent's Handlers, and potentially
      * to its parent, recursively up the namespace.
      *
--- a/jdk/src/share/classes/java/util/logging/LoggingMXBean.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LoggingMXBean.java	Wed Jul 05 17:01:15 2017 +0200
@@ -105,8 +105,8 @@
      *
      * @param loggerName The name of the <tt>Logger</tt> to be set.
      *                   Must be non-null.
-     * @param levelName The name of the level to set the specified logger to,
-     *                 or <tt>null</tt> if to set the level to inherit
+     * @param levelName The name of the level to set on the specified logger,
+     *                 or <tt>null</tt> if setting the level to inherit
      *                 from its nearest ancestor.
      *
      * @throws IllegalArgumentException if the specified logger
--- a/jdk/src/share/classes/java/util/logging/MemoryHandler.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/MemoryHandler.java	Wed Jul 05 17:01:15 2017 +0200
@@ -136,7 +136,7 @@
      * @param size    the number of log records to buffer (must be greater than zero)
      * @param pushLevel  message level to push on
      *
-     * @throws IllegalArgumentException is size is <= 0
+     * @throws IllegalArgumentException if size is <= 0
      */
     public MemoryHandler(Handler target, int size, Level pushLevel) {
         if (target == null || pushLevel == null) {
@@ -258,7 +258,7 @@
      * This method checks if the <tt>LogRecord</tt> has an appropriate level and
      * whether it satisfies any <tt>Filter</tt>.  However it does <b>not</b>
      * check whether the <tt>LogRecord</tt> would result in a "push" of the
-     * buffer contents. It will return false if the <tt>LogRecord</tt> is Null.
+     * buffer contents. It will return false if the <tt>LogRecord</tt> is null.
      * <p>
      * @param record  a <tt>LogRecord</tt>
      * @return true if the <tt>LogRecord</tt> would be logged.
--- a/jdk/src/share/classes/java/util/logging/StreamHandler.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/StreamHandler.java	Wed Jul 05 17:01:15 2017 +0200
@@ -220,7 +220,7 @@
      * <p>
      * This method checks if the <tt>LogRecord</tt> has an appropriate level and
      * whether it satisfies any <tt>Filter</tt>.  It will also return false if
-     * no output stream has been assigned yet or the LogRecord is Null.
+     * no output stream has been assigned yet or the LogRecord is null.
      * <p>
      * @param record  a <tt>LogRecord</tt>
      * @return true if the <tt>LogRecord</tt> would be logged.
--- a/jdk/src/share/classes/java/util/zip/ZipEntry.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/zip/ZipEntry.java	Wed Jul 05 17:01:15 2017 +0200
@@ -253,14 +253,10 @@
      * the first 0xFFFF bytes are output to the ZIP file entry.
      *
      * @param comment the comment string
-     * @exception IllegalArgumentException if the length of the specified
-     *            comment string is greater than 0xFFFF bytes
+     *
      * @see #getComment()
      */
     public void setComment(String comment) {
-        if (comment != null && comment.length() > 0xffff) {
-            throw new IllegalArgumentException("invalid entry comment length");
-        }
         this.comment = comment;
     }
 
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java	Wed Jul 05 17:01:15 2017 +0200
@@ -195,7 +195,10 @@
         if (charset == null)
             throw new NullPointerException("charset is null");
         this.zc = ZipCoder.get(charset);
+        long t0 = System.nanoTime();
         jzfile = open(name, mode, file.lastModified());
+        sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
+        sun.misc.PerfCounter.getZipFileCount().increment();
         this.name = name;
         this.total = getTotal(jzfile);
     }
--- a/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java	Wed Jul 05 17:01:15 2017 +0200
@@ -168,8 +168,8 @@
  * The majority of methods for setting placeholder parameters take two parameters,
  *  with the first parameter
  * indicating which placeholder parameter is to be set, and the second parameter
- * giving the value to be set.  Methods such as <code>getInt</code>,
- * <code>getString</code>, <code>getBoolean</code>, and <code>getLong</code> fall into
+ * giving the value to be set.  Methods such as <code>setInt</code>,
+ * <code>setString</code>, <code>setBoolean</code>, and <code>setLong</code> fall into
  * this category.  After these methods have been called, a call to the method
  * <code>getParams</code> will return an array with the values that have been set. Each
  * element in the array is an <code>Object</code> instance representing the
@@ -3259,9 +3259,9 @@
     * @param x the parameter value
     * @exception SQLException if a database access error occurs or
     * this method is called on a closed <code>CallableStatement</code>
-    * @see #getBoolean
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
+    * @see #getParams
     * @since 1.4
     */
    public void setBoolean(String parameterName, boolean x) throws SQLException{
@@ -3281,7 +3281,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getByte
+    * @see #getParams
     * @since 1.4
     */
    public void setByte(String parameterName, byte x) throws SQLException{
@@ -3301,7 +3301,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getShort
+    * @see #getParams
     * @since 1.4
     */
    public void setShort(String parameterName, short x) throws SQLException{
@@ -3320,7 +3320,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getInt
+    * @see #getParams
     * @since 1.4
     */
    public void setInt(String parameterName, int x) throws SQLException{
@@ -3339,7 +3339,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getLong
+    * @see #getParams
     * @since 1.4
     */
    public void setLong(String parameterName, long x) throws SQLException{
@@ -3358,7 +3358,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getFloat
+    * @see #getParams
     * @since 1.4
     */
    public void setFloat(String parameterName, float x) throws SQLException{
@@ -3377,7 +3377,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getDouble
+    * @see #getParams
     * @since 1.4
     */
    public void setDouble(String parameterName, double x) throws SQLException{
@@ -3398,7 +3398,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getBigDecimal
+    * @see #getParams
     * @since 1.4
     */
    public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
@@ -3421,7 +3421,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getString
+    * @see #getParams
     * @since 1.4
     */
    public void setString(String parameterName, String x) throws SQLException{
@@ -3443,7 +3443,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getBytes
+    * @see #getParams
     * @since 1.4
     */
    public void setBytes(String parameterName, byte x[]) throws SQLException{
@@ -3464,7 +3464,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getTimestamp
+    * @see #getParams
     * @since 1.4
     */
    public void setTimestamp(String parameterName, java.sql.Timestamp x)
@@ -3712,7 +3712,7 @@
     * or  <code>STRUCT</code> data type and the JDBC driver does not support
     * this data type
     * @see Types
-    * @see #getObject
+    * @see #getParams
     * @since 1.4
     */
    public void setObject(String parameterName, Object x, int targetSqlType, int scale)
@@ -3740,7 +3740,7 @@
     *  <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
     * or  <code>STRUCT</code> data type and the JDBC driver does not support
     * this data type
-    * @see #getObject
+    * @see #getParams
     * @since 1.4
     */
    public void setObject(String parameterName, Object x, int targetSqlType)
@@ -3782,7 +3782,7 @@
    *            <code>Object</code> parameter is ambiguous
    * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
    * this method
-   * @see #getObject
+   * @see #getParams
    * @since 1.4
    */
   public void setObject(String parameterName, Object x) throws SQLException{
@@ -4064,7 +4064,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getDate
+    * @see #getParams
     * @since 1.4
     */
    public void setDate(String parameterName, java.sql.Date x)
@@ -4091,7 +4091,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getDate
+    * @see #getParams
     * @since 1.4
     */
    public void setDate(String parameterName, java.sql.Date x, Calendar cal)
@@ -4111,7 +4111,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getTime
+    * @see #getParams
     * @since 1.4
     */
    public void setTime(String parameterName, java.sql.Time x)
@@ -4138,7 +4138,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getTime
+    * @see #getParams
     * @since 1.4
     */
    public void setTime(String parameterName, java.sql.Time x, Calendar cal)
@@ -4165,7 +4165,7 @@
     * this method is called on a closed <code>CallableStatement</code>
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
-    * @see #getTimestamp
+    * @see #getParams
     * @since 1.4
     */
    public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/misc/PerfCounter.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.misc;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.LongBuffer;
+import java.security.AccessController;
+
+/**
+ * Performance counter support for internal JRE classes.
+ * This class defines a fixed list of counters for the platform
+ * to use as an interim solution until RFE# 6209222 is implemented.
+ * The perf counters will be created in the jvmstat perf buffer
+ * that the HotSpot VM creates. The default size is 32K and thus
+ * the number of counters is bounded.  You can alter the size
+ * with -XX:PerfDataMemorySize=<bytes> option. If there is
+ * insufficient memory in the jvmstat perf buffer, the C heap memory
+ * will be used and thus the application will continue to run if
+ * the counters added exceeds the buffer size but the counters
+ * will be missing.
+ *
+ * See HotSpot jvmstat implementation for certain circumstances
+ * that the jvmstat perf buffer is not supported.
+ *
+ */
+public class PerfCounter {
+    private static final Perf perf =
+        AccessController.doPrivileged(new Perf.GetPerfAction());
+
+    // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp
+    private final static int V_Constant  = 1;
+    private final static int V_Monotonic = 2;
+    private final static int V_Variable  = 3;
+    private final static int U_None      = 1;
+
+    private final String name;
+    private final LongBuffer lb;
+
+    private PerfCounter(String name, int type) {
+        this.name = name;
+        ByteBuffer bb = perf.createLong(name, U_None, type, 0L);
+        bb.order(ByteOrder.nativeOrder());
+        this.lb = bb.asLongBuffer();
+    }
+
+    static PerfCounter newPerfCounter(String name) {
+        return new PerfCounter(name, V_Variable);
+    }
+
+    static PerfCounter newConstantPerfCounter(String name) {
+        PerfCounter c = new PerfCounter(name, V_Constant);
+        return c;
+    }
+
+    /**
+     * Returns the current value of the perf counter.
+     */
+    public synchronized long get() {
+        return lb.get(0);
+    }
+
+    /**
+     * Sets the value of the perf counter to the given newValue.
+     */
+    public synchronized void set(long newValue) {
+        lb.put(0, newValue);
+    }
+
+    /**
+     * Adds the given value to the perf counter.
+     */
+    public synchronized void add(long value) {
+        long res = get() + value;
+        lb.put(0, res);
+    }
+
+    /**
+     * Increments the perf counter with 1.
+     */
+    public void increment() {
+        add(1);
+    }
+
+    /**
+     * Adds the given interval to the perf counter.
+     */
+    public void addTime(long interval) {
+        add(interval);
+    }
+
+    /**
+     * Adds the elapsed time from the given start time (ns) to the perf counter.
+     */
+    public void addElapsedTimeFrom(long startTime) {
+        add(System.nanoTime() - startTime);
+    }
+
+    @Override
+    public String toString() {
+        return name + " = " + get();
+    }
+
+    static class CoreCounters {
+        static final PerfCounter pdt   = newPerfCounter("sun.classloader.parentDelegationTime");
+        static final PerfCounter lc    = newPerfCounter("sun.classloader.findClasses");
+        static final PerfCounter lct   = newPerfCounter("sun.classloader.findClassTime");
+        static final PerfCounter rcbt  = newPerfCounter("sun.urlClassLoader.readClassBytesTime");
+        static final PerfCounter zfc   = newPerfCounter("sun.zip.zipFiles");
+        static final PerfCounter zfot  = newPerfCounter("sun.zip.zipFile.openTime");
+    }
+
+    static class WindowsClientCounters {
+        static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available");
+    }
+
+    /**
+     * Number of findClass calls
+     */
+    public static PerfCounter getFindClasses() {
+        return CoreCounters.lc;
+    }
+
+    /**
+     * Time (ns) spent in finding classes that includes
+     * lookup and read class bytes and defineClass
+     */
+    public static PerfCounter getFindClassTime() {
+        return CoreCounters.lct;
+    }
+
+    /**
+     * Time (ns) spent in finding classes
+     */
+    public static PerfCounter getReadClassBytesTime() {
+        return CoreCounters.rcbt;
+    }
+
+    /**
+     * Time (ns) spent in the parent delegation to
+     * the parent of the defining class loader
+     */
+    public static PerfCounter getParentDelegationTime() {
+        return CoreCounters.pdt;
+    }
+
+    /**
+     * Number of zip files opened.
+     */
+    public static PerfCounter getZipFileCount() {
+        return CoreCounters.zfc;
+    }
+
+    /**
+     * Time (ns) spent in opening the zip files that
+     * includes building the entries hash table
+     */
+    public static PerfCounter getZipFileOpenTime() {
+        return CoreCounters.zfot;
+    }
+
+    /**
+     * D3D graphic pipeline available
+     */
+    public static PerfCounter getD3DAvailable() {
+        return WindowsClientCounters.d3dAvailable;
+    }
+}
--- a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,9 @@
 
 package sun.net.spi;
 
-import sun.net.www.http.*;
 import sun.net.NetProperties;
 import java.net.*;
 import java.util.*;
-import java.util.regex.*;
 import java.io.*;
 import sun.misc.RegexpPool;
 import java.security.AccessController;
@@ -102,17 +100,22 @@
      */
 
     static class NonProxyInfo {
+        // Default value for nonProxyHosts, this provides backward compatibility
+        // by excluding localhost and its litteral notations.
+        static final String defStringVal = "localhost|127.*|[::1]";
+
         String hostsSource;
         RegexpPool hostsPool;
-        String property;
+        final String property;
+        final String defaultVal;
+        static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null, defStringVal);
+        static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null, defStringVal);
 
-        static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null);
-        static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null);
-
-        NonProxyInfo(String p, String s, RegexpPool pool) {
+        NonProxyInfo(String p, String s, RegexpPool pool, String d) {
             property = p;
             hostsSource = s;
             hostsPool = pool;
+            defaultVal = d;
         }
     }
 
@@ -130,7 +133,6 @@
         }
         String protocol = uri.getScheme();
         String host = uri.getHost();
-        int port = uri.getPort();
 
         if (host == null) {
             // This is a hack to ensure backward compatibility in two
@@ -149,11 +151,6 @@
                 }
                 i = auth.lastIndexOf(':');
                 if (i >= 0) {
-                    try {
-                        port = Integer.parseInt(auth.substring(i+1));
-                    } catch (NumberFormatException e) {
-                        port = -1;
-                    }
                     auth = auth.substring(0,i);
                 }
                 host = auth;
@@ -165,13 +162,6 @@
         }
         List<Proxy> proxyl = new ArrayList<Proxy>(1);
 
-        // special case localhost and loopback addresses to
-        // not go through proxy
-        if (isLoopback(host)) {
-            proxyl.add(Proxy.NO_PROXY);
-            return proxyl;
-        }
-
         NonProxyInfo pinfo = null;
 
         if ("http".equalsIgnoreCase(protocol)) {
@@ -244,9 +234,14 @@
                                 nphosts = NetProperties.get(nprop.property);
                                 synchronized (nprop) {
                                     if (nphosts == null) {
-                                        nprop.hostsSource = null;
-                                        nprop.hostsPool = null;
-                                    } else {
+                                        if (nprop.defaultVal != null) {
+                                            nphosts = nprop.defaultVal;
+                                        } else {
+                                            nprop.hostsSource = null;
+                                            nprop.hostsPool = null;
+                                        }
+                                    }
+                                    if (nphosts != null) {
                                         if (!nphosts.equals(nprop.hostsSource)) {
                                             RegexpPool pool = new RegexpPool();
                                             StringTokenizer st = new StringTokenizer(nphosts, "|", false);
@@ -334,107 +329,6 @@
         }
     }
 
-    private boolean isLoopback(String host) {
-        if (host == null || host.length() == 0)
-            return false;
-
-        if (host.equalsIgnoreCase("localhost"))
-            return true;
-
-        /* The string could represent a numerical IP address.
-         * For IPv4 addresses, check whether it starts with 127.
-         * For IPv6 addresses, check whether it is ::1 or its equivalent.
-         * Don't check IPv4-mapped or IPv4-compatible addresses
-         */
-
-        if (host.startsWith("127.")) {
-            // possible IPv4 loopback address
-            int p = 4;
-            int q;
-            int n = host.length();
-            // Per RFC2732: At most three digits per byte
-            // Further constraint: Each element fits in a byte
-            if ((q = scanByte(host, p, n)) <= p) return false;   p = q;
-            if ((q = scan(host, p, n, '.')) <= p) return q == n && number > 0;  p = q;
-            if ((q = scanByte(host, p, n)) <= p) return false;   p = q;
-            if ((q = scan(host, p, n, '.')) <= p) return q == n && number > 0;  p = q;
-            if ((q = scanByte(host, p, n)) <= p) return false;
-            return q == n && number > 0;
-        }
-
-        if (host.endsWith(":1")) {
-            final Pattern p6 = Pattern.compile("::1|(0:){7}1|(0:){1,6}:1");
-            return p6.matcher(host).matches();
-        }
-        return false;
-    }
-
-    // Character-class masks, in reverse order from RFC2396 because
-    // initializers for static fields cannot make forward references.
-
-    // Compute a low-order mask for the characters
-    // between first and last, inclusive
-    private static long lowMask(char first, char last) {
-        long m = 0;
-        int f = Math.max(Math.min(first, 63), 0);
-        int l = Math.max(Math.min(last, 63), 0);
-        for (int i = f; i <= l; i++)
-            m |= 1L << i;
-        return m;
-    }
-    // digit    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
-    //            "8" | "9"
-    private static final long L_DIGIT = lowMask('0', '9');
-    private static final long H_DIGIT = 0L;
-
-    // Scan a string of decimal digits whose value fits in a byte
-    //
-    private int number;
-    private int scanByte(String input, int start, int n)
-    {
-        int p = start;
-        int q = scan(input, p, n, L_DIGIT, H_DIGIT);
-        if (q <= p) return q;
-        number = Integer.parseInt(input.substring(p, q));
-        if (number > 255) return p;
-        return q;
-    }
-
-    // Scan a specific char: If the char at the given start position is
-    // equal to c, return the index of the next char; otherwise, return the
-    // start position.
-    //
-    private int scan(String input, int start, int end, char c) {
-        if ((start < end) && (input.charAt(start) == c))
-            return start + 1;
-        return start;
-    }
-
-    // Scan chars that match the given mask pair
-    //
-    private int scan(String input, int start, int n, long lowMask, long highMask)
-    {
-        int p = start;
-        while (p < n) {
-            char c = input.charAt(p);
-            if (match(c, lowMask, highMask)) {
-                p++;
-                continue;
-            }
-            break;
-        }
-        return p;
-    }
-
-    // Tell whether the given character is permitted by the given mask pair
-    private boolean match(char c, long lowMask, long highMask) {
-        if (c < 64)
-            return ((1L << c) & lowMask) != 0;
-        if (c < 128)
-            return ((1L << (c - 64)) & highMask) != 0;
-        return false;
-    }
-
     private native static boolean init();
     private native Proxy getSystemProxy(String protocol, String host);
 }
--- a/jdk/src/share/classes/sun/net/www/http/HttpCapture.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/http/HttpCapture.java	Wed Jul 05 17:01:15 2017 +0200
@@ -24,14 +24,12 @@
  */
 
 package sun.net.www.http;
+
 import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.regex.*;
 import sun.net.NetProperties;
-import java.util.regex.*;
+import sun.util.logging.PlatformLogger;
 
 /**
  * Main class of the HTTP traffic capture tool.
@@ -62,76 +60,6 @@
     private static boolean initialized = false;
     private static volatile ArrayList<Pattern> patterns = null;
     private static volatile ArrayList<String> capFiles = null;
-    /* Logging is done in an ugly way so that it does not require the presence
-     * the java.util.logging package. If the Logger class is not available, then
-     * logging is turned off. This is for helping the modularization effort.
-     */
-    private static Object logger = null;
-    private static boolean logging = false;
-
-    static {
-        Class cl;
-        try {
-            cl = Class.forName("java.util.logging.Logger");
-        } catch (ClassNotFoundException ex) {
-            cl = null;
-        }
-        if (cl != null) {
-            try {
-                Method m = cl.getMethod("getLogger", String.class);
-                logger = m.invoke(null, "sun.net.www.protocol.http.HttpURLConnection");
-                logging = true;
-            } catch (NoSuchMethodException noSuchMethodException) {
-            } catch (SecurityException securityException) {
-            } catch (IllegalAccessException illegalAccessException) {
-            } catch (IllegalArgumentException illegalArgumentException) {
-            } catch (InvocationTargetException invocationTargetException) {
-            }
-        }
-    }
-
-    public static void fine(String s) {
-        if (logging) {
-            ((Logger)logger).fine(s);
-        }
-    }
-
-    public static void finer(String s) {
-        if (logging) {
-            ((Logger)logger).finer(s);
-        }
-    }
-
-    public static void finest(String s) {
-        if (logging) {
-            ((Logger)logger).finest(s);
-        }
-    }
-
-    public static void severe(String s) {
-        if (logging) {
-            ((Logger)logger).finest(s);
-        }
-    }
-
-    public static void info(String s) {
-        if (logging) {
-            ((Logger)logger).info(s);
-        }
-    }
-
-    public static void warning(String s) {
-        if (logging) {
-            ((Logger)logger).warning(s);
-        }
-    }
-
-    public static boolean isLoggable(String level) {
-        if (!logging) {
-            return false;
-        }
-        return ((Logger)logger).isLoggable(Level.parse(level));
-    }
 
     private static synchronized void init() {
         initialized = true;
@@ -187,7 +115,7 @@
             out = new BufferedWriter(new FileWriter(file, true));
             out.write("URL: " + url + "\n");
         } catch (IOException ex) {
-            Logger.getLogger(HttpCapture.class.getName()).log(Level.SEVERE, null, ex);
+            PlatformLogger.getLogger(HttpCapture.class.getName()).severe(null, ex);
         }
     }
 
--- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Wed Jul 05 17:01:15 2017 +0200
@@ -35,6 +35,7 @@
 import sun.net.www.MeteredStream;
 import sun.net.www.ParseUtil;
 import sun.net.www.protocol.http.HttpURLConnection;
+import sun.util.logging.PlatformLogger;
 
 /**
  * @author Herb Jellinek
@@ -804,8 +805,9 @@
 
             if (isKeepingAlive())   {
                 // Wrap KeepAliveStream if keep alive is enabled.
-                if (HttpCapture.isLoggable("FINEST")) {
-                    HttpCapture.finest("KeepAlive stream used: " + url);
+                PlatformLogger logger = HttpURLConnection.getHttpLogger();
+                if (logger.isLoggable(PlatformLogger.FINEST)) {
+                    logger.finest("KeepAlive stream used: " + url);
                 }
                 serverInput = new KeepAliveStream(serverInput, pi, cl, this);
                 failedOnce = false;
--- a/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,12 +25,11 @@
 
 package sun.net.www.http;
 
-import java.io.InputStream;
 import java.io.IOException;
 import java.io.NotSerializableException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.net.URL;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * A class that implements a cache of idle Http connections for keep-alive
@@ -39,7 +38,7 @@
  * @author Dave Brown
  */
 public class KeepAliveCache
-    extends ConcurrentHashMap<KeepAliveKey, ClientVector>
+    extends HashMap<KeepAliveKey, ClientVector>
     implements Runnable {
     private static final long serialVersionUID = -2937172892064557949L;
 
@@ -163,8 +162,8 @@
      * Errs on the side of caution (leave connections idle for a relatively
      * short time).
      */
+    @Override
     public void run() {
-        int total_cache;
         do {
             try {
                 Thread.sleep(LIFETIME);
@@ -311,6 +310,7 @@
     /**
      * Determine whether or not two objects of this type are equal
      */
+    @Override
     public boolean equals(Object obj) {
         if ((obj instanceof KeepAliveKey) == false)
             return false;
@@ -325,6 +325,7 @@
      * The hashCode() for this object is the string hashCode() of
      * concatenation of the protocol, host name and port.
      */
+    @Override
     public int hashCode() {
         String str = protocol+host+port;
         return this.obj == null? str.hashCode() :
--- a/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,10 +25,7 @@
 
 package sun.net.www.http;
 
-import java.net.URL;
-import java.net.HttpURLConnection;
 import java.io.*;
-import java.util.StringTokenizer;
 import sun.net.ProgressSource;
 import sun.net.www.MeteredStream;
 
@@ -50,9 +47,8 @@
     // has this KeepAliveStream been put on the queue for asynchronous cleanup.
     protected boolean queuedForCleanup = false;
 
-    private static KeepAliveStreamCleaner queue = new KeepAliveStreamCleaner();
-    private static Thread cleanerThread = null;
-    private static boolean startCleanupThread;
+    private static final KeepAliveStreamCleaner queue = new KeepAliveStreamCleaner();
+    private static Thread cleanerThread; // null
 
     /**
      * Constructor
@@ -155,43 +151,46 @@
         }
     }
 
-    private static synchronized void queueForCleanup(KeepAliveCleanerEntry kace) {
-        if(queue != null && !kace.getQueuedForCleanup()) {
-            if (!queue.offer(kace)) {
-                kace.getHttpClient().closeServer();
-                return;
+    private static void queueForCleanup(KeepAliveCleanerEntry kace) {
+        synchronized(queue) {
+            if(!kace.getQueuedForCleanup()) {
+                if (!queue.offer(kace)) {
+                    kace.getHttpClient().closeServer();
+                    return;
+                }
+
+                kace.setQueuedForCleanup();
+                queue.notifyAll();
+            }
+
+            boolean startCleanupThread = (cleanerThread == null);
+            if (!startCleanupThread) {
+                if (!cleanerThread.isAlive()) {
+                    startCleanupThread = true;
+                }
             }
 
-            kace.setQueuedForCleanup();
-        }
-
-        startCleanupThread = (cleanerThread == null);
-        if (!startCleanupThread) {
-            if (!cleanerThread.isAlive()) {
-                startCleanupThread = true;
-            }
-        }
+            if (startCleanupThread) {
+                java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction<Void>() {
+                    public Void run() {
+                        // We want to create the Keep-Alive-SocketCleaner in the
+                        // system threadgroup
+                        ThreadGroup grp = Thread.currentThread().getThreadGroup();
+                        ThreadGroup parent = null;
+                        while ((parent = grp.getParent()) != null) {
+                            grp = parent;
+                        }
 
-        if (startCleanupThread) {
-            java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction<Void>() {
-                public Void run() {
-                    // We want to create the Keep-Alive-SocketCleaner in the
-                    // system threadgroup
-                    ThreadGroup grp = Thread.currentThread().getThreadGroup();
-                    ThreadGroup parent = null;
-                    while ((parent = grp.getParent()) != null) {
-                        grp = parent;
+                        cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
+                        cleanerThread.setDaemon(true);
+                        cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
+                        cleanerThread.start();
+                        return null;
                     }
-
-                    cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
-                    cleanerThread.setDaemon(true);
-                    cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
-                    cleanerThread.start();
-                    return null;
-                }
-            });
-        }
+                });
+            }
+        } // queue
     }
 
     protected long remainingToRead() {
--- a/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,9 +25,8 @@
 
 package sun.net.www.http;
 
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
 import java.io.IOException;
+import java.util.LinkedList;
 import sun.net.NetProperties;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -44,7 +43,9 @@
  */
 
 @SuppressWarnings("serial")  // never serialized
-public class KeepAliveStreamCleaner extends LinkedBlockingQueue<KeepAliveCleanerEntry> implements Runnable
+class KeepAliveStreamCleaner
+    extends LinkedList<KeepAliveCleanerEntry>
+    implements Runnable
 {
     // maximum amount of remaining data that we will try to cleanup
     protected static int MAX_DATA_REMAINING = 512;
@@ -78,23 +79,39 @@
     }
 
 
-    public KeepAliveStreamCleaner()
-    {
-        super(MAX_CAPACITY);
+    @Override
+    public boolean offer(KeepAliveCleanerEntry e) {
+        if (size() >= MAX_CAPACITY)
+            return false;
+
+        return super.offer(e);
     }
 
-    public KeepAliveStreamCleaner(int capacity)
-    {
-        super(capacity);
-    }
-
+    @Override
     public void run()
     {
         KeepAliveCleanerEntry kace = null;
 
         do {
             try {
-                kace = poll((long)TIMEOUT, TimeUnit.MILLISECONDS);
+                synchronized(this) {
+                    long before = System.currentTimeMillis();
+                    long timeout = TIMEOUT;
+                    while ((kace = poll()) == null) {
+                        this.wait(timeout);
+
+                        long after = System.currentTimeMillis();
+                        long elapsed = after - before;
+                        if (elapsed > timeout) {
+                            /* one last try */
+                            kace = poll();
+                            break;
+                        }
+                        before = after;
+                        timeout -= elapsed;
+                    }
+                }
+
                 if(kace == null)
                     break;
 
--- a/jdk/src/share/classes/sun/net/www/protocol/http/AuthCache.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/AuthCache.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,14 +25,6 @@
 
 package sun.net.www.protocol.http;
 
-import java.io.IOException;
-import java.net.URL;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Enumeration;
-import java.util.HashMap;
-
 /**
  * @author Michael McMahon
  *
@@ -49,7 +41,7 @@
      * A:[B:]C:D:E[:F]   Between 4 and 6 fields separated by ":"
      *          where the fields have the following meaning:
      * A is "s" or "p" for server or proxy authentication respectively
-     * B is optional and is "D", "B", or "N" for digest, basic or ntlm auth.
+     * B is optional and is the {@link AuthScheme}, e.g. BASIC, DIGEST, NTLM, etc
      * C is either "http" or "https"
      * D is the hostname
      * E is the port number
--- a/jdk/src/share/classes/sun/net/www/protocol/http/AuthCacheValue.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/AuthCacheValue.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,15 +25,8 @@
 
 package sun.net.www.protocol.http;
 
-import java.io.IOException;
 import java.io.Serializable;
-import java.net.*;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Enumeration;
-import java.util.HashMap;
-
+import java.net.PasswordAuthentication;
 
 /**
  * AuthCacheValue: interface to minimise exposure to authentication cache
@@ -62,8 +55,16 @@
 
     AuthCacheValue() {}
 
+    /**
+     * Proxy or Server
+     */
     abstract Type getAuthType ();
 
+    /**
+     * Authentication scheme
+     */
+    abstract AuthScheme getAuthScheme();
+
    /**
     * name of server/proxy
     */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/AuthScheme.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.net.www.protocol.http;
+
+/* Authentication schemes supported by the http implementation. New schemes, if
+ * supported, should be defined here.
+ */
+public enum AuthScheme {
+    BASIC,
+    DIGEST,
+    NTLM,
+    NEGOTIATE,
+    KERBEROS,
+    UNKNOWN;
+}
+
--- a/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java	Wed Jul 05 17:01:15 2017 +0200
@@ -85,6 +85,11 @@
             AuthCacheValue.Type.Server:
             AuthCacheValue.Type.Proxy;
     }
+
+    AuthScheme getAuthScheme() {
+        return authScheme;
+    }
+
     public String getHost() {
         return host;
     }
@@ -151,7 +156,7 @@
     }
 
     //public String toString () {
-        //return ("{"+type+":"+authType+":"+protocol+":"+host+":"+port+":"+realm+":"+path+"}");
+        //return ("{"+type+":"+authScheme+":"+protocol+":"+host+":"+port+":"+realm+":"+path+"}");
     //}
 
     // REMIND:  This cache just grows forever.  We should put in a bounded
@@ -160,8 +165,8 @@
     /** The type (server/proxy) of authentication this is.  Used for key lookup */
     char type;
 
-    /** The authentication type (basic/digest). Also used for key lookup */
-    char authType;
+    /** The authentication scheme (basic/digest). Also used for key lookup */
+    AuthScheme authScheme;
 
     /** The protocol/scheme (i.e. http or https ). Need to keep the caches
      *  logically separate for the two protocols. This field is only used
@@ -183,9 +188,9 @@
     String path;
 
     /** Use this constructor only for proxy entries */
-    AuthenticationInfo(char type, char authType, String host, int port, String realm) {
+    AuthenticationInfo(char type, AuthScheme authScheme, String host, int port, String realm) {
         this.type = type;
-        this.authType = authType;
+        this.authScheme = authScheme;
         this.protocol = "";
         this.host = host.toLowerCase();
         this.port = port;
@@ -206,9 +211,9 @@
      * Constructor used to limit the authorization to the path within
      * the URL. Use this constructor for origin server entries.
      */
-    AuthenticationInfo(char type, char authType, URL url, String realm) {
+    AuthenticationInfo(char type, AuthScheme authScheme, URL url, String realm) {
         this.type = type;
-        this.authType = authType;
+        this.authScheme = authScheme;
         this.protocol = url.getProtocol().toLowerCase();
         this.host = url.getHost().toLowerCase();
         this.port = url.getPort();
@@ -264,12 +269,12 @@
      * In this case we do not use the path because the protection space
      * is identified by the host:port:realm only
      */
-    static AuthenticationInfo getServerAuth(URL url, String realm, char atype) {
+    static AuthenticationInfo getServerAuth(URL url, String realm, AuthScheme scheme) {
         int port = url.getPort();
         if (port == -1) {
             port = url.getDefaultPort();
         }
-        String key = SERVER_AUTHENTICATION + ":" + atype + ":" + url.getProtocol().toLowerCase()
+        String key = SERVER_AUTHENTICATION + ":" + scheme + ":" + url.getProtocol().toLowerCase()
                      + ":" + url.getHost().toLowerCase() + ":" + port + ":" + realm;
         AuthenticationInfo cached = getAuth(key, null);
         if ((cached == null) && requestIsInProgress (key)) {
@@ -308,8 +313,8 @@
      * Used in response to a challenge. Note, the protocol field is always
      * blank for proxies.
      */
-    static AuthenticationInfo getProxyAuth(String host, int port, String realm, char atype) {
-        String key = PROXY_AUTHENTICATION + ":" + atype + "::" + host.toLowerCase()
+    static AuthenticationInfo getProxyAuth(String host, int port, String realm, AuthScheme scheme) {
+        String key = PROXY_AUTHENTICATION + ":" + scheme + "::" + host.toLowerCase()
                         + ":" + port + ":" + realm;
         AuthenticationInfo cached = (AuthenticationInfo) cache.get(key, null);
         if ((cached == null) && requestIsInProgress (key)) {
@@ -409,7 +414,7 @@
         // This must be kept in sync with the getXXXAuth() methods in this
         // class.
         if (includeRealm) {
-            return type + ":" + authType + ":" + protocol + ":"
+            return type + ":" + authScheme + ":" + protocol + ":"
                         + host + ":" + port + ":" + realm;
         } else {
             return type + ":" + protocol + ":" + host + ":" + port;
--- a/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java	Wed Jul 05 17:01:15 2017 +0200
@@ -44,8 +44,6 @@
 
     private static final long serialVersionUID = 100L;
 
-    static final char BASIC_AUTH = 'B';
-
     /** The authentication string for this host, port, and realm.  This is
         a simple BASE64 encoding of "login:password".    */
     String auth;
@@ -56,7 +54,7 @@
     public BasicAuthentication(boolean isProxy, String host, int port,
                                String realm, PasswordAuthentication pw) {
         super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              BASIC_AUTH, host, port, realm);
+              AuthScheme.BASIC, host, port, realm);
         String plain = pw.getUserName() + ":";
         byte[] nameBytes = null;
         try {
@@ -86,7 +84,7 @@
     public BasicAuthentication(boolean isProxy, String host, int port,
                                String realm, String auth) {
         super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              BASIC_AUTH, host, port, realm);
+              AuthScheme.BASIC, host, port, realm);
         this.auth = "Basic " + auth;
     }
 
@@ -96,7 +94,7 @@
     public BasicAuthentication(boolean isProxy, URL url, String realm,
                                    PasswordAuthentication pw) {
         super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              BASIC_AUTH, url, realm);
+              AuthScheme.BASIC, url, realm);
         String plain = pw.getUserName() + ":";
         byte[] nameBytes = null;
         try {
@@ -126,7 +124,7 @@
     public BasicAuthentication(boolean isProxy, URL url, String realm,
                                    String auth) {
         super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              BASIC_AUTH, url, realm);
+              AuthScheme.BASIC, url, realm);
         this.auth = "Basic " + auth;
     }
 
--- a/jdk/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java	Wed Jul 05 17:01:15 2017 +0200
@@ -38,7 +38,6 @@
 import java.security.NoSuchAlgorithmException;
 import static sun.net.www.protocol.http.HttpURLConnection.HTTP_CONNECT;
 
-
 /**
  * DigestAuthentication: Encapsulate an http server authentication using
  * the "Digest" scheme, as described in RFC2069 and updated in RFC2617
@@ -50,8 +49,6 @@
 
     private static final long serialVersionUID = 100L;
 
-    static final char DIGEST_AUTH = 'D';
-
     private String authMethod;
 
     // Authentication parameters defined in RFC2617.
@@ -178,7 +175,10 @@
     public DigestAuthentication(boolean isProxy, URL url, String realm,
                                 String authMethod, PasswordAuthentication pw,
                                 Parameters params) {
-        super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, DIGEST_AUTH,url, realm);
+        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+              AuthScheme.DIGEST,
+              url,
+              realm);
         this.authMethod = authMethod;
         this.pw = pw;
         this.params = params;
@@ -187,7 +187,11 @@
     public DigestAuthentication(boolean isProxy, String host, int port, String realm,
                                 String authMethod, PasswordAuthentication pw,
                                 Parameters params) {
-        super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, DIGEST_AUTH,host, port, realm);
+        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+              AuthScheme.DIGEST,
+              host,
+              port,
+              realm);
         this.authMethod = authMethod;
         this.pw = pw;
         this.params = params;
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java	Wed Jul 05 17:01:15 2017 +0200
@@ -49,8 +49,10 @@
 
     @Override
     public String format(LogRecord record) {
-        if (!"sun.net.www.http.HttpCapture".equalsIgnoreCase(record.getSourceClassName())) {
-            // Don't change format for stuff that doesn't concern us
+        String sourceClassName = record.getSourceClassName();
+        if (sourceClassName == null ||
+            !(sourceClassName.startsWith("sun.net.www.protocol.http") ||
+              sourceClassName.startsWith("sun.net.www.http"))) {
             return super.format(record);
         }
         String src = record.getMessage();
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Jul 05 17:01:15 2017 +0200
@@ -57,11 +57,17 @@
 import sun.net.www.http.PosterOutputStream;
 import sun.net.www.http.ChunkedInputStream;
 import sun.net.www.http.ChunkedOutputStream;
-import sun.net.www.http.HttpCapture;
+import sun.util.logging.PlatformLogger;
 import java.text.SimpleDateFormat;
 import java.util.TimeZone;
 import java.net.MalformedURLException;
 import java.nio.ByteBuffer;
+import static sun.net.www.protocol.http.AuthScheme.BASIC;
+import static sun.net.www.protocol.http.AuthScheme.DIGEST;
+import static sun.net.www.protocol.http.AuthScheme.NTLM;
+import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
+import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
+import static sun.net.www.protocol.http.AuthScheme.UNKNOWN;
 
 /**
  * A class to represent an HTTP connection to a remote object.
@@ -231,9 +237,11 @@
     boolean             needToCheck = true;
     private boolean doingNTLM2ndStage = false; /* doing the 2nd stage of an NTLM server authentication */
     private boolean doingNTLMp2ndStage = false; /* doing the 2nd stage of an NTLM proxy authentication */
-    /* try auth without calling Authenticator */
-    private boolean tryTransparentNTLMServer = NTLMAuthentication.supportsTransparentAuth();
-    private boolean tryTransparentNTLMProxy = NTLMAuthentication.supportsTransparentAuth();
+
+    /* try auth without calling Authenticator. Used for transparent NTLM authentication */
+    private boolean tryTransparentNTLMServer = true;
+    private boolean tryTransparentNTLMProxy = true;
+
     /* Used by Windows specific code */
     Object authObj;
 
@@ -284,6 +292,10 @@
     private int connectTimeout = -1;
     private int readTimeout = -1;
 
+    /* Logging support */
+    private static final PlatformLogger logger =
+            PlatformLogger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
+
     /*
      * privileged request password authentication
      *
@@ -301,20 +313,25 @@
         return java.security.AccessController.doPrivileged(
             new java.security.PrivilegedAction<PasswordAuthentication>() {
                 public PasswordAuthentication run() {
-                    if (HttpCapture.isLoggable("FINEST")) {
-                        HttpCapture.finest("Requesting Authentication: host =" + host + " url = " + url);
+                    if (logger.isLoggable(PlatformLogger.FINEST)) {
+                        logger.finest("Requesting Authentication: host =" + host + " url = " + url);
                     }
                     PasswordAuthentication pass = Authenticator.requestPasswordAuthentication(
                         host, addr, port, protocol,
                         prompt, scheme, url, authType);
-                    if (HttpCapture.isLoggable("FINEST")) {
-                        HttpCapture.finest("Authentication returned: " + (pass != null ? pass.toString() : "null"));
+                    if (logger.isLoggable(PlatformLogger.FINEST)) {
+                        logger.finest("Authentication returned: " + (pass != null ? pass.toString() : "null"));
                     }
                     return pass;
                 }
             });
     }
 
+    /* Logging support */
+    public static PlatformLogger getHttpLogger() {
+        return logger;
+    }
+
     /*
      * checks the validity of http message header and throws
      * IllegalArgumentException if invalid.
@@ -463,8 +480,8 @@
 
             setRequests=true;
         }
-        if (HttpCapture.isLoggable("FINE")) {
-            HttpCapture.fine(requests.toString());
+        if (logger.isLoggable(PlatformLogger.FINE)) {
+            logger.fine(requests.toString());
         }
         http.writeRequests(requests, poster);
         if (ps.checkError()) {
@@ -728,9 +745,9 @@
                         && !(cachedResponse instanceof SecureCacheResponse)) {
                         cachedResponse = null;
                     }
-                    if (HttpCapture.isLoggable("FINEST")) {
-                        HttpCapture.finest("Cache Request for " + uri + " / " + getRequestMethod());
-                        HttpCapture.finest("From cache: " + (cachedResponse != null ? cachedResponse.toString() : "null"));
+                    if (logger.isLoggable(PlatformLogger.FINEST)) {
+                        logger.finest("Cache Request for " + uri + " / " + getRequestMethod());
+                        logger.finest("From cache: " + (cachedResponse != null ? cachedResponse.toString() : "null"));
                     }
                     if (cachedResponse != null) {
                         cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders());
@@ -769,8 +786,8 @@
                              });
                 if (sel != null) {
                     URI uri = sun.net.www.ParseUtil.toURI(url);
-                    if (HttpCapture.isLoggable("FINEST")) {
-                        HttpCapture.finest("ProxySelector Request for " + uri);
+                    if (logger.isLoggable(PlatformLogger.FINEST)) {
+                        logger.finest("ProxySelector Request for " + uri);
                     }
                     Iterator<Proxy> it = sel.select(uri).iterator();
                     Proxy p;
@@ -786,9 +803,9 @@
                                 http = getNewHttpClient(url, p, connectTimeout, false);
                                 http.setReadTimeout(readTimeout);
                             }
-                            if (HttpCapture.isLoggable("FINEST")) {
+                            if (logger.isLoggable(PlatformLogger.FINEST)) {
                                 if (p != null) {
-                                    HttpCapture.finest("Proxy used: " + p.toString());
+                                    logger.finest("Proxy used: " + p.toString());
                                 }
                             }
                             break;
@@ -1018,15 +1035,15 @@
 
             URI uri = ParseUtil.toURI(url);
             if (uri != null) {
-                if (HttpCapture.isLoggable("FINEST")) {
-                    HttpCapture.finest("CookieHandler request for " + uri);
+                if (logger.isLoggable(PlatformLogger.FINEST)) {
+                    logger.finest("CookieHandler request for " + uri);
                 }
                 Map<String, List<String>> cookies
                     = cookieHandler.get(
                         uri, requests.getHeaders(EXCLUDE_HEADERS));
                 if (!cookies.isEmpty()) {
-                    if (HttpCapture.isLoggable("FINEST")) {
-                        HttpCapture.finest("Cookies retrieved: " + cookies.toString());
+                    if (logger.isLoggable(PlatformLogger.FINEST)) {
+                        logger.finest("Cookies retrieved: " + cookies.toString());
                     }
                     for (Map.Entry<String, List<String>> entry :
                              cookies.entrySet()) {
@@ -1157,8 +1174,8 @@
                     writeRequests();
                 }
                 http.parseHTTP(responses, pi, this);
-                if (HttpCapture.isLoggable("FINE")) {
-                    HttpCapture.fine(responses.toString());
+                if (logger.isLoggable(PlatformLogger.FINE)) {
+                    logger.fine(responses.toString());
                 }
                 inputStream = http.getInputStream();
 
@@ -1270,7 +1287,7 @@
                     String raw = srvHdr.raw();
                     if (!doingNTLM2ndStage) {
                         if ((serverAuthentication != null)&&
-                            !(serverAuthentication instanceof NTLMAuthentication)) {
+                            serverAuthentication.getAuthScheme() != NTLM) {
                             if (serverAuthentication.isAuthorizationStale (raw)) {
                                 /* we can retry with the current credentials */
                                 disconnectInternal();
@@ -1523,8 +1540,8 @@
      */
     private AuthenticationInfo
         resetProxyAuthentication(AuthenticationInfo proxyAuthentication, AuthenticationHeader auth) {
-        if ((proxyAuthentication != null )&& ! (proxyAuthentication instanceof
-                                                        NTLMAuthentication)) {
+        if ((proxyAuthentication != null )&&
+             proxyAuthentication.getAuthScheme() != NTLM) {
             String raw = auth.raw();
             if (proxyAuthentication.isAuthorizationStale (raw)) {
                 /* we can retry with the current credentials */
@@ -1602,8 +1619,8 @@
                 http.parseHTTP(responses, null, this);
 
                 /* Log the response to the CONNECT */
-                if (HttpCapture.isLoggable("FINE")) {
-                    HttpCapture.fine(responses.toString());
+                if (logger.isLoggable(PlatformLogger.FINE)) {
+                    logger.fine(responses.toString());
                 }
 
                 statusLine = responses.getValue(0);
@@ -1730,8 +1747,8 @@
         setPreemptiveProxyAuthentication(requests);
 
          /* Log the CONNECT request */
-        if (HttpCapture.isLoggable("FINE")) {
-            HttpCapture.fine(requests.toString());
+        if (logger.isLoggable(PlatformLogger.FINE)) {
+            logger.fine(requests.toString());
         }
 
         http.writeRequests(requests, null);
@@ -1776,28 +1793,31 @@
             HeaderParser p = authhdr.headerParser();
             String realm = p.findValue("realm");
             String scheme = authhdr.scheme();
-            char schemeID;
+            AuthScheme authScheme = UNKNOWN;
             if ("basic".equalsIgnoreCase(scheme)) {
-                schemeID = BasicAuthentication.BASIC_AUTH;
+                authScheme = BASIC;
             } else if ("digest".equalsIgnoreCase(scheme)) {
-                schemeID = DigestAuthentication.DIGEST_AUTH;
+                authScheme = DIGEST;
             } else if ("ntlm".equalsIgnoreCase(scheme)) {
-                schemeID = NTLMAuthentication.NTLM_AUTH;
+                authScheme = NTLM;
                 doingNTLMp2ndStage = true;
             } else if ("Kerberos".equalsIgnoreCase(scheme)) {
-                schemeID = NegotiateAuthentication.KERBEROS_AUTH;
+                authScheme = KERBEROS;
                 doingNTLMp2ndStage = true;
             } else if ("Negotiate".equalsIgnoreCase(scheme)) {
-                schemeID = NegotiateAuthentication.NEGOTIATE_AUTH;
+                authScheme = NEGOTIATE;
                 doingNTLMp2ndStage = true;
-            } else {
-                schemeID = 0;
             }
+
             if (realm == null)
                 realm = "";
-            ret = AuthenticationInfo.getProxyAuth(host, port, realm, schemeID);
+            ret = AuthenticationInfo.getProxyAuth(host,
+                                                  port,
+                                                  realm,
+                                                  authScheme);
             if (ret == null) {
-                if (schemeID == BasicAuthentication.BASIC_AUTH) {
+                switch (authScheme) {
+                case BASIC:
                     InetAddress addr = null;
                     try {
                         final String finalHost = host;
@@ -1818,9 +1838,9 @@
                     if (a != null) {
                         ret = new BasicAuthentication(true, host, port, realm, a);
                     }
-                } else if (schemeID == DigestAuthentication.DIGEST_AUTH) {
-                    PasswordAuthentication a =
-                        privilegedRequestPasswordAuthentication(
+                    break;
+                case DIGEST:
+                    a = privilegedRequestPasswordAuthentication(
                                     host, null, port, url.getProtocol(),
                                     realm, scheme, url, RequestorType.PROXY);
                     if (a != null) {
@@ -1829,29 +1849,49 @@
                         ret = new DigestAuthentication(true, host, port, realm,
                                                             scheme, a, params);
                     }
-                } else if (schemeID == NTLMAuthentication.NTLM_AUTH) {
-                    PasswordAuthentication a = null;
-                    if (!tryTransparentNTLMProxy) {
-                        a = privilegedRequestPasswordAuthentication(
-                                            host, null, port, url.getProtocol(),
-                                            "", scheme, url, RequestorType.PROXY);
+                    break;
+                case NTLM:
+                    if (NTLMAuthenticationProxy.proxy.supported) {
+                        /* tryTransparentNTLMProxy will always be true the first
+                         * time around, but verify that the platform supports it
+                         * otherwise don't try. */
+                        if (tryTransparentNTLMProxy) {
+                            tryTransparentNTLMProxy =
+                                    NTLMAuthenticationProxy.proxy.supportsTransparentAuth;
+                        }
+                        a = null;
+                        if (tryTransparentNTLMProxy) {
+                            logger.finest("Trying Transparent NTLM authentication");
+                        } else {
+                            a = privilegedRequestPasswordAuthentication(
+                                                host, null, port, url.getProtocol(),
+                                                "", scheme, url, RequestorType.PROXY);
+                        }
+                        /* If we are not trying transparent authentication then
+                         * we need to have a PasswordAuthentication instance. For
+                         * transparent authentication (Windows only) the username
+                         * and password will be picked up from the current logged
+                         * on users credentials.
+                        */
+                        if (tryTransparentNTLMProxy ||
+                              (!tryTransparentNTLMProxy && a != null)) {
+                            ret = NTLMAuthenticationProxy.proxy.create(true, host, port, a);
+                        }
+
+                        /* set to false so that we do not try again */
+                        tryTransparentNTLMProxy = false;
                     }
-                    /* If we are not trying transparent authentication then
-                     * we need to have a PasswordAuthentication instance. For
-                     * transparent authentication (Windows only) the username
-                     * and password will be picked up from the current logged
-                     * on users credentials.
-                    */
-                    if (tryTransparentNTLMProxy ||
-                          (!tryTransparentNTLMProxy && a != null)) {
-                        ret = new NTLMAuthentication(true, host, port, a);
-                    }
-
-                    tryTransparentNTLMProxy = false;
-                } else if (schemeID == NegotiateAuthentication.NEGOTIATE_AUTH) {
+                    break;
+                case NEGOTIATE:
                     ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
-                } else if (schemeID == NegotiateAuthentication.KERBEROS_AUTH) {
+                    break;
+                case KERBEROS:
                     ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
+                    break;
+                case UNKNOWN:
+                    logger.finest("Unknown/Unsupported authentication scheme: " + scheme);
+                default:
+                    throw new AssertionError("should not reach here");
                 }
             }
             // For backwards compatibility, we also try defaultAuth
@@ -1875,8 +1915,8 @@
                 }
             }
         }
-        if (HttpCapture.isLoggable("FINER")) {
-            HttpCapture.finer("Proxy Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
+        if (logger.isLoggable(PlatformLogger.FINER)) {
+            logger.finer("Proxy Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
         }
         return ret;
     }
@@ -1896,27 +1936,26 @@
             HeaderParser p = authhdr.headerParser();
             String realm = p.findValue("realm");
             String scheme = authhdr.scheme();
-            char schemeID;
+            AuthScheme authScheme = UNKNOWN;
             if ("basic".equalsIgnoreCase(scheme)) {
-                schemeID = BasicAuthentication.BASIC_AUTH;
+                authScheme = BASIC;
             } else if ("digest".equalsIgnoreCase(scheme)) {
-                schemeID = DigestAuthentication.DIGEST_AUTH;
+                authScheme = DIGEST;
             } else if ("ntlm".equalsIgnoreCase(scheme)) {
-                schemeID = NTLMAuthentication.NTLM_AUTH;
+                authScheme = NTLM;
                 doingNTLM2ndStage = true;
             } else if ("Kerberos".equalsIgnoreCase(scheme)) {
-                schemeID = NegotiateAuthentication.KERBEROS_AUTH;
+                authScheme = KERBEROS;
                 doingNTLM2ndStage = true;
             } else if ("Negotiate".equalsIgnoreCase(scheme)) {
-                schemeID = NegotiateAuthentication.NEGOTIATE_AUTH;
+                authScheme = NEGOTIATE;
                 doingNTLM2ndStage = true;
-            } else {
-                schemeID = 0;
             }
+
             domain = p.findValue ("domain");
             if (realm == null)
                 realm = "";
-            ret = AuthenticationInfo.getServerAuth(url, realm, schemeID);
+            ret = AuthenticationInfo.getServerAuth(url, realm, authScheme);
             InetAddress addr = null;
             if (ret == null) {
                 try {
@@ -1931,13 +1970,14 @@
                 port = url.getDefaultPort();
             }
             if (ret == null) {
-                if (schemeID == NegotiateAuthentication.KERBEROS_AUTH) {
+                switch(authScheme) {
+                case KERBEROS:
                     ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
-                }
-                if (schemeID == NegotiateAuthentication.NEGOTIATE_AUTH) {
+                    break;
+                case NEGOTIATE:
                     ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
-                }
-                if (schemeID == BasicAuthentication.BASIC_AUTH) {
+                    break;
+                case BASIC:
                     PasswordAuthentication a =
                         privilegedRequestPasswordAuthentication(
                             url.getHost(), addr, port, url.getProtocol(),
@@ -1945,45 +1985,60 @@
                     if (a != null) {
                         ret = new BasicAuthentication(false, url, realm, a);
                     }
-                }
-
-                if (schemeID == DigestAuthentication.DIGEST_AUTH) {
-                    PasswordAuthentication a =
-                        privilegedRequestPasswordAuthentication(
+                    break;
+                case DIGEST:
+                    a = privilegedRequestPasswordAuthentication(
                             url.getHost(), addr, port, url.getProtocol(),
                             realm, scheme, url, RequestorType.SERVER);
                     if (a != null) {
                         digestparams = new DigestAuthentication.Parameters();
                         ret = new DigestAuthentication(false, url, realm, scheme, a, digestparams);
                     }
-                }
+                    break;
+                case NTLM:
+                    if (NTLMAuthenticationProxy.proxy.supported) {
+                        URL url1;
+                        try {
+                            url1 = new URL (url, "/"); /* truncate the path */
+                        } catch (Exception e) {
+                            url1 = url;
+                        }
 
-                if (schemeID == NTLMAuthentication.NTLM_AUTH) {
-                    URL url1;
-                    try {
-                        url1 = new URL (url, "/"); /* truncate the path */
-                    } catch (Exception e) {
-                        url1 = url;
+                        /* tryTransparentNTLMServer will always be true the first
+                         * time around, but verify that the platform supports it
+                         * otherwise don't try. */
+                        if (tryTransparentNTLMServer) {
+                            tryTransparentNTLMServer =
+                                    NTLMAuthenticationProxy.proxy.supportsTransparentAuth;
+                        }
+                        a = null;
+                        if (tryTransparentNTLMServer) {
+                            logger.finest("Trying Transparent NTLM authentication");
+                        } else {
+                            a = privilegedRequestPasswordAuthentication(
+                                url.getHost(), addr, port, url.getProtocol(),
+                                "", scheme, url, RequestorType.SERVER);
+                        }
+
+                        /* If we are not trying transparent authentication then
+                         * we need to have a PasswordAuthentication instance. For
+                         * transparent authentication (Windows only) the username
+                         * and password will be picked up from the current logged
+                         * on users credentials.
+                         */
+                        if (tryTransparentNTLMServer ||
+                              (!tryTransparentNTLMServer && a != null)) {
+                            ret = NTLMAuthenticationProxy.proxy.create(false, url1, a);
+                        }
+
+                        /* set to false so that we do not try again */
+                        tryTransparentNTLMServer = false;
                     }
-                    PasswordAuthentication a = null;
-                    if (!tryTransparentNTLMServer) {
-                        a = privilegedRequestPasswordAuthentication(
-                            url.getHost(), addr, port, url.getProtocol(),
-                            "", scheme, url, RequestorType.SERVER);
-                    }
-
-                    /* If we are not trying transparent authentication then
-                     * we need to have a PasswordAuthentication instance. For
-                     * transparent authentication (Windows only) the username
-                     * and password will be picked up from the current logged
-                     * on users credentials.
-                     */
-                    if (tryTransparentNTLMServer ||
-                          (!tryTransparentNTLMServer && a != null)) {
-                        ret = new NTLMAuthentication(false, url1, a);
-                    }
-
-                    tryTransparentNTLMServer = false;
+                    break;
+                case UNKNOWN:
+                    logger.finest("Unknown/Unsupported authentication scheme: " + scheme);
+                default:
+                    throw new AssertionError("should not reach here");
                 }
             }
 
@@ -2005,8 +2060,8 @@
                 }
             }
         }
-        if (HttpCapture.isLoggable("FINER")) {
-            HttpCapture.finer("Server Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
+        if (logger.isLoggable(PlatformLogger.FINER)) {
+            logger.finer("Server Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
         }
         return ret;
     }
@@ -2081,8 +2136,8 @@
         if (streaming()) {
             throw new HttpRetryException (RETRY_MSG3, stat, loc);
         }
-        if (HttpCapture.isLoggable("FINE")) {
-            HttpCapture.fine("Redirected from " + url + " to " + locUrl);
+        if (logger.isLoggable(PlatformLogger.FINE)) {
+            logger.fine("Redirected from " + url + " to " + locUrl);
         }
 
         // clear out old response headers!!!!
--- a/jdk/src/share/classes/sun/net/www/protocol/http/InMemoryCookieStore.java	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,393 +0,0 @@
-/*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.net.www.protocol.http;
-
-import java.net.URI;
-import java.net.CookieStore;
-import java.net.HttpCookie;
-import java.net.URISyntaxException;
-import java.util.List;
-import java.util.Map;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * A simple in-memory java.net.CookieStore implementation
- *
- * @author Edward Wang
- * @since 1.6
- */
-public class InMemoryCookieStore implements CookieStore {
-    // the in-memory representation of cookies
-    private List<HttpCookie> cookieJar = null;
-
-    // the cookies are indexed by its domain and associated uri (if present)
-    // CAUTION: when a cookie removed from main data structure (i.e. cookieJar),
-    //          it won't be cleared in domainIndex & uriIndex. Double-check the
-    //          presence of cookie when retrieve one form index store.
-    private Map<String, List<HttpCookie>> domainIndex = null;
-    private Map<URI, List<HttpCookie>> uriIndex = null;
-
-    // use ReentrantLock instead of syncronized for scalability
-    private ReentrantLock lock = null;
-
-
-    /**
-     * The default ctor
-     */
-    public InMemoryCookieStore() {
-        cookieJar = new ArrayList<HttpCookie>();
-        domainIndex = new HashMap<String, List<HttpCookie>>();
-        uriIndex = new HashMap<URI, List<HttpCookie>>();
-
-        lock = new ReentrantLock(false);
-    }
-
-    /**
-     * Add one cookie into cookie store.
-     */
-    public void add(URI uri, HttpCookie cookie) {
-        // pre-condition : argument can't be null
-        if (cookie == null) {
-            throw new NullPointerException("cookie is null");
-        }
-
-
-        lock.lock();
-        try {
-            // remove the ole cookie if there has had one
-            cookieJar.remove(cookie);
-
-            // add new cookie if it has a non-zero max-age
-            if (cookie.getMaxAge() != 0) {
-                cookieJar.add(cookie);
-                // and add it to domain index
-                if (cookie.getDomain() != null) {
-                    addIndex(domainIndex, cookie.getDomain(), cookie);
-                }
-                // add it to uri index, too
-                addIndex(uriIndex, getEffectiveURI(uri), cookie);
-            }
-        } finally {
-            lock.unlock();
-        }
-    }
-
-
-    /**
-     * Get all cookies, which:
-     *  1) given uri domain-matches with, or, associated with
-     *     given uri when added to the cookie store.
-     *  3) not expired.
-     * See RFC 2965 sec. 3.3.4 for more detail.
-     */
-    public List<HttpCookie> get(URI uri) {
-        // argument can't be null
-        if (uri == null) {
-            throw new NullPointerException("uri is null");
-        }
-
-        List<HttpCookie> cookies = new ArrayList<HttpCookie>();
-        boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
-        lock.lock();
-        try {
-            // check domainIndex first
-            getInternal1(cookies, domainIndex, uri.getHost(), secureLink);
-            // check uriIndex then
-            getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink);
-        } finally {
-            lock.unlock();
-        }
-
-        return cookies;
-    }
-
-    /**
-     * Get all cookies in cookie store, except those have expired
-     */
-    public List<HttpCookie> getCookies() {
-        List<HttpCookie> rt;
-
-        lock.lock();
-        try {
-            Iterator<HttpCookie> it = cookieJar.iterator();
-            while (it.hasNext()) {
-                if (it.next().hasExpired()) {
-                    it.remove();
-                }
-            }
-        } finally {
-            rt = Collections.unmodifiableList(cookieJar);
-            lock.unlock();
-        }
-
-        return rt;
-    }
-
-    /**
-     * Get all URIs, which are associated with at least one cookie
-     * of this cookie store.
-     */
-    public List<URI> getURIs() {
-        List<URI> uris = new ArrayList<URI>();
-
-        lock.lock();
-        try {
-            Iterator<URI> it = uriIndex.keySet().iterator();
-            while (it.hasNext()) {
-                URI uri = it.next();
-                List<HttpCookie> cookies = uriIndex.get(uri);
-                if (cookies == null || cookies.size() == 0) {
-                    // no cookies list or an empty list associated with
-                    // this uri entry, delete it
-                    it.remove();
-                }
-            }
-        } finally {
-            uris.addAll(uriIndex.keySet());
-            lock.unlock();
-        }
-
-        return uris;
-    }
-
-
-    /**
-     * Remove a cookie from store
-     */
-    public boolean remove(URI uri, HttpCookie ck) {
-        // argument can't be null
-        if (ck == null) {
-            throw new NullPointerException("cookie is null");
-        }
-
-        boolean modified = false;
-        lock.lock();
-        try {
-            modified = cookieJar.remove(ck);
-        } finally {
-            lock.unlock();
-        }
-
-        return modified;
-    }
-
-
-    /**
-     * Remove all cookies in this cookie store.
-     */
-    public boolean removeAll() {
-        lock.lock();
-        try {
-            cookieJar.clear();
-            domainIndex.clear();
-            uriIndex.clear();
-        } finally {
-            lock.unlock();
-        }
-
-        return true;
-    }
-
-
-    /* ---------------- Private operations -------------- */
-
-
-    /*
-     * This is almost the same as HttpCookie.domainMatches except for
-     * one difference: It won't reject cookies when the 'H' part of the
-     * domain contains a dot ('.').
-     * I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com
-     * and the cookie domain is .domain.com, then it should be rejected.
-     * However that's not how the real world works. Browsers don't reject and
-     * some sites, like yahoo.com do actually expect these cookies to be
-     * passed along.
-     * And should be used for 'old' style cookies (aka Netscape type of cookies)
-     */
-    private boolean netscapeDomainMatches(String domain, String host)
-    {
-        if (domain == null || host == null) {
-            return false;
-        }
-
-        // if there's no embedded dot in domain and domain is not .local
-        boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
-        int embeddedDotInDomain = domain.indexOf('.');
-        if (embeddedDotInDomain == 0) {
-            embeddedDotInDomain = domain.indexOf('.', 1);
-        }
-        if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) {
-            return false;
-        }
-
-        // if the host name contains no dot and the domain name is .local
-        int firstDotInHost = host.indexOf('.');
-        if (firstDotInHost == -1 && isLocalDomain) {
-            return true;
-        }
-
-        int domainLength = domain.length();
-        int lengthDiff = host.length() - domainLength;
-        if (lengthDiff == 0) {
-            // if the host name and the domain name are just string-compare euqal
-            return host.equalsIgnoreCase(domain);
-        } else if (lengthDiff > 0) {
-            // need to check H & D component
-            String H = host.substring(0, lengthDiff);
-            String D = host.substring(lengthDiff);
-
-            return (D.equalsIgnoreCase(domain));
-        } else if (lengthDiff == -1) {
-            // if domain is actually .host
-            return (domain.charAt(0) == '.' &&
-                    host.equalsIgnoreCase(domain.substring(1)));
-        }
-
-        return false;
-    }
-
-    private void getInternal1(List<HttpCookie> cookies, Map<String, List<HttpCookie>> cookieIndex,
-            String host, boolean secureLink) {
-        // Use a separate list to handle cookies that need to be removed so
-        // that there is no conflict with iterators.
-        ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>();
-        for (Map.Entry<String, List<HttpCookie>> entry : cookieIndex.entrySet()) {
-            String domain = entry.getKey();
-            List<HttpCookie> lst = entry.getValue();
-            for (HttpCookie c : lst) {
-                if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) ||
-                        (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) {
-                    if ((cookieJar.indexOf(c) != -1)) {
-                        // the cookie still in main cookie store
-                        if (!c.hasExpired()) {
-                            // don't add twice and make sure it's the proper
-                            // security level
-                            if ((secureLink || !c.getSecure()) &&
-                                    !cookies.contains(c)) {
-                                cookies.add(c);
-                            }
-                        } else {
-                            toRemove.add(c);
-                        }
-                    } else {
-                        // the cookie has beed removed from main store,
-                        // so also remove it from domain indexed store
-                        toRemove.add(c);
-                    }
-                }
-            }
-            // Clear up the cookies that need to be removed
-            for (HttpCookie c : toRemove) {
-                lst.remove(c);
-                cookieJar.remove(c);
-
-            }
-            toRemove.clear();
-        }
-    }
-
-    // @param cookies           [OUT] contains the found cookies
-    // @param cookieIndex       the index
-    // @param comparator        the prediction to decide whether or not
-    //                          a cookie in index should be returned
-    private <T> void getInternal2(List<HttpCookie> cookies,
-                                Map<T, List<HttpCookie>> cookieIndex,
-                                Comparable<T> comparator, boolean secureLink)
-    {
-        for (T index : cookieIndex.keySet()) {
-            if (comparator.compareTo(index) == 0) {
-                List<HttpCookie> indexedCookies = cookieIndex.get(index);
-                // check the list of cookies associated with this domain
-                if (indexedCookies != null) {
-                    Iterator<HttpCookie> it = indexedCookies.iterator();
-                    while (it.hasNext()) {
-                        HttpCookie ck = it.next();
-                        if (cookieJar.indexOf(ck) != -1) {
-                            // the cookie still in main cookie store
-                            if (!ck.hasExpired()) {
-                                // don't add twice
-                                if ((secureLink || !ck.getSecure()) &&
-                                        !cookies.contains(ck))
-                                    cookies.add(ck);
-                            } else {
-                                it.remove();
-                                cookieJar.remove(ck);
-                            }
-                        } else {
-                            // the cookie has beed removed from main store,
-                            // so also remove it from domain indexed store
-                            it.remove();
-                        }
-                    }
-                } // end of indexedCookies != null
-            } // end of comparator.compareTo(index) == 0
-        } // end of cookieIndex iteration
-    }
-
-    // add 'cookie' indexed by 'index' into 'indexStore'
-    private <T> void addIndex(Map<T, List<HttpCookie>> indexStore,
-                              T index,
-                              HttpCookie cookie)
-    {
-        if (index != null) {
-            List<HttpCookie> cookies = indexStore.get(index);
-            if (cookies != null) {
-                // there may already have the same cookie, so remove it first
-                cookies.remove(cookie);
-
-                cookies.add(cookie);
-            } else {
-                cookies = new ArrayList<HttpCookie>();
-                cookies.add(cookie);
-                indexStore.put(index, cookies);
-            }
-        }
-    }
-
-
-    //
-    // for cookie purpose, the effective uri should only be http://host
-    // the path will be taken into account when path-match algorithm applied
-    //
-    private URI getEffectiveURI(URI uri) {
-        URI effectiveURI = null;
-        try {
-            effectiveURI = new URI("http",
-                                   uri.getHost(),
-                                   null,  // path component
-                                   null,  // query component
-                                   null   // fragment component
-                                  );
-        } catch (URISyntaxException ignored) {
-            effectiveURI = uri;
-        }
-
-        return effectiveURI;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.net.www.protocol.http;
+
+import java.net.URL;
+import java.net.PasswordAuthentication;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import sun.util.logging.PlatformLogger;
+
+/**
+ * Proxy class for loading NTLMAuthentication, so as to remove static
+ * dependancy.
+ */
+class NTLMAuthenticationProxy {
+    private static Method supportsTA;
+    private static final String clazzStr = "sun.net.www.protocol.http.NTLMAuthentication";
+    private static final String supportsTAStr = "supportsTransparentAuth";
+
+    static final NTLMAuthenticationProxy proxy = tryLoadNTLMAuthentication();
+    static final boolean supported = proxy != null ? true : false;
+    static final boolean supportsTransparentAuth = supported ? supportsTransparentAuth(supportsTA) : false;
+
+    private final Constructor<? extends AuthenticationInfo> threeArgCtr;
+    private final Constructor<? extends AuthenticationInfo> fiveArgCtr;
+
+    private NTLMAuthenticationProxy(Constructor<? extends AuthenticationInfo> threeArgCtr,
+                                    Constructor<? extends AuthenticationInfo> fiveArgCtr) {
+        this.threeArgCtr = threeArgCtr;
+        this.fiveArgCtr = fiveArgCtr;
+    }
+
+
+    AuthenticationInfo create(boolean isProxy,
+                              URL url,
+                              PasswordAuthentication pw) {
+        try {
+            return threeArgCtr.newInstance(isProxy, url, pw);
+        } catch (ReflectiveOperationException roe) {
+            finest(roe);
+        }
+
+        return null;
+    }
+
+    AuthenticationInfo create(boolean isProxy,
+                              String host,
+                              int port,
+                              PasswordAuthentication pw) {
+        try {
+            return fiveArgCtr.newInstance(isProxy, host, port, pw);
+        } catch (ReflectiveOperationException roe) {
+            finest(roe);
+        }
+
+        return null;
+    }
+
+    /* Returns true if the NTLM implementation supports transparent
+     * authentication (try with the current users credentials before
+     * prompting for username and password, etc).
+     */
+    private static boolean supportsTransparentAuth(Method method) {
+        try {
+            return (Boolean)method.invoke(null);
+        } catch (ReflectiveOperationException roe) {
+            finest(roe);
+        }
+
+        return false;
+    }
+
+    /**
+     * Loads the NTLM authentiation implementation through reflection. If
+     * the class is present, then it must have the required constructors and
+     * method. Otherwise, it is considered an error.
+     */
+    @SuppressWarnings("unchecked")
+    private static NTLMAuthenticationProxy tryLoadNTLMAuthentication() {
+        Class<? extends AuthenticationInfo> cl;
+        Constructor<? extends AuthenticationInfo> threeArg, fiveArg;
+        try {
+            cl = (Class<? extends AuthenticationInfo>)Class.forName(clazzStr, true, null);
+            if (cl != null) {
+                threeArg = cl.getConstructor(boolean.class,
+                                             URL.class,
+                                             PasswordAuthentication.class);
+                fiveArg = cl.getConstructor(boolean.class,
+                                            String.class,
+                                            int.class,
+                                            PasswordAuthentication.class);
+                supportsTA = cl.getDeclaredMethod(supportsTAStr);
+                return new NTLMAuthenticationProxy(threeArg,
+                                                   fiveArg);
+            }
+        } catch (ClassNotFoundException cnfe) {
+            finest(cnfe);
+        } catch (ReflectiveOperationException roe) {
+            throw new AssertionError(roe);
+        }
+
+        return null;
+    }
+
+    static void finest(Exception e) {
+        PlatformLogger logger = HttpURLConnection.getHttpLogger();
+        logger.finest("NTLMAuthenticationProxy: " + e);
+    }
+}
--- a/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java	Wed Jul 05 17:01:15 2017 +0200
@@ -30,11 +30,14 @@
 import sun.net.www.HeaderParser;
 import sun.misc.BASE64Decoder;
 import sun.misc.BASE64Encoder;
+import sun.util.logging.PlatformLogger;
 
 import java.net.URL;
 import java.io.IOException;
 import java.net.Authenticator.RequestorType;
-
+import java.lang.reflect.Constructor;
+import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
+import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
 
 /**
  * NegotiateAuthentication:
@@ -49,9 +52,6 @@
 
     final private HttpCallerInfo hci;
 
-    static final char NEGOTIATE_AUTH = 'S';
-    static final char KERBEROS_AUTH = 'K';
-
     // These maps are used to manage the GSS availability for diffrent
     // hosts. The key for both maps is the host name.
     // <code>supported</code> is set when isSupported is checked,
@@ -68,11 +68,10 @@
     * @param hci a schemed object.
     */
     public NegotiateAuthentication(HttpCallerInfo hci) {
-        super(RequestorType.PROXY==hci.authType?
-                    PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
-                hci.scheme.equalsIgnoreCase("Negotiate")?
-                    NEGOTIATE_AUTH:KERBEROS_AUTH,
-                hci.url, "");
+        super(RequestorType.PROXY==hci.authType ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+              hci.scheme.equalsIgnoreCase("Negotiate") ? NEGOTIATE : KERBEROS,
+              hci.url,
+              "");
         this.hci = hci;
     }
 
@@ -249,13 +248,41 @@
         // The current implementation will make sure NegotiatorImpl is not
         // directly referenced when compiling, thus smooth the way of building
         // the J2SE platform where HttpURLConnection is a bootstrap class.
+        //
+        // Makes NegotiatorImpl, and the security classes it references, a
+        // runtime dependency rather than a static one.
 
-        Class clazz = Class.forName("sun.net.www.protocol.http.NegotiatorImpl");
-        java.lang.reflect.Constructor c = clazz.getConstructor(HttpCallerInfo.class);
-        return (Negotiator) (c.newInstance(hci));
+        Class clazz;
+        Constructor c;
+        try {
+            clazz = Class.forName("sun.net.www.protocol.http.NegotiatorImpl", true, null);
+            c = clazz.getConstructor(HttpCallerInfo.class);
+        } catch (ClassNotFoundException cnfe) {
+            finest(cnfe);
+            throw cnfe;
+        } catch (ReflectiveOperationException roe) {
+            // if the class is there then something seriously wrong if
+            // the constructor is not.
+            throw new AssertionError(roe);
+        }
+
+        try {
+            return (Negotiator) (c.newInstance(hci));
+        } catch (ReflectiveOperationException roe) {
+            finest(roe);
+            Throwable t = roe.getCause();
+            if (t != null && t instanceof Exception)
+                finest((Exception)t);
+            throw roe;
+        }
     }
 
     abstract byte[] firstToken() throws IOException;
 
     abstract byte[] nextToken(byte[] in) throws IOException;
+
+    static void finest(Exception e) {
+        PlatformLogger logger = HttpURLConnection.getHttpLogger();
+        logger.finest("NegotiateAuthentication: " + e);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/action/GetBooleanSecurityPropertyAction.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.security.action;
+
+import java.security.Security;
+
+/**
+ * A convenience class for retrieving the boolean value of a security property
+ * as a privileged action.
+ *
+ * <p>An instance of this class can be used as the argument of
+ * <code>AccessController.doPrivileged</code>.
+ *
+ * <p>The following code retrieves the boolean value of the security
+ * property named <code>"prop"</code> as a privileged action: <p>
+ *
+ * <pre>
+ * boolean b = java.security.AccessController.doPrivileged
+ *              (new GetBooleanSecurityPropertyAction("prop")).booleanValue();
+ * </pre>
+ *
+ */
+public class GetBooleanSecurityPropertyAction
+        implements java.security.PrivilegedAction<Boolean> {
+    private String theProp;
+
+    /**
+     * Constructor that takes the name of the security property whose boolean
+     * value needs to be determined.
+     *
+     * @param theProp the name of the security property
+     */
+    public GetBooleanSecurityPropertyAction(String theProp) {
+        this.theProp = theProp;
+    }
+
+    /**
+     * Determines the boolean value of the security property whose name was
+     * specified in the constructor.
+     *
+     * @return the <code>Boolean</code> value of the security property.
+     */
+    public Boolean run() {
+        boolean b = false;
+        try {
+            String value = Security.getProperty(theProp);
+            b = (value != null) && value.equalsIgnoreCase("true");
+        } catch (NullPointerException e) {}
+        return b;
+    }
+}
--- a/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/ec/ECDHKeyAgreement.java	Wed Jul 05 17:01:15 2017 +0200
@@ -39,21 +39,6 @@
  */
 public final class ECDHKeyAgreement extends KeyAgreementSpi {
 
-    // flag indicating whether the native ECC implementation is present
-    private static boolean implementationPresent = true;
-    static {
-        try {
-            AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                public Void run() {
-                    System.loadLibrary("sunecc");
-                    return null;
-                }
-            });
-        } catch (UnsatisfiedLinkError e) {
-            implementationPresent = false;
-        }
-    }
-
     // private key, if initialized
     private ECPrivateKey privateKey;
 
@@ -65,16 +50,12 @@
 
     /**
      * Constructs a new ECDHKeyAgreement.
-     *
-     * @exception ProviderException if the native ECC library is unavailable.
      */
     public ECDHKeyAgreement() {
-        if (!implementationPresent) {
-            throw new ProviderException("ECDH implementation is not available");
-        }
     }
 
     // see JCE spec
+    @Override
     protected void engineInit(Key key, SecureRandom random)
             throws InvalidKeyException {
         if (!(key instanceof PrivateKey)) {
@@ -86,6 +67,7 @@
     }
 
     // see JCE spec
+    @Override
     protected void engineInit(Key key, AlgorithmParameterSpec params,
             SecureRandom random) throws InvalidKeyException,
             InvalidAlgorithmParameterException {
@@ -97,6 +79,7 @@
     }
 
     // see JCE spec
+    @Override
     protected Key engineDoPhase(Key key, boolean lastPhase)
             throws InvalidKeyException, IllegalStateException {
         if (privateKey == null) {
@@ -130,6 +113,7 @@
     }
 
     // see JCE spec
+    @Override
     protected byte[] engineGenerateSecret() throws IllegalStateException {
         if ((privateKey == null) || (publicValue == null)) {
             throw new IllegalStateException("Not initialized correctly");
@@ -150,6 +134,7 @@
     }
 
     // see JCE spec
+    @Override
     protected int engineGenerateSecret(byte[] sharedSecret, int
             offset) throws IllegalStateException, ShortBufferException {
         if (offset + secretLen > sharedSecret.length) {
@@ -162,6 +147,7 @@
     }
 
     // see JCE spec
+    @Override
     protected SecretKey engineGenerateSecret(String algorithm)
             throws IllegalStateException, NoSuchAlgorithmException,
             InvalidKeyException {
--- a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java	Wed Jul 05 17:01:15 2017 +0200
@@ -52,21 +52,6 @@
  */
 abstract class ECDSASignature extends SignatureSpi {
 
-    // flag indicating whether the native ECC implementation is present
-    private static boolean implementationPresent = true;
-    static {
-        try {
-            AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                public Void run() {
-                    System.loadLibrary("sunecc");
-                    return null;
-                }
-            });
-        } catch (UnsatisfiedLinkError e) {
-            implementationPresent = false;
-        }
-    }
-
     // message digest implementation we use
     private final MessageDigest messageDigest;
 
@@ -88,24 +73,13 @@
      * @exception ProviderException if the native ECC library is unavailable.
      */
     ECDSASignature() {
-        if (!implementationPresent) {
-            throw new
-                ProviderException("ECDSA implementation is not available");
-        }
         messageDigest = null;
     }
 
     /**
      * Constructs a new ECDSASignature. Used by subclasses.
-     *
-     * @exception ProviderException if the native ECC library is unavailable.
      */
     ECDSASignature(String digestName) {
-        if (!implementationPresent) {
-            throw new
-                ProviderException("ECDSA implementation is not available");
-        }
-
         try {
             messageDigest = MessageDigest.getInstance(digestName);
         } catch (NoSuchAlgorithmException e) {
@@ -299,8 +273,8 @@
         byte[] encodedParams = ECParameters.encodeParameters(params); // DER OID
         int keySize = params.getCurve().getField().getFieldSize();
 
-        // seed is twice the key size (in bytes)
-        byte[] seed = new byte[((keySize + 7) >> 3) * 2];
+        // seed is twice the key size (in bytes) plus 1
+        byte[] seed = new byte[(((keySize + 7) >> 3) + 1) * 2];
         if (random == null) {
             random = JCAUtil.getSecureRandom();
         }
@@ -356,6 +330,7 @@
 
     // Convert the concatenation of R and S into their DER encoding
     private byte[] encodeSignature(byte[] signature) throws SignatureException {
+
         try {
 
             int n = signature.length >> 1;
--- a/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/ec/ECKeyPairGenerator.java	Wed Jul 05 17:01:15 2017 +0200
@@ -46,20 +46,6 @@
  */
 public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
 
-    // flag indicating whether the native ECC implementation is present
-    private static boolean implementationPresent = true;
-    static {
-        try {
-            AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                public Void run() {
-                    System.loadLibrary("sunecc");
-                    return null;
-                }
-            });
-        } catch (UnsatisfiedLinkError e) {
-            implementationPresent = false;
-        }
-    }
     private static final int KEY_SIZE_MIN = 112; // min bits (see ecc_impl.h)
     private static final int KEY_SIZE_MAX = 571; // max bits (see ecc_impl.h)
     private static final int KEY_SIZE_DEFAULT = 256;
@@ -75,13 +61,8 @@
 
     /**
      * Constructs a new ECKeyPairGenerator.
-     *
-     * @exception ProviderException if the native ECC library is unavailable.
      */
     public ECKeyPairGenerator() {
-        if (!implementationPresent) {
-            throw new ProviderException("EC implementation is not available");
-        }
         // initialize to default in case the app does not call initialize()
         initialize(KEY_SIZE_DEFAULT, null);
     }
@@ -133,8 +114,8 @@
         byte[] encodedParams =
             ECParameters.encodeParameters((ECParameterSpec)params);
 
-        // seed is twice the key size (in bytes)
-        byte[] seed = new byte[2 * ((keySize + 7) >> 3)];
+        // seed is twice the key size (in bytes) plus 1
+        byte[] seed = new byte[(((keySize + 7) >> 3) + 1) * 2];
         if (random == null) {
             random = JCAUtil.getSecureRandom();
         }
--- a/jdk/src/share/classes/sun/security/ec/SunEC.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/ec/SunEC.java	Wed Jul 05 17:01:15 2017 +0200
@@ -39,7 +39,10 @@
  * via JNI to a C++ wrapper class which in turn calls C functions.
  * The Java classes are packaged into the signed sunec.jar in the JRE
  * extensions directory and the C++ and C functions are packaged into
- * libsunecc.so or sunecc.dll in the JRE native libraries directory.
+ * libsunec.so or sunec.dll in the JRE native libraries directory.
+ * If the native library is not present then this provider is registered
+ * with support for fewer ECC algorithms (KeyPairGenerator, Signature and
+ * KeyAgreement are omitted).
  *
  * @since   1.7
  */
@@ -47,6 +50,22 @@
 
     private static final long serialVersionUID = -2279741672933606418L;
 
+    // flag indicating whether the full EC implementation is present
+    // (when native library is absent then fewer EC algorithms are available)
+    private static boolean useFullImplementation = true;
+    static {
+        try {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    System.loadLibrary("sunec"); // check for native library
+                    return null;
+                }
+            });
+        } catch (UnsatisfiedLinkError e) {
+            useFullImplementation = false;
+        }
+    }
+
     public SunEC() {
         super("SunEC", 1.7d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
 
@@ -54,10 +73,10 @@
         // the provider. Otherwise, create a temporary map and use a
         // doPrivileged() call at the end to transfer the contents
         if (System.getSecurityManager() == null) {
-            SunECEntries.putEntries(this);
+            SunECEntries.putEntries(this, useFullImplementation);
         } else {
             Map<Object, Object> map = new HashMap<Object, Object>();
-            SunECEntries.putEntries(map);
+            SunECEntries.putEntries(map, useFullImplementation);
             AccessController.doPrivileged(new PutAllAction(this, map));
         }
     }
--- a/jdk/src/share/classes/sun/security/ec/SunECEntries.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/ec/SunECEntries.java	Wed Jul 05 17:01:15 2017 +0200
@@ -38,7 +38,93 @@
         // empty
     }
 
-    static void putEntries(Map<Object, Object> map) {
+    static void putEntries(Map<Object, Object> map,
+        boolean useFullImplementation) {
+
+        /*
+         *  Key Factory engine
+         */
+        map.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
+        map.put("Alg.Alias.KeyFactory.EllipticCurve", "EC");
+
+        map.put("KeyFactory.EC ImplementedIn", "Software");
+
+        /*
+         * Algorithm Parameter engine
+         */
+        map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
+        map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
+
+        map.put("AlgorithmParameters.EC KeySize", "256");
+
+        map.put("AlgorithmParameters.EC ImplementedIn", "Software");
+
+        map.put("AlgorithmParameters.EC SupportedCurves",
+
+            // A list comprising lists of curve names and object identifiers.
+            // '[' ( <curve-name> ',' )+ <curve-object-identifier> ']' '|'
+
+            // SEC 2 prime curves
+            "[secp112r1,1.3.132.0.6]|" +
+            "[secp112r2,1.3.132.0.7]|" +
+            "[secp128r1,1.3.132.0.28]|" +
+            "[secp128r2,1.3.132.0.29]|" +
+            "[secp160k1,1.3.132.0.9]|" +
+            "[secp160r1,1.3.132.0.8]|" +
+            "[secp160r2,1.3.132.0.30]|" +
+            "[secp192k1,1.3.132.0.31]|" +
+            "[secp192r1,NIST P-192,X9.62 prime192v1,1.2.840.10045.3.1.1]|" +
+            "[secp224k1,1.3.132.0.32]|" +
+            "[secp224r1,NIST P-224,1.3.132.0.33]|" +
+            "[secp256k1,1.3.132.0.10]|" +
+            "[secp256r1,NIST P-256,X9.62 prime256v1,1.2.840.10045.3.1.7]|" +
+            "[secp384r1,NIST P-384,1.3.132.0.34]|" +
+            "[secp521r1,NIST P-521,1.3.132.0.35]|" +
+
+            // ANSI X9.62 prime curves
+            "[X9.62 prime192v2,1.2.840.10045.3.1.2]|" +
+            "[X9.62 prime192v3,1.2.840.10045.3.1.3]|" +
+            "[X9.62 prime239v1,1.2.840.10045.3.1.4]|" +
+            "[X9.62 prime239v2,1.2.840.10045.3.1.5]|" +
+            "[X9.62 prime239v3,1.2.840.10045.3.1.6]|" +
+
+            // SEC 2 binary curves
+            "[sect113r1,1.3.132.0.4]|" +
+            "[sect113r2,1.3.132.0.5]|" +
+            "[sect131r1,1.3.132.0.22]|" +
+            "[sect131r2,1.3.132.0.23]|" +
+            "[sect163k1,NIST K-163,1.3.132.0.1]|" +
+            "[sect163r1,1.3.132.0.2]|" +
+            "[sect163r2,NIST B-163,1.3.132.0.15]|" +
+            "[sect193r1,1.3.132.0.24]|" +
+            "[sect193r2,1.3.132.0.25]|" +
+            "[sect233k1,NIST K-233,1.3.132.0.26]|" +
+            "[sect233r1,NIST B-233,1.3.132.0.27]|" +
+            "[sect239k1,1.3.132.0.3]|" +
+            "[sect283k1,NIST K-283,1.3.132.0.16]|" +
+            "[sect283r1,NIST B-283,1.3.132.0.17]|" +
+            "[sect409k1,NIST K-409,1.3.132.0.36]|" +
+            "[sect409r1,NIST B-409,1.3.132.0.37]|" +
+            "[sect571k1,NIST K-571,1.3.132.0.38]|" +
+            "[sect571r1,NIST B-571,1.3.132.0.39]|" +
+
+            // ANSI X9.62 binary curves
+            "[X9.62 c2tnb191v1,1.2.840.10045.3.0.5]|" +
+            "[X9.62 c2tnb191v2,1.2.840.10045.3.0.6]|" +
+            "[X9.62 c2tnb191v3,1.2.840.10045.3.0.7]|" +
+            "[X9.62 c2tnb239v1,1.2.840.10045.3.0.11]|" +
+            "[X9.62 c2tnb239v2,1.2.840.10045.3.0.12]|" +
+            "[X9.62 c2tnb239v3,1.2.840.10045.3.0.13]|" +
+            "[X9.62 c2tnb359v1,1.2.840.10045.3.0.18]|" +
+            "[X9.62 c2tnb431r1,1.2.840.10045.3.0.20]");
+
+        /*
+         * Register the algorithms below only when the full ECC implementation
+         * is available
+         */
+        if (!useFullImplementation) {
+            return;
+        }
 
         /*
          * Signature engines
@@ -62,48 +148,31 @@
         map.put("Signature.SHA384withECDSA SupportedKeyClasses", ecKeyClasses);
         map.put("Signature.SHA512withECDSA SupportedKeyClasses", ecKeyClasses);
 
+        map.put("Signature.SHA1withECDSA KeySize", "256");
+
+        map.put("Signature.NONEwithECDSA ImplementedIn", "Software");
+        map.put("Signature.SHA1withECDSA ImplementedIn", "Software");
+        map.put("Signature.SHA256withECDSA ImplementedIn", "Software");
+        map.put("Signature.SHA384withECDSA ImplementedIn", "Software");
+        map.put("Signature.SHA512withECDSA ImplementedIn", "Software");
+
         /*
          *  Key Pair Generator engine
          */
         map.put("KeyPairGenerator.EC", "sun.security.ec.ECKeyPairGenerator");
         map.put("Alg.Alias.KeyPairGenerator.EllipticCurve", "EC");
 
-        /*
-         *  Key Factory engine
-         */
-        map.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
-        map.put("Alg.Alias.KeyFactory.EllipticCurve", "EC");
+        map.put("KeyPairGenerator.EC KeySize", "256");
 
-        /*
-         * Algorithm Parameter engine
-         */
-        map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
-        map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
+        map.put("KeyPairGenerator.EC ImplementedIn", "Software");
 
         /*
          * Key Agreement engine
          */
         map.put("KeyAgreement.ECDH", "sun.security.ec.ECDHKeyAgreement");
+
         map.put("KeyAgreement.ECDH SupportedKeyClasses", ecKeyClasses);
 
-        /*
-         * Key sizes
-         */
-        map.put("Signature.SHA1withECDSA KeySize", "256");
-        map.put("KeyPairGenerator.EC KeySize", "256");
-        map.put("AlgorithmParameterGenerator.ECDSA KeySize", "256");
-
-        /*
-         * Implementation type: software or hardware
-         */
-        map.put("Signature.NONEwithECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA1withECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA256withECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA384withECDSA ImplementedIn", "Software");
-        map.put("Signature.SHA512withECDSA ImplementedIn", "Software");
-        map.put("KeyPairGenerator.EC ImplementedIn", "Software");
-        map.put("KeyFactory.EC ImplementedIn", "Software");
         map.put("KeyAgreement.ECDH ImplementedIn", "Software");
-        map.put("AlgorithmParameters.EC ImplementedIn", "Software");
     }
 }
--- a/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Portions Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Portions Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -149,6 +149,11 @@
                 send(realm,tempKdc,useTCP);
                 break;
             } catch (Exception e) {
+                if (DEBUG) {
+                    System.out.println(">>> KrbKdcReq send: error trying " +
+                            tempKdc);
+                    e.printStackTrace(System.out);
+                }
                 savedException = e;
             }
         }
@@ -179,10 +184,36 @@
         /*
          * Get port number for this KDC.
          */
-        StringTokenizer strTok = new StringTokenizer(tempKdc, ":");
-        String kdc = strTok.nextToken();
-        if (strTok.hasMoreTokens()) {
-            String portStr = strTok.nextToken();
+        String kdc = null;
+        String portStr = null;
+
+        if (tempKdc.charAt(0) == '[') {     // Explicit IPv6 in []
+            int pos = tempKdc.indexOf(']', 1);
+            if (pos == -1) {
+                throw new IOException("Illegal KDC: " + tempKdc);
+            }
+            kdc = tempKdc.substring(1, pos);
+            if (pos != tempKdc.length() - 1) {  // with port number
+                if (tempKdc.charAt(pos+1) != ':') {
+                    throw new IOException("Illegal KDC: " + tempKdc);
+                }
+                portStr = tempKdc.substring(pos+2);
+            }
+        } else {
+            int colon = tempKdc.indexOf(':');
+            if (colon == -1) {      // Hostname or IPv4 host only
+                kdc = tempKdc;
+            } else {
+                int nextColon = tempKdc.indexOf(':', colon+1);
+                if (nextColon > 0) {    // >=2 ":", IPv6 with no port
+                    kdc = tempKdc;
+                } else {                // 1 ":", hostname or IPv4 with port
+                    kdc = tempKdc.substring(0, colon);
+                    portStr = tempKdc.substring(colon+1);
+                }
+            }
+        }
+        if (portStr != null) {
             int tempPort = parsePositiveIntString(portStr);
             if (tempPort > 0)
                 port = tempPort;
--- a/jdk/src/share/classes/sun/security/provider/certpath/Builder.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/Builder.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,12 +26,14 @@
 package sun.security.provider.certpath;
 
 import java.io.IOException;
+import java.security.AccessController;
 import java.security.GeneralSecurityException;
 import java.security.cert.*;
 import java.util.*;
 
 import javax.security.auth.x500.X500Principal;
 
+import sun.security.action.GetBooleanAction;
 import sun.security.util.Debug;
 import sun.security.x509.GeneralNames;
 import sun.security.x509.GeneralNameInterface;
@@ -64,9 +66,8 @@
      * Authority Information Access extension shall be enabled. Currently
      * disabled by default for compatibility reasons.
      */
-    final static boolean USE_AIA =
-        DistributionPointFetcher.getBooleanProperty
-            ("com.sun.security.enableAIAcaIssuers", false);
+    final static boolean USE_AIA = AccessController.doPrivileged
+        (new GetBooleanAction("com.sun.security.enableAIAcaIssuers"));
 
     /**
      * Initialize the builder with the input parameters.
--- a/jdk/src/share/classes/sun/security/provider/certpath/CertId.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CertId.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,11 @@
 
 package sun.security.provider.certpath;
 
-import java.io.*;
+import java.io.IOException;
 import java.math.BigInteger;
 import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import sun.misc.HexDumpEncoder;
 import sun.security.x509.*;
@@ -54,21 +56,28 @@
 public class CertId {
 
     private static final boolean debug = false;
-    private AlgorithmId hashAlgId;
-    private byte[] issuerNameHash;
-    private byte[] issuerKeyHash;
-    private SerialNumber certSerialNumber;
+    private static final AlgorithmId SHA1_ALGID
+        = new AlgorithmId(AlgorithmId.SHA_oid);
+    private final AlgorithmId hashAlgId;
+    private final byte[] issuerNameHash;
+    private final byte[] issuerKeyHash;
+    private final SerialNumber certSerialNumber;
     private int myhash = -1; // hashcode for this CertId
 
     /**
      * Creates a CertId. The hash algorithm used is SHA-1.
      */
-    public CertId(X509CertImpl issuerCert, SerialNumber serialNumber)
-        throws Exception {
+    public CertId(X509Certificate issuerCert, SerialNumber serialNumber)
+        throws IOException {
 
         // compute issuerNameHash
-        MessageDigest md = MessageDigest.getInstance("SHA1");
-        hashAlgId = AlgorithmId.get("SHA1");
+        MessageDigest md = null;
+        try {
+            md = MessageDigest.getInstance("SHA1");
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new IOException("Unable to create CertId", nsae);
+        }
+        hashAlgId = SHA1_ALGID;
         md.update(issuerCert.getSubjectX500Principal().getEncoded());
         issuerNameHash = md.digest();
 
@@ -90,6 +99,7 @@
                 encoder.encode(issuerNameHash));
             System.out.println("issuerKeyHash is " +
                 encoder.encode(issuerKeyHash));
+            System.out.println("SerialNumber is " + serialNumber.getNumber());
         }
     }
 
@@ -97,7 +107,6 @@
      * Creates a CertId from its ASN.1 DER encoding.
      */
     public CertId(DerInputStream derIn) throws IOException {
-
         hashAlgId = AlgorithmId.parse(derIn.getDerValue());
         issuerNameHash = derIn.getOctetString();
         issuerKeyHash = derIn.getOctetString();
@@ -157,7 +166,7 @@
      *
      * @return the hashcode value.
      */
-    public int hashCode() {
+    @Override public int hashCode() {
         if (myhash == -1) {
             myhash = hashAlgId.hashCode();
             for (int i = 0; i < issuerNameHash.length; i++) {
@@ -180,8 +189,7 @@
      * @param other the object to test for equality with this object.
      * @return true if the objects are considered equal, false otherwise.
      */
-    public boolean equals(Object other) {
-
+    @Override public boolean equals(Object other) {
         if (this == other) {
             return true;
         }
@@ -203,7 +211,7 @@
     /**
      * Create a string representation of the CertId.
      */
-    public String toString() {
+    @Override public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("CertId \n");
         sb.append("Algorithm: " + hashAlgId.toString() +"\n");
--- a/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java	Wed Jul 05 17:01:15 2017 +0200
@@ -80,6 +80,7 @@
         { false, false, false, false, false, false, true };
     private static final boolean[] ALL_REASONS =
         {true, true, true, true, true, true, true, true, true};
+    private boolean mOnlyEECert = false;
 
     // Maximum clock skew in milliseconds (15 minutes) allowed when checking
     // validity of CRLs
@@ -114,6 +115,12 @@
     CrlRevocationChecker(TrustAnchor anchor, PKIXParameters params,
         Collection<X509Certificate> certs) throws CertPathValidatorException
     {
+        this(anchor, params, certs, false);
+    }
+
+    CrlRevocationChecker(TrustAnchor anchor, PKIXParameters params,
+        Collection<X509Certificate> certs, boolean onlyEECert)
+        throws CertPathValidatorException {
         mAnchor = anchor;
         mParams = params;
         mStores = new ArrayList<CertStore>(params.getCertStores());
@@ -133,6 +140,7 @@
         }
         Date testDate = params.getDate();
         mCurrentTime = (testDate != null ? testDate : new Date());
+        mOnlyEECert = onlyEECert;
         init(false);
     }
 
@@ -264,6 +272,13 @@
                 " ---checking " + msg + "...");
         }
 
+        if (mOnlyEECert && currCert.getBasicConstraints() != -1) {
+            if (debug != null) {
+                debug.println("Skipping revocation check, not end entity cert");
+            }
+            return;
+        }
+
         // reject circular dependencies - RFC 3280 is not explicit on how
         // to handle this, so we feel it is safest to reject them until
         // the issue is resolved in the PKIX WG.
--- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Wed Jul 05 17:01:15 2017 +0200
@@ -32,7 +32,7 @@
 import java.security.cert.*;
 import javax.security.auth.x500.X500Principal;
 
-import sun.security.action.GetPropertyAction;
+import sun.security.action.GetBooleanAction;
 import sun.security.util.Debug;
 import sun.security.util.DerOutputStream;
 import sun.security.x509.*;
@@ -62,28 +62,8 @@
      * extension shall be enabled. Currently disabled by default for
      * compatibility and legal reasons.
      */
-    private final static boolean USE_CRLDP =
-        getBooleanProperty("com.sun.security.enableCRLDP", false);
-
-    /**
-     * Return the value of the boolean System property propName.
-     */
-    public static boolean getBooleanProperty(String propName,
-            boolean defaultValue) {
-        // if set, require value of either true or false
-        String b = AccessController.doPrivileged(
-                new GetPropertyAction(propName));
-        if (b == null) {
-            return defaultValue;
-        } else if (b.equalsIgnoreCase("false")) {
-            return false;
-        } else if (b.equalsIgnoreCase("true")) {
-            return true;
-        } else {
-            throw new RuntimeException("Value of " + propName
-            + " must either be 'true' or 'false'");
-        }
-    }
+    private final static boolean USE_CRLDP = AccessController.doPrivileged
+        (new GetBooleanAction("com.sun.security.enableCRLDP"));
 
     // singleton instance
     private static final DistributionPointFetcher INSTANCE =
--- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java	Wed Jul 05 17:01:15 2017 +0200
@@ -82,6 +82,7 @@
     TrustAnchor trustAnchor;
     private Comparator<X509Certificate> comparator;
     private boolean searchAllCertStores = true;
+    private boolean onlyEECert = false;
 
     /**
      * Initialize the builder with the input parameters.
@@ -89,7 +90,8 @@
      * @param params the parameter set used to build a certification path
      */
     ForwardBuilder(PKIXBuilderParameters buildParams,
-        X500Principal targetSubjectDN, boolean searchAllCertStores)
+        X500Principal targetSubjectDN, boolean searchAllCertStores,
+        boolean onlyEECert)
     {
         super(buildParams, targetSubjectDN);
 
@@ -108,6 +110,7 @@
         }
         comparator = new PKIXCertComparator(trustedSubjectDNs);
         this.searchAllCertStores = searchAllCertStores;
+        this.onlyEECert = onlyEECert;
     }
 
     /**
@@ -875,8 +878,8 @@
             /* Check revocation if it is enabled */
             if (buildParams.isRevocationEnabled()) {
                 try {
-                    CrlRevocationChecker crlChecker =
-                        new CrlRevocationChecker(anchor, buildParams);
+                    CrlRevocationChecker crlChecker = new CrlRevocationChecker
+                        (anchor, buildParams, null, onlyEECert);
                     crlChecker.check(cert, anchor.getCAPublicKey(), true);
                 } catch (CertPathValidatorException cpve) {
                     if (debug != null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.security.provider.certpath;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.HttpURLConnection;
+import java.security.cert.CertificateException;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CRLReason;
+import java.security.cert.Extension;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import static sun.security.provider.certpath.OCSPResponse.*;
+import sun.security.util.Debug;
+import sun.security.x509.AccessDescription;
+import sun.security.x509.AuthorityInfoAccessExtension;
+import sun.security.x509.GeneralName;
+import sun.security.x509.GeneralNameInterface;
+import sun.security.x509.URIName;
+import sun.security.x509.X509CertImpl;
+
+/**
+ * This is a class that checks the revocation status of a certificate(s) using
+ * OCSP. It is not a PKIXCertPathChecker and therefore can be used outside of
+ * the CertPathValidator framework. It is useful when you want to
+ * just check the revocation status of a certificate, and you don't want to
+ * incur the overhead of validating all of the certificates in the
+ * associated certificate chain.
+ *
+ * @author Sean Mullan
+ */
+public final class OCSP {
+
+    private static final Debug debug = Debug.getInstance("certpath");
+
+    private OCSP() {}
+
+    /**
+     * Obtains the revocation status of a certificate using OCSP using the most
+     * common defaults. The OCSP responder URI is retrieved from the
+     * certificate's AIA extension. The OCSP responder certificate is assumed
+     * to be the issuer's certificate (or issued by the issuer CA).
+     *
+     * @param cert the certificate to be checked
+     * @param issuerCert the issuer certificate
+     * @return the RevocationStatus
+     * @throws IOException if there is an exception connecting to or
+     *    communicating with the OCSP responder
+     * @throws CertPathValidatorException if an exception occurs while
+     *    encoding the OCSP Request or validating the OCSP Response
+     */
+    public static RevocationStatus check(X509Certificate cert,
+        X509Certificate issuerCert)
+        throws IOException, CertPathValidatorException {
+        CertId certId = null;
+        URI responderURI = null;
+        try {
+            X509CertImpl certImpl = X509CertImpl.toImpl(cert);
+            responderURI = getResponderURI(certImpl);
+            if (responderURI == null) {
+                throw new CertPathValidatorException
+                    ("No OCSP Responder URI in certificate");
+            }
+            certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException
+                ("Exception while encoding OCSPRequest", ce);
+        } catch (IOException ioe) {
+            throw new CertPathValidatorException
+                ("Exception while encoding OCSPRequest", ioe);
+        }
+        OCSPResponse ocspResponse = check(Collections.singletonList(certId),
+            responderURI, issuerCert, null);
+        return (RevocationStatus) ocspResponse.getSingleResponse(certId);
+    }
+
+    /**
+     * Obtains the revocation status of a certificate using OCSP.
+     *
+     * @param cert the certificate to be checked
+     * @param issuerCert the issuer certificate
+     * @param responderURI the URI of the OCSP responder
+     * @param responderCert the OCSP responder's certificate
+     * @param date the time the validity of the OCSP responder's certificate
+     *    should be checked against. If null, the current time is used.
+     * @return the RevocationStatus
+     * @throws IOException if there is an exception connecting to or
+     *    communicating with the OCSP responder
+     * @throws CertPathValidatorException if an exception occurs while
+     *    encoding the OCSP Request or validating the OCSP Response
+     */
+    public static RevocationStatus check(X509Certificate cert,
+        X509Certificate issuerCert, URI responderURI, X509Certificate
+        responderCert, Date date)
+        throws IOException, CertPathValidatorException {
+        CertId certId = null;
+        try {
+            X509CertImpl certImpl = X509CertImpl.toImpl(cert);
+            certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException
+                ("Exception while encoding OCSPRequest", ce);
+        } catch (IOException ioe) {
+            throw new CertPathValidatorException
+                ("Exception while encoding OCSPRequest", ioe);
+        }
+        OCSPResponse ocspResponse = check(Collections.singletonList(certId),
+            responderURI, responderCert, date);
+        return (RevocationStatus) ocspResponse.getSingleResponse(certId);
+    }
+
+    /**
+     * Checks the revocation status of a list of certificates using OCSP.
+     *
+     * @param certs the CertIds to be checked
+     * @param responderURI the URI of the OCSP responder
+     * @param responderCert the OCSP responder's certificate
+     * @param date the time the validity of the OCSP responder's certificate
+     *    should be checked against. If null, the current time is used.
+     * @return the OCSPResponse
+     * @throws IOException if there is an exception connecting to or
+     *    communicating with the OCSP responder
+     * @throws CertPathValidatorException if an exception occurs while
+     *    encoding the OCSP Request or validating the OCSP Response
+     */
+    static OCSPResponse check(List<CertId> certIds, URI responderURI,
+        X509Certificate responderCert, Date date)
+        throws IOException, CertPathValidatorException {
+
+        byte[] bytes = null;
+        try {
+            OCSPRequest request = new OCSPRequest(certIds);
+            bytes = request.encodeBytes();
+        } catch (IOException ioe) {
+            throw new CertPathValidatorException
+                ("Exception while encoding OCSPRequest", ioe);
+        }
+
+        InputStream in = null;
+        OutputStream out = null;
+        byte[] response = null;
+        try {
+            URL url = responderURI.toURL();
+            if (debug != null) {
+                debug.println("connecting to OCSP service at: " + url);
+            }
+            HttpURLConnection con = (HttpURLConnection)url.openConnection();
+            con.setDoOutput(true);
+            con.setDoInput(true);
+            con.setRequestMethod("POST");
+            con.setRequestProperty
+                ("Content-type", "application/ocsp-request");
+            con.setRequestProperty
+                ("Content-length", String.valueOf(bytes.length));
+            out = con.getOutputStream();
+            out.write(bytes);
+            out.flush();
+            // Check the response
+            if (debug != null &&
+                con.getResponseCode() != HttpURLConnection.HTTP_OK) {
+                debug.println("Received HTTP error: " + con.getResponseCode()
+                    + " - " + con.getResponseMessage());
+            }
+            in = con.getInputStream();
+            int contentLength = con.getContentLength();
+            if (contentLength == -1) {
+                contentLength = Integer.MAX_VALUE;
+            }
+            response = new byte[contentLength > 2048 ? 2048 : contentLength];
+            int total = 0;
+            while (total < contentLength) {
+                int count = in.read(response, total, response.length - total);
+                if (count < 0)
+                    break;
+
+                total += count;
+                if (total >= response.length && total < contentLength) {
+                    response = Arrays.copyOf(response, total * 2);
+                }
+            }
+            response = Arrays.copyOf(response, total);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException ioe) {
+                    throw ioe;
+                }
+            }
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ioe) {
+                    throw ioe;
+                }
+            }
+        }
+
+        OCSPResponse ocspResponse = null;
+        try {
+            ocspResponse = new OCSPResponse(response, date, responderCert);
+        } catch (IOException ioe) {
+            // response decoding exception
+            throw new CertPathValidatorException(ioe);
+        }
+        if (ocspResponse.getResponseStatus() != ResponseStatus.SUCCESSFUL) {
+            throw new CertPathValidatorException
+                ("OCSP response error: " + ocspResponse.getResponseStatus());
+        }
+
+        // Check that the response includes a response for all of the
+        // certs that were supplied in the request
+        for (CertId certId : certIds) {
+            SingleResponse sr = ocspResponse.getSingleResponse(certId);
+            if (sr == null) {
+                if (debug != null) {
+                    debug.println("No response found for CertId: " + certId);
+                }
+                throw new CertPathValidatorException(
+                    "OCSP response does not include a response for a " +
+                    "certificate supplied in the OCSP request");
+            }
+            if (debug != null) {
+                debug.println("Status of certificate (with serial number " +
+                    certId.getSerialNumber() + ") is: " + sr.getCertStatus());
+            }
+        }
+        return ocspResponse;
+    }
+
+    /**
+     * Returns the URI of the OCSP Responder as specified in the
+     * certificate's Authority Information Access extension, or null if
+     * not specified.
+     *
+     * @param cert the certificate
+     * @return the URI of the OCSP Responder, or null if not specified
+     */
+    public static URI getResponderURI(X509Certificate cert) {
+        try {
+            return getResponderURI(X509CertImpl.toImpl(cert));
+        } catch (CertificateException ce) {
+            // treat this case as if the cert had no extension
+            return null;
+        }
+    }
+
+    static URI getResponderURI(X509CertImpl certImpl) {
+
+        // Examine the certificate's AuthorityInfoAccess extension
+        AuthorityInfoAccessExtension aia =
+            certImpl.getAuthorityInfoAccessExtension();
+        if (aia == null) {
+            return null;
+        }
+
+        List<AccessDescription> descriptions = aia.getAccessDescriptions();
+        for (AccessDescription description : descriptions) {
+            if (description.getAccessMethod().equals(
+                AccessDescription.Ad_OCSP_Id)) {
+
+                GeneralName generalName = description.getAccessLocation();
+                if (generalName.getType() == GeneralNameInterface.NAME_URI) {
+                    URIName uri = (URIName) generalName.getName();
+                    return uri.getURI();
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The Revocation Status of a certificate.
+     */
+    public static interface RevocationStatus {
+        public enum CertStatus { GOOD, REVOKED, UNKNOWN };
+
+        /**
+         * Returns the revocation status.
+         */
+        CertStatus getCertStatus();
+        /**
+         * Returns the time when the certificate was revoked, or null
+         * if it has not been revoked.
+         */
+        Date getRevocationTime();
+        /**
+         * Returns the reason the certificate was revoked, or null if it
+         * has not been revoked.
+         */
+        CRLReason getRevocationReason();
+
+        /**
+         * Returns a Map of additional extensions.
+         */
+        Map<String, Extension> getSingleExtensions();
+    }
+}
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,19 +25,20 @@
 
 package sun.security.provider.certpath;
 
-import java.io.*;
+import java.io.IOException;
 import java.math.BigInteger;
 import java.util.*;
 import java.security.AccessController;
-import java.security.Principal;
 import java.security.PrivilegedAction;
 import java.security.Security;
 import java.security.cert.*;
 import java.security.cert.CertPathValidatorException.BasicReason;
-import java.net.*;
+import java.net.URI;
+import java.net.URISyntaxException;
 import javax.security.auth.x500.X500Principal;
 
-import sun.security.util.*;
+import static sun.security.provider.certpath.OCSP.*;
+import sun.security.util.Debug;
 import sun.security.x509.*;
 
 /**
@@ -50,27 +51,18 @@
  */
 class OCSPChecker extends PKIXCertPathChecker {
 
-    public static final String OCSP_ENABLE_PROP = "ocsp.enable";
-    public static final String OCSP_URL_PROP = "ocsp.responderURL";
-    public static final String OCSP_CERT_SUBJECT_PROP =
+    static final String OCSP_ENABLE_PROP = "ocsp.enable";
+    static final String OCSP_URL_PROP = "ocsp.responderURL";
+    static final String OCSP_CERT_SUBJECT_PROP =
         "ocsp.responderCertSubjectName";
-    public static final String OCSP_CERT_ISSUER_PROP =
-        "ocsp.responderCertIssuerName";
-    public static final String OCSP_CERT_NUMBER_PROP =
+    static final String OCSP_CERT_ISSUER_PROP = "ocsp.responderCertIssuerName";
+    static final String OCSP_CERT_NUMBER_PROP =
         "ocsp.responderCertSerialNumber";
 
     private static final String HEX_DIGITS = "0123456789ABCDEFabcdef";
     private static final Debug DEBUG = Debug.getInstance("certpath");
     private static final boolean dump = false;
 
-    // Supported extensions
-    private static final int OCSP_NONCE_DATA[] =
-        { 1, 3, 6, 1, 5, 5, 7, 48, 1, 2 };
-    private static final ObjectIdentifier OCSP_NONCE_OID;
-    static {
-        OCSP_NONCE_OID = ObjectIdentifier.newInternal(OCSP_NONCE_DATA);
-    }
-
     private int remainingCerts;
 
     private X509Certificate[] certs;
@@ -79,19 +71,26 @@
 
     private PKIXParameters pkixParams;
 
+    private boolean onlyEECert = false;
+
     /**
      * Default Constructor
      *
      * @param certPath the X509 certification path
      * @param pkixParams the input PKIX parameter set
-     * @exception CertPathValidatorException Exception thrown if cert path
-     * does not validate.
+     * @throws CertPathValidatorException if OCSPChecker can not be created
      */
     OCSPChecker(CertPath certPath, PKIXParameters pkixParams)
         throws CertPathValidatorException {
+        this(certPath, pkixParams, false);
+    }
+
+    OCSPChecker(CertPath certPath, PKIXParameters pkixParams, boolean onlyEECert)
+        throws CertPathValidatorException {
 
         this.cp = certPath;
         this.pkixParams = pkixParams;
+        this.onlyEECert = onlyEECert;
         List<? extends Certificate> tmp = cp.getCertificates();
         certs = tmp.toArray(new X509Certificate[tmp.size()]);
         init(false);
@@ -101,6 +100,7 @@
      * Initializes the internal state of the checker from parameters
      * specified in the constructor
      */
+    @Override
     public void init(boolean forward) throws CertPathValidatorException {
         if (!forward) {
             remainingCerts = certs.length + 1;
@@ -110,11 +110,11 @@
         }
     }
 
-    public boolean isForwardCheckingSupported() {
+    @Override public boolean isForwardCheckingSupported() {
         return false;
     }
 
-    public Set<String> getSupportedExtensions() {
+    @Override public Set<String> getSupportedExtensions() {
         return Collections.<String>emptySet();
     }
 
@@ -127,300 +127,233 @@
      * @exception CertPathValidatorException Exception is thrown if the
      *            certificate has been revoked.
      */
+    @Override
     public void check(Certificate cert, Collection<String> unresolvedCritExts)
         throws CertPathValidatorException {
 
-        InputStream in = null;
-        OutputStream out = null;
-
         // Decrement the certificate counter
         remainingCerts--;
 
+        X509CertImpl currCertImpl = null;
         try {
-            X509Certificate responderCert = null;
-            boolean seekResponderCert = false;
-            X500Principal responderSubjectName = null;
-            X500Principal responderIssuerName = null;
-            BigInteger responderSerialNumber = null;
+            currCertImpl = X509CertImpl.toImpl((X509Certificate)cert);
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException(ce);
+        }
+
+        if (onlyEECert && currCertImpl.getBasicConstraints() != -1) {
+            if (DEBUG != null) {
+                DEBUG.println("Skipping revocation check, not end entity cert");
+            }
+            return;
+        }
 
-            boolean seekIssuerCert = true;
-            X509CertImpl issuerCertImpl = null;
-            X509CertImpl currCertImpl =
-                X509CertImpl.toImpl((X509Certificate)cert);
+        /*
+         * OCSP security property values, in the following order:
+         *   1. ocsp.responderURL
+         *   2. ocsp.responderCertSubjectName
+         *   3. ocsp.responderCertIssuerName
+         *   4. ocsp.responderCertSerialNumber
+         */
+        // should cache these properties to avoid calling every time?
+        String[] properties = getOCSPProperties();
+
+        // Check whether OCSP is feasible before seeking cert information
+        URI uri = getOCSPServerURI(currCertImpl, properties[0]);
 
-            /*
-             * OCSP security property values, in the following order:
-             *   1. ocsp.responderURL
-             *   2. ocsp.responderCertSubjectName
-             *   3. ocsp.responderCertIssuerName
-             *   4. ocsp.responderCertSerialNumber
-             */
-            String[] properties = getOCSPProperties();
+        // When responder's subject name is set then the issuer/serial
+        // properties are ignored
+        X500Principal responderSubjectName = null;
+        X500Principal responderIssuerName = null;
+        BigInteger responderSerialNumber = null;
+        if (properties[1] != null) {
+            responderSubjectName = new X500Principal(properties[1]);
+        } else if (properties[2] != null && properties[3] != null) {
+            responderIssuerName = new X500Principal(properties[2]);
+            // remove colon or space separators
+            String value = stripOutSeparators(properties[3]);
+            responderSerialNumber = new BigInteger(value, 16);
+        } else if (properties[2] != null || properties[3] != null) {
+            throw new CertPathValidatorException(
+                "Must specify both ocsp.responderCertIssuerName and " +
+                "ocsp.responderCertSerialNumber properties");
+        }
 
-            // Check whether OCSP is feasible before seeking cert information
-            URL url = getOCSPServerURL(currCertImpl, properties);
+        // If the OCSP responder cert properties are set then the
+        // identified cert must be located in the trust anchors or
+        // in the cert stores.
+        boolean seekResponderCert = false;
+        if (responderSubjectName != null || responderIssuerName != null) {
+            seekResponderCert = true;
+        }
 
-            // When responder's subject name is set then the issuer/serial
-            // properties are ignored
-            if (properties[1] != null) {
-                responderSubjectName = new X500Principal(properties[1]);
+        // Set the issuer certificate to the next cert in the chain
+        // (unless we're processing the final cert).
+        X509Certificate issuerCert = null;
+        boolean seekIssuerCert = true;
+        X509Certificate responderCert = null;
+        if (remainingCerts < certs.length) {
+            issuerCert = certs[remainingCerts];
+            seekIssuerCert = false; // done
 
-            } else if (properties[2] != null && properties[3] != null) {
-                responderIssuerName = new X500Principal(properties[2]);
-                // remove colon or space separators
-                String value = stripOutSeparators(properties[3]);
-                responderSerialNumber = new BigInteger(value, 16);
+            // By default, the OCSP responder's cert is the same as the
+            // issuer of the cert being validated.
+            if (!seekResponderCert) {
+                responderCert = issuerCert;
+                if (DEBUG != null) {
+                    DEBUG.println("Responder's certificate is the same " +
+                        "as the issuer of the certificate being validated");
+                }
+            }
+        }
 
-            } else if (properties[2] != null || properties[3] != null) {
-                throw new CertPathValidatorException(
-                    "Must specify both ocsp.responderCertIssuerName and " +
-                    "ocsp.responderCertSerialNumber properties");
+        // Check anchor certs for:
+        //    - the issuer cert (of the cert being validated)
+        //    - the OCSP responder's cert
+        if (seekIssuerCert || seekResponderCert) {
+
+            if (DEBUG != null && seekResponderCert) {
+                DEBUG.println("Searching trust anchors for responder's " +
+                    "certificate");
             }
 
-            // If the OCSP responder cert properties are set then the
-            // identified cert must be located in the trust anchors or
-            // in the cert stores.
-            if (responderSubjectName != null || responderIssuerName != null) {
-                seekResponderCert = true;
+            // Extract the anchor certs
+            Iterator<TrustAnchor> anchors
+                = pkixParams.getTrustAnchors().iterator();
+            if (!anchors.hasNext()) {
+                throw new CertPathValidatorException(
+                    "Must specify at least one trust anchor");
             }
 
-            // Set the issuer certificate to the next cert in the chain
-            // (unless we're processing the final cert).
-            if (remainingCerts < certs.length) {
-                issuerCertImpl = X509CertImpl.toImpl(certs[remainingCerts]);
-                seekIssuerCert = false; // done
+            X500Principal certIssuerName =
+                currCertImpl.getIssuerX500Principal();
+            while (anchors.hasNext() && (seekIssuerCert || seekResponderCert)) {
+
+                TrustAnchor anchor = anchors.next();
+                X509Certificate anchorCert = anchor.getTrustedCert();
+                X500Principal anchorSubjectName =
+                    anchorCert.getSubjectX500Principal();
+
+                if (dump) {
+                    System.out.println("Issuer DN is " + certIssuerName);
+                    System.out.println("Subject DN is " + anchorSubjectName);
+                }
+
+                // Check if anchor cert is the issuer cert
+                if (seekIssuerCert &&
+                    certIssuerName.equals(anchorSubjectName)) {
+
+                    issuerCert = anchorCert;
+                    seekIssuerCert = false; // done
 
-                // By default, the OCSP responder's cert is the same as the
-                // issuer of the cert being validated.
-                if (! seekResponderCert) {
-                    responderCert = certs[remainingCerts];
-                    if (DEBUG != null) {
-                        DEBUG.println("Responder's certificate is the same " +
-                            "as the issuer of the certificate being validated");
+                    // By default, the OCSP responder's cert is the same as
+                    // the issuer of the cert being validated.
+                    if (!seekResponderCert && responderCert == null) {
+                        responderCert = anchorCert;
+                        if (DEBUG != null) {
+                            DEBUG.println("Responder's certificate is the" +
+                                " same as the issuer of the certificate " +
+                                "being validated");
+                        }
+                    }
+                }
+
+                // Check if anchor cert is the responder cert
+                if (seekResponderCert) {
+                    // Satisfy the responder subject name property only, or
+                    // satisfy the responder issuer name and serial number
+                    // properties only
+                    if ((responderSubjectName != null &&
+                         responderSubjectName.equals(anchorSubjectName)) ||
+                        (responderIssuerName != null &&
+                         responderSerialNumber != null &&
+                         responderIssuerName.equals(
+                         anchorCert.getIssuerX500Principal()) &&
+                         responderSerialNumber.equals(
+                         anchorCert.getSerialNumber()))) {
+
+                        responderCert = anchorCert;
+                        seekResponderCert = false; // done
                     }
                 }
             }
+            if (issuerCert == null) {
+                throw new CertPathValidatorException(
+                    "No trusted certificate for " + currCertImpl.getIssuerDN());
+            }
 
-            // Check anchor certs for:
-            //    - the issuer cert (of the cert being validated)
-            //    - the OCSP responder's cert
-            if (seekIssuerCert || seekResponderCert) {
-
-                if (DEBUG != null && seekResponderCert) {
-                    DEBUG.println("Searching trust anchors for responder's " +
+            // Check cert stores if responder cert has not yet been found
+            if (seekResponderCert) {
+                if (DEBUG != null) {
+                    DEBUG.println("Searching cert stores for responder's " +
                         "certificate");
                 }
-
-                // Extract the anchor certs
-                Iterator anchors = pkixParams.getTrustAnchors().iterator();
-                if (! anchors.hasNext()) {
-                    throw new CertPathValidatorException(
-                        "Must specify at least one trust anchor");
+                X509CertSelector filter = null;
+                if (responderSubjectName != null) {
+                    filter = new X509CertSelector();
+                    filter.setSubject(responderSubjectName);
+                } else if (responderIssuerName != null &&
+                    responderSerialNumber != null) {
+                    filter = new X509CertSelector();
+                    filter.setIssuer(responderIssuerName);
+                    filter.setSerialNumber(responderSerialNumber);
                 }
-
-                X500Principal certIssuerName =
-                    currCertImpl.getIssuerX500Principal();
-                while (anchors.hasNext() &&
-                        (seekIssuerCert || seekResponderCert)) {
-
-                    TrustAnchor anchor = (TrustAnchor)anchors.next();
-                    X509Certificate anchorCert = anchor.getTrustedCert();
-                    X500Principal anchorSubjectName =
-                        anchorCert.getSubjectX500Principal();
-
-                    if (dump) {
-                        System.out.println("Issuer DN is " + certIssuerName);
-                        System.out.println("Subject DN is " +
-                            anchorSubjectName);
-                    }
-
-                    // Check if anchor cert is the issuer cert
-                    if (seekIssuerCert &&
-                        certIssuerName.equals(anchorSubjectName)) {
-
-                        issuerCertImpl = X509CertImpl.toImpl(anchorCert);
-                        seekIssuerCert = false; // done
-
-                        // By default, the OCSP responder's cert is the same as
-                        // the issuer of the cert being validated.
-                        if (! seekResponderCert && responderCert == null) {
-                            responderCert = anchorCert;
+                if (filter != null) {
+                    List<CertStore> certStores = pkixParams.getCertStores();
+                    for (CertStore certStore : certStores) {
+                        Iterator i = null;
+                        try {
+                            i = certStore.getCertificates(filter).iterator();
+                        } catch (CertStoreException cse) {
+                            // ignore and try next certStore
                             if (DEBUG != null) {
-                                DEBUG.println("Responder's certificate is the" +
-                                    " same as the issuer of the certificate " +
-                                    "being validated");
+                                DEBUG.println("CertStore exception:" + cse);
                             }
+                            continue;
                         }
-                    }
-
-                    // Check if anchor cert is the responder cert
-                    if (seekResponderCert) {
-                        // Satisfy the responder subject name property only, or
-                        // satisfy the responder issuer name and serial number
-                        // properties only
-                        if ((responderSubjectName != null &&
-                             responderSubjectName.equals(anchorSubjectName)) ||
-                            (responderIssuerName != null &&
-                             responderSerialNumber != null &&
-                             responderIssuerName.equals(
-                                anchorCert.getIssuerX500Principal()) &&
-                             responderSerialNumber.equals(
-                                anchorCert.getSerialNumber()))) {
-
-                            responderCert = anchorCert;
+                        if (i.hasNext()) {
+                            responderCert = (X509Certificate) i.next();
                             seekResponderCert = false; // done
-                        }
-                    }
-                }
-                if (issuerCertImpl == null) {
-                    throw new CertPathValidatorException(
-                        "No trusted certificate for " +
-                        currCertImpl.getIssuerDN());
-                }
-
-                // Check cert stores if responder cert has not yet been found
-                if (seekResponderCert) {
-                    if (DEBUG != null) {
-                        DEBUG.println("Searching cert stores for responder's " +
-                            "certificate");
-                    }
-                    X509CertSelector filter = null;
-                    if (responderSubjectName != null) {
-                        filter = new X509CertSelector();
-                        filter.setSubject(responderSubjectName.getName());
-                    } else if (responderIssuerName != null &&
-                        responderSerialNumber != null) {
-                        filter = new X509CertSelector();
-                        filter.setIssuer(responderIssuerName.getName());
-                        filter.setSerialNumber(responderSerialNumber);
-                    }
-                    if (filter != null) {
-                        List<CertStore> certStores = pkixParams.getCertStores();
-                        for (CertStore certStore : certStores) {
-                            Iterator i =
-                                certStore.getCertificates(filter).iterator();
-                            if (i.hasNext()) {
-                                responderCert = (X509Certificate) i.next();
-                                seekResponderCert = false; // done
-                                break;
-                            }
+                            break;
                         }
                     }
                 }
             }
-
-            // Could not find the certificate identified in the OCSP properties
-            if (seekResponderCert) {
-                throw new CertPathValidatorException(
-                    "Cannot find the responder's certificate " +
-                    "(set using the OCSP security properties).");
-            }
-
-            // Construct an OCSP Request
-            OCSPRequest ocspRequest =
-                new OCSPRequest(currCertImpl, issuerCertImpl);
-
-            // Use the URL to the OCSP service that was created earlier
-            HttpURLConnection con = (HttpURLConnection)url.openConnection();
-            if (DEBUG != null) {
-                DEBUG.println("connecting to OCSP service at: " + url);
-            }
-
-            // Indicate that both input and output will be performed,
-            // that the method is POST, and that the content length is
-            // the length of the byte array
+        }
 
-            con.setDoOutput(true);
-            con.setDoInput(true);
-            con.setRequestMethod("POST");
-            con.setRequestProperty("Content-type", "application/ocsp-request");
-            byte[] bytes = ocspRequest.encodeBytes();
-            CertId certId = ocspRequest.getCertId();
-
-            con.setRequestProperty("Content-length",
-                String.valueOf(bytes.length));
-            out = con.getOutputStream();
-            out.write(bytes);
-            out.flush();
-
-            // Check the response
-            if (DEBUG != null &&
-                con.getResponseCode() != HttpURLConnection.HTTP_OK) {
-                DEBUG.println("Received HTTP error: " + con.getResponseCode() +
-                    " - " + con.getResponseMessage());
-            }
-            in = con.getInputStream();
-
-            byte[] response = null;
-            int total = 0;
-            int contentLength = con.getContentLength();
-            if (contentLength != -1) {
-                response = new byte[contentLength];
-            } else {
-                response = new byte[2048];
-                contentLength = Integer.MAX_VALUE;
-            }
+        // Could not find the certificate identified in the OCSP properties
+        if (seekResponderCert) {
+            throw new CertPathValidatorException(
+                "Cannot find the responder's certificate " +
+                "(set using the OCSP security properties).");
+        }
 
-            while (total < contentLength) {
-                int count = in.read(response, total, response.length - total);
-                if (count < 0)
-                    break;
-
-                total += count;
-                if (total >= response.length && total < contentLength) {
-                    response = Arrays.copyOf(response, total * 2);
-                }
-            }
-            response = Arrays.copyOf(response, total);
-
-            OCSPResponse ocspResponse = new OCSPResponse(response, pkixParams,
-                responderCert);
-            // Check that response applies to the cert that was supplied
-            if (! certId.equals(ocspResponse.getCertId())) {
-                throw new CertPathValidatorException(
-                    "Certificate in the OCSP response does not match the " +
-                    "certificate supplied in the OCSP request.");
-            }
-            SerialNumber serialNumber = currCertImpl.getSerialNumberObject();
-            int certOCSPStatus = ocspResponse.getCertStatus(serialNumber);
-
-            if (DEBUG != null) {
-                DEBUG.println("Status of certificate (with serial number " +
-                    serialNumber.getNumber() + ") is: " +
-                    OCSPResponse.certStatusToText(certOCSPStatus));
-            }
+        CertId certId = null;
+        OCSPResponse response = null;
+        try {
+            certId = new CertId
+                (issuerCert, currCertImpl.getSerialNumberObject());
+            response = OCSP.check(Collections.singletonList(certId), uri,
+                responderCert, pkixParams.getDate());
+        } catch (IOException ioe) {
+            // should allow this to pass if network failures are acceptable
+            throw new CertPathValidatorException
+                ("Unable to send OCSP request", ioe);
+        }
 
-            if (certOCSPStatus == OCSPResponse.CERT_STATUS_REVOKED) {
-                Throwable t = new CertificateRevokedException(
-                        ocspResponse.getRevocationTime(),
-                        ocspResponse.getRevocationReason(),
-                        responderCert.getSubjectX500Principal(),
-                        ocspResponse.getSingleExtensions());
-                throw new CertPathValidatorException(t.getMessage(), t,
-                        null, -1, BasicReason.REVOKED);
-
-            } else if (certOCSPStatus == OCSPResponse.CERT_STATUS_UNKNOWN) {
-                throw new CertPathValidatorException(
-                    "Certificate's revocation status is unknown", null, cp,
-                    remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS);
-            }
-        } catch (Exception e) {
-            throw new CertPathValidatorException(e);
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException ioe) {
-                    throw new CertPathValidatorException(ioe);
-                }
-            }
-            if (out != null) {
-                try {
-                    out.close();
-                } catch (IOException ioe) {
-                    throw new CertPathValidatorException(ioe);
-                }
-            }
+        RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId);
+        RevocationStatus.CertStatus certStatus = rs.getCertStatus();
+        if (certStatus == RevocationStatus.CertStatus.REVOKED) {
+            Throwable t = new CertificateRevokedException(
+                rs.getRevocationTime(), rs.getRevocationReason(),
+                responderCert.getSubjectX500Principal(),
+                rs.getSingleExtensions());
+            throw new CertPathValidatorException(t.getMessage(), t,
+                null, -1, BasicReason.REVOKED);
+        } else if (certStatus == RevocationStatus.CertStatus.UNKNOWN) {
+            throw new CertPathValidatorException(
+                "Certificate's revocation status is unknown", null, cp,
+                remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS);
         }
     }
 
@@ -431,20 +364,18 @@
      *   3. ocsp.responderCertIssuerName
      *   4. ocsp.responderCertSerialNumber
      */
-    private static URL getOCSPServerURL(X509CertImpl currCertImpl,
-        String[] properties)
-        throws CertificateParsingException, CertPathValidatorException {
+    private static URI getOCSPServerURI(X509CertImpl currCertImpl,
+        String responderURL) throws CertPathValidatorException {
 
-        if (properties[0] != null) {
-           try {
-                return new URL(properties[0]);
-           } catch (java.net.MalformedURLException e) {
+        if (responderURL != null) {
+            try {
+                return new URI(responderURL);
+            } catch (URISyntaxException e) {
                 throw new CertPathValidatorException(e);
-           }
+            }
         }
 
         // Examine the certificate's AuthorityInfoAccess extension
-
         AuthorityInfoAccessExtension aia =
             currCertImpl.getAuthorityInfoAccessExtension();
         if (aia == null) {
@@ -459,13 +390,8 @@
 
                 GeneralName generalName = description.getAccessLocation();
                 if (generalName.getType() == GeneralNameInterface.NAME_URI) {
-                    try {
-                        URIName uri = (URIName) generalName.getName();
-                        return (new URL(uri.getName()));
-
-                    } catch (java.net.MalformedURLException e) {
-                        throw new CertPathValidatorException(e);
-                    }
+                    URIName uri = (URIName) generalName.getName();
+                    return uri.getURI();
                 }
             }
         }
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPRequest.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPRequest.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,9 @@
 package sun.security.provider.certpath;
 
 import java.io.IOException;
-import java.security.cert.CertPathValidatorException;
+import java.util.Collections;
+import java.util.List;
 import sun.misc.HexDumpEncoder;
-import sun.security.x509.*;
 import sun.security.util.*;
 
 /**
@@ -77,47 +77,33 @@
     private static final Debug debug = Debug.getInstance("certpath");
     private static final boolean dump = false;
 
-    // Serial number of the certificates to be checked for revocation
-    private SerialNumber serialNumber;
-
-    // Issuer's certificate (for computing certId hash values)
-    private X509CertImpl issuerCert;
-
-    // CertId of the certificate to be checked
-    private CertId certId = null;
+    // List of request CertIds
+    private final List<CertId> certIds;
 
     /*
      * Constructs an OCSPRequest. This constructor is used
      * to construct an unsigned OCSP Request for a single user cert.
      */
-    // used by OCSPChecker
-    OCSPRequest(X509CertImpl userCert, X509CertImpl issuerCert)
-        throws CertPathValidatorException {
-
-        if (issuerCert == null) {
-            throw new CertPathValidatorException("Null IssuerCertificate");
-        }
-        this.issuerCert = issuerCert;
-        serialNumber = userCert.getSerialNumberObject();
+    OCSPRequest(CertId certId) {
+        this.certIds = Collections.singletonList(certId);
     }
 
-    // used by OCSPChecker
+    OCSPRequest(List<CertId> certIds) {
+        this.certIds = certIds;
+    }
+
     byte[] encodeBytes() throws IOException {
 
         // encode tbsRequest
         DerOutputStream tmp = new DerOutputStream();
-        DerOutputStream derSingleReqList  = new DerOutputStream();
-        SingleRequest singleRequest = null;
-
-        try {
-            singleRequest = new SingleRequest(issuerCert, serialNumber);
-        } catch (Exception e) {
-            throw new IOException("Error encoding OCSP request");
+        DerOutputStream requestsOut = new DerOutputStream();
+        for (CertId certId : certIds) {
+            DerOutputStream certIdOut = new DerOutputStream();
+            certId.encode(certIdOut);
+            requestsOut.write(DerValue.tag_Sequence, certIdOut);
         }
 
-        certId = singleRequest.getCertId();
-        singleRequest.encode(derSingleReqList);
-        tmp.write(DerValue.tag_Sequence, derSingleReqList);
+        tmp.write(DerValue.tag_Sequence, requestsOut);
         // No extensions supported
         DerOutputStream tbsRequest = new DerOutputStream();
         tbsRequest.write(DerValue.tag_Sequence, tmp);
@@ -130,35 +116,14 @@
 
         if (dump) {
             HexDumpEncoder hexEnc = new HexDumpEncoder();
-            System.out.println ("OCSPRequest bytes are... ");
+            System.out.println("OCSPRequest bytes are... ");
             System.out.println(hexEnc.encode(bytes));
         }
 
-        return(bytes);
-    }
-
-    // used by OCSPChecker
-    CertId getCertId() {
-        return certId;
+        return bytes;
     }
 
-    private static class SingleRequest {
-        private CertId certId;
-
-        // No extensions are set
-
-        private SingleRequest(X509CertImpl cert, SerialNumber serialNo) throws Exception {
-            certId = new CertId(cert, serialNo);
-        }
-
-        private void encode(DerOutputStream out) throws IOException {
-            DerOutputStream tmp = new DerOutputStream();
-            certId.encode(tmp);
-            out.write(DerValue.tag_Sequence, tmp);
-        }
-
-        private CertId getCertId() {
-            return certId;
-        }
+    List<CertId> getCertIds() {
+        return certIds;
     }
 }
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java	Wed Jul 05 17:01:15 2017 +0200
@@ -28,17 +28,16 @@
 import java.io.*;
 import java.math.BigInteger;
 import java.security.*;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.CRLReason;
 import java.security.cert.X509Certificate;
-import java.security.cert.PKIXParameters;
-import javax.security.auth.x500.X500Principal;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
 import sun.misc.HexDumpEncoder;
 import sun.security.x509.*;
 import sun.security.util.*;
@@ -113,32 +112,29 @@
  * @author      Ram Marti
  */
 
-class OCSPResponse {
+public final class OCSPResponse {
 
-    // Certificate status CHOICE
-    public static final int CERT_STATUS_GOOD = 0;
-    public static final int CERT_STATUS_REVOKED = 1;
-    public static final int CERT_STATUS_UNKNOWN = 2;
+    public enum ResponseStatus {
+        SUCCESSFUL,            // Response has valid confirmations
+        MALFORMED_REQUEST,     // Illegal confirmation request
+        INTERNAL_ERROR,        // Internal error in issuer
+        TRY_LATER,             // Try again later
+        UNUSED,                // is not used
+        SIG_REQUIRED,          // Must sign the request
+        UNAUTHORIZED           // Request unauthorized
+    };
+    private static ResponseStatus[] rsvalues = ResponseStatus.values();
 
     private static final Debug DEBUG = Debug.getInstance("certpath");
     private static final boolean dump = false;
-    private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID;
-    private static final ObjectIdentifier OCSP_NONCE_EXTENSION_OID;
-    static {
-        ObjectIdentifier tmp1 = null;
-        ObjectIdentifier tmp2 = null;
-        try {
-            tmp1 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.1");
-            tmp2 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.2");
-        } catch (Exception e) {
-            // should not happen; log and exit
-        }
-        OCSP_BASIC_RESPONSE_OID = tmp1;
-        OCSP_NONCE_EXTENSION_OID = tmp2;
-    }
+    private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID =
+        ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 1});
+    private static final ObjectIdentifier OCSP_NONCE_EXTENSION_OID =
+        ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 2});
 
-    // OCSP response status code
-    private static final int OCSP_RESPONSE_OK = 0;
+    private static final int CERT_STATUS_GOOD = 0;
+    private static final int CERT_STATUS_REVOKED = 1;
+    private static final int CERT_STATUS_UNKNOWN = 2;
 
     // ResponderID CHOICE tags
     private static final int NAME_TAG = 1;
@@ -147,7 +143,8 @@
     // Object identifier for the OCSPSigning key purpose
     private static final String KP_OCSP_SIGNING_OID = "1.3.6.1.5.5.7.3.9";
 
-    private SingleResponse singleResponse;
+    private final ResponseStatus responseStatus;
+    private final Map<CertId, SingleResponse> singleResponseMap;
 
     // Maximum clock skew in milliseconds (15 minutes) allowed when checking
     // validity of OCSP responses
@@ -159,301 +156,300 @@
     /*
      * Create an OCSP response from its ASN.1 DER encoding.
      */
-    // used by OCSPChecker
-    OCSPResponse(byte[] bytes, PKIXParameters params,
+    OCSPResponse(byte[] bytes, Date dateCheckedAgainst,
         X509Certificate responderCert)
         throws IOException, CertPathValidatorException {
 
-        try {
-            int responseStatus;
-            ObjectIdentifier  responseType;
-            int version;
-            CertificateIssuerName responderName = null;
-            Date producedAtDate;
-            AlgorithmId sigAlgId;
-            byte[] ocspNonce;
+        // OCSPResponse
+        if (dump) {
+            HexDumpEncoder hexEnc = new HexDumpEncoder();
+            System.out.println("OCSPResponse bytes are...");
+            System.out.println(hexEnc.encode(bytes));
+        }
+        DerValue der = new DerValue(bytes);
+        if (der.tag != DerValue.tag_Sequence) {
+            throw new IOException("Bad encoding in OCSP response: " +
+                "expected ASN.1 SEQUENCE tag.");
+        }
+        DerInputStream derIn = der.getData();
 
-            // OCSPResponse
-            if (dump) {
-                HexDumpEncoder hexEnc = new HexDumpEncoder();
-                System.out.println("OCSPResponse bytes are...");
-                System.out.println(hexEnc.encode(bytes));
-            }
-            DerValue der = new DerValue(bytes);
-            if (der.tag != DerValue.tag_Sequence) {
-                throw new IOException("Bad encoding in OCSP response: " +
-                    "expected ASN.1 SEQUENCE tag.");
-            }
-            DerInputStream derIn = der.getData();
-
-            // responseStatus
-            responseStatus = derIn.getEnumerated();
-            if (DEBUG != null) {
-                DEBUG.println("OCSP response: " +
-                    responseToText(responseStatus));
-            }
-            if (responseStatus != OCSP_RESPONSE_OK) {
-                throw new CertPathValidatorException(
-                    "OCSP Response Failure: " +
-                        responseToText(responseStatus));
-            }
+        // responseStatus
+        int status = derIn.getEnumerated();
+        if (status >= 0 && status < rsvalues.length) {
+            responseStatus = rsvalues[status];
+        } else {
+            // unspecified responseStatus
+            throw new IOException("Unknown OCSPResponse status: " + status);
+        }
+        if (DEBUG != null) {
+            DEBUG.println("OCSP response status: " + responseStatus);
+        }
+        if (responseStatus != ResponseStatus.SUCCESSFUL) {
+            // no need to continue, responseBytes are not set.
+            singleResponseMap = Collections.emptyMap();
+            return;
+        }
 
-            // responseBytes
-            der = derIn.getDerValue();
-            if (! der.isContextSpecific((byte)0)) {
-                throw new IOException("Bad encoding in responseBytes element " +
-                    "of OCSP response: expected ASN.1 context specific tag 0.");
-            };
-            DerValue tmp = der.data.getDerValue();
-            if (tmp.tag != DerValue.tag_Sequence) {
-                throw new IOException("Bad encoding in responseBytes element " +
-                    "of OCSP response: expected ASN.1 SEQUENCE tag.");
-            }
+        // responseBytes
+        der = derIn.getDerValue();
+        if (!der.isContextSpecific((byte)0)) {
+            throw new IOException("Bad encoding in responseBytes element " +
+                "of OCSP response: expected ASN.1 context specific tag 0.");
+        }
+        DerValue tmp = der.data.getDerValue();
+        if (tmp.tag != DerValue.tag_Sequence) {
+            throw new IOException("Bad encoding in responseBytes element " +
+                "of OCSP response: expected ASN.1 SEQUENCE tag.");
+        }
 
-            // responseType
-            derIn = tmp.data;
-            responseType = derIn.getOID();
-            if (responseType.equals(OCSP_BASIC_RESPONSE_OID)) {
-                if (DEBUG != null) {
-                    DEBUG.println("OCSP response type: basic");
-                }
-            } else {
-                if (DEBUG != null) {
-                    DEBUG.println("OCSP response type: " + responseType);
-                }
-                throw new IOException("Unsupported OCSP response type: " +
-                    responseType);
+        // responseType
+        derIn = tmp.data;
+        ObjectIdentifier responseType = derIn.getOID();
+        if (responseType.equals(OCSP_BASIC_RESPONSE_OID)) {
+            if (DEBUG != null) {
+                DEBUG.println("OCSP response type: basic");
+            }
+        } else {
+            if (DEBUG != null) {
+                DEBUG.println("OCSP response type: " + responseType);
             }
+            throw new IOException("Unsupported OCSP response type: " +
+                responseType);
+        }
 
-            // BasicOCSPResponse
-            DerInputStream basicOCSPResponse =
-                new DerInputStream(derIn.getOctetString());
+        // BasicOCSPResponse
+        DerInputStream basicOCSPResponse =
+            new DerInputStream(derIn.getOctetString());
 
-            DerValue[]  seqTmp = basicOCSPResponse.getSequence(2);
-            DerValue responseData = seqTmp[0];
+        DerValue[] seqTmp = basicOCSPResponse.getSequence(2);
+        if (seqTmp.length < 3) {
+            throw new IOException("Unexpected BasicOCSPResponse value");
+        }
 
-            // Need the DER encoded ResponseData to verify the signature later
-            byte[] responseDataDer = seqTmp[0].toByteArray();
+        DerValue responseData = seqTmp[0];
+
+        // Need the DER encoded ResponseData to verify the signature later
+        byte[] responseDataDer = seqTmp[0].toByteArray();
 
-            // tbsResponseData
-            if (responseData.tag != DerValue.tag_Sequence) {
-                throw new IOException("Bad encoding in tbsResponseData " +
-                    " element of OCSP response: expected ASN.1 SEQUENCE tag.");
-            }
-            DerInputStream seqDerIn = responseData.data;
-            DerValue seq = seqDerIn.getDerValue();
+        // tbsResponseData
+        if (responseData.tag != DerValue.tag_Sequence) {
+            throw new IOException("Bad encoding in tbsResponseData " +
+                "element of OCSP response: expected ASN.1 SEQUENCE tag.");
+        }
+        DerInputStream seqDerIn = responseData.data;
+        DerValue seq = seqDerIn.getDerValue();
 
-            // version
-            if (seq.isContextSpecific((byte)0)) {
-                // seq[0] is version
-                if (seq.isConstructed() && seq.isContextSpecific()) {
-                    //System.out.println ("version is available");
-                    seq = seq.data.getDerValue();
-                    version = seq.getInteger();
-                    if (seq.data.available() != 0) {
-                        throw new IOException("Bad encoding in version " +
-                            " element of OCSP response: bad format");
-                    }
-                    seq = seqDerIn.getDerValue();
-                }
-            }
-
-            // responderID
-            short tag = (byte)(seq.tag & 0x1f);
-            if (tag == NAME_TAG) {
-                responderName = new CertificateIssuerName(seq.getData());
-                if (DEBUG != null) {
-                    DEBUG.println("OCSP Responder name: " + responderName);
+        // version
+        if (seq.isContextSpecific((byte)0)) {
+            // seq[0] is version
+            if (seq.isConstructed() && seq.isContextSpecific()) {
+                //System.out.println ("version is available");
+                seq = seq.data.getDerValue();
+                int version = seq.getInteger();
+                if (seq.data.available() != 0) {
+                    throw new IOException("Bad encoding in version " +
+                        " element of OCSP response: bad format");
                 }
-            } else if (tag == KEY_TAG) {
-                // Ignore, for now
-            } else {
-                throw new IOException("Bad encoding in responderID element " +
-                    "of OCSP response: expected ASN.1 context specific tag 0 " +
-                    "or 1");
+                seq = seqDerIn.getDerValue();
             }
+        }
 
-            // producedAt
-            seq = seqDerIn.getDerValue();
-            producedAtDate = seq.getGeneralizedTime();
+        // responderID
+        short tag = (byte)(seq.tag & 0x1f);
+        if (tag == NAME_TAG) {
+            if (DEBUG != null) {
+                X500Name responderName = new X500Name(seq.getData());
+                DEBUG.println("OCSP Responder name: " + responderName);
+            }
+        } else if (tag == KEY_TAG) {
+            // Ignore, for now
+        } else {
+            throw new IOException("Bad encoding in responderID element of " +
+                "OCSP response: expected ASN.1 context specific tag 0 or 1");
+        }
 
-            // responses
-            DerValue[] singleResponseDer = seqDerIn.getSequence(1);
-            // Examine only the first response
-            singleResponse = new SingleResponse(singleResponseDer[0]);
+        // producedAt
+        seq = seqDerIn.getDerValue();
+        if (DEBUG != null) {
+            Date producedAtDate = seq.getGeneralizedTime();
+            DEBUG.println("OCSP response produced at: " + producedAtDate);
+        }
 
-            // responseExtensions
-            if (seqDerIn.available() > 0) {
-                seq = seqDerIn.getDerValue();
-                if (seq.isContextSpecific((byte)1)) {
-                    DerValue[]  responseExtDer = seq.data.getSequence(3);
-                    Extension[] responseExtension =
-                        new Extension[responseExtDer.length];
-                    for (int i = 0; i < responseExtDer.length; i++) {
-                        responseExtension[i] = new Extension(responseExtDer[i]);
-                        if (DEBUG != null) {
-                            DEBUG.println("OCSP extension: " +
-                                responseExtension[i]);
-                        }
-                        if ((responseExtension[i].getExtensionId()).equals(
-                            OCSP_NONCE_EXTENSION_OID)) {
-                            ocspNonce =
-                                responseExtension[i].getExtensionValue();
+        // responses
+        DerValue[] singleResponseDer = seqDerIn.getSequence(1);
+        singleResponseMap
+            = new HashMap<CertId, SingleResponse>(singleResponseDer.length);
+        if (DEBUG != null) {
+            DEBUG.println("OCSP number of SingleResponses: "
+                + singleResponseDer.length);
+        }
+        for (int i = 0; i < singleResponseDer.length; i++) {
+            SingleResponse singleResponse
+                = new SingleResponse(singleResponseDer[i]);
+            singleResponseMap.put(singleResponse.getCertId(), singleResponse);
+        }
 
-                        } else if (responseExtension[i].isCritical())  {
-                            throw new IOException(
-                                "Unsupported OCSP critical extension: " +
-                                responseExtension[i].getExtensionId());
-                        }
+        // responseExtensions
+        if (seqDerIn.available() > 0) {
+            seq = seqDerIn.getDerValue();
+            if (seq.isContextSpecific((byte)1)) {
+                DerValue[] responseExtDer = seq.data.getSequence(3);
+                for (int i = 0; i < responseExtDer.length; i++) {
+                    Extension responseExtension
+                        = new Extension(responseExtDer[i]);
+                    if (DEBUG != null) {
+                        DEBUG.println("OCSP extension: " + responseExtension);
+                    }
+                    if (responseExtension.getExtensionId().equals(
+                        OCSP_NONCE_EXTENSION_OID)) {
+                        /*
+                        ocspNonce =
+                            responseExtension[i].getExtensionValue();
+                         */
+                    } else if (responseExtension.isCritical())  {
+                        throw new IOException(
+                            "Unsupported OCSP critical extension: " +
+                            responseExtension.getExtensionId());
                     }
                 }
             }
-
-            // signatureAlgorithmId
-            sigAlgId = AlgorithmId.parse(seqTmp[1]);
+        }
 
-            // signature
-            byte[] signature = seqTmp[2].getBitString();
-            X509CertImpl[] x509Certs = null;
+        // signatureAlgorithmId
+        AlgorithmId sigAlgId = AlgorithmId.parse(seqTmp[1]);
+
+        // signature
+        byte[] signature = seqTmp[2].getBitString();
+        X509CertImpl[] x509Certs = null;
 
-            // if seq[3] is available , then it is a sequence of certificates
-            if (seqTmp.length > 3) {
-                // certs are available
-                DerValue seqCert = seqTmp[3];
-                if (! seqCert.isContextSpecific((byte)0)) {
-                    throw new IOException("Bad encoding in certs element " +
-                    "of OCSP response: expected ASN.1 context specific tag 0.");
-                }
-                DerValue[] certs = (seqCert.getData()).getSequence(3);
-                x509Certs = new X509CertImpl[certs.length];
+        // if seq[3] is available , then it is a sequence of certificates
+        if (seqTmp.length > 3) {
+            // certs are available
+            DerValue seqCert = seqTmp[3];
+            if (!seqCert.isContextSpecific((byte)0)) {
+                throw new IOException("Bad encoding in certs element of " +
+                    "OCSP response: expected ASN.1 context specific tag 0.");
+            }
+            DerValue[] certs = seqCert.getData().getSequence(3);
+            x509Certs = new X509CertImpl[certs.length];
+            try {
                 for (int i = 0; i < certs.length; i++) {
                     x509Certs[i] = new X509CertImpl(certs[i].toByteArray());
                 }
+            } catch (CertificateException ce) {
+                throw new IOException("Bad encoding in X509 Certificate", ce);
             }
+        }
 
-            // Check whether the cert returned by the responder is trusted
-            if (x509Certs != null && x509Certs[0] != null) {
-                X509CertImpl cert = x509Certs[0];
+        // Check whether the cert returned by the responder is trusted
+        if (x509Certs != null && x509Certs[0] != null) {
+            X509CertImpl cert = x509Certs[0];
 
-                // First check if the cert matches the responder cert which
-                // was set locally.
-                if (cert.equals(responderCert)) {
-                    // cert is trusted, now verify the signed response
+            // First check if the cert matches the responder cert which
+            // was set locally.
+            if (cert.equals(responderCert)) {
+                // cert is trusted, now verify the signed response
 
-                // Next check if the cert was issued by the responder cert
-                // which was set locally.
-                } else if (cert.getIssuerX500Principal().equals(
-                    responderCert.getSubjectX500Principal())) {
+            // Next check if the cert was issued by the responder cert
+            // which was set locally.
+            } else if (cert.getIssuerX500Principal().equals(
+                responderCert.getSubjectX500Principal())) {
 
-                    // Check for the OCSPSigning key purpose
+                // Check for the OCSPSigning key purpose
+                try {
                     List<String> keyPurposes = cert.getExtendedKeyUsage();
                     if (keyPurposes == null ||
                         !keyPurposes.contains(KP_OCSP_SIGNING_OID)) {
-                        if (DEBUG != null) {
-                            DEBUG.println("Responder's certificate is not " +
-                                "valid for signing OCSP responses.");
-                        }
                         throw new CertPathValidatorException(
                             "Responder's certificate not valid for signing " +
                             "OCSP responses");
                     }
-
-                    // check the validity
-                    try {
-                        Date dateCheckedAgainst = params.getDate();
-                        if (dateCheckedAgainst == null) {
-                            cert.checkValidity();
-                        } else {
-                            cert.checkValidity(dateCheckedAgainst);
-                        }
-                    } catch (GeneralSecurityException e) {
-                        if (DEBUG != null) {
-                            DEBUG.println("Responder's certificate is not " +
-                                "within the validity period.");
-                        }
-                        throw new CertPathValidatorException(
-                            "Responder's certificate not within the " +
-                            "validity period");
-                    }
+                } catch (CertificateParsingException cpe) {
+                    // assume cert is not valid for signing
+                    throw new CertPathValidatorException(
+                        "Responder's certificate not valid for signing " +
+                        "OCSP responses", cpe);
+                }
 
-                    // check for revocation
-                    //
-                    // A CA may specify that an OCSP client can trust a
-                    // responder for the lifetime of the responder's
-                    // certificate. The CA does so by including the
-                    // extension id-pkix-ocsp-nocheck.
-                    //
-                    Extension noCheck =
-                            cert.getExtension(PKIXExtensions.OCSPNoCheck_Id);
-                    if (noCheck != null) {
-                        if (DEBUG != null) {
-                            DEBUG.println("Responder's certificate includes " +
-                                "the extension id-pkix-ocsp-nocheck.");
-                        }
+                // check the validity
+                try {
+                    if (dateCheckedAgainst == null) {
+                        cert.checkValidity();
                     } else {
-                        // we should do the revocating checking of the
-                        // authorized responder in a future update.
+                        cert.checkValidity(dateCheckedAgainst);
                     }
+                } catch (GeneralSecurityException e) {
+                    throw new CertPathValidatorException(
+                        "Responder's certificate not within the " +
+                        "validity period", e);
+                }
 
-                    // verify the signature
-                    try {
-                        cert.verify(responderCert.getPublicKey());
-                        responderCert = cert;
-                        // cert is trusted, now verify the signed response
-
-                    } catch (GeneralSecurityException e) {
-                        responderCert = null;
+                // check for revocation
+                //
+                // A CA may specify that an OCSP client can trust a
+                // responder for the lifetime of the responder's
+                // certificate. The CA does so by including the
+                // extension id-pkix-ocsp-nocheck.
+                //
+                Extension noCheck =
+                    cert.getExtension(PKIXExtensions.OCSPNoCheck_Id);
+                if (noCheck != null) {
+                    if (DEBUG != null) {
+                        DEBUG.println("Responder's certificate includes " +
+                            "the extension id-pkix-ocsp-nocheck.");
                     }
                 } else {
-                    if (DEBUG != null) {
-                        DEBUG.println("Responder's certificate is not " +
-                            "authorized to sign OCSP responses.");
-                    }
-                    throw new CertPathValidatorException(
-                        "Responder's certificate not authorized to sign " +
-                        "OCSP responses");
+                    // we should do the revocation checking of the
+                    // authorized responder in a future update.
                 }
-            }
 
-            // Confirm that the signed response was generated using the public
-            // key from the trusted responder cert
-            if (responderCert != null) {
+                // verify the signature
+                try {
+                    cert.verify(responderCert.getPublicKey());
+                    responderCert = cert;
+                    // cert is trusted, now verify the signed response
 
-                if (! verifyResponse(responseDataDer, responderCert,
-                    sigAlgId, signature, params)) {
-                    if (DEBUG != null) {
-                        DEBUG.println("Error verifying OCSP Responder's " +
-                            "signature");
-                    }
-                    throw new CertPathValidatorException(
-                        "Error verifying OCSP Responder's signature");
+                } catch (GeneralSecurityException e) {
+                    responderCert = null;
                 }
             } else {
-                // Need responder's cert in order to verify the signature
-                if (DEBUG != null) {
-                    DEBUG.println("Unable to verify OCSP Responder's " +
-                        "signature");
-                }
+                throw new CertPathValidatorException(
+                    "Responder's certificate is not authorized to sign " +
+                    "OCSP responses");
+            }
+        }
+
+        // Confirm that the signed response was generated using the public
+        // key from the trusted responder cert
+        if (responderCert != null) {
+            if (!verifyResponse(responseDataDer, responderCert,
+                sigAlgId, signature)) {
                 throw new CertPathValidatorException(
-                    "Unable to verify OCSP Responder's signature");
+                    "Error verifying OCSP Responder's signature");
             }
-        } catch (CertPathValidatorException cpve) {
-            throw cpve;
-        } catch (Exception e) {
-            throw new CertPathValidatorException(e);
+        } else {
+            // Need responder's cert in order to verify the signature
+            throw new CertPathValidatorException(
+                "Unable to verify OCSP Responder's signature");
         }
     }
 
+    /**
+     * Returns the OCSP ResponseStatus.
+     */
+    ResponseStatus getResponseStatus() {
+        return responseStatus;
+    }
+
     /*
      * Verify the signature of the OCSP response.
      * The responder's cert is implicitly trusted.
      */
     private boolean verifyResponse(byte[] responseData, X509Certificate cert,
-        AlgorithmId sigAlgId, byte[] signBytes, PKIXParameters params)
-        throws SignatureException {
+        AlgorithmId sigAlgId, byte[] signBytes)
+        throws CertPathValidatorException {
 
         try {
-
             Signature respSignature = Signature.getInstance(sigAlgId.getName());
             respSignature.initVerify(cert);
             respSignature.update(responseData);
@@ -472,92 +468,33 @@
                 return false;
             }
         } catch (InvalidKeyException ike) {
-            throw new SignatureException(ike);
-
+            throw new CertPathValidatorException(ike);
         } catch (NoSuchAlgorithmException nsae) {
-            throw new SignatureException(nsae);
+            throw new CertPathValidatorException(nsae);
+        } catch (SignatureException se) {
+            throw new CertPathValidatorException(se);
         }
     }
 
-    /*
-     * Return the revocation status code for a given certificate.
-     */
-    // used by OCSPChecker
-    int getCertStatus(SerialNumber sn) {
-        // ignore serial number for now; if we support multiple
-        // requests/responses then it will be used
-        return singleResponse.getStatus();
-    }
-
-    // used by OCSPChecker
-    CertId getCertId() {
-        return singleResponse.getCertId();
-    }
-
-    Date getRevocationTime() {
-        return singleResponse.getRevocationTime();
-    }
-
-    CRLReason getRevocationReason() {
-        return singleResponse.getRevocationReason();
-    }
-
-    Map<String, java.security.cert.Extension> getSingleExtensions() {
-        return singleResponse.getSingleExtensions();
-    }
-
-    /*
-     * Map an OCSP response status code to a string.
+    /**
+     * Returns the SingleResponse of the specified CertId, or null if
+     * there is no response for that CertId.
      */
-    static private String responseToText(int status) {
-        switch (status)  {
-        case 0:
-            return "Successful";
-        case 1:
-            return "Malformed request";
-        case 2:
-            return "Internal error";
-        case 3:
-            return "Try again later";
-        case 4:
-            return "Unused status code";
-        case 5:
-            return "Request must be signed";
-        case 6:
-            return "Request is unauthorized";
-        default:
-            return ("Unknown status code: " + status);
-        }
-    }
-
-    /*
-     * Map a certificate's revocation status code to a string.
-     */
-    // used by OCSPChecker
-    static String certStatusToText(int certStatus) {
-        switch (certStatus)  {
-        case 0:
-            return "Good";
-        case 1:
-            return "Revoked";
-        case 2:
-            return "Unknown";
-        default:
-            return ("Unknown certificate status code: " + certStatus);
-        }
+    SingleResponse getSingleResponse(CertId certId) {
+        return singleResponseMap.get(certId);
     }
 
     /*
      * A class representing a single OCSP response.
      */
-    private class SingleResponse {
-        private CertId certId;
-        private int certStatus;
-        private Date thisUpdate;
-        private Date nextUpdate;
-        private Date revocationTime;
-        private CRLReason revocationReason = CRLReason.UNSPECIFIED;
-        private HashMap<String, java.security.cert.Extension> singleExtensions;
+    final static class SingleResponse implements OCSP.RevocationStatus {
+        private final CertId certId;
+        private final CertStatus certStatus;
+        private final Date thisUpdate;
+        private final Date nextUpdate;
+        private final Date revocationTime;
+        private final CRLReason revocationReason;
+        private final Map<String, java.security.cert.Extension> singleExtensions;
 
         private SingleResponse(DerValue der) throws IOException {
             if (der.tag != DerValue.tag_Sequence) {
@@ -568,35 +505,48 @@
             certId = new CertId(tmp.getDerValue().data);
             DerValue derVal = tmp.getDerValue();
             short tag = (byte)(derVal.tag & 0x1f);
-            if (tag ==  CERT_STATUS_GOOD) {
-                certStatus = CERT_STATUS_GOOD;
-            } else if (tag == CERT_STATUS_REVOKED) {
-                certStatus = CERT_STATUS_REVOKED;
+            if (tag ==  CERT_STATUS_REVOKED) {
+                certStatus = CertStatus.REVOKED;
                 revocationTime = derVal.data.getGeneralizedTime();
                 if (derVal.data.available() != 0) {
-                    int reason = derVal.getEnumerated();
-                    // if reason out-of-range just leave as UNSPECIFIED
-                    if (reason >= 0 && reason < values.length) {
-                        revocationReason = values[reason];
+                    DerValue dv = derVal.data.getDerValue();
+                    tag = (byte)(dv.tag & 0x1f);
+                    if (tag == 0) {
+                        int reason = dv.data.getEnumerated();
+                        // if reason out-of-range just leave as UNSPECIFIED
+                        if (reason >= 0 && reason < values.length) {
+                            revocationReason = values[reason];
+                        } else {
+                            revocationReason = CRLReason.UNSPECIFIED;
+                        }
+                    } else {
+                        revocationReason = CRLReason.UNSPECIFIED;
                     }
+                } else {
+                    revocationReason = CRLReason.UNSPECIFIED;
                 }
                 // RevokedInfo
                 if (DEBUG != null) {
                     DEBUG.println("Revocation time: " + revocationTime);
                     DEBUG.println("Revocation reason: " + revocationReason);
                 }
-
-            } else if (tag == CERT_STATUS_UNKNOWN) {
-                certStatus = CERT_STATUS_UNKNOWN;
-
             } else {
-                throw new IOException("Invalid certificate status");
+                revocationTime = null;
+                revocationReason = CRLReason.UNSPECIFIED;
+                if (tag == CERT_STATUS_GOOD) {
+                    certStatus = CertStatus.GOOD;
+                } else if (tag == CERT_STATUS_UNKNOWN) {
+                    certStatus = CertStatus.UNKNOWN;
+                } else {
+                    throw new IOException("Invalid certificate status");
+                }
             }
 
             thisUpdate = tmp.getGeneralizedTime();
 
             if (tmp.available() == 0)  {
                 // we are done
+                nextUpdate = null;
             } else {
                 derVal = tmp.getDerValue();
                 tag = (byte)(derVal.tag & 0x1f);
@@ -610,6 +560,8 @@
                         derVal = tmp.getDerValue();
                         tag = (byte)(derVal.tag & 0x1f);
                     }
+                } else {
+                    nextUpdate = null;
                 }
             }
             // singleExtensions
@@ -627,7 +579,11 @@
                             DEBUG.println("OCSP single extension: " + ext);
                         }
                     }
+                } else {
+                    singleExtensions = Collections.emptyMap();
                 }
+            } else {
+                singleExtensions = Collections.emptyMap();
             }
 
             long now = System.currentTimeMillis();
@@ -657,7 +613,7 @@
         /*
          * Return the certificate's revocation status code
          */
-        private int getStatus() {
+        @Override public CertStatus getCertStatus() {
             return certStatus;
         }
 
@@ -665,28 +621,28 @@
             return certId;
         }
 
-        private Date getRevocationTime() {
-            return revocationTime;
+        @Override public Date getRevocationTime() {
+            return (Date) revocationTime.clone();
         }
 
-        private CRLReason getRevocationReason() {
+        @Override public CRLReason getRevocationReason() {
             return revocationReason;
         }
 
-        private Map<String, java.security.cert.Extension> getSingleExtensions() {
-            return singleExtensions;
+        @Override
+        public Map<String, java.security.cert.Extension> getSingleExtensions() {
+            return Collections.unmodifiableMap(singleExtensions);
         }
 
         /**
          * Construct a string representation of a single OCSP response.
          */
-        public String toString() {
+        @Override public String toString() {
             StringBuilder sb = new StringBuilder();
             sb.append("SingleResponse:  \n");
             sb.append(certId);
-            sb.append("\nCertStatus: "+ certStatusToText(getCertStatus(null)) +
-                "\n");
-            if (certStatus == CERT_STATUS_REVOKED) {
+            sb.append("\nCertStatus: "+ certStatus + "\n");
+            if (certStatus == CertStatus.REVOKED) {
                 sb.append("revocationTime is " + revocationTime + "\n");
                 sb.append("revocationReason is " + revocationReason + "\n");
             }
--- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
 import java.io.IOException;
 import java.security.AccessController;
 import java.security.InvalidAlgorithmParameterException;
-import java.security.PrivilegedAction;
-import java.security.Security;
 import java.security.cert.CertPath;
 import java.security.cert.CertPathParameters;
 import java.security.cert.CertPathValidatorException;
@@ -49,6 +47,7 @@
 import java.util.Date;
 import java.util.Set;
 import javax.security.auth.x500.X500Principal;
+import sun.security.action.GetBooleanSecurityPropertyAction;
 import sun.security.util.Debug;
 
 /**
@@ -67,7 +66,8 @@
     private List<PKIXCertPathChecker> userCheckers;
     private String sigProvider;
     private BasicChecker basicChecker;
-    private String ocspProperty;
+    private boolean ocspEnabled = false;
+    private boolean onlyEECert = false;
 
     /**
      * Default constructor.
@@ -253,13 +253,12 @@
 
         if (pkixParam.isRevocationEnabled()) {
             // Examine OCSP security property
-            ocspProperty = AccessController.doPrivileged(
-                new PrivilegedAction<String>() {
-                    public String run() {
-                        return
-                            Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP);
-                    }
-                });
+            ocspEnabled = AccessController.doPrivileged(
+                new GetBooleanSecurityPropertyAction
+                    (OCSPChecker.OCSP_ENABLE_PROP));
+            onlyEECert = AccessController.doPrivileged(
+                new GetBooleanSecurityPropertyAction
+                    ("com.sun.security.onlyCheckRevocationOfEECert"));
         }
     }
 
@@ -301,15 +300,15 @@
         if (pkixParam.isRevocationEnabled()) {
 
             // Use OCSP if it has been enabled
-            if ("true".equalsIgnoreCase(ocspProperty)) {
+            if (ocspEnabled) {
                 OCSPChecker ocspChecker =
-                    new OCSPChecker(cpOriginal, pkixParam);
+                    new OCSPChecker(cpOriginal, pkixParam, onlyEECert);
                 certPathCheckers.add(ocspChecker);
             }
 
             // Always use CRLs
-            CrlRevocationChecker revocationChecker =
-                new CrlRevocationChecker(anchor, pkixParam, certList);
+            CrlRevocationChecker revocationChecker = new
+                CrlRevocationChecker(anchor, pkixParam, certList, onlyEECert);
             certPathCheckers.add(revocationChecker);
         }
 
--- a/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package sun.security.provider.certpath;
 
 import java.io.IOException;
+import java.security.AccessController;
 import java.security.GeneralSecurityException;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.Principal;
@@ -44,6 +45,7 @@
 import java.util.Set;
 import javax.security.auth.x500.X500Principal;
 
+import sun.security.action.GetBooleanSecurityPropertyAction;
 import sun.security.x509.X500Name;
 import sun.security.x509.PKIXExtensions;
 import sun.security.util.Debug;
@@ -85,6 +87,7 @@
     private PublicKey finalPublicKey;
     private X509CertSelector targetSel;
     private List<CertStore> orderedCertStores;
+    private boolean onlyEECert = false;
 
     /**
      * Create an instance of <code>SunCertPathBuilder</code>.
@@ -97,6 +100,9 @@
         } catch (CertificateException e) {
             throw new CertPathBuilderException(e);
         }
+        onlyEECert = AccessController.doPrivileged(
+            new GetBooleanSecurityPropertyAction
+                ("com.sun.security.onlyCheckRevocationOfEECert"));
     }
 
     /**
@@ -256,7 +262,6 @@
 
     /*
      * Private build reverse method.
-     *
      */
     private void buildReverse(List<List<Vertex>> adjacencyList,
         LinkedList<X509Certificate> certPathList) throws Exception
@@ -296,7 +301,7 @@
             currentState.updateState(anchor);
             // init the crl checker
             currentState.crlChecker =
-                new CrlRevocationChecker(null, buildParams);
+                new CrlRevocationChecker(null, buildParams, null, onlyEECert);
             try {
                 depthFirstSearchReverse(null, currentState,
                 new ReverseBuilder(buildParams, targetSubjectDN), adjacencyList,
@@ -341,10 +346,12 @@
         adjacencyList.add(new LinkedList<Vertex>());
 
         // init the crl checker
-        currentState.crlChecker = new CrlRevocationChecker(null, buildParams);
+        currentState.crlChecker
+            = new CrlRevocationChecker(null, buildParams, null, onlyEECert);
 
         depthFirstSearchForward(targetSubjectDN, currentState,
-          new ForwardBuilder(buildParams, targetSubjectDN, searchAllCertStores),
+          new ForwardBuilder
+              (buildParams, targetSubjectDN, searchAllCertStores, onlyEECert),
           adjacencyList, certPathList);
     }
 
@@ -486,8 +493,8 @@
                     userCheckers.add(mustCheck, basicChecker);
                     mustCheck++;
                     if (buildParams.isRevocationEnabled()) {
-                        userCheckers.add(mustCheck,
-                            new CrlRevocationChecker(anchor, buildParams));
+                        userCheckers.add(mustCheck, new CrlRevocationChecker
+                            (anchor, buildParams, null, onlyEECert));
                         mustCheck++;
                     }
                 }
--- a/jdk/src/share/classes/sun/security/x509/AccessDescription.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/x509/AccessDescription.java	Wed Jul 05 17:01:15 2017 +0200
@@ -113,7 +113,7 @@
         } else {
             method = accessMethod.toString();
         }
-        return ("accessMethod: " + method +
+        return ("\n   accessMethod: " + method +
                 "\n   accessLocation: " + accessLocation.toString() + "\n");
     }
 }
--- a/jdk/src/share/classes/sun/util/LocaleServiceProviderPool.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/util/LocaleServiceProviderPool.java	Wed Jul 05 17:01:15 2017 +0200
@@ -39,8 +39,8 @@
 import java.util.ServiceConfigurationError;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
 import java.util.spi.LocaleServiceProvider;
+import sun.util.logging.PlatformLogger;
 import sun.util.resources.LocaleData;
 import sun.util.resources.OpenListResourceBundle;
 
@@ -122,10 +122,15 @@
                 }
             });
         }  catch (PrivilegedActionException e) {
-            Logger.getLogger("sun.util.LocaleServiceProviderPool").config(e.toString());
+            config(e.toString());
         }
     }
 
+    private static void config(String message) {
+        PlatformLogger logger = PlatformLogger.getLogger("sun.util.LocaleServiceProviderPool");
+        logger.config(message);
+    }
+
     /**
      * Lazy loaded set of available locales.
      * Loading all locales is a very long operation.
@@ -337,7 +342,7 @@
                     if (providersObj != null) {
                         return providersObj;
                     } else if (isObjectProvider) {
-                        Logger.getLogger("sun.util.LocaleServiceProviderPool").config(
+                        config(
                             "A locale sensitive service provider returned null for a localized objects,  which should not happen.  provider: " + lsp + " locale: " + requested);
                     }
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,635 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+package sun.util.logging;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import sun.misc.JavaLangAccess;
+import sun.misc.SharedSecrets;
+
+/**
+ * Platform logger provides an API for the JRE components to log
+ * messages.  This enables the runtime components to eliminate the
+ * static dependency of the logging facility and also defers the
+ * java.util.logging initialization until it is enabled.
+ * In addition, the PlatformLogger API can be used if the logging
+ * module does not exist.
+ *
+ * If the logging facility is not enabled, the platform loggers
+ * will output log messages per the default logging configuration
+ * (see below). In this implementation, it does not log the
+ * the stack frame information issuing the log message.
+ *
+ * When the logging facility is enabled (at startup or runtime),
+ * the java.util.logging.Logger will be created for each platform
+ * logger and all log messages will be forwarded to the Logger
+ * to handle.
+ *
+ * Logging facility is "enabled" when one of the following
+ * conditions is met:
+ * 1) a system property "java.util.logging.config.class" or
+ *    "java.util.logging.config.file" is set
+ * 2) java.util.logging.LogManager or java.util.logging.Logger
+ *    is referenced that will trigger the logging initialization.
+ *
+ * Default logging configuration:
+ *   global logging level = INFO
+ *   handlers = java.util.logging.ConsoleHandler
+ *   java.util.logging.ConsoleHandler.level = INFO
+ *   java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+ *
+ * Limitation:
+ * <JAVA_HOME>/lib/logging.properties is the system-wide logging
+ * configuration defined in the specification and read in the
+ * default case to configure any java.util.logging.Logger instances.
+ * Platform loggers will not detect if <JAVA_HOME>/lib/logging.properties
+ * is modified. In other words, unless the java.util.logging API
+ * is used at runtime or the logging system properties is set,
+ * the platform loggers will use the default setting described above.
+ * The platform loggers are designed for JDK developers use and
+ * this limitation can be workaround with setting
+ * -Djava.util.logging.config.file system property.
+ *
+ * @since 1.7
+ */
+public class PlatformLogger {
+    // Same values as java.util.logging.Level for easy mapping
+    public static final int OFF     = Integer.MAX_VALUE;
+    public static final int SEVERE  = 1000;
+    public static final int WARNING = 900;
+    public static final int INFO    = 800;
+    public static final int CONFIG  = 700;
+    public static final int FINE    = 500;
+    public static final int FINER   = 400;
+    public static final int FINEST  = 300;
+    public static final int ALL     = Integer.MIN_VALUE;
+
+    private static final int defaultLevel = INFO;
+    private static boolean loggingEnabled;
+    static {
+        loggingEnabled = AccessController.doPrivileged(
+            new PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    String cname = System.getProperty("java.util.logging.config.class");
+                    String fname = System.getProperty("java.util.logging.config.file");
+                    return (cname != null || fname != null);
+                }
+            });
+    }
+
+    // Table of known loggers.  Maps names to PlatformLoggers.
+    private static Map<String,WeakReference<PlatformLogger>> loggers =
+        new HashMap<String,WeakReference<PlatformLogger>>();
+
+    /**
+     * Returns a PlatformLogger of a given name.
+     */
+    public static synchronized PlatformLogger getLogger(String name) {
+        PlatformLogger log = null;
+        WeakReference<PlatformLogger> ref = loggers.get(name);
+        if (ref != null) {
+            log = ref.get();
+        }
+        if (log == null) {
+            log = new PlatformLogger(name);
+            loggers.put(name, new WeakReference<PlatformLogger>(log));
+        }
+        return log;
+    }
+
+    /**
+     * Initialize java.util.logging.Logger objects for all platform loggers.
+     * This method is called from LogManager.readPrimordialConfiguration().
+     */
+    public static synchronized void redirectPlatformLoggers() {
+        if (loggingEnabled || !JavaLogger.supported) return;
+
+        loggingEnabled = true;
+        for (Map.Entry<String, WeakReference<PlatformLogger>> entry : loggers.entrySet()) {
+            WeakReference<PlatformLogger> ref = entry.getValue();
+            PlatformLogger plog = ref.get();
+            if (plog != null) {
+                plog.newJavaLogger();
+            }
+        }
+    }
+
+    /**
+     * Creates a new JavaLogger that the platform logger uses
+     */
+    private void newJavaLogger() {
+        logger = new JavaLogger(logger.name, logger.effectiveLevel);
+    }
+
+    // logger may be replaced with a JavaLogger object
+    // when the logging facility is enabled
+    private volatile LoggerProxy logger;
+
+    private PlatformLogger(String name) {
+        if (loggingEnabled) {
+            this.logger = new JavaLogger(name);
+        } else {
+            this.logger = new LoggerProxy(name);
+        }
+    }
+
+    /**
+     * A convenience method to test if the logger is turned off.
+     * (i.e. its level is OFF).
+     */
+    public boolean isEnabled() {
+        return logger.isEnabled();
+    }
+
+    /**
+     * Gets the name for this platform logger.
+     */
+    public String getName() {
+        return logger.name;
+    }
+
+    /**
+     * Returns true if a message of the given level would actually
+     * be logged by this logger.
+     */
+    public boolean isLoggable(int level) {
+        return logger.isLoggable(level);
+    }
+
+    /**
+     * Gets the current log level.  Returns 0 if the current effective level
+     * is not set (equivalent to Logger.getLevel() returns null).
+     */
+    public int getLevel() {
+        return logger.getLevel();
+    }
+
+    /**
+     * Sets the log level.
+     */
+    public void setLevel(int newLevel) {
+        logger.setLevel(newLevel);
+    }
+
+    /**
+     * Logs a SEVERE message.
+     */
+    public void severe(String msg) {
+        logger.doLog(SEVERE, msg);
+    }
+
+    public void severe(String msg, Throwable t) {
+        logger.doLog(SEVERE, msg, t);
+    }
+
+    public void severe(String msg, Object... params) {
+        logger.doLog(SEVERE, msg, params);
+    }
+
+    /**
+     * Logs a WARNING message.
+     */
+    public void warning(String msg) {
+        logger.doLog(WARNING, msg);
+    }
+
+    public void warning(String msg, Throwable t) {
+        logger.doLog(WARNING, msg, t);
+    }
+
+    public void warning(String msg, Object... params) {
+        logger.doLog(WARNING, msg, params);
+    }
+
+    /**
+     * Logs an INFO message.
+     */
+    public void info(String msg) {
+        logger.doLog(INFO, msg);
+    }
+
+    public void info(String msg, Throwable t) {
+        logger.doLog(INFO, msg, t);
+    }
+
+    public void info(String msg, Object... params) {
+        logger.doLog(INFO, msg, params);
+    }
+
+    /**
+     * Logs a CONFIG message.
+     */
+    public void config(String msg) {
+        logger.doLog(CONFIG, msg);
+    }
+
+    public void config(String msg, Throwable t) {
+        logger.doLog(CONFIG, msg, t);
+    }
+
+    public void config(String msg, Object... params) {
+        logger.doLog(CONFIG, msg, params);
+    }
+
+    /**
+     * Logs a FINE message.
+     */
+    public void fine(String msg) {
+        logger.doLog(FINE, msg);
+    }
+
+    public void fine(String msg, Throwable t) {
+        logger.doLog(FINE, msg, t);
+    }
+
+    public void fine(String msg, Object... params) {
+        logger.doLog(FINE, msg, params);
+    }
+
+    /**
+     * Logs a FINER message.
+     */
+    public void finer(String msg) {
+        logger.doLog(FINER, msg);
+    }
+
+    public void finer(String msg, Throwable t) {
+        logger.doLog(FINER, msg, t);
+    }
+
+    public void finer(String msg, Object... params) {
+        logger.doLog(FINER, msg, params);
+    }
+
+    /**
+     * Logs a FINEST message.
+     */
+    public void finest(String msg) {
+        logger.doLog(FINEST, msg);
+    }
+
+    public void finest(String msg, Throwable t) {
+        logger.doLog(FINEST, msg, t);
+    }
+
+    public void finest(String msg, Object... params) {
+        logger.doLog(FINEST, msg, params);
+    }
+
+    /**
+     * Default platform logging support - output messages to
+     * System.err - equivalent to ConsoleHandler with SimpleFormatter.
+     */
+    static class LoggerProxy {
+        private static final PrintStream defaultStream = System.err;
+        private static final String lineSeparator = AccessController.doPrivileged(
+            new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty("line.separator");
+                }
+            });
+
+        final String name;
+        volatile int levelValue;
+        volatile int effectiveLevel = 0; // current effective level value
+
+        LoggerProxy(String name) {
+            this(name, defaultLevel);
+        }
+
+        LoggerProxy(String name, int level) {
+            this.name = name;
+            this.levelValue = level == 0 ? defaultLevel : level;
+        }
+
+        boolean isEnabled() {
+            return levelValue != OFF;
+        }
+
+        int getLevel() {
+            return effectiveLevel;
+        }
+
+        void setLevel(int newLevel) {
+            levelValue = newLevel;
+            effectiveLevel = newLevel;
+        }
+
+        void doLog(int level, String msg) {
+            if (level < levelValue || levelValue == OFF) {
+                return;
+            }
+            defaultStream.println(format(level, msg, null));
+        }
+
+        void doLog(int level, String msg, Throwable thrown) {
+            if (level < levelValue || levelValue == OFF) {
+                return;
+            }
+            defaultStream.println(format(level, msg, thrown));
+        }
+
+        void doLog(int level, String msg, Object... params) {
+            if (level < levelValue || levelValue == OFF) {
+                return;
+            }
+            String newMsg = formatMessage(msg, params);
+            defaultStream.println(format(level, newMsg, null));
+        }
+
+        public boolean isLoggable(int level) {
+            if (level < levelValue || levelValue == OFF) {
+                return false;
+            }
+            return true;
+        }
+
+        private static final String format = "{0,date} {0,time}";
+
+        private Object args[] = new Object[1];
+        private MessageFormat formatter;
+        private Date dat;
+
+        // Copied from java.util.logging.Formatter.formatMessage
+        private String formatMessage(String format, Object... parameters) {
+            // Do the formatting.
+            try {
+                if (parameters == null || parameters.length == 0) {
+                    // No parameters.  Just return format string.
+                    return format;
+                }
+                // Is it a java.text style format?
+                // Ideally we could match with
+                // Pattern.compile("\\{\\d").matcher(format).find())
+                // However the cost is 14% higher, so we cheaply check for
+                // 1 of the first 4 parameters
+                if (format.indexOf("{0") >= 0 || format.indexOf("{1") >=0 ||
+                            format.indexOf("{2") >=0|| format.indexOf("{3") >=0) {
+                    return java.text.MessageFormat.format(format, parameters);
+                }
+                return format;
+            } catch (Exception ex) {
+                // Formatting failed: use format string.
+                return format;
+            }
+        }
+
+        private synchronized String format(int level, String msg, Throwable thrown) {
+            StringBuffer sb = new StringBuffer();
+            // Minimize memory allocations here.
+            if (dat == null) {
+                dat = new Date();
+                formatter = new MessageFormat(format);
+            }
+            dat.setTime(System.currentTimeMillis());
+            args[0] = dat;
+            StringBuffer text = new StringBuffer();
+            formatter.format(args, text, null);
+            sb.append(text);
+            sb.append(" ");
+            sb.append(getCallerInfo());
+            sb.append(lineSeparator);
+            sb.append(PlatformLogger.getLevelName(level));
+            sb.append(": ");
+            sb.append(msg);
+            if (thrown != null) {
+                try {
+                    StringWriter sw = new StringWriter();
+                    PrintWriter pw = new PrintWriter(sw);
+                    thrown.printStackTrace(pw);
+                    pw.close();
+                    sb.append(sw.toString());
+                } catch (Exception ex) {
+                    throw new AssertionError(ex);
+                }
+            }
+
+            return sb.toString();
+        }
+
+        // Returns the caller's class and method's name; best effort
+        // if cannot infer, return the logger's name.
+        private String getCallerInfo() {
+            String sourceClassName = null;
+            String sourceMethodName = null;
+
+            JavaLangAccess access = SharedSecrets.getJavaLangAccess();
+            Throwable throwable = new Throwable();
+            int depth = access.getStackTraceDepth(throwable);
+
+            String logClassName = "sun.util.logging.PlatformLogger";
+            boolean lookingForLogger = true;
+            for (int ix = 0; ix < depth; ix++) {
+                // Calling getStackTraceElement directly prevents the VM
+                // from paying the cost of building the entire stack frame.
+                StackTraceElement frame =
+                    access.getStackTraceElement(throwable, ix);
+                String cname = frame.getClassName();
+                if (lookingForLogger) {
+                    // Skip all frames until we have found the first logger frame.
+                    if (cname.equals(logClassName)) {
+                        lookingForLogger = false;
+                    }
+                } else {
+                    if (!cname.equals(logClassName)) {
+                        // We've found the relevant frame.
+                        sourceClassName = cname;
+                        sourceMethodName = frame.getMethodName();
+                        break;
+                    }
+                }
+            }
+
+            if (sourceClassName != null) {
+                return sourceClassName + " " + sourceMethodName;
+            } else {
+                return name;
+            }
+        }
+    }
+
+    /**
+     * JavaLogger forwards all the calls to its corresponding
+     * java.util.logging.Logger object.
+     */
+    static class JavaLogger extends LoggerProxy {
+        private static final boolean supported;
+        private static final Class<?> loggerClass;
+        private static final Class<?> levelClass;
+        private static final Method getLoggerMethod;
+        private static final Method setLevelMethod;
+        private static final Method getLevelMethod;
+        private static final Method isLoggableMethod;
+        private static final Method logMethod;
+        private static final Method logThrowMethod;
+        private static final Method logParamsMethod;
+        private static final Map<Integer, Object> levelObjects =
+            new HashMap<Integer, Object>();
+
+        static {
+            loggerClass = getClass("java.util.logging.Logger");
+            levelClass = getClass("java.util.logging.Level");
+            getLoggerMethod = getMethod(loggerClass, "getLogger", String.class);
+            setLevelMethod = getMethod(loggerClass, "setLevel", levelClass);
+            getLevelMethod = getMethod(loggerClass, "getLevel");
+            isLoggableMethod = getMethod(loggerClass, "isLoggable", levelClass);
+            logMethod = getMethod(loggerClass, "log", levelClass, String.class);
+            logThrowMethod = getMethod(loggerClass, "log", levelClass, String.class, Throwable.class);
+            logParamsMethod = getMethod(loggerClass, "log", levelClass, String.class, Object[].class);
+            supported = (loggerClass != null && levelClass != null && getLoggerMethod != null &&
+                         getLevelMethod != null && setLevelMethod != null &&
+                         logMethod != null && logThrowMethod != null && logParamsMethod != null);
+            if (supported) {
+                // initialize the map to Level objects
+                getLevelObjects();
+            }
+        }
+
+        private static Class<?> getClass(String name) {
+            try {
+                return Class.forName(name, true, null);
+            } catch (ClassNotFoundException e) {
+                return null;
+            }
+        }
+
+        private static Method getMethod(Class<?> cls, String name, Class<?>... parameterTypes) {
+            if (cls == null) return null;
+
+            try {
+                return cls.getMethod(name, parameterTypes);
+            } catch (NoSuchMethodException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        private static Object invoke(Method m, Object obj, Object... params) {
+            try {
+                return m.invoke(obj, params);
+            } catch (IllegalAccessException e) {
+                throw new AssertionError(e);
+            } catch (InvocationTargetException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        private static void getLevelObjects() {
+            // get all java.util.logging.Level objects
+            Method parseLevelMethod = getMethod(levelClass, "parse", String.class);
+            int[] levelArray = new int[] {OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL};
+            for (int l : levelArray) {
+                Object o = invoke(parseLevelMethod, null, getLevelName(l));
+                levelObjects.put(l, o);
+            }
+        }
+
+        private final Object javaLogger;
+        JavaLogger(String name) {
+            this(name, 0);
+        }
+
+        JavaLogger(String name, int level) {
+            super(name, level);
+            this.javaLogger = invoke(getLoggerMethod, null, name);
+            if (level != 0) {
+                // level has been updated and so set the Logger's level
+                invoke(setLevelMethod, javaLogger, levelObjects.get(level));
+            }
+        }
+
+       /**
+        * Let Logger.log() do the filtering since if the level of a
+        * platform logger is altered directly from
+        * java.util.logging.Logger.setLevel(), the levelValue will
+        * not be updated.
+        */
+        void doLog(int level, String msg) {
+            invoke(logMethod, javaLogger, levelObjects.get(level), msg);
+        }
+
+        void doLog(int level, String msg, Throwable t) {
+            invoke(logThrowMethod, javaLogger, levelObjects.get(level), msg, t);
+        }
+
+        void doLog(int level, String msg, Object... params) {
+            invoke(logParamsMethod, javaLogger, levelObjects.get(level), msg, params);
+        }
+
+        boolean isEnabled() {
+            Object level = invoke(getLevelMethod, javaLogger);
+            return level == null || level.equals(levelObjects.get(OFF)) == false;
+        }
+
+        int getLevel() {
+            Object level = invoke(getLevelMethod, javaLogger);
+            if (level != null) {
+                for (Map.Entry<Integer, Object> l : levelObjects.entrySet()) {
+                    if (level == l.getValue()) {
+                        return l.getKey();
+                    }
+                }
+            }
+            return 0;
+        }
+
+        void setLevel(int newLevel) {
+            levelValue = newLevel;
+            invoke(setLevelMethod, javaLogger, levelObjects.get(newLevel));
+        }
+
+        public boolean isLoggable(int level) {
+            return (Boolean) invoke(isLoggableMethod, javaLogger, levelObjects.get(level));
+        }
+    }
+
+
+    private static String getLevelName(int level) {
+        switch (level) {
+            case OFF     : return "OFF";
+            case SEVERE  : return "SEVERE";
+            case WARNING : return "WARNING";
+            case INFO    : return "INFO";
+            case CONFIG  : return "CONFIG";
+            case FINE    : return "FINE";
+            case FINER   : return "FINER";
+            case FINEST  : return "FINEST";
+            case ALL     : return "ALL";
+            default      : return "UNKNOWN";
+        }
+    }
+
+}
--- a/jdk/src/share/demo/jvmti/waiters/Agent.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Agent.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -72,36 +72,30 @@
 {
     jvmtiError err;
     Monitor   *m;
-
-    /* We use tags to track these, the tag is the Monitor pointer */
-    err = jvmti->RawMonitorEnter(lock); {
-        check_jvmti_error(jvmti, err, "raw monitor enter");
+    jlong      tag;
 
-        /* The raw monitor enter/exit protects us from creating two
-         *   instances for the same object.
-         */
-        jlong tag;
-
-        m   = NULL;
-        tag = (jlong)0;
-        err = jvmti->GetTag(object, &tag);
-        check_jvmti_error(jvmti, err, "get tag");
+    m   = NULL;
+    tag = (jlong)0;
+    err = jvmti->GetTag(object, &tag);
+    check_jvmti_error(jvmti, err, "get tag");
+    /*LINTED*/
+    m = (Monitor *)(void *)(ptrdiff_t)tag;
+    if ( m == NULL ) {
+        m = new Monitor(jvmti, env, object);
+        /* Save monitor on list */
+        if (monitor_count == monitor_list_size) {
+            monitor_list_size += monitor_list_grow_size;
+            monitor_list = (Monitor**)realloc((void*)monitor_list,
+                (monitor_list_size)*(int)sizeof(Monitor*));
+        }
+        monitor_list[monitor_count] = m;
+        m->set_slot(monitor_count);
+        monitor_count++;
         /*LINTED*/
-        m = (Monitor *)(void *)(ptrdiff_t)tag;
-        if ( m == NULL ) {
-            m = new Monitor(jvmti, env, object);
-            /*LINTED*/
-            tag = (jlong)(ptrdiff_t)(void *)m;
-            err = jvmti->SetTag(object, tag);
-            check_jvmti_error(jvmti, err, "set tag");
-            /* Save monitor on list */
-            monitor_list = (Monitor**)realloc((void*)monitor_list,
-                                (monitor_count+1)*(int)sizeof(Monitor*));
-            monitor_list[monitor_count++] = m;
-        }
-    } err = jvmti->RawMonitorExit(lock);
-    check_jvmti_error(jvmti, err, "raw monitor exit");
-
+        tag = (jlong)(ptrdiff_t)(void *)m;
+        err = jvmti->SetTag(object, tag);
+        check_jvmti_error(jvmti, err, "set tag");
+    }
     return m;
 }
 
@@ -112,12 +106,11 @@
 
     stdout_message("Agent created..\n");
     stdout_message("VMInit...\n");
-    /* Create a Monitor lock to use */
-    err = jvmti->CreateRawMonitor("waiters Agent lock", &lock);
-    check_jvmti_error(jvmti, err, "create raw monitor");
     /* Start monitor list */
     monitor_count = 0;
-    monitor_list  = (Monitor**)malloc((int)sizeof(Monitor*));
+    monitor_list_size = initial_monitor_list_size;
+    monitor_list = (Monitor**)
+        malloc(monitor_list_size*(int)sizeof(Monitor*));
 }
 
 Agent::~Agent()
@@ -134,9 +127,6 @@
         delete monitor_list[i];
     }
     free(monitor_list);
-    /* Destroy the Monitor lock to use */
-    err = jvmti->DestroyRawMonitor(lock);
-    check_jvmti_error(jvmti, err, "destroy raw monitor");
     /* Print death message */
     stdout_message("VMDeath...\n");
 }
@@ -215,8 +205,16 @@
     /* We just cast the tag to a C++ pointer and delete it.
      *   we know it can only be a Monitor *.
      */
-    Monitor *m;
+    Monitor   *m;
     /*LINTED*/
     m = (Monitor *)(ptrdiff_t)tag;
+    if (monitor_count > 1) {
+        /* Move the last element to this Monitor's slot */
+        int slot = m->get_slot();
+        Monitor *last = monitor_list[monitor_count-1];
+        monitor_list[slot] = last;
+        last->set_slot(slot);
+    }
+    monitor_count--;
     delete m;
 }
--- a/jdk/src/share/demo/jvmti/waiters/Agent.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Agent.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -34,8 +34,12 @@
 class Agent {
 
   private:
-    jrawMonitorID lock;
+    enum {
+      initial_monitor_list_size = 64,
+      monitor_list_grow_size = 16
+    };
     Monitor     **monitor_list;
+    unsigned      monitor_list_size;
     unsigned      monitor_count;
     Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread);
     Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
--- a/jdk/src/share/demo/jvmti/waiters/Monitor.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Monitor.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -73,6 +73,16 @@
         name, contends, waits, timeouts);
 }
 
+int Monitor::get_slot()
+{
+    return slot;
+}
+
+void Monitor::set_slot(int aslot)
+{
+    slot = aslot;
+}
+
 void Monitor::contended()
 {
     contends++;
--- a/jdk/src/share/demo/jvmti/waiters/Monitor.hpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Monitor.hpp	Wed Jul 05 17:01:15 2017 +0200
@@ -35,6 +35,7 @@
 
   private:
     char     name[64];
+    int      slot;
     unsigned contends;
     unsigned waits;
     unsigned timeouts;
@@ -42,6 +43,8 @@
   public:
     Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
     ~Monitor();
+    int get_slot();
+    void set_slot(int i);
     void contended();
     void waited();
     void timeout();
--- a/jdk/src/share/javavm/export/jvm.h	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/javavm/export/jvm.h	Wed Jul 05 17:01:15 2017 +0200
@@ -375,6 +375,12 @@
 JVM_ResolveClass(JNIEnv *env, jclass cls);
 
 /*
+ * Find a class from a boot class loader. Returns NULL if class not found.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
+
+/*
  * Find a class from a given class loader. Throw ClassNotFoundException
  * or NoClassDefFoundError depending on the value of the last
  * argument.
--- a/jdk/src/share/lib/net.properties	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/lib/net.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -32,7 +32,7 @@
 #
 # http.proxyHost=
 # http.proxyPort=80
-# http.nonProxyHosts=localhost|127.0.0.1
+http.nonProxyHosts=localhost|127.*|[::1]
 #
 # HTTPS Proxy Settings. proxyHost is the name of the proxy server
 # (e.g. proxy.mydomain.com), proxyPort is the port number to use (default
@@ -49,7 +49,7 @@
 #
 # ftp.proxyHost=
 # ftp.proxyPort=80
-# ftp.nonProxyHosts=localhost|127.0.0.1
+ftp.nonProxyHosts=localhost|127.*|[::1]
 #
 # Gopher Proxy settings. proxyHost is the name of the proxy server
 # (e.g. proxy.mydomain.com), proxyPort is the port number to use (default
--- a/jdk/src/share/native/java/lang/ClassLoader.c	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/native/java/lang/ClassLoader.c	Wed Jul 05 17:01:15 2017 +0200
@@ -237,6 +237,9 @@
     JVM_ResolveClass(env, cls);
 }
 
+/*
+ * Returns NULL if class not found.
+ */
 JNIEXPORT jclass JNICALL
 Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
                                               jstring classname)
@@ -246,7 +249,6 @@
     char buf[128];
 
     if (classname == NULL) {
-        JNU_ThrowClassNotFoundException(env, 0);
         return 0;
     }
 
@@ -258,11 +260,10 @@
     VerifyFixClassname(clname);
 
     if (!VerifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
-        JNU_ThrowClassNotFoundException(env, clname);
         goto done;
     }
 
-    cls = JVM_FindClassFromClassLoader(env, clname, JNI_FALSE, 0, JNI_FALSE);
+    cls = JVM_FindClassFromBootLoader(env, clname);
 
  done:
     if (clname != buf) {
--- a/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Jul 05 17:01:15 2017 +0200
@@ -24,7 +24,7 @@
  */
 
 #include <jni.h>
-#include "ecc_impl.h"
+#include "impl/ecc_impl.h"
 
 #define ILLEGAL_STATE_EXCEPTION "java/lang/IllegalStateException"
 #define INVALID_ALGORITHM_PARAMETER_EXCEPTION \
--- a/jdk/src/share/native/sun/security/ec/ec.c	Wed Jul 05 17:00:34 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1099 +0,0 @@
-/* *********************************************************************
- *
- * Sun elects to have this file available under and governed by the
- * Mozilla Public License Version 1.1 ("MPL") (see
- * http://www.mozilla.org/MPL/ for full license text). For the avoidance
- * of doubt and subject to the following, Sun also elects to allow
- * licensees to use this file under the MPL, the GNU General Public
- * License version 2 only or the Lesser General Public License version
- * 2.1 only. Any references to the "GNU General Public License version 2
- * or later" or "GPL" in the following shall be construed to mean the
- * GNU General Public License version 2 only. Any references to the "GNU
- * Lesser General Public License version 2.1 or later" or "LGPL" in the
- * following shall be construed to mean the GNU Lesser General Public
- * License version 2.1 only. However, the following notice accompanied
- * the original version of this file:
- *
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Elliptic Curve Cryptography library.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 2003
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dr Vipul Gupta <vipul.gupta@sun.com> and
- *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- *********************************************************************** */
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident   "%Z%%M% %I%     %E% SMI"
-
-#include "mplogic.h"
-#include "ec.h"
-#include "ecl.h"
-
-#include <sys/types.h>
-#ifndef _KERNEL
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef _WIN32
-#include <strings.h>
-#endif /* _WIN32 */
-
-#endif
-#include "ecl-exp.h"
-#include "mpi.h"
-#include "ecc_impl.h"
-
-#ifdef _KERNEL
-#define PORT_ZFree(p, l)                bzero((p), (l)); kmem_free((p), (l))
-#else
-#ifndef _WIN32
-#define PORT_ZFree(p, l)                bzero((p), (l)); free((p))
-#else
-#define PORT_ZFree(p, l)                memset((p), 0, (l)); free((p))
-#endif /* _WIN32 */
-#endif
-
-/*
- * Returns true if pointP is the point at infinity, false otherwise
- */
-PRBool
-ec_point_at_infinity(SECItem *pointP)
-{
-    unsigned int i;
-
-    for (i = 1; i < pointP->len; i++) {
-        if (pointP->data[i] != 0x00) return PR_FALSE;
-    }
-
-    return PR_TRUE;
-}
-
-/*
- * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
- * the curve whose parameters are encoded in params with base point G.
- */
-SECStatus
-ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
-             const SECItem *pointP, SECItem *pointQ, int kmflag)
-{
-    mp_int Px, Py, Qx, Qy;
-    mp_int Gx, Gy, order, irreducible, a, b;
-#if 0 /* currently don't support non-named curves */
-    unsigned int irr_arr[5];
-#endif
-    ECGroup *group = NULL;
-    SECStatus rv = SECFailure;
-    mp_err err = MP_OKAY;
-    int len;
-
-#if EC_DEBUG
-    int i;
-    char mpstr[256];
-
-    printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len);
-    for (i = 0; i < params->DEREncoding.len; i++)
-            printf("%02x:", params->DEREncoding.data[i]);
-    printf("\n");
-
-        if (k1 != NULL) {
-                mp_tohex(k1, mpstr);
-                printf("ec_points_mul: scalar k1: %s\n", mpstr);
-                mp_todecimal(k1, mpstr);
-                printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
-        }
-
-        if (k2 != NULL) {
-                mp_tohex(k2, mpstr);
-                printf("ec_points_mul: scalar k2: %s\n", mpstr);
-                mp_todecimal(k2, mpstr);
-                printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
-        }
-
-        if (pointP != NULL) {
-                printf("ec_points_mul: pointP [len=%d]:", pointP->len);
-                for (i = 0; i < pointP->len; i++)
-                        printf("%02x:", pointP->data[i]);
-                printf("\n");
-        }
-#endif
-
-        /* NOTE: We only support uncompressed points for now */
-        len = (params->fieldID.size + 7) >> 3;
-        if (pointP != NULL) {
-                if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
-                        (pointP->len != (2 * len + 1))) {
-                        return SECFailure;
-                };
-        }
-
-        MP_DIGITS(&Px) = 0;
-        MP_DIGITS(&Py) = 0;
-        MP_DIGITS(&Qx) = 0;
-        MP_DIGITS(&Qy) = 0;
-        MP_DIGITS(&Gx) = 0;
-        MP_DIGITS(&Gy) = 0;
-        MP_DIGITS(&order) = 0;
-        MP_DIGITS(&irreducible) = 0;
-        MP_DIGITS(&a) = 0;
-        MP_DIGITS(&b) = 0;
-        CHECK_MPI_OK( mp_init(&Px, kmflag) );
-        CHECK_MPI_OK( mp_init(&Py, kmflag) );
-        CHECK_MPI_OK( mp_init(&Qx, kmflag) );
-        CHECK_MPI_OK( mp_init(&Qy, kmflag) );
-        CHECK_MPI_OK( mp_init(&Gx, kmflag) );
-        CHECK_MPI_OK( mp_init(&Gy, kmflag) );
-        CHECK_MPI_OK( mp_init(&order, kmflag) );
-        CHECK_MPI_OK( mp_init(&irreducible, kmflag) );
-        CHECK_MPI_OK( mp_init(&a, kmflag) );
-        CHECK_MPI_OK( mp_init(&b, kmflag) );
-
-        if ((k2 != NULL) && (pointP != NULL)) {
-                /* Initialize Px and Py */
-                CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
-                CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
-        }
-
-        /* construct from named params, if possible */
-        if (params->name != ECCurve_noName) {
-                group = ECGroup_fromName(params->name, kmflag);
-        }
-
-#if 0 /* currently don't support non-named curves */
-        if (group == NULL) {
-                /* Set up mp_ints containing the curve coefficients */
-                CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1,
-                                                                                  (mp_size) len) );
-                CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len,
-                                                                                  (mp_size) len) );
-                SECITEM_TO_MPINT( params->order, &order );
-                SECITEM_TO_MPINT( params->curve.a, &a );
-                SECITEM_TO_MPINT( params->curve.b, &b );
-                if (params->fieldID.type == ec_field_GFp) {
-                        SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
-                        group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor);
-                } else {
-                        SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
-                        irr_arr[0] = params->fieldID.size;
-                        irr_arr[1] = params->fieldID.k1;
-                        irr_arr[2] = params->fieldID.k2;
-                        irr_arr[3] = params->fieldID.k3;
-                        irr_arr[4] = 0;
-                        group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor);
-                }
-        }
-#endif
-        if (group == NULL)
-                goto cleanup;
-
-        if ((k2 != NULL) && (pointP != NULL)) {
-                CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
-        } else {
-                CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
-    }
-
-    /* Construct the SECItem representation of point Q */
-    pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
-    CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
-                                      (mp_size) len) );
-    CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
-                                      (mp_size) len) );
-
-    rv = SECSuccess;
-
-#if EC_DEBUG
-    printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
-    for (i = 0; i < pointQ->len; i++)
-            printf("%02x:", pointQ->data[i]);
-    printf("\n");
-#endif
-
-cleanup:
-    ECGroup_free(group);
-    mp_clear(&Px);
-    mp_clear(&Py);
-    mp_clear(&Qx);
-    mp_clear(&Qy);
-    mp_clear(&Gx);
-    mp_clear(&Gy);
-    mp_clear(&order);
-    mp_clear(&irreducible);
-    mp_clear(&a);
-    mp_clear(&b);
-    if (err) {
-        MP_TO_SEC_ERROR(err);
-        rv = SECFailure;
-    }
-
-    return rv;
-}
-
-/* Generates a new EC key pair. The private key is a supplied
- * value and the public key is the result of performing a scalar
- * point multiplication of that value with the curve's base point.
- */
-SECStatus
-ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
-    const unsigned char *privKeyBytes, int privKeyLen, int kmflag)
-{
-    SECStatus rv = SECFailure;
-    PRArenaPool *arena;
-    ECPrivateKey *key;
-    mp_int k;
-    mp_err err = MP_OKAY;
-    int len;
-
-#if EC_DEBUG
-    printf("ec_NewKey called\n");
-#endif
-
-#ifndef _WIN32
-int printf();
-#endif /* _WIN32 */
-
-    if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        return SECFailure;
-    }
-
-    /* Initialize an arena for the EC key. */
-    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
-        return SECFailure;
-
-    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey),
-        kmflag);
-    if (!key) {
-        PORT_FreeArena(arena, PR_TRUE);
-        return SECFailure;
-    }
-
-    /* Set the version number (SEC 1 section C.4 says it should be 1) */
-    SECITEM_AllocItem(arena, &key->version, 1, kmflag);
-    key->version.data[0] = 1;
-
-    /* Copy all of the fields from the ECParams argument to the
-     * ECParams structure within the private key.
-     */
-    key->ecParams.arena = arena;
-    key->ecParams.type = ecParams->type;
-    key->ecParams.fieldID.size = ecParams->fieldID.size;
-    key->ecParams.fieldID.type = ecParams->fieldID.type;
-    if (ecParams->fieldID.type == ec_field_GFp) {
-        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
-            &ecParams->fieldID.u.prime, kmflag));
-    } else {
-        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
-            &ecParams->fieldID.u.poly, kmflag));
-    }
-    key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
-    key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
-    key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
-    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
-        &ecParams->curve.a, kmflag));
-    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
-        &ecParams->curve.b, kmflag));
-    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
-        &ecParams->curve.seed, kmflag));
-    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
-        &ecParams->base, kmflag));
-    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
-        &ecParams->order, kmflag));
-    key->ecParams.cofactor = ecParams->cofactor;
-    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
-        &ecParams->DEREncoding, kmflag));
-    key->ecParams.name = ecParams->name;
-    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
-        &ecParams->curveOID, kmflag));
-
-    len = (ecParams->fieldID.size + 7) >> 3;
-    SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1, kmflag);
-    len = ecParams->order.len;
-    SECITEM_AllocItem(arena, &key->privateValue, len, kmflag);
-
-    /* Copy private key */
-    if (privKeyLen >= len) {
-        memcpy(key->privateValue.data, privKeyBytes, len);
-    } else {
-        memset(key->privateValue.data, 0, (len - privKeyLen));
-        memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
-    }
-
-    /* Compute corresponding public key */
-    MP_DIGITS(&k) = 0;
-    CHECK_MPI_OK( mp_init(&k, kmflag) );
-    CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
-        (mp_size) len) );
-
-    rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag);
-    if (rv != SECSuccess) goto cleanup;
-    *privKey = key;
-
-cleanup:
-    mp_clear(&k);
-    if (rv)
-        PORT_FreeArena(arena, PR_TRUE);
-
-#if EC_DEBUG
-    printf("ec_NewKey returning %s\n",
-        (rv == SECSuccess) ? "success" : "failure");
-#endif
-
-    return rv;
-
-}
-
-/* Generates a new EC key pair. The private key is a supplied
- * random value (in seed) and the public key is the result of
- * performing a scalar point multiplication of that value with
- * the curve's base point.
- */
-SECStatus
-EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
-    const unsigned char *seed, int seedlen, int kmflag)
-{
-    SECStatus rv = SECFailure;
-    rv = ec_NewKey(ecParams, privKey, seed, seedlen, kmflag);
-    return rv;
-}
-
-/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
- * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
- * random number generator.
- *
- * Parameters
- * - order: a buffer that holds the curve's group order
- * - len: the length in octets of the order buffer
- * - random: a buffer of 2 * len random bytes
- * - randomlen: the length in octets of the random buffer
- *
- * Return Value
- * Returns a buffer of len octets that holds the private key. The caller
- * is responsible for freeing the buffer with PORT_ZFree.
- */
-static unsigned char *
-ec_GenerateRandomPrivateKey(const unsigned char *order, int len,
-    const unsigned char *random, int randomlen, int kmflag)
-{
-    SECStatus rv = SECSuccess;
-    mp_err err;
-    unsigned char *privKeyBytes = NULL;
-    mp_int privKeyVal, order_1, one;
-
-    MP_DIGITS(&privKeyVal) = 0;
-    MP_DIGITS(&order_1) = 0;
-    MP_DIGITS(&one) = 0;
-    CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) );
-    CHECK_MPI_OK( mp_init(&order_1, kmflag) );
-    CHECK_MPI_OK( mp_init(&one, kmflag) );
-
-    /*
-     * Reduces the 2*len buffer of random bytes modulo the group order.
-     */
-    if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
-    if (randomlen != 2 * len) {
-        randomlen = 2 * len;
-    }
-    /* No need to generate - random bytes are now supplied */
-    /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/
-    memcpy(privKeyBytes, random, randomlen);
-
-    CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
-    CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
-    CHECK_MPI_OK( mp_set_int(&one, 1) );
-    CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
-    CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
-    CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
-    CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
-    memset(privKeyBytes+len, 0, len);
-cleanup:
-    mp_clear(&privKeyVal);
-    mp_clear(&order_1);
-    mp_clear(&one);
-    if (err < MP_OKAY) {
-        MP_TO_SEC_ERROR(err);
-        rv = SECFailure;
-    }
-    if (rv != SECSuccess && privKeyBytes) {
-#ifdef _KERNEL
-        kmem_free(privKeyBytes, 2*len);
-#else
-        free(privKeyBytes);
-#endif
-        privKeyBytes = NULL;
-    }
-    return privKeyBytes;
-}
-
-/* Generates a new EC key pair. The private key is a random value and
- * the public key is the result of performing a scalar point multiplication
- * of that value with the curve's base point.
- */
-SECStatus
-EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
-    const unsigned char* random, int randomlen, int kmflag)
-{
-    SECStatus rv = SECFailure;
-    int len;
-    unsigned char *privKeyBytes = NULL;
-
-    if (!ecParams) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        return SECFailure;
-    }
-
-    len = ecParams->order.len;
-    privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len,
-        random, randomlen, kmflag);
-    if (privKeyBytes == NULL) goto cleanup;
-    /* generate public key */
-    CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len, kmflag) );
-
-cleanup:
-    if (privKeyBytes) {
-        PORT_ZFree(privKeyBytes, len * 2);
-    }
-#if EC_DEBUG
-    printf("EC_NewKey returning %s\n",
-        (rv == SECSuccess) ? "success" : "failure");
-#endif
-
-    return rv;
-}
-
-/* Validates an EC public key as described in Section 5.2.2 of
- * X9.62. The ECDH primitive when used without the cofactor does
- * not address small subgroup attacks, which may occur when the
- * public key is not valid. These attacks can be prevented by
- * validating the public key before using ECDH.
- */
-SECStatus
-EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue, int kmflag)
-{
-    mp_int Px, Py;
-    ECGroup *group = NULL;
-    SECStatus rv = SECFailure;
-    mp_err err = MP_OKAY;
-    int len;
-
-    if (!ecParams || !publicValue) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        return SECFailure;
-    }
-
-    /* NOTE: We only support uncompressed points for now */
-    len = (ecParams->fieldID.size + 7) >> 3;
-    if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
-        PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
-        return SECFailure;
-    } else if (publicValue->len != (2 * len + 1)) {
-        PORT_SetError(SEC_ERROR_BAD_KEY);
-        return SECFailure;
-    }
-
-    MP_DIGITS(&Px) = 0;
-    MP_DIGITS(&Py) = 0;
-    CHECK_MPI_OK( mp_init(&Px, kmflag) );
-    CHECK_MPI_OK( mp_init(&Py, kmflag) );
-
-    /* Initialize Px and Py */
-    CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
-    CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );
-
-    /* construct from named params */
-    group = ECGroup_fromName(ecParams->name, kmflag);
-    if (group == NULL) {
-        /*
-         * ECGroup_fromName fails if ecParams->name is not a valid
-         * ECCurveName value, or if we run out of memory, or perhaps
-         * for other reasons.  Unfortunately if ecParams->name is a
-         * valid ECCurveName value, we don't know what the right error
-         * code should be because ECGroup_fromName doesn't return an
-         * error code to the caller.  Set err to MP_UNDEF because
-         * that's what ECGroup_fromName uses internally.
-         */
-        if ((ecParams->name <= ECCurve_noName) ||
-            (ecParams->name >= ECCurve_pastLastCurve)) {
-            err = MP_BADARG;
-        } else {
-            err = MP_UNDEF;
-        }
-        goto cleanup;
-    }
-
-    /* validate public point */
-    if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
-        if (err == MP_NO) {
-            PORT_SetError(SEC_ERROR_BAD_KEY);
-            rv = SECFailure;
-            err = MP_OKAY;  /* don't change the error code */
-        }
-        goto cleanup;
-    }
-
-    rv = SECSuccess;
-
-cleanup:
-    ECGroup_free(group);
-    mp_clear(&Px);
-    mp_clear(&Py);
-    if (err) {
-        MP_TO_SEC_ERROR(err);
-        rv = SECFailure;
-    }
-    return rv;
-}
-
-/*
-** Performs an ECDH key derivation by computing the scalar point
-** multiplication of privateValue and publicValue (with or without the
-** cofactor) and returns the x-coordinate of the resulting elliptic
-** curve point in derived secret.  If successful, derivedSecret->data
-** is set to the address of the newly allocated buffer containing the
-** derived secret, and derivedSecret->len is the size of the secret
-** produced. It is the caller's responsibility to free the allocated
-** buffer containing the derived secret.
-*/
-SECStatus
-ECDH_Derive(SECItem  *publicValue,
-            ECParams *ecParams,
-            SECItem  *privateValue,
-            PRBool    withCofactor,
-            SECItem  *derivedSecret,
-            int kmflag)
-{
-    SECStatus rv = SECFailure;
-    unsigned int len = 0;
-    SECItem pointQ = {siBuffer, NULL, 0};
-    mp_int k; /* to hold the private value */
-    mp_int cofactor;
-    mp_err err = MP_OKAY;
-#if EC_DEBUG
-    int i;
-#endif
-
-    if (!publicValue || !ecParams || !privateValue ||
-        !derivedSecret) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        return SECFailure;
-    }
-
-    memset(derivedSecret, 0, sizeof *derivedSecret);
-    len = (ecParams->fieldID.size + 7) >> 3;
-    pointQ.len = 2*len + 1;
-    if ((pointQ.data = PORT_Alloc(2*len + 1, kmflag)) == NULL) goto cleanup;
-
-    MP_DIGITS(&k) = 0;
-    CHECK_MPI_OK( mp_init(&k, kmflag) );
-    CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
-                                          (mp_size) privateValue->len) );
-
-    if (withCofactor && (ecParams->cofactor != 1)) {
-            /* multiply k with the cofactor */
-            MP_DIGITS(&cofactor) = 0;
-            CHECK_MPI_OK( mp_init(&cofactor, kmflag) );
-            mp_set(&cofactor, ecParams->cofactor);
-            CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
-    }
-
-    /* Multiply our private key and peer's public point */
-    if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag) != SECSuccess) ||
-        ec_point_at_infinity(&pointQ))
-        goto cleanup;
-
-    /* Allocate memory for the derived secret and copy
-     * the x co-ordinate of pointQ into it.
-     */
-    SECITEM_AllocItem(NULL, derivedSecret, len, kmflag);
-    memcpy(derivedSecret->data, pointQ.data + 1, len);
-
-    rv = SECSuccess;
-
-#if EC_DEBUG
-    printf("derived_secret:\n");
-    for (i = 0; i < derivedSecret->len; i++)
-        printf("%02x:", derivedSecret->data[i]);
-    printf("\n");
-#endif
-
-cleanup:
-    mp_clear(&k);
-
-    if (pointQ.data) {
-        PORT_ZFree(pointQ.data, 2*len + 1);
-    }
-
-    return rv;
-}
-
-/* Computes the ECDSA signature (a concatenation of two values r and s)
- * on the digest using the given key and the random value kb (used in
- * computing s).
- */
-SECStatus
-ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
-    const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag)
-{
-    SECStatus rv = SECFailure;
-    mp_int x1;
-    mp_int d, k;     /* private key, random integer */
-    mp_int r, s;     /* tuple (r, s) is the signature */
-    mp_int n;
-    mp_err err = MP_OKAY;
-    ECParams *ecParams = NULL;
-    SECItem kGpoint = { siBuffer, NULL, 0};
-    int flen = 0;    /* length in bytes of the field size */
-    unsigned olen;   /* length in bytes of the base point order */
-
-#if EC_DEBUG
-    char mpstr[256];
-#endif
-
-    /* Initialize MPI integers. */
-    /* must happen before the first potential call to cleanup */
-    MP_DIGITS(&x1) = 0;
-    MP_DIGITS(&d) = 0;
-    MP_DIGITS(&k) = 0;
-    MP_DIGITS(&r) = 0;
-    MP_DIGITS(&s) = 0;
-    MP_DIGITS(&n) = 0;
-
-    /* Check args */
-    if (!key || !signature || !digest || !kb || (kblen < 0)) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        goto cleanup;
-    }
-
-    ecParams = &(key->ecParams);
-    flen = (ecParams->fieldID.size + 7) >> 3;
-    olen = ecParams->order.len;
-    if (signature->data == NULL) {
-        /* a call to get the signature length only */
-        goto finish;
-    }
-    if (signature->len < 2*olen) {
-        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
-        rv = SECBufferTooSmall;
-        goto cleanup;
-    }
-
-
-    CHECK_MPI_OK( mp_init(&x1, kmflag) );
-    CHECK_MPI_OK( mp_init(&d, kmflag) );
-    CHECK_MPI_OK( mp_init(&k, kmflag) );
-    CHECK_MPI_OK( mp_init(&r, kmflag) );
-    CHECK_MPI_OK( mp_init(&s, kmflag) );
-    CHECK_MPI_OK( mp_init(&n, kmflag) );
-
-    SECITEM_TO_MPINT( ecParams->order, &n );
-    SECITEM_TO_MPINT( key->privateValue, &d );
-    CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
-    /* Make sure k is in the interval [1, n-1] */
-    if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
-#if EC_DEBUG
-        printf("k is outside [1, n-1]\n");
-        mp_tohex(&k, mpstr);
-        printf("k : %s \n", mpstr);
-        mp_tohex(&n, mpstr);
-        printf("n : %s \n", mpstr);
-#endif
-        PORT_SetError(SEC_ERROR_NEED_RANDOM);
-        goto cleanup;
-    }
-
-    /*
-    ** ANSI X9.62, Section 5.3.2, Step 2
-    **
-    ** Compute kG
-    */
-    kGpoint.len = 2*flen + 1;
-    kGpoint.data = PORT_Alloc(2*flen + 1, kmflag);
-    if ((kGpoint.data == NULL) ||
-        (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag)
-            != SECSuccess))
-        goto cleanup;
-
-    /*
-    ** ANSI X9.62, Section 5.3.3, Step 1
-    **
-    ** Extract the x co-ordinate of kG into x1
-    */
-    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
-                                          (mp_size) flen) );
-
-    /*
-    ** ANSI X9.62, Section 5.3.3, Step 2
-    **
-    ** r = x1 mod n  NOTE: n is the order of the curve
-    */
-    CHECK_MPI_OK( mp_mod(&x1, &n, &r) );
-
-    /*
-    ** ANSI X9.62, Section 5.3.3, Step 3
-    **
-    ** verify r != 0
-    */
-    if (mp_cmp_z(&r) == 0) {
-        PORT_SetError(SEC_ERROR_NEED_RANDOM);
-        goto cleanup;
-    }
-
-    /*
-    ** ANSI X9.62, Section 5.3.3, Step 4
-    **
-    ** s = (k**-1 * (HASH(M) + d*r)) mod n
-    */
-    SECITEM_TO_MPINT(*digest, &s);        /* s = HASH(M)     */
-
-    /* In the definition of EC signing, digests are truncated
-     * to the length of n in bits.
-     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
-    if (digest->len*8 > ecParams->fieldID.size) {
-        mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size);
-    }
-
-#if EC_DEBUG
-    mp_todecimal(&n, mpstr);
-    printf("n : %s (dec)\n", mpstr);
-    mp_todecimal(&d, mpstr);
-    printf("d : %s (dec)\n", mpstr);
-    mp_tohex(&x1, mpstr);
-    printf("x1: %s\n", mpstr);
-    mp_todecimal(&s, mpstr);
-    printf("digest: %s (decimal)\n", mpstr);
-    mp_todecimal(&r, mpstr);
-    printf("r : %s (dec)\n", mpstr);
-    mp_tohex(&r, mpstr);
-    printf("r : %s\n", mpstr);
-#endif
-
-    CHECK_MPI_OK( mp_invmod(&k, &n, &k) );      /* k = k**-1 mod n */
-    CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) );  /* d = d * r mod n */
-    CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) );  /* s = s + d mod n */
-    CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) );  /* s = s * k mod n */
-
-#if EC_DEBUG
-    mp_todecimal(&s, mpstr);
-    printf("s : %s (dec)\n", mpstr);
-    mp_tohex(&s, mpstr);
-    printf("s : %s\n", mpstr);
-#endif
-
-    /*
-    ** ANSI X9.62, Section 5.3.3, Step 5
-    **
-    ** verify s != 0
-    */
-    if (mp_cmp_z(&s) == 0) {
-        PORT_SetError(SEC_ERROR_NEED_RANDOM);
-        goto cleanup;
-    }
-
-   /*
-    **
-    ** Signature is tuple (r, s)
-    */
-    CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) );
-    CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) );
-finish:
-    signature->len = 2*olen;
-
-    rv = SECSuccess;
-    err = MP_OKAY;
-cleanup:
-    mp_clear(&x1);
-    mp_clear(&d);
-    mp_clear(&k);
-    mp_clear(&r);
-    mp_clear(&s);
-    mp_clear(&n);
-
-    if (kGpoint.data) {
-        PORT_ZFree(kGpoint.data, 2*flen + 1);
-    }
-
-    if (err) {
-        MP_TO_SEC_ERROR(err);
-        rv = SECFailure;
-    }
-
-#if EC_DEBUG
-    printf("ECDSA signing with seed %s\n",
-        (rv == SECSuccess) ? "succeeded" : "failed");
-#endif
-
-   return rv;
-}
-
-/*
-** Computes the ECDSA signature on the digest using the given key
-** and a random seed.
-*/
-SECStatus
-ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest,
-    const unsigned char* random, int randomLen, int kmflag)
-{
-    SECStatus rv = SECFailure;
-    int len;
-    unsigned char *kBytes= NULL;
-
-    if (!key) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        return SECFailure;
-    }
-
-    /* Generate random value k */
-    len = key->ecParams.order.len;
-    kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len,
-        random, randomLen, kmflag);
-    if (kBytes == NULL) goto cleanup;
-
-    /* Generate ECDSA signature with the specified k value */
-    rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag);
-
-cleanup:
-    if (kBytes) {
-        PORT_ZFree(kBytes, len * 2);
-    }
-
-#if EC_DEBUG
-    printf("ECDSA signing %s\n",
-        (rv == SECSuccess) ? "succeeded" : "failed");
-#endif
-
-    return rv;
-}
-
-/*
-** Checks the signature on the given digest using the key provided.
-*/
-SECStatus
-ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
-                 const SECItem *digest, int kmflag)
-{
-    SECStatus rv = SECFailure;
-    mp_int r_, s_;           /* tuple (r', s') is received signature) */
-    mp_int c, u1, u2, v;     /* intermediate values used in verification */
-    mp_int x1;
-    mp_int n;
-    mp_err err = MP_OKAY;
-    ECParams *ecParams = NULL;
-    SECItem pointC = { siBuffer, NULL, 0 };
-    int slen;       /* length in bytes of a half signature (r or s) */
-    int flen;       /* length in bytes of the field size */
-    unsigned olen;  /* length in bytes of the base point order */
-
-#if EC_DEBUG
-    char mpstr[256];
-    printf("ECDSA verification called\n");
-#endif
-
-    /* Initialize MPI integers. */
-    /* must happen before the first potential call to cleanup */
-    MP_DIGITS(&r_) = 0;
-    MP_DIGITS(&s_) = 0;
-    MP_DIGITS(&c) = 0;
-    MP_DIGITS(&u1) = 0;
-    MP_DIGITS(&u2) = 0;
-    MP_DIGITS(&x1) = 0;
-    MP_DIGITS(&v)  = 0;
-    MP_DIGITS(&n)  = 0;
-
-    /* Check args */
-    if (!key || !signature || !digest) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        goto cleanup;
-    }
-
-    ecParams = &(key->ecParams);
-    flen = (ecParams->fieldID.size + 7) >> 3;
-    olen = ecParams->order.len;
-    if (signature->len == 0 || signature->len%2 != 0 ||
-        signature->len > 2*olen) {
-        PORT_SetError(SEC_ERROR_INPUT_LEN);
-        goto cleanup;
-    }
-    slen = signature->len/2;
-
-    SECITEM_AllocItem(NULL, &pointC, 2*flen + 1, kmflag);
-    if (pointC.data == NULL)
-        goto cleanup;
-
-    CHECK_MPI_OK( mp_init(&r_, kmflag) );
-    CHECK_MPI_OK( mp_init(&s_, kmflag) );
-    CHECK_MPI_OK( mp_init(&c, kmflag)  );
-    CHECK_MPI_OK( mp_init(&u1, kmflag) );
-    CHECK_MPI_OK( mp_init(&u2, kmflag) );
-    CHECK_MPI_OK( mp_init(&x1, kmflag)  );
-    CHECK_MPI_OK( mp_init(&v, kmflag)  );
-    CHECK_MPI_OK( mp_init(&n, kmflag)  );
-
-    /*
-    ** Convert received signature (r', s') into MPI integers.
-    */
-    CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) );
-    CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) );
-
-    /*
-    ** ANSI X9.62, Section 5.4.2, Steps 1 and 2
-    **
-    ** Verify that 0 < r' < n and 0 < s' < n
-    */
-    SECITEM_TO_MPINT(ecParams->order, &n);
-    if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
-        mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) {
-        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
-        goto cleanup; /* will return rv == SECFailure */
-    }
-
-    /*
-    ** ANSI X9.62, Section 5.4.2, Step 3
-    **
-    ** c = (s')**-1 mod n
-    */
-    CHECK_MPI_OK( mp_invmod(&s_, &n, &c) );      /* c = (s')**-1 mod n */
-
-    /*
-    ** ANSI X9.62, Section 5.4.2, Step 4
-    **
-    ** u1 = ((HASH(M')) * c) mod n
-    */
-    SECITEM_TO_MPINT(*digest, &u1);                  /* u1 = HASH(M)     */
-
-    /* In the definition of EC signing, digests are truncated
-     * to the length of n in bits.
-     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
-    if (digest->len*8 > ecParams->fieldID.size) {  /* u1 = HASH(M')     */
-        mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size);
-    }
-
-#if EC_DEBUG
-    mp_todecimal(&r_, mpstr);
-    printf("r_: %s (dec)\n", mpstr);
-    mp_todecimal(&s_, mpstr);
-    printf("s_: %s (dec)\n", mpstr);
-    mp_todecimal(&c, mpstr);
-    printf("c : %s (dec)\n", mpstr);
-    mp_todecimal(&u1, mpstr);
-    printf("digest: %s (dec)\n", mpstr);
-#endif
-
-    CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) );  /* u1 = u1 * c mod n */
-
-    /*
-    ** ANSI X9.62, Section 5.4.2, Step 4
-    **
-    ** u2 = ((r') * c) mod n
-    */
-    CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );
-
-    /*
-    ** ANSI X9.62, Section 5.4.3, Step 1
-    **
-    ** Compute u1*G + u2*Q
-    ** Here, A = u1.G     B = u2.Q    and   C = A + B
-    ** If the result, C, is the point at infinity, reject the signature
-    */
-    if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag)
-        != SECSuccess) {
-        rv = SECFailure;
-        goto cleanup;
-    }
-    if (ec_point_at_infinity(&pointC)) {
-        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
-        rv = SECFailure;
-        goto cleanup;
-    }
-
-    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) );
-
-    /*
-    ** ANSI X9.62, Section 5.4.4, Step 2
-    **
-    ** v = x1 mod n
-    */
-    CHECK_MPI_OK( mp_mod(&x1, &n, &v) );
-
-#if EC_DEBUG
-    mp_todecimal(&r_, mpstr);
-    printf("r_: %s (dec)\n", mpstr);
-    mp_todecimal(&v, mpstr);
-    printf("v : %s (dec)\n", mpstr);
-#endif
-
-    /*
-    ** ANSI X9.62, Section 5.4.4, Step 3
-    **
-    ** Verification:  v == r'
-    */
-    if (mp_cmp(&v, &r_)) {
-        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
-        rv = SECFailure; /* Signature failed to verify. */
-    } else {
-        rv = SECSuccess; /* Signature verified. */
-    }
-
-#if EC_DEBUG
-    mp_todecimal(&u1, mpstr);
-    printf("u1: %s (dec)\n", mpstr);
-    mp_todecimal(&u2, mpstr);
-    printf("u2: %s (dec)\n", mpstr);
-    mp_tohex(&x1, mpstr);
-    printf("x1: %s\n", mpstr);
-    mp_todecimal(&v, mpstr);
-    printf("v : %s (dec)\n", mpstr);
-#endif
-
-cleanup:
-    mp_clear(&r_);
-    mp_clear(&s_);
-    mp_clear(&c);
-    mp_clear(&u1);
-    mp_clear(&u2);
-    mp_clear(&x1);
-    mp_clear(&v);
-    mp_clear(&n);
-
-    if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
-    if (err) {
-        MP_TO_SEC_ERROR(err);
-        rv = SECFailure;
-    }
-
-#if EC_DEBUG
-    printf("ECDSA verification %s\n",
-        (rv == SECSuccess) ? "succeeded" : "failed");
-#endif
-
-    return rv;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,1099 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Elliptic Curve Cryptography library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dr Vipul Gupta <vipul.gupta@sun.com> and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mplogic.h"
+#include "ec.h"
+#include "ecl.h"
+
+#include <sys/types.h>
+#ifndef _KERNEL
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <strings.h>
+#endif /* _WIN32 */
+
+#endif
+#include "ecl-exp.h"
+#include "mpi.h"
+#include "ecc_impl.h"
+
+#ifdef _KERNEL
+#define PORT_ZFree(p, l)                bzero((p), (l)); kmem_free((p), (l))
+#else
+#ifndef _WIN32
+#define PORT_ZFree(p, l)                bzero((p), (l)); free((p))
+#else
+#define PORT_ZFree(p, l)                memset((p), 0, (l)); free((p))
+#endif /* _WIN32 */
+#endif
+
+/*
+ * Returns true if pointP is the point at infinity, false otherwise
+ */
+PRBool
+ec_point_at_infinity(SECItem *pointP)
+{
+    unsigned int i;
+
+    for (i = 1; i < pointP->len; i++) {
+        if (pointP->data[i] != 0x00) return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+
+/*
+ * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
+ * the curve whose parameters are encoded in params with base point G.
+ */
+SECStatus
+ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
+             const SECItem *pointP, SECItem *pointQ, int kmflag)
+{
+    mp_int Px, Py, Qx, Qy;
+    mp_int Gx, Gy, order, irreducible, a, b;
+#if 0 /* currently don't support non-named curves */
+    unsigned int irr_arr[5];
+#endif
+    ECGroup *group = NULL;
+    SECStatus rv = SECFailure;
+    mp_err err = MP_OKAY;
+    int len;
+
+#if EC_DEBUG
+    int i;
+    char mpstr[256];
+
+    printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len);
+    for (i = 0; i < params->DEREncoding.len; i++)
+            printf("%02x:", params->DEREncoding.data[i]);
+    printf("\n");
+
+        if (k1 != NULL) {
+                mp_tohex(k1, mpstr);
+                printf("ec_points_mul: scalar k1: %s\n", mpstr);
+                mp_todecimal(k1, mpstr);
+                printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
+        }
+
+        if (k2 != NULL) {
+                mp_tohex(k2, mpstr);
+                printf("ec_points_mul: scalar k2: %s\n", mpstr);
+                mp_todecimal(k2, mpstr);
+                printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
+        }
+
+        if (pointP != NULL) {
+                printf("ec_points_mul: pointP [len=%d]:", pointP->len);
+                for (i = 0; i < pointP->len; i++)
+                        printf("%02x:", pointP->data[i]);
+                printf("\n");
+        }
+#endif
+
+        /* NOTE: We only support uncompressed points for now */
+        len = (params->fieldID.size + 7) >> 3;
+        if (pointP != NULL) {
+                if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
+                        (pointP->len != (2 * len + 1))) {
+                        return SECFailure;
+                };
+        }
+
+        MP_DIGITS(&Px) = 0;
+        MP_DIGITS(&Py) = 0;
+        MP_DIGITS(&Qx) = 0;
+        MP_DIGITS(&Qy) = 0;
+        MP_DIGITS(&Gx) = 0;
+        MP_DIGITS(&Gy) = 0;
+        MP_DIGITS(&order) = 0;
+        MP_DIGITS(&irreducible) = 0;
+        MP_DIGITS(&a) = 0;
+        MP_DIGITS(&b) = 0;
+        CHECK_MPI_OK( mp_init(&Px, kmflag) );
+        CHECK_MPI_OK( mp_init(&Py, kmflag) );
+        CHECK_MPI_OK( mp_init(&Qx, kmflag) );
+        CHECK_MPI_OK( mp_init(&Qy, kmflag) );
+        CHECK_MPI_OK( mp_init(&Gx, kmflag) );
+        CHECK_MPI_OK( mp_init(&Gy, kmflag) );
+        CHECK_MPI_OK( mp_init(&order, kmflag) );
+        CHECK_MPI_OK( mp_init(&irreducible, kmflag) );
+        CHECK_MPI_OK( mp_init(&a, kmflag) );
+        CHECK_MPI_OK( mp_init(&b, kmflag) );
+
+        if ((k2 != NULL) && (pointP != NULL)) {
+                /* Initialize Px and Py */
+                CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
+                CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
+        }
+
+        /* construct from named params, if possible */
+        if (params->name != ECCurve_noName) {
+                group = ECGroup_fromName(params->name, kmflag);
+        }
+
+#if 0 /* currently don't support non-named curves */
+        if (group == NULL) {
+                /* Set up mp_ints containing the curve coefficients */
+                CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1,
+                                                                                  (mp_size) len) );
+                CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len,
+                                                                                  (mp_size) len) );
+                SECITEM_TO_MPINT( params->order, &order );
+                SECITEM_TO_MPINT( params->curve.a, &a );
+                SECITEM_TO_MPINT( params->curve.b, &b );
+                if (params->fieldID.type == ec_field_GFp) {
+                        SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
+                        group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor);
+                } else {
+                        SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
+                        irr_arr[0] = params->fieldID.size;
+                        irr_arr[1] = params->fieldID.k1;
+                        irr_arr[2] = params->fieldID.k2;
+                        irr_arr[3] = params->fieldID.k3;
+                        irr_arr[4] = 0;
+                        group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor);
+                }
+        }
+#endif
+        if (group == NULL)
+                goto cleanup;
+
+        if ((k2 != NULL) && (pointP != NULL)) {
+                CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
+        } else {
+                CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
+    }
+
+    /* Construct the SECItem representation of point Q */
+    pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
+    CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
+                                      (mp_size) len) );
+    CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
+                                      (mp_size) len) );
+
+    rv = SECSuccess;
+
+#if EC_DEBUG
+    printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
+    for (i = 0; i < pointQ->len; i++)
+            printf("%02x:", pointQ->data[i]);
+    printf("\n");
+#endif
+
+cleanup:
+    ECGroup_free(group);
+    mp_clear(&Px);
+    mp_clear(&Py);
+    mp_clear(&Qx);
+    mp_clear(&Qy);
+    mp_clear(&Gx);
+    mp_clear(&Gy);
+    mp_clear(&order);
+    mp_clear(&irreducible);
+    mp_clear(&a);
+    mp_clear(&b);
+    if (err) {
+        MP_TO_SEC_ERROR(err);
+        rv = SECFailure;
+    }
+
+    return rv;
+}
+
+/* Generates a new EC key pair. The private key is a supplied
+ * value and the public key is the result of performing a scalar
+ * point multiplication of that value with the curve's base point.
+ */
+SECStatus
+ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
+    const unsigned char *privKeyBytes, int privKeyLen, int kmflag)
+{
+    SECStatus rv = SECFailure;
+    PRArenaPool *arena;
+    ECPrivateKey *key;
+    mp_int k;
+    mp_err err = MP_OKAY;
+    int len;
+
+#if EC_DEBUG
+    printf("ec_NewKey called\n");
+#endif
+
+#ifndef _WIN32
+int printf();
+#endif /* _WIN32 */
+
+    if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    /* Initialize an arena for the EC key. */
+    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
+        return SECFailure;
+
+    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey),
+        kmflag);
+    if (!key) {
+        PORT_FreeArena(arena, PR_TRUE);
+        return SECFailure;
+    }
+
+    /* Set the version number (SEC 1 section C.4 says it should be 1) */
+    SECITEM_AllocItem(arena, &key->version, 1, kmflag);
+    key->version.data[0] = 1;
+
+    /* Copy all of the fields from the ECParams argument to the
+     * ECParams structure within the private key.
+     */
+    key->ecParams.arena = arena;
+    key->ecParams.type = ecParams->type;
+    key->ecParams.fieldID.size = ecParams->fieldID.size;
+    key->ecParams.fieldID.type = ecParams->fieldID.type;
+    if (ecParams->fieldID.type == ec_field_GFp) {
+        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
+            &ecParams->fieldID.u.prime, kmflag));
+    } else {
+        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
+            &ecParams->fieldID.u.poly, kmflag));
+    }
+    key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
+    key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
+    key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
+        &ecParams->curve.a, kmflag));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
+        &ecParams->curve.b, kmflag));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
+        &ecParams->curve.seed, kmflag));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
+        &ecParams->base, kmflag));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
+        &ecParams->order, kmflag));
+    key->ecParams.cofactor = ecParams->cofactor;
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
+        &ecParams->DEREncoding, kmflag));
+    key->ecParams.name = ecParams->name;
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
+        &ecParams->curveOID, kmflag));
+
+    len = (ecParams->fieldID.size + 7) >> 3;
+    SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1, kmflag);
+    len = ecParams->order.len;
+    SECITEM_AllocItem(arena, &key->privateValue, len, kmflag);
+
+    /* Copy private key */
+    if (privKeyLen >= len) {
+        memcpy(key->privateValue.data, privKeyBytes, len);
+    } else {
+        memset(key->privateValue.data, 0, (len - privKeyLen));
+        memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
+    }
+
+    /* Compute corresponding public key */
+    MP_DIGITS(&k) = 0;
+    CHECK_MPI_OK( mp_init(&k, kmflag) );
+    CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
+        (mp_size) len) );
+
+    rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag);
+    if (rv != SECSuccess) goto cleanup;
+    *privKey = key;
+
+cleanup:
+    mp_clear(&k);
+    if (rv)
+        PORT_FreeArena(arena, PR_TRUE);
+
+#if EC_DEBUG
+    printf("ec_NewKey returning %s\n",
+        (rv == SECSuccess) ? "success" : "failure");
+#endif
+
+    return rv;
+
+}
+
+/* Generates a new EC key pair. The private key is a supplied
+ * random value (in seed) and the public key is the result of
+ * performing a scalar point multiplication of that value with
+ * the curve's base point.
+ */
+SECStatus
+EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
+    const unsigned char *seed, int seedlen, int kmflag)
+{
+    SECStatus rv = SECFailure;
+    rv = ec_NewKey(ecParams, privKey, seed, seedlen, kmflag);
+    return rv;
+}
+
+/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
+ * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
+ * random number generator.
+ *
+ * Parameters
+ * - order: a buffer that holds the curve's group order
+ * - len: the length in octets of the order buffer
+ * - random: a buffer of 2 * len random bytes
+ * - randomlen: the length in octets of the random buffer
+ *
+ * Return Value
+ * Returns a buffer of len octets that holds the private key. The caller
+ * is responsible for freeing the buffer with PORT_ZFree.
+ */
+static unsigned char *
+ec_GenerateRandomPrivateKey(const unsigned char *order, int len,
+    const unsigned char *random, int randomlen, int kmflag)
+{
+    SECStatus rv = SECSuccess;
+    mp_err err;
+    unsigned char *privKeyBytes = NULL;
+    mp_int privKeyVal, order_1, one;
+
+    MP_DIGITS(&privKeyVal) = 0;
+    MP_DIGITS(&order_1) = 0;
+    MP_DIGITS(&one) = 0;
+    CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) );
+    CHECK_MPI_OK( mp_init(&order_1, kmflag) );
+    CHECK_MPI_OK( mp_init(&one, kmflag) );
+
+    /*
+     * Reduces the 2*len buffer of random bytes modulo the group order.
+     */
+    if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
+    if (randomlen != 2 * len) {
+        randomlen = 2 * len;
+    }
+    /* No need to generate - random bytes are now supplied */
+    /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/
+    memcpy(privKeyBytes, random, randomlen);
+
+    CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
+    CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
+    CHECK_MPI_OK( mp_set_int(&one, 1) );
+    CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
+    CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
+    CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
+    CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
+    memset(privKeyBytes+len, 0, len);
+cleanup:
+    mp_clear(&privKeyVal);
+    mp_clear(&order_1);
+    mp_clear(&one);
+    if (err < MP_OKAY) {
+        MP_TO_SEC_ERROR(err);
+        rv = SECFailure;
+    }
+    if (rv != SECSuccess && privKeyBytes) {
+#ifdef _KERNEL
+        kmem_free(privKeyBytes, 2*len);
+#else
+        free(privKeyBytes);
+#endif
+        privKeyBytes = NULL;
+    }
+    return privKeyBytes;
+}
+
+/* Generates a new EC key pair. The private key is a random value and
+ * the public key is the result of performing a scalar point multiplication
+ * of that value with the curve's base point.
+ */
+SECStatus
+EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
+    const unsigned char* random, int randomlen, int kmflag)
+{
+    SECStatus rv = SECFailure;
+    int len;
+    unsigned char *privKeyBytes = NULL;
+
+    if (!ecParams) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    len = ecParams->order.len;
+    privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len,
+        random, randomlen, kmflag);
+    if (privKeyBytes == NULL) goto cleanup;
+    /* generate public key */
+    CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len, kmflag) );
+
+cleanup:
+    if (privKeyBytes) {
+        PORT_ZFree(privKeyBytes, len * 2);
+    }
+#if EC_DEBUG
+    printf("EC_NewKey returning %s\n",
+        (rv == SECSuccess) ? "success" : "failure");
+#endif
+
+    return rv;
+}
+
+/* Validates an EC public key as described in Section 5.2.2 of
+ * X9.62. The ECDH primitive when used without the cofactor does
+ * not address small subgroup attacks, which may occur when the
+ * public key is not valid. These attacks can be prevented by
+ * validating the public key before using ECDH.
+ */
+SECStatus
+EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue, int kmflag)
+{
+    mp_int Px, Py;
+    ECGroup *group = NULL;
+    SECStatus rv = SECFailure;
+    mp_err err = MP_OKAY;
+    int len;
+
+    if (!ecParams || !publicValue) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    /* NOTE: We only support uncompressed points for now */
+    len = (ecParams->fieldID.size + 7) >> 3;
+    if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+        PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
+        return SECFailure;
+    } else if (publicValue->len != (2 * len + 1)) {
+        PORT_SetError(SEC_ERROR_BAD_KEY);
+        return SECFailure;
+    }
+
+    MP_DIGITS(&Px) = 0;
+    MP_DIGITS(&Py) = 0;
+    CHECK_MPI_OK( mp_init(&Px, kmflag) );
+    CHECK_MPI_OK( mp_init(&Py, kmflag) );
+
+    /* Initialize Px and Py */
+    CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
+    CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );
+
+    /* construct from named params */
+    group = ECGroup_fromName(ecParams->name, kmflag);
+    if (group == NULL) {
+        /*
+         * ECGroup_fromName fails if ecParams->name is not a valid
+         * ECCurveName value, or if we run out of memory, or perhaps
+         * for other reasons.  Unfortunately if ecParams->name is a
+         * valid ECCurveName value, we don't know what the right error
+         * code should be because ECGroup_fromName doesn't return an
+         * error code to the caller.  Set err to MP_UNDEF because
+         * that's what ECGroup_fromName uses internally.
+         */
+        if ((ecParams->name <= ECCurve_noName) ||
+            (ecParams->name >= ECCurve_pastLastCurve)) {
+            err = MP_BADARG;
+        } else {
+            err = MP_UNDEF;
+        }
+        goto cleanup;
+    }
+
+    /* validate public point */
+    if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
+        if (err == MP_NO) {
+            PORT_SetError(SEC_ERROR_BAD_KEY);
+            rv = SECFailure;
+            err = MP_OKAY;  /* don't change the error code */
+        }
+        goto cleanup;
+    }
+
+    rv = SECSuccess;
+
+cleanup:
+    ECGroup_free(group);
+    mp_clear(&Px);
+    mp_clear(&Py);
+    if (err) {
+        MP_TO_SEC_ERROR(err);
+        rv = SECFailure;
+    }
+    return rv;
+}
+
+/*
+** Performs an ECDH key derivation by computing the scalar point
+** multiplication of privateValue and publicValue (with or without the
+** cofactor) and returns the x-coordinate of the resulting elliptic
+** curve point in derived secret.  If successful, derivedSecret->data
+** is set to the address of the newly allocated buffer containing the
+** derived secret, and derivedSecret->len is the size of the secret
+** produced. It is the caller's responsibility to free the allocated
+** buffer containing the derived secret.
+*/
+SECStatus
+ECDH_Derive(SECItem  *publicValue,
+            ECParams *ecParams,
+            SECItem  *privateValue,
+            PRBool    withCofactor,
+            SECItem  *derivedSecret,
+            int kmflag)
+{
+    SECStatus rv = SECFailure;
+    unsigned int len = 0;
+    SECItem pointQ = {siBuffer, NULL, 0};
+    mp_int k; /* to hold the private value */
+    mp_int cofactor;
+    mp_err err = MP_OKAY;
+#if EC_DEBUG
+    int i;
+#endif
+
+    if (!publicValue || !ecParams || !privateValue ||
+        !derivedSecret) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    memset(derivedSecret, 0, sizeof *derivedSecret);
+    len = (ecParams->fieldID.size + 7) >> 3;
+    pointQ.len = 2*len + 1;
+    if ((pointQ.data = PORT_Alloc(2*len + 1, kmflag)) == NULL) goto cleanup;
+
+    MP_DIGITS(&k) = 0;
+    CHECK_MPI_OK( mp_init(&k, kmflag) );
+    CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
+                                          (mp_size) privateValue->len) );
+
+    if (withCofactor && (ecParams->cofactor != 1)) {
+            /* multiply k with the cofactor */
+            MP_DIGITS(&cofactor) = 0;
+            CHECK_MPI_OK( mp_init(&cofactor, kmflag) );
+            mp_set(&cofactor, ecParams->cofactor);
+            CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
+    }
+
+    /* Multiply our private key and peer's public point */
+    if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag) != SECSuccess) ||
+        ec_point_at_infinity(&pointQ))
+        goto cleanup;
+
+    /* Allocate memory for the derived secret and copy
+     * the x co-ordinate of pointQ into it.
+     */
+    SECITEM_AllocItem(NULL, derivedSecret, len, kmflag);
+    memcpy(derivedSecret->data, pointQ.data + 1, len);
+
+    rv = SECSuccess;
+
+#if EC_DEBUG
+    printf("derived_secret:\n");
+    for (i = 0; i < derivedSecret->len; i++)
+        printf("%02x:", derivedSecret->data[i]);
+    printf("\n");
+#endif
+
+cleanup:
+    mp_clear(&k);
+
+    if (pointQ.data) {
+        PORT_ZFree(pointQ.data, 2*len + 1);
+    }
+
+    return rv;
+}
+
+/* Computes the ECDSA signature (a concatenation of two values r and s)
+ * on the digest using the given key and the random value kb (used in
+ * computing s).
+ */
+SECStatus
+ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
+    const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag)
+{
+    SECStatus rv = SECFailure;
+    mp_int x1;
+    mp_int d, k;     /* private key, random integer */
+    mp_int r, s;     /* tuple (r, s) is the signature */
+    mp_int n;
+    mp_err err = MP_OKAY;
+    ECParams *ecParams = NULL;
+    SECItem kGpoint = { siBuffer, NULL, 0};
+    int flen = 0;    /* length in bytes of the field size */
+    unsigned olen;   /* length in bytes of the base point order */
+
+#if EC_DEBUG
+    char mpstr[256];
+#endif
+
+    /* Initialize MPI integers. */
+    /* must happen before the first potential call to cleanup */
+    MP_DIGITS(&x1) = 0;
+    MP_DIGITS(&d) = 0;
+    MP_DIGITS(&k) = 0;
+    MP_DIGITS(&r) = 0;
+    MP_DIGITS(&s) = 0;
+    MP_DIGITS(&n) = 0;
+
+    /* Check args */
+    if (!key || !signature || !digest || !kb || (kblen < 0)) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        goto cleanup;
+    }
+
+    ecParams = &(key->ecParams);
+    flen = (ecParams->fieldID.size + 7) >> 3;
+    olen = ecParams->order.len;
+    if (signature->data == NULL) {
+        /* a call to get the signature length only */
+        goto finish;
+    }
+    if (signature->len < 2*olen) {
+        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+        rv = SECBufferTooSmall;
+        goto cleanup;
+    }
+
+
+    CHECK_MPI_OK( mp_init(&x1, kmflag) );
+    CHECK_MPI_OK( mp_init(&d, kmflag) );
+    CHECK_MPI_OK( mp_init(&k, kmflag) );
+    CHECK_MPI_OK( mp_init(&r, kmflag) );
+    CHECK_MPI_OK( mp_init(&s, kmflag) );
+    CHECK_MPI_OK( mp_init(&n, kmflag) );
+
+    SECITEM_TO_MPINT( ecParams->order, &n );
+    SECITEM_TO_MPINT( key->privateValue, &d );
+    CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
+    /* Make sure k is in the interval [1, n-1] */
+    if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
+#if EC_DEBUG
+        printf("k is outside [1, n-1]\n");
+        mp_tohex(&k, mpstr);
+        printf("k : %s \n", mpstr);
+        mp_tohex(&n, mpstr);
+        printf("n : %s \n", mpstr);
+#endif
+        PORT_SetError(SEC_ERROR_NEED_RANDOM);
+        goto cleanup;
+    }
+
+    /*
+    ** ANSI X9.62, Section 5.3.2, Step 2
+    **
+    ** Compute kG
+    */
+    kGpoint.len = 2*flen + 1;
+    kGpoint.data = PORT_Alloc(2*flen + 1, kmflag);
+    if ((kGpoint.data == NULL) ||
+        (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag)
+            != SECSuccess))
+        goto cleanup;
+
+    /*
+    ** ANSI X9.62, Section 5.3.3, Step 1
+    **
+    ** Extract the x co-ordinate of kG into x1
+    */
+    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
+                                          (mp_size) flen) );
+
+    /*
+    ** ANSI X9.62, Section 5.3.3, Step 2
+    **
+    ** r = x1 mod n  NOTE: n is the order of the curve
+    */
+    CHECK_MPI_OK( mp_mod(&x1, &n, &r) );
+
+    /*
+    ** ANSI X9.62, Section 5.3.3, Step 3
+    **
+    ** verify r != 0
+    */
+    if (mp_cmp_z(&r) == 0) {
+        PORT_SetError(SEC_ERROR_NEED_RANDOM);
+        goto cleanup;
+    }
+
+    /*
+    ** ANSI X9.62, Section 5.3.3, Step 4
+    **
+    ** s = (k**-1 * (HASH(M) + d*r)) mod n
+    */
+    SECITEM_TO_MPINT(*digest, &s);        /* s = HASH(M)     */
+
+    /* In the definition of EC signing, digests are truncated
+     * to the length of n in bits.
+     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
+    if (digest->len*8 > ecParams->fieldID.size) {
+        mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size);
+    }
+
+#if EC_DEBUG
+    mp_todecimal(&n, mpstr);
+    printf("n : %s (dec)\n", mpstr);
+    mp_todecimal(&d, mpstr);
+    printf("d : %s (dec)\n", mpstr);
+    mp_tohex(&x1, mpstr);
+    printf("x1: %s\n", mpstr);
+    mp_todecimal(&s, mpstr);
+    printf("digest: %s (decimal)\n", mpstr);
+    mp_todecimal(&r, mpstr);
+    printf("r : %s (dec)\n", mpstr);
+    mp_tohex(&r, mpstr);
+    printf("r : %s\n", mpstr);
+#endif
+
+    CHECK_MPI_OK( mp_invmod(&k, &n, &k) );      /* k = k**-1 mod n */
+    CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) );  /* d = d * r mod n */
+    CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) );  /* s = s + d mod n */
+    CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) );  /* s = s * k mod n */
+
+#if EC_DEBUG
+    mp_todecimal(&s, mpstr);
+    printf("s : %s (dec)\n", mpstr);
+    mp_tohex(&s, mpstr);
+    printf("s : %s\n", mpstr);
+#endif
+
+    /*
+    ** ANSI X9.62, Section 5.3.3, Step 5
+    **
+    ** verify s != 0
+    */
+    if (mp_cmp_z(&s) == 0) {
+        PORT_SetError(SEC_ERROR_NEED_RANDOM);
+        goto cleanup;
+    }
+
+   /*
+    **
+    ** Signature is tuple (r, s)
+    */
+    CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) );
+    CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) );
+finish:
+    signature->len = 2*olen;
+
+    rv = SECSuccess;
+    err = MP_OKAY;
+cleanup:
+    mp_clear(&x1);
+    mp_clear(&d);
+    mp_clear(&k);
+    mp_clear(&r);
+    mp_clear(&s);
+    mp_clear(&n);
+
+    if (kGpoint.data) {
+        PORT_ZFree(kGpoint.data, 2*flen + 1);
+    }
+
+    if (err) {
+        MP_TO_SEC_ERROR(err);
+        rv = SECFailure;
+    }
+
+#if EC_DEBUG
+    printf("ECDSA signing with seed %s\n",
+        (rv == SECSuccess) ? "succeeded" : "failed");
+#endif
+
+   return rv;
+}
+
+/*
+** Computes the ECDSA signature on the digest using the given key
+** and a random seed.
+*/
+SECStatus
+ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest,
+    const unsigned char* random, int randomLen, int kmflag)
+{
+    SECStatus rv = SECFailure;
+    int len;
+    unsigned char *kBytes= NULL;
+
+    if (!key) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    /* Generate random value k */
+    len = key->ecParams.order.len;
+    kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len,
+        random, randomLen, kmflag);
+    if (kBytes == NULL) goto cleanup;
+
+    /* Generate ECDSA signature with the specified k value */
+    rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag);
+
+cleanup:
+    if (kBytes) {
+        PORT_ZFree(kBytes, len * 2);
+    }
+
+#if EC_DEBUG
+    printf("ECDSA signing %s\n",
+        (rv == SECSuccess) ? "succeeded" : "failed");
+#endif
+
+    return rv;
+}
+
+/*
+** Checks the signature on the given digest using the key provided.
+*/
+SECStatus
+ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
+                 const SECItem *digest, int kmflag)
+{
+    SECStatus rv = SECFailure;
+    mp_int r_, s_;           /* tuple (r', s') is received signature) */
+    mp_int c, u1, u2, v;     /* intermediate values used in verification */
+    mp_int x1;
+    mp_int n;
+    mp_err err = MP_OKAY;
+    ECParams *ecParams = NULL;
+    SECItem pointC = { siBuffer, NULL, 0 };
+    int slen;       /* length in bytes of a half signature (r or s) */
+    int flen;       /* length in bytes of the field size */
+    unsigned olen;  /* length in bytes of the base point order */
+
+#if EC_DEBUG
+    char mpstr[256];
+    printf("ECDSA verification called\n");
+#endif
+
+    /* Initialize MPI integers. */
+    /* must happen before the first potential call to cleanup */
+    MP_DIGITS(&r_) = 0;
+    MP_DIGITS(&s_) = 0;
+    MP_DIGITS(&c) = 0;
+    MP_DIGITS(&u1) = 0;
+    MP_DIGITS(&u2) = 0;
+    MP_DIGITS(&x1) = 0;
+    MP_DIGITS(&v)  = 0;
+    MP_DIGITS(&n)  = 0;
+
+    /* Check args */
+    if (!key || !signature || !digest) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        goto cleanup;
+    }
+
+    ecParams = &(key->ecParams);
+    flen = (ecParams->fieldID.size + 7) >> 3;
+    olen = ecParams->order.len;
+    if (signature->len == 0 || signature->len%2 != 0 ||
+        signature->len > 2*olen) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        goto cleanup;
+    }
+    slen = signature->len/2;
+
+    SECITEM_AllocItem(NULL, &pointC, 2*flen + 1, kmflag);
+    if (pointC.data == NULL)
+        goto cleanup;
+
+    CHECK_MPI_OK( mp_init(&r_, kmflag) );
+    CHECK_MPI_OK( mp_init(&s_, kmflag) );
+    CHECK_MPI_OK( mp_init(&c, kmflag)  );
+    CHECK_MPI_OK( mp_init(&u1, kmflag) );
+    CHECK_MPI_OK( mp_init(&u2, kmflag) );
+    CHECK_MPI_OK( mp_init(&x1, kmflag)  );
+    CHECK_MPI_OK( mp_init(&v, kmflag)  );
+    CHECK_MPI_OK( mp_init(&n, kmflag)  );
+
+    /*
+    ** Convert received signature (r', s') into MPI integers.
+    */
+    CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) );
+    CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) );
+
+    /*
+    ** ANSI X9.62, Section 5.4.2, Steps 1 and 2
+    **
+    ** Verify that 0 < r' < n and 0 < s' < n
+    */
+    SECITEM_TO_MPINT(ecParams->order, &n);
+    if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
+        mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) {
+        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+        goto cleanup; /* will return rv == SECFailure */
+    }
+
+    /*
+    ** ANSI X9.62, Section 5.4.2, Step 3
+    **
+    ** c = (s')**-1 mod n
+    */
+    CHECK_MPI_OK( mp_invmod(&s_, &n, &c) );      /* c = (s')**-1 mod n */
+
+    /*
+    ** ANSI X9.62, Section 5.4.2, Step 4
+    **
+    ** u1 = ((HASH(M')) * c) mod n
+    */
+    SECITEM_TO_MPINT(*digest, &u1);                  /* u1 = HASH(M)     */
+
+    /* In the definition of EC signing, digests are truncated
+     * to the length of n in bits.
+     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
+    if (digest->len*8 > ecParams->fieldID.size) {  /* u1 = HASH(M')     */
+        mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size);
+    }
+
+#if EC_DEBUG
+    mp_todecimal(&r_, mpstr);
+    printf("r_: %s (dec)\n", mpstr);
+    mp_todecimal(&s_, mpstr);
+    printf("s_: %s (dec)\n", mpstr);
+    mp_todecimal(&c, mpstr);
+    printf("c : %s (dec)\n", mpstr);
+    mp_todecimal(&u1, mpstr);
+    printf("digest: %s (dec)\n", mpstr);
+#endif
+
+    CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) );  /* u1 = u1 * c mod n */
+
+    /*
+    ** ANSI X9.62, Section 5.4.2, Step 4
+    **
+    ** u2 = ((r') * c) mod n
+    */
+    CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );
+
+    /*
+    ** ANSI X9.62, Section 5.4.3, Step 1
+    **
+    ** Compute u1*G + u2*Q
+    ** Here, A = u1.G     B = u2.Q    and   C = A + B
+    ** If the result, C, is the point at infinity, reject the signature
+    */
+    if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag)
+        != SECSuccess) {
+        rv = SECFailure;
+        goto cleanup;
+    }
+    if (ec_point_at_infinity(&pointC)) {
+        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+        rv = SECFailure;
+        goto cleanup;
+    }
+
+    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) );
+
+    /*
+    ** ANSI X9.62, Section 5.4.4, Step 2
+    **
+    ** v = x1 mod n
+    */
+    CHECK_MPI_OK( mp_mod(&x1, &n, &v) );
+
+#if EC_DEBUG
+    mp_todecimal(&r_, mpstr);
+    printf("r_: %s (dec)\n", mpstr);
+    mp_todecimal(&v, mpstr);
+    printf("v : %s (dec)\n", mpstr);
+#endif
+
+    /*
+    ** ANSI X9.62, Section 5.4.4, Step 3
+    **
+    ** Verification:  v == r'
+    */
+    if (mp_cmp(&v, &r_)) {
+        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+        rv = SECFailure; /* Signature failed to verify. */
+    } else {
+        rv = SECSuccess; /* Signature verified. */
+    }
+
+#if EC_DEBUG
+    mp_todecimal(&u1, mpstr);
+    printf("u1: %s (dec)\n", mpstr);
+    mp_todecimal(&u2, mpstr);
+    printf("u2: %s (dec)\n", mpstr);
+    mp_tohex(&x1, mpstr);
+    printf("x1: %s\n", mpstr);
+    mp_todecimal(&v, mpstr);
+    printf("v : %s (dec)\n", mpstr);
+#endif
+
+cleanup:
+    mp_clear(&r_);
+    mp_clear(&s_);
+    mp_clear(&c);
+    mp_clear(&u1);
+    mp_clear(&u2);
+    mp_clear(&x1);
+    mp_clear(&v);
+    mp_clear(&n);
+
+    if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
+    if (err) {
+        MP_TO_SEC_ERROR(err);
+        rv = SECFailure;
+    }
+
+#if EC_DEBUG
+    printf("ECDSA verification %s\n",
+        (rv == SECSuccess) ? "succeeded" : "failed");
+#endif
+
+    return rv;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,72 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Elliptic Curve Cryptography library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef __ec_h_
+#define __ec_h_
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#define EC_DEBUG                          0
+#define EC_POINT_FORM_COMPRESSED_Y0    0x02
+#define EC_POINT_FORM_COMPRESSED_Y1    0x03
+#define EC_POINT_FORM_UNCOMPRESSED     0x04
+#define EC_POINT_FORM_HYBRID_Y0        0x06
+#define EC_POINT_FORM_HYBRID_Y1        0x07
+
+#define ANSI_X962_CURVE_OID_TOTAL_LEN    10
+#define SECG_CURVE_OID_TOTAL_LEN          7
+
+#endif /* __ec_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,146 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for binary polynomial field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _EC2_H
+#define _EC2_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecl-priv.h"
+
+/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
+mp_err ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py);
+
+/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
+mp_err ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py);
+
+/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
+ * qy). Uses affine coordinates. */
+mp_err ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py,
+                                                  const mp_int *qx, const mp_int *qy, mp_int *rx,
+                                                  mp_int *ry, const ECGroup *group);
+
+/* Computes R = P - Q.  Uses affine coordinates. */
+mp_err ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py,
+                                                  const mp_int *qx, const mp_int *qy, mp_int *rx,
+                                                  mp_int *ry, const ECGroup *group);
+
+/* Computes R = 2P.  Uses affine coordinates. */
+mp_err ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+                                                  mp_int *ry, const ECGroup *group);
+
+/* Validates a point on a GF2m curve. */
+mp_err ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the irreducible that
+ * determines the field GF2m.  Uses affine coordinates. */
+mp_err ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px,
+                                                  const mp_int *py, mp_int *rx, mp_int *ry,
+                                                  const ECGroup *group);
+#endif
+
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the irreducible that
+ * determines the field GF2m.  Uses Montgomery projective coordinates. */
+mp_err ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px,
+                                                   const mp_int *py, mp_int *rx, mp_int *ry,
+                                                   const ECGroup *group);
+
+#ifdef ECL_ENABLE_GF2M_PROJ
+/* Converts a point P(px, py) from affine coordinates to projective
+ * coordinates R(rx, ry, rz). */
+mp_err ec_GF2m_pt_aff2proj(const mp_int *px, const mp_int *py, mp_int *rx,
+                                                   mp_int *ry, mp_int *rz, const ECGroup *group);
+
+/* Converts a point P(px, py, pz) from projective coordinates to affine
+ * coordinates R(rx, ry). */
+mp_err ec_GF2m_pt_proj2aff(const mp_int *px, const mp_int *py,
+                                                   const mp_int *pz, mp_int *rx, mp_int *ry,
+                                                   const ECGroup *group);
+
+/* Checks if point P(px, py, pz) is at infinity.  Uses projective
+ * coordinates. */
+mp_err ec_GF2m_pt_is_inf_proj(const mp_int *px, const mp_int *py,
+                                                          const mp_int *pz);
+
+/* Sets P(px, py, pz) to be the point at infinity.  Uses projective
+ * coordinates. */
+mp_err ec_GF2m_pt_set_inf_proj(mp_int *px, mp_int *py, mp_int *pz);
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, qz).  Uses projective coordinates. */
+mp_err ec_GF2m_pt_add_proj(const mp_int *px, const mp_int *py,
+                                                   const mp_int *pz, const mp_int *qx,
+                                                   const mp_int *qy, mp_int *rx, mp_int *ry,
+                                                   mp_int *rz, const ECGroup *group);
+
+/* Computes R = 2P.  Uses projective coordinates. */
+mp_err ec_GF2m_pt_dbl_proj(const mp_int *px, const mp_int *py,
+                                                   const mp_int *pz, mp_int *rx, mp_int *ry,
+                                                   mp_int *rz, const ECGroup *group);
+
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GF2m.  Uses projective coordinates. */
+mp_err ec_GF2m_pt_mul_proj(const mp_int *n, const mp_int *px,
+                                                   const mp_int *py, mp_int *rx, mp_int *ry,
+                                                   const ECGroup *group);
+#endif
+
+#endif /* _EC2_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_163.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,281 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for binary polynomial field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ *   Stephen Fung <fungstep@hotmail.com>, and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ec2.h"
+#include "mp_gf2m.h"
+#include "mp_gf2m-priv.h"
+#include "mpi.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Fast reduction for polynomials over a 163-bit curve. Assumes reduction
+ * polynomial with terms {163, 7, 6, 3, 0}. */
+mp_err
+ec_GF2m_163_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit *u, z;
+
+        if (a != r) {
+                MP_CHECKOK(mp_copy(a, r));
+        }
+#ifdef ECL_SIXTY_FOUR_BIT
+        if (MP_USED(r) < 6) {
+                MP_CHECKOK(s_mp_pad(r, 6));
+        }
+        u = MP_DIGITS(r);
+        MP_USED(r) = 6;
+
+        /* u[5] only has 6 significant bits */
+        z = u[5];
+        u[2] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
+        z = u[4];
+        u[2] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
+        u[1] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
+        z = u[3];
+        u[1] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
+        u[0] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
+        z = u[2] >> 35;                         /* z only has 29 significant bits */
+        u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
+        /* clear bits above 163 */
+        u[5] = u[4] = u[3] = 0;
+        u[2] ^= z << 35;
+#else
+        if (MP_USED(r) < 11) {
+                MP_CHECKOK(s_mp_pad(r, 11));
+        }
+        u = MP_DIGITS(r);
+        MP_USED(r) = 11;
+
+        /* u[11] only has 6 significant bits */
+        z = u[10];
+        u[5] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+        u[4] ^= (z << 29);
+        z = u[9];
+        u[5] ^= (z >> 28) ^ (z >> 29);
+        u[4] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+        u[3] ^= (z << 29);
+        z = u[8];
+        u[4] ^= (z >> 28) ^ (z >> 29);
+        u[3] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+        u[2] ^= (z << 29);
+        z = u[7];
+        u[3] ^= (z >> 28) ^ (z >> 29);
+        u[2] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+        u[1] ^= (z << 29);
+        z = u[6];
+        u[2] ^= (z >> 28) ^ (z >> 29);
+        u[1] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+        u[0] ^= (z << 29);
+        z = u[5] >> 3;                          /* z only has 29 significant bits */
+        u[1] ^= (z >> 25) ^ (z >> 26);
+        u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
+        /* clear bits above 163 */
+        u[11] = u[10] = u[9] = u[8] = u[7] = u[6] = 0;
+        u[5] ^= z << 3;
+#endif
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* Fast squaring for polynomials over a 163-bit curve. Assumes reduction
+ * polynomial with terms {163, 7, 6, 3, 0}. */
+mp_err
+ec_GF2m_163_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit *u, *v;
+
+        v = MP_DIGITS(a);
+
+#ifdef ECL_SIXTY_FOUR_BIT
+        if (MP_USED(a) < 3) {
+                return mp_bsqrmod(a, meth->irr_arr, r);
+        }
+        if (MP_USED(r) < 6) {
+                MP_CHECKOK(s_mp_pad(r, 6));
+        }
+        MP_USED(r) = 6;
+#else
+        if (MP_USED(a) < 6) {
+                return mp_bsqrmod(a, meth->irr_arr, r);
+        }
+        if (MP_USED(r) < 12) {
+                MP_CHECKOK(s_mp_pad(r, 12));
+        }
+        MP_USED(r) = 12;
+#endif
+        u = MP_DIGITS(r);
+
+#ifdef ECL_THIRTY_TWO_BIT
+        u[11] = gf2m_SQR1(v[5]);
+        u[10] = gf2m_SQR0(v[5]);
+        u[9] = gf2m_SQR1(v[4]);
+        u[8] = gf2m_SQR0(v[4]);
+        u[7] = gf2m_SQR1(v[3]);
+        u[6] = gf2m_SQR0(v[3]);
+#endif
+        u[5] = gf2m_SQR1(v[2]);
+        u[4] = gf2m_SQR0(v[2]);
+        u[3] = gf2m_SQR1(v[1]);
+        u[2] = gf2m_SQR0(v[1]);
+        u[1] = gf2m_SQR1(v[0]);
+        u[0] = gf2m_SQR0(v[0]);
+        return ec_GF2m_163_mod(r, r, meth);
+
+  CLEANUP:
+        return res;
+}
+
+/* Fast multiplication for polynomials over a 163-bit curve. Assumes
+ * reduction polynomial with terms {163, 7, 6, 3, 0}. */
+mp_err
+ec_GF2m_163_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a2 = 0, a1 = 0, a0, b2 = 0, b1 = 0, b0;
+
+#ifdef ECL_THIRTY_TWO_BIT
+        mp_digit a5 = 0, a4 = 0, a3 = 0, b5 = 0, b4 = 0, b3 = 0;
+        mp_digit rm[6];
+#endif
+
+        if (a == b) {
+                return ec_GF2m_163_sqr(a, r, meth);
+        } else {
+                switch (MP_USED(a)) {
+#ifdef ECL_THIRTY_TWO_BIT
+                case 6:
+                        a5 = MP_DIGIT(a, 5);
+                case 5:
+                        a4 = MP_DIGIT(a, 4);
+                case 4:
+                        a3 = MP_DIGIT(a, 3);
+#endif
+                case 3:
+                        a2 = MP_DIGIT(a, 2);
+                case 2:
+                        a1 = MP_DIGIT(a, 1);
+                default:
+                        a0 = MP_DIGIT(a, 0);
+                }
+                switch (MP_USED(b)) {
+#ifdef ECL_THIRTY_TWO_BIT
+                case 6:
+                        b5 = MP_DIGIT(b, 5);
+                case 5:
+                        b4 = MP_DIGIT(b, 4);
+                case 4:
+                        b3 = MP_DIGIT(b, 3);
+#endif
+                case 3:
+                        b2 = MP_DIGIT(b, 2);
+                case 2:
+                        b1 = MP_DIGIT(b, 1);
+                default:
+                        b0 = MP_DIGIT(b, 0);
+                }
+#ifdef ECL_SIXTY_FOUR_BIT
+                MP_CHECKOK(s_mp_pad(r, 6));
+                s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
+                MP_USED(r) = 6;
+                s_mp_clamp(r);
+#else
+                MP_CHECKOK(s_mp_pad(r, 12));
+                s_bmul_3x3(MP_DIGITS(r) + 6, a5, a4, a3, b5, b4, b3);
+                s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
+                s_bmul_3x3(rm, a5 ^ a2, a4 ^ a1, a3 ^ a0, b5 ^ b2, b4 ^ b1,
+                                   b3 ^ b0);
+                rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 11);
+                rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 10);
+                rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 9);
+                rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 8);
+                rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 7);
+                rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 6);
+                MP_DIGIT(r, 8) ^= rm[5];
+                MP_DIGIT(r, 7) ^= rm[4];
+                MP_DIGIT(r, 6) ^= rm[3];
+                MP_DIGIT(r, 5) ^= rm[2];
+                MP_DIGIT(r, 4) ^= rm[1];
+                MP_DIGIT(r, 3) ^= rm[0];
+                MP_USED(r) = 12;
+                s_mp_clamp(r);
+#endif
+                return ec_GF2m_163_mod(r, r, meth);
+        }
+
+  CLEANUP:
+        return res;
+}
+
+/* Wire in fast field arithmetic for 163-bit curves. */
+mp_err
+ec_group_set_gf2m163(ECGroup *group, ECCurveName name)
+{
+        group->meth->field_mod = &ec_GF2m_163_mod;
+        group->meth->field_mul = &ec_GF2m_163_mul;
+        group->meth->field_sqr = &ec_GF2m_163_sqr;
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_193.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,298 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for binary polynomial field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ *   Stephen Fung <fungstep@hotmail.com>, and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ec2.h"
+#include "mp_gf2m.h"
+#include "mp_gf2m-priv.h"
+#include "mpi.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Fast reduction for polynomials over a 193-bit curve. Assumes reduction
+ * polynomial with terms {193, 15, 0}. */
+mp_err
+ec_GF2m_193_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit *u, z;
+
+        if (a != r) {
+                MP_CHECKOK(mp_copy(a, r));
+        }
+#ifdef ECL_SIXTY_FOUR_BIT
+        if (MP_USED(r) < 7) {
+                MP_CHECKOK(s_mp_pad(r, 7));
+        }
+        u = MP_DIGITS(r);
+        MP_USED(r) = 7;
+
+        /* u[6] only has 2 significant bits */
+        z = u[6];
+        u[3] ^= (z << 14) ^ (z >> 1);
+        u[2] ^= (z << 63);
+        z = u[5];
+        u[3] ^= (z >> 50);
+        u[2] ^= (z << 14) ^ (z >> 1);
+        u[1] ^= (z << 63);
+        z = u[4];
+        u[2] ^= (z >> 50);
+        u[1] ^= (z << 14) ^ (z >> 1);
+        u[0] ^= (z << 63);
+        z = u[3] >> 1;                          /* z only has 63 significant bits */
+        u[1] ^= (z >> 49);
+        u[0] ^= (z << 15) ^ z;
+        /* clear bits above 193 */
+        u[6] = u[5] = u[4] = 0;
+        u[3] ^= z << 1;
+#else
+        if (MP_USED(r) < 13) {
+                MP_CHECKOK(s_mp_pad(r, 13));
+        }
+        u = MP_DIGITS(r);
+        MP_USED(r) = 13;
+
+        /* u[12] only has 2 significant bits */
+        z = u[12];
+        u[6] ^= (z << 14) ^ (z >> 1);
+        u[5] ^= (z << 31);
+        z = u[11];
+        u[6] ^= (z >> 18);
+        u[5] ^= (z << 14) ^ (z >> 1);
+        u[4] ^= (z << 31);
+        z = u[10];
+        u[5] ^= (z >> 18);
+        u[4] ^= (z << 14) ^ (z >> 1);
+        u[3] ^= (z << 31);
+        z = u[9];
+        u[4] ^= (z >> 18);
+        u[3] ^= (z << 14) ^ (z >> 1);
+        u[2] ^= (z << 31);
+        z = u[8];
+        u[3] ^= (z >> 18);
+        u[2] ^= (z << 14) ^ (z >> 1);
+        u[1] ^= (z << 31);
+        z = u[7];
+        u[2] ^= (z >> 18);
+        u[1] ^= (z << 14) ^ (z >> 1);
+        u[0] ^= (z << 31);
+        z = u[6] >> 1;                          /* z only has 31 significant bits */
+        u[1] ^= (z >> 17);
+        u[0] ^= (z << 15) ^ z;
+        /* clear bits above 193 */
+        u[12] = u[11] = u[10] = u[9] = u[8] = u[7] = 0;
+        u[6] ^= z << 1;
+#endif
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* Fast squaring for polynomials over a 193-bit curve. Assumes reduction
+ * polynomial with terms {193, 15, 0}. */
+mp_err
+ec_GF2m_193_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit *u, *v;
+
+        v = MP_DIGITS(a);
+
+#ifdef ECL_SIXTY_FOUR_BIT
+        if (MP_USED(a) < 4) {
+                return mp_bsqrmod(a, meth->irr_arr, r);
+        }
+        if (MP_USED(r) < 7) {
+                MP_CHECKOK(s_mp_pad(r, 7));
+        }
+        MP_USED(r) = 7;
+#else
+        if (MP_USED(a) < 7) {
+                return mp_bsqrmod(a, meth->irr_arr, r);
+        }
+        if (MP_USED(r) < 13) {
+                MP_CHECKOK(s_mp_pad(r, 13));
+        }
+        MP_USED(r) = 13;
+#endif
+        u = MP_DIGITS(r);
+
+#ifdef ECL_THIRTY_TWO_BIT
+        u[12] = gf2m_SQR0(v[6]);
+        u[11] = gf2m_SQR1(v[5]);
+        u[10] = gf2m_SQR0(v[5]);
+        u[9] = gf2m_SQR1(v[4]);
+        u[8] = gf2m_SQR0(v[4]);
+        u[7] = gf2m_SQR1(v[3]);
+#endif
+        u[6] = gf2m_SQR0(v[3]);
+        u[5] = gf2m_SQR1(v[2]);
+        u[4] = gf2m_SQR0(v[2]);
+        u[3] = gf2m_SQR1(v[1]);
+        u[2] = gf2m_SQR0(v[1]);
+        u[1] = gf2m_SQR1(v[0]);
+        u[0] = gf2m_SQR0(v[0]);
+        return ec_GF2m_193_mod(r, r, meth);
+
+  CLEANUP:
+        return res;
+}
+
+/* Fast multiplication for polynomials over a 193-bit curve. Assumes
+ * reduction polynomial with terms {193, 15, 0}. */
+mp_err
+ec_GF2m_193_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
+
+#ifdef ECL_THIRTY_TWO_BIT
+        mp_digit a6 = 0, a5 = 0, a4 = 0, b6 = 0, b5 = 0, b4 = 0;
+        mp_digit rm[8];
+#endif
+
+        if (a == b) {
+                return ec_GF2m_193_sqr(a, r, meth);
+        } else {
+                switch (MP_USED(a)) {
+#ifdef ECL_THIRTY_TWO_BIT
+                case 7:
+                        a6 = MP_DIGIT(a, 6);
+                case 6:
+                        a5 = MP_DIGIT(a, 5);
+                case 5:
+                        a4 = MP_DIGIT(a, 4);
+#endif
+                case 4:
+                        a3 = MP_DIGIT(a, 3);
+                case 3:
+                        a2 = MP_DIGIT(a, 2);
+                case 2:
+                        a1 = MP_DIGIT(a, 1);
+                default:
+                        a0 = MP_DIGIT(a, 0);
+                }
+                switch (MP_USED(b)) {
+#ifdef ECL_THIRTY_TWO_BIT
+                case 7:
+                        b6 = MP_DIGIT(b, 6);
+                case 6:
+                        b5 = MP_DIGIT(b, 5);
+                case 5:
+                        b4 = MP_DIGIT(b, 4);
+#endif
+                case 4:
+                        b3 = MP_DIGIT(b, 3);
+                case 3:
+                        b2 = MP_DIGIT(b, 2);
+                case 2:
+                        b1 = MP_DIGIT(b, 1);
+                default:
+                        b0 = MP_DIGIT(b, 0);
+                }
+#ifdef ECL_SIXTY_FOUR_BIT
+                MP_CHECKOK(s_mp_pad(r, 8));
+                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+                MP_USED(r) = 8;
+                s_mp_clamp(r);
+#else
+                MP_CHECKOK(s_mp_pad(r, 14));
+                s_bmul_3x3(MP_DIGITS(r) + 8, a6, a5, a4, b6, b5, b4);
+                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+                s_bmul_4x4(rm, a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b3, b6 ^ b2, b5 ^ b1,
+                                   b4 ^ b0);
+                rm[7] ^= MP_DIGIT(r, 7);
+                rm[6] ^= MP_DIGIT(r, 6);
+                rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
+                rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
+                rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
+                rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
+                rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
+                rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
+                MP_DIGIT(r, 11) ^= rm[7];
+                MP_DIGIT(r, 10) ^= rm[6];
+                MP_DIGIT(r, 9) ^= rm[5];
+                MP_DIGIT(r, 8) ^= rm[4];
+                MP_DIGIT(r, 7) ^= rm[3];
+                MP_DIGIT(r, 6) ^= rm[2];
+                MP_DIGIT(r, 5) ^= rm[1];
+                MP_DIGIT(r, 4) ^= rm[0];
+                MP_USED(r) = 14;
+                s_mp_clamp(r);
+#endif
+                return ec_GF2m_193_mod(r, r, meth);
+        }
+
+  CLEANUP:
+        return res;
+}
+
+/* Wire in fast field arithmetic for 193-bit curves. */
+mp_err
+ec_group_set_gf2m193(ECGroup *group, ECCurveName name)
+{
+        group->meth->field_mod = &ec_GF2m_193_mod;
+        group->meth->field_mul = &ec_GF2m_193_mul;
+        group->meth->field_sqr = &ec_GF2m_193_sqr;
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_233.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,321 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for binary polynomial field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ *   Stephen Fung <fungstep@hotmail.com>, and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ec2.h"
+#include "mp_gf2m.h"
+#include "mp_gf2m-priv.h"
+#include "mpi.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Fast reduction for polynomials over a 233-bit curve. Assumes reduction
+ * polynomial with terms {233, 74, 0}. */
+mp_err
+ec_GF2m_233_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit *u, z;
+
+        if (a != r) {
+                MP_CHECKOK(mp_copy(a, r));
+        }
+#ifdef ECL_SIXTY_FOUR_BIT
+        if (MP_USED(r) < 8) {
+                MP_CHECKOK(s_mp_pad(r, 8));
+        }
+        u = MP_DIGITS(r);
+        MP_USED(r) = 8;
+
+        /* u[7] only has 18 significant bits */
+        z = u[7];
+        u[4] ^= (z << 33) ^ (z >> 41);
+        u[3] ^= (z << 23);
+        z = u[6];
+        u[4] ^= (z >> 31);
+        u[3] ^= (z << 33) ^ (z >> 41);
+        u[2] ^= (z << 23);
+        z = u[5];
+        u[3] ^= (z >> 31);
+        u[2] ^= (z << 33) ^ (z >> 41);
+        u[1] ^= (z << 23);
+        z = u[4];
+        u[2] ^= (z >> 31);
+        u[1] ^= (z << 33) ^ (z >> 41);
+        u[0] ^= (z << 23);
+        z = u[3] >> 41;                         /* z only has 23 significant bits */
+        u[1] ^= (z << 10);
+        u[0] ^= z;
+        /* clear bits above 233 */
+        u[7] = u[6] = u[5] = u[4] = 0;
+        u[3] ^= z << 41;
+#else
+        if (MP_USED(r) < 15) {
+                MP_CHECKOK(s_mp_pad(r, 15));
+        }
+        u = MP_DIGITS(r);
+        MP_USED(r) = 15;
+
+        /* u[14] only has 18 significant bits */
+        z = u[14];
+        u[9] ^= (z << 1);
+        u[7] ^= (z >> 9);
+        u[6] ^= (z << 23);
+        z = u[13];
+        u[9] ^= (z >> 31);
+        u[8] ^= (z << 1);
+        u[6] ^= (z >> 9);
+        u[5] ^= (z << 23);
+        z = u[12];
+        u[8] ^= (z >> 31);
+        u[7] ^= (z << 1);
+        u[5] ^= (z >> 9);
+        u[4] ^= (z << 23);
+        z = u[11];
+        u[7] ^= (z >> 31);
+        u[6] ^= (z << 1);
+        u[4] ^= (z >> 9);
+        u[3] ^= (z << 23);
+        z = u[10];
+        u[6] ^= (z >> 31);
+        u[5] ^= (z << 1);
+        u[3] ^= (z >> 9);
+        u[2] ^= (z << 23);
+        z = u[9];
+        u[5] ^= (z >> 31);
+        u[4] ^= (z << 1);
+        u[2] ^= (z >> 9);
+        u[1] ^= (z << 23);
+        z = u[8];
+        u[4] ^= (z >> 31);
+        u[3] ^= (z << 1);
+        u[1] ^= (z >> 9);
+        u[0] ^= (z << 23);
+        z = u[7] >> 9;                          /* z only has 23 significant bits */
+        u[3] ^= (z >> 22);
+        u[2] ^= (z << 10);
+        u[0] ^= z;
+        /* clear bits above 233 */
+        u[14] = u[13] = u[12] = u[11] = u[10] = u[9] = u[8] = 0;
+        u[7] ^= z << 9;
+#endif
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* Fast squaring for polynomials over a 233-bit curve. Assumes reduction
+ * polynomial with terms {233, 74, 0}. */
+mp_err
+ec_GF2m_233_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit *u, *v;
+
+        v = MP_DIGITS(a);
+
+#ifdef ECL_SIXTY_FOUR_BIT
+        if (MP_USED(a) < 4) {
+                return mp_bsqrmod(a, meth->irr_arr, r);
+        }
+        if (MP_USED(r) < 8) {
+                MP_CHECKOK(s_mp_pad(r, 8));
+        }
+        MP_USED(r) = 8;
+#else
+        if (MP_USED(a) < 8) {
+                return mp_bsqrmod(a, meth->irr_arr, r);
+        }
+        if (MP_USED(r) < 15) {
+                MP_CHECKOK(s_mp_pad(r, 15));
+        }
+        MP_USED(r) = 15;
+#endif
+        u = MP_DIGITS(r);
+
+#ifdef ECL_THIRTY_TWO_BIT
+        u[14] = gf2m_SQR0(v[7]);
+        u[13] = gf2m_SQR1(v[6]);
+        u[12] = gf2m_SQR0(v[6]);
+        u[11] = gf2m_SQR1(v[5]);
+        u[10] = gf2m_SQR0(v[5]);
+        u[9] = gf2m_SQR1(v[4]);
+        u[8] = gf2m_SQR0(v[4]);
+#endif
+        u[7] = gf2m_SQR1(v[3]);
+        u[6] = gf2m_SQR0(v[3]);
+        u[5] = gf2m_SQR1(v[2]);
+        u[4] = gf2m_SQR0(v[2]);
+        u[3] = gf2m_SQR1(v[1]);
+        u[2] = gf2m_SQR0(v[1]);
+        u[1] = gf2m_SQR1(v[0]);
+        u[0] = gf2m_SQR0(v[0]);
+        return ec_GF2m_233_mod(r, r, meth);
+
+  CLEANUP:
+        return res;
+}
+
+/* Fast multiplication for polynomials over a 233-bit curve. Assumes
+ * reduction polynomial with terms {233, 74, 0}. */
+mp_err
+ec_GF2m_233_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
+
+#ifdef ECL_THIRTY_TWO_BIT
+        mp_digit a7 = 0, a6 = 0, a5 = 0, a4 = 0, b7 = 0, b6 = 0, b5 = 0, b4 =
+                0;
+        mp_digit rm[8];
+#endif
+
+        if (a == b) {
+                return ec_GF2m_233_sqr(a, r, meth);
+        } else {
+                switch (MP_USED(a)) {
+#ifdef ECL_THIRTY_TWO_BIT
+                case 8:
+                        a7 = MP_DIGIT(a, 7);
+                case 7:
+                        a6 = MP_DIGIT(a, 6);
+                case 6:
+                        a5 = MP_DIGIT(a, 5);
+                case 5:
+                        a4 = MP_DIGIT(a, 4);
+#endif
+                case 4:
+                        a3 = MP_DIGIT(a, 3);
+                case 3:
+                        a2 = MP_DIGIT(a, 2);
+                case 2:
+                        a1 = MP_DIGIT(a, 1);
+                default:
+                        a0 = MP_DIGIT(a, 0);
+                }
+                switch (MP_USED(b)) {
+#ifdef ECL_THIRTY_TWO_BIT
+                case 8:
+                        b7 = MP_DIGIT(b, 7);
+                case 7:
+                        b6 = MP_DIGIT(b, 6);
+                case 6:
+                        b5 = MP_DIGIT(b, 5);
+                case 5:
+                        b4 = MP_DIGIT(b, 4);
+#endif
+                case 4:
+                        b3 = MP_DIGIT(b, 3);
+                case 3:
+                        b2 = MP_DIGIT(b, 2);
+                case 2:
+                        b1 = MP_DIGIT(b, 1);
+                default:
+                        b0 = MP_DIGIT(b, 0);
+                }
+#ifdef ECL_SIXTY_FOUR_BIT
+                MP_CHECKOK(s_mp_pad(r, 8));
+                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+                MP_USED(r) = 8;
+                s_mp_clamp(r);
+#else
+                MP_CHECKOK(s_mp_pad(r, 16));
+                s_bmul_4x4(MP_DIGITS(r) + 8, a7, a6, a5, a4, b7, b6, b5, b4);
+                s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+                s_bmul_4x4(rm, a7 ^ a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b7 ^ b3,
+                                   b6 ^ b2, b5 ^ b1, b4 ^ b0);
+                rm[7] ^= MP_DIGIT(r, 7) ^ MP_DIGIT(r, 15);
+                rm[6] ^= MP_DIGIT(r, 6) ^ MP_DIGIT(r, 14);
+                rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
+                rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
+                rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
+                rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
+                rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
+                rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
+                MP_DIGIT(r, 11) ^= rm[7];
+                MP_DIGIT(r, 10) ^= rm[6];
+                MP_DIGIT(r, 9) ^= rm[5];
+                MP_DIGIT(r, 8) ^= rm[4];
+                MP_DIGIT(r, 7) ^= rm[3];
+                MP_DIGIT(r, 6) ^= rm[2];
+                MP_DIGIT(r, 5) ^= rm[1];
+                MP_DIGIT(r, 4) ^= rm[0];
+                MP_USED(r) = 16;
+                s_mp_clamp(r);
+#endif
+                return ec_GF2m_233_mod(r, r, meth);
+        }
+
+  CLEANUP:
+        return res;
+}
+
+/* Wire in fast field arithmetic for 233-bit curves. */
+mp_err
+ec_group_set_gf2m233(ECGroup *group, ECCurveName name)
+{
+        group->meth->field_mod = &ec_GF2m_233_mod;
+        group->meth->field_mul = &ec_GF2m_233_mul;
+        group->meth->field_sqr = &ec_GF2m_233_sqr;
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_aff.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,368 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for binary polynomial field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ec2.h"
+#include "mplogic.h"
+#include "mp_gf2m.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py)
+{
+
+        if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
+                return MP_YES;
+        } else {
+                return MP_NO;
+        }
+
+}
+
+/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py)
+{
+        mp_zero(px);
+        mp_zero(py);
+        return MP_OKAY;
+}
+
+/* Computes R = P + Q based on IEEE P1363 A.10.2. Elliptic curve points P,
+ * Q, and R can all be identical. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+                                   const mp_int *qy, mp_int *rx, mp_int *ry,
+                                   const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int lambda, tempx, tempy;
+
+        MP_DIGITS(&lambda) = 0;
+        MP_DIGITS(&tempx) = 0;
+        MP_DIGITS(&tempy) = 0;
+        MP_CHECKOK(mp_init(&lambda, FLAG(px)));
+        MP_CHECKOK(mp_init(&tempx, FLAG(px)));
+        MP_CHECKOK(mp_init(&tempy, FLAG(px)));
+        /* if P = inf, then R = Q */
+        if (ec_GF2m_pt_is_inf_aff(px, py) == 0) {
+                MP_CHECKOK(mp_copy(qx, rx));
+                MP_CHECKOK(mp_copy(qy, ry));
+                res = MP_OKAY;
+                goto CLEANUP;
+        }
+        /* if Q = inf, then R = P */
+        if (ec_GF2m_pt_is_inf_aff(qx, qy) == 0) {
+                MP_CHECKOK(mp_copy(px, rx));
+                MP_CHECKOK(mp_copy(py, ry));
+                res = MP_OKAY;
+                goto CLEANUP;
+        }
+        /* if px != qx, then lambda = (py+qy) / (px+qx), tempx = a + lambda^2
+         * + lambda + px + qx */
+        if (mp_cmp(px, qx) != 0) {
+                MP_CHECKOK(group->meth->field_add(py, qy, &tempy, group->meth));
+                MP_CHECKOK(group->meth->field_add(px, qx, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_div(&tempy, &tempx, &lambda, group->meth));
+                MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&tempx, &lambda, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&tempx, &group->curvea, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&tempx, px, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&tempx, qx, &tempx, group->meth));
+        } else {
+                /* if py != qy or qx = 0, then R = inf */
+                if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) {
+                        mp_zero(rx);
+                        mp_zero(ry);
+                        res = MP_OKAY;
+                        goto CLEANUP;
+                }
+                /* lambda = qx + qy / qx */
+                MP_CHECKOK(group->meth->field_div(qy, qx, &lambda, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&lambda, qx, &lambda, group->meth));
+                /* tempx = a + lambda^2 + lambda */
+                MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&tempx, &lambda, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&tempx, &group->curvea, &tempx, group->meth));
+        }
+        /* ry = (qx + tempx) * lambda + tempx + qy */
+        MP_CHECKOK(group->meth->field_add(qx, &tempx, &tempy, group->meth));
+        MP_CHECKOK(group->meth->
+                           field_mul(&tempy, &lambda, &tempy, group->meth));
+        MP_CHECKOK(group->meth->
+                           field_add(&tempy, &tempx, &tempy, group->meth));
+        MP_CHECKOK(group->meth->field_add(&tempy, qy, ry, group->meth));
+        /* rx = tempx */
+        MP_CHECKOK(mp_copy(&tempx, rx));
+
+  CLEANUP:
+        mp_clear(&lambda);
+        mp_clear(&tempx);
+        mp_clear(&tempy);
+        return res;
+}
+
+/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
+ * identical. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+                                   const mp_int *qy, mp_int *rx, mp_int *ry,
+                                   const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int nqy;
+
+        MP_DIGITS(&nqy) = 0;
+        MP_CHECKOK(mp_init(&nqy, FLAG(px)));
+        /* nqy = qx+qy */
+        MP_CHECKOK(group->meth->field_add(qx, qy, &nqy, group->meth));
+        MP_CHECKOK(group->point_add(px, py, qx, &nqy, rx, ry, group));
+  CLEANUP:
+        mp_clear(&nqy);
+        return res;
+}
+
+/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+ * affine coordinates. */
+mp_err
+ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+                                   mp_int *ry, const ECGroup *group)
+{
+        return group->point_add(px, py, px, py, rx, ry, group);
+}
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
+/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
+ * R can be identical. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
+                                   mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int k, k3, qx, qy, sx, sy;
+        int b1, b3, i, l;
+
+        MP_DIGITS(&k) = 0;
+        MP_DIGITS(&k3) = 0;
+        MP_DIGITS(&qx) = 0;
+        MP_DIGITS(&qy) = 0;
+        MP_DIGITS(&sx) = 0;
+        MP_DIGITS(&sy) = 0;
+        MP_CHECKOK(mp_init(&k));
+        MP_CHECKOK(mp_init(&k3));
+        MP_CHECKOK(mp_init(&qx));
+        MP_CHECKOK(mp_init(&qy));
+        MP_CHECKOK(mp_init(&sx));
+        MP_CHECKOK(mp_init(&sy));
+
+        /* if n = 0 then r = inf */
+        if (mp_cmp_z(n) == 0) {
+                mp_zero(rx);
+                mp_zero(ry);
+                res = MP_OKAY;
+                goto CLEANUP;
+        }
+        /* Q = P, k = n */
+        MP_CHECKOK(mp_copy(px, &qx));
+        MP_CHECKOK(mp_copy(py, &qy));
+        MP_CHECKOK(mp_copy(n, &k));
+        /* if n < 0 then Q = -Q, k = -k */
+        if (mp_cmp_z(n) < 0) {
+                MP_CHECKOK(group->meth->field_add(&qx, &qy, &qy, group->meth));
+                MP_CHECKOK(mp_neg(&k, &k));
+        }
+#ifdef ECL_DEBUG                                /* basic double and add method */
+        l = mpl_significant_bits(&k) - 1;
+        MP_CHECKOK(mp_copy(&qx, &sx));
+        MP_CHECKOK(mp_copy(&qy, &sy));
+        for (i = l - 1; i >= 0; i--) {
+                /* S = 2S */
+                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+                /* if k_i = 1, then S = S + Q */
+                if (mpl_get_bit(&k, i) != 0) {
+                        MP_CHECKOK(group->
+                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+                }
+        }
+#else                                                   /* double and add/subtract method from
+                                                                 * standard */
+        /* k3 = 3 * k */
+        MP_CHECKOK(mp_set_int(&k3, 3));
+        MP_CHECKOK(mp_mul(&k, &k3, &k3));
+        /* S = Q */
+        MP_CHECKOK(mp_copy(&qx, &sx));
+        MP_CHECKOK(mp_copy(&qy, &sy));
+        /* l = index of high order bit in binary representation of 3*k */
+        l = mpl_significant_bits(&k3) - 1;
+        /* for i = l-1 downto 1 */
+        for (i = l - 1; i >= 1; i--) {
+                /* S = 2S */
+                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+                b3 = MP_GET_BIT(&k3, i);
+                b1 = MP_GET_BIT(&k, i);
+                /* if k3_i = 1 and k_i = 0, then S = S + Q */
+                if ((b3 == 1) && (b1 == 0)) {
+                        MP_CHECKOK(group->
+                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+                        /* if k3_i = 0 and k_i = 1, then S = S - Q */
+                } else if ((b3 == 0) && (b1 == 1)) {
+                        MP_CHECKOK(group->
+                                           point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
+                }
+        }
+#endif
+        /* output S */
+        MP_CHECKOK(mp_copy(&sx, rx));
+        MP_CHECKOK(mp_copy(&sy, ry));
+
+  CLEANUP:
+        mp_clear(&k);
+        mp_clear(&k3);
+        mp_clear(&qx);
+        mp_clear(&qy);
+        mp_clear(&sx);
+        mp_clear(&sy);
+        return res;
+}
+#endif
+
+/* Validates a point on a GF2m curve. */
+mp_err
+ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
+{
+        mp_err res = MP_NO;
+        mp_int accl, accr, tmp, pxt, pyt;
+
+        MP_DIGITS(&accl) = 0;
+        MP_DIGITS(&accr) = 0;
+        MP_DIGITS(&tmp) = 0;
+        MP_DIGITS(&pxt) = 0;
+        MP_DIGITS(&pyt) = 0;
+        MP_CHECKOK(mp_init(&accl, FLAG(px)));
+        MP_CHECKOK(mp_init(&accr, FLAG(px)));
+        MP_CHECKOK(mp_init(&tmp, FLAG(px)));
+        MP_CHECKOK(mp_init(&pxt, FLAG(px)));
+        MP_CHECKOK(mp_init(&pyt, FLAG(px)));
+
+    /* 1: Verify that publicValue is not the point at infinity */
+        if (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+    /* 2: Verify that the coordinates of publicValue are elements
+     *    of the field.
+     */
+        if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
+                (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+    /* 3: Verify that publicValue is on the curve. */
+        if (group->meth->field_enc) {
+                group->meth->field_enc(px, &pxt, group->meth);
+                group->meth->field_enc(py, &pyt, group->meth);
+        } else {
+                mp_copy(px, &pxt);
+                mp_copy(py, &pyt);
+        }
+        /* left-hand side: y^2 + x*y  */
+        MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
+        MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) );
+        MP_CHECKOK( group->meth->field_add(&accl, &tmp, &accl, group->meth) );
+        /* right-hand side: x^3 + a*x^2 + b */
+        MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
+        MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
+        MP_CHECKOK( group->meth->field_mul(&group->curvea, &tmp, &tmp, group->meth) );
+        MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
+        MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
+        /* check LHS - RHS == 0 */
+        MP_CHECKOK( group->meth->field_add(&accl, &accr, &accr, group->meth) );
+        if (mp_cmp_z(&accr) != 0) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+    /* 4: Verify that the order of the curve times the publicValue
+     *    is the point at infinity.
+     */
+        MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
+        if (ec_GF2m_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+
+        res = MP_YES;
+
+CLEANUP:
+        mp_clear(&accl);
+        mp_clear(&accr);
+        mp_clear(&tmp);
+        mp_clear(&pxt);
+        mp_clear(&pyt);
+        return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec2_mont.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,296 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for binary polynomial field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ *   Stephen Fung <fungstep@hotmail.com>, and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ec2.h"
+#include "mplogic.h"
+#include "mp_gf2m.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery
+ * projective coordinates. Uses algorithm Mdouble in appendix of Lopez, J.
+ * and Dahab, R.  "Fast multiplication on elliptic curves over GF(2^m)
+ * without precomputation". modified to not require precomputation of
+ * c=b^{2^{m-1}}. */
+static mp_err
+gf2m_Mdouble(mp_int *x, mp_int *z, const ECGroup *group, int kmflag)
+{
+        mp_err res = MP_OKAY;
+        mp_int t1;
+
+        MP_DIGITS(&t1) = 0;
+        MP_CHECKOK(mp_init(&t1, kmflag));
+
+        MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(z, &t1, group->meth));
+        MP_CHECKOK(group->meth->field_mul(x, &t1, z, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(&t1, &t1, group->meth));
+        MP_CHECKOK(group->meth->
+                           field_mul(&group->curveb, &t1, &t1, group->meth));
+        MP_CHECKOK(group->meth->field_add(x, &t1, x, group->meth));
+
+  CLEANUP:
+        mp_clear(&t1);
+        return res;
+}
+
+/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in
+ * Montgomery projective coordinates. Uses algorithm Madd in appendix of
+ * Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ * GF(2^m) without precomputation". */
+static mp_err
+gf2m_Madd(const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, mp_int *z2,
+                  const ECGroup *group, int kmflag)
+{
+        mp_err res = MP_OKAY;
+        mp_int t1, t2;
+
+        MP_DIGITS(&t1) = 0;
+        MP_DIGITS(&t2) = 0;
+        MP_CHECKOK(mp_init(&t1, kmflag));
+        MP_CHECKOK(mp_init(&t2, kmflag));
+
+        MP_CHECKOK(mp_copy(x, &t1));
+        MP_CHECKOK(group->meth->field_mul(x1, z2, x1, group->meth));
+        MP_CHECKOK(group->meth->field_mul(z1, x2, z1, group->meth));
+        MP_CHECKOK(group->meth->field_mul(x1, z1, &t2, group->meth));
+        MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(z1, z1, group->meth));
+        MP_CHECKOK(group->meth->field_mul(z1, &t1, x1, group->meth));
+        MP_CHECKOK(group->meth->field_add(x1, &t2, x1, group->meth));
+
+  CLEANUP:
+        mp_clear(&t1);
+        mp_clear(&t2);
+        return res;
+}
+
+/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
+ * using Montgomery point multiplication algorithm Mxy() in appendix of
+ * Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ * GF(2^m) without precomputation". Returns: 0 on error 1 if return value
+ * should be the point at infinity 2 otherwise */
+static int
+gf2m_Mxy(const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
+                 mp_int *x2, mp_int *z2, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        int ret = 0;
+        mp_int t3, t4, t5;
+
+        MP_DIGITS(&t3) = 0;
+        MP_DIGITS(&t4) = 0;
+        MP_DIGITS(&t5) = 0;
+        MP_CHECKOK(mp_init(&t3, FLAG(x2)));
+        MP_CHECKOK(mp_init(&t4, FLAG(x2)));
+        MP_CHECKOK(mp_init(&t5, FLAG(x2)));
+
+        if (mp_cmp_z(z1) == 0) {
+                mp_zero(x2);
+                mp_zero(z2);
+                ret = 1;
+                goto CLEANUP;
+        }
+
+        if (mp_cmp_z(z2) == 0) {
+                MP_CHECKOK(mp_copy(x, x2));
+                MP_CHECKOK(group->meth->field_add(x, y, z2, group->meth));
+                ret = 2;
+                goto CLEANUP;
+        }
+
+        MP_CHECKOK(mp_set_int(&t5, 1));
+        if (group->meth->field_enc) {
+                MP_CHECKOK(group->meth->field_enc(&t5, &t5, group->meth));
+        }
+
+        MP_CHECKOK(group->meth->field_mul(z1, z2, &t3, group->meth));
+
+        MP_CHECKOK(group->meth->field_mul(z1, x, z1, group->meth));
+        MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
+        MP_CHECKOK(group->meth->field_mul(z2, x, z2, group->meth));
+        MP_CHECKOK(group->meth->field_mul(z2, x1, x1, group->meth));
+        MP_CHECKOK(group->meth->field_add(z2, x2, z2, group->meth));
+
+        MP_CHECKOK(group->meth->field_mul(z2, z1, z2, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(x, &t4, group->meth));
+        MP_CHECKOK(group->meth->field_add(&t4, y, &t4, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&t4, &t3, &t4, group->meth));
+        MP_CHECKOK(group->meth->field_add(&t4, z2, &t4, group->meth));
+
+        MP_CHECKOK(group->meth->field_mul(&t3, x, &t3, group->meth));
+        MP_CHECKOK(group->meth->field_div(&t5, &t3, &t3, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&t3, &t4, &t4, group->meth));
+        MP_CHECKOK(group->meth->field_mul(x1, &t3, x2, group->meth));
+        MP_CHECKOK(group->meth->field_add(x2, x, z2, group->meth));
+
+        MP_CHECKOK(group->meth->field_mul(z2, &t4, z2, group->meth));
+        MP_CHECKOK(group->meth->field_add(z2, y, z2, group->meth));
+
+        ret = 2;
+
+  CLEANUP:
+        mp_clear(&t3);
+        mp_clear(&t4);
+        mp_clear(&t5);
+        if (res == MP_OKAY) {
+                return ret;
+        } else {
+                return 0;
+        }
+}
+
+/* Computes R = nP based on algorithm 2P of Lopex, J. and Dahab, R.  "Fast
+ * multiplication on elliptic curves over GF(2^m) without
+ * precomputation". Elliptic curve points P and R can be identical. Uses
+ * Montgomery projective coordinates. */
+mp_err
+ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px, const mp_int *py,
+                                        mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int x1, x2, z1, z2;
+        int i, j;
+        mp_digit top_bit, mask;
+
+        MP_DIGITS(&x1) = 0;
+        MP_DIGITS(&x2) = 0;
+        MP_DIGITS(&z1) = 0;
+        MP_DIGITS(&z2) = 0;
+        MP_CHECKOK(mp_init(&x1, FLAG(n)));
+        MP_CHECKOK(mp_init(&x2, FLAG(n)));
+        MP_CHECKOK(mp_init(&z1, FLAG(n)));
+        MP_CHECKOK(mp_init(&z2, FLAG(n)));
+
+        /* if result should be point at infinity */
+        if ((mp_cmp_z(n) == 0) || (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES)) {
+                MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
+                goto CLEANUP;
+        }
+
+        MP_CHECKOK(mp_copy(px, &x1));   /* x1 = px */
+        MP_CHECKOK(mp_set_int(&z1, 1)); /* z1 = 1 */
+        MP_CHECKOK(group->meth->field_sqr(&x1, &z2, group->meth));      /* z2 =
+                                                                                                                                 * x1^2 =
+                                                                                                                                 * px^2 */
+        MP_CHECKOK(group->meth->field_sqr(&z2, &x2, group->meth));
+        MP_CHECKOK(group->meth->field_add(&x2, &group->curveb, &x2, group->meth));      /* x2
+                                                                                                                                                                 * =
+                                                                                                                                                                 * px^4
+                                                                                                                                                                 * +
+                                                                                                                                                                 * b
+                                                                                                                                                                 */
+
+        /* find top-most bit and go one past it */
+        i = MP_USED(n) - 1;
+        j = MP_DIGIT_BIT - 1;
+        top_bit = 1;
+        top_bit <<= MP_DIGIT_BIT - 1;
+        mask = top_bit;
+        while (!(MP_DIGITS(n)[i] & mask)) {
+                mask >>= 1;
+                j--;
+        }
+        mask >>= 1;
+        j--;
+
+        /* if top most bit was at word break, go to next word */
+        if (!mask) {
+                i--;
+                j = MP_DIGIT_BIT - 1;
+                mask = top_bit;
+        }
+
+        for (; i >= 0; i--) {
+                for (; j >= 0; j--) {
+                        if (MP_DIGITS(n)[i] & mask) {
+                                MP_CHECKOK(gf2m_Madd(px, &x1, &z1, &x2, &z2, group, FLAG(n)));
+                                MP_CHECKOK(gf2m_Mdouble(&x2, &z2, group, FLAG(n)));
+                        } else {
+                                MP_CHECKOK(gf2m_Madd(px, &x2, &z2, &x1, &z1, group, FLAG(n)));
+                                MP_CHECKOK(gf2m_Mdouble(&x1, &z1, group, FLAG(n)));
+                        }
+                        mask >>= 1;
+                }
+                j = MP_DIGIT_BIT - 1;
+                mask = top_bit;
+        }
+
+        /* convert out of "projective" coordinates */
+        i = gf2m_Mxy(px, py, &x1, &z1, &x2, &z2, group);
+        if (i == 0) {
+                res = MP_BADARG;
+                goto CLEANUP;
+        } else if (i == 1) {
+                MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
+        } else {
+                MP_CHECKOK(mp_copy(&x2, rx));
+                MP_CHECKOK(mp_copy(&z2, ry));
+        }
+
+  CLEANUP:
+        mp_clear(&x1);
+        mp_clear(&x2);
+        mp_clear(&z1);
+        mp_clear(&z2);
+        return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ec_naf.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,123 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecl-priv.h"
+
+/* Returns 2^e as an integer. This is meant to be used for small powers of
+ * two. */
+int
+ec_twoTo(int e)
+{
+        int a = 1;
+        int i;
+
+        for (i = 0; i < e; i++) {
+                a *= 2;
+        }
+        return a;
+}
+
+/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
+ * be an array of signed char's to output to, bitsize should be the number
+ * of bits of out, in is the original scalar, and w is the window size.
+ * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
+ * Menezes, "Software implementation of elliptic curve cryptography over
+ * binary fields", Proc. CHES 2000. */
+mp_err
+ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, int w)
+{
+        mp_int k;
+        mp_err res = MP_OKAY;
+        int i, twowm1, mask;
+
+        twowm1 = ec_twoTo(w - 1);
+        mask = 2 * twowm1 - 1;
+
+        MP_DIGITS(&k) = 0;
+        MP_CHECKOK(mp_init_copy(&k, in));
+
+        i = 0;
+        /* Compute wNAF form */
+        while (mp_cmp_z(&k) > 0) {
+                if (mp_isodd(&k)) {
+                        out[i] = MP_DIGIT(&k, 0) & mask;
+                        if (out[i] >= twowm1)
+                                out[i] -= 2 * twowm1;
+
+                        /* Subtract off out[i].  Note mp_sub_d only works with
+                         * unsigned digits */
+                        if (out[i] >= 0) {
+                                mp_sub_d(&k, out[i], &k);
+                        } else {
+                                mp_add_d(&k, -(out[i]), &k);
+                        }
+                } else {
+                        out[i] = 0;
+                }
+                mp_div_2(&k, &k);
+                i++;
+        }
+        /* Zero out the remaining elements of the out array. */
+        for (; i < bitsize + 1; i++) {
+                out[i] = 0;
+        }
+  CLEANUP:
+        mp_clear(&k);
+        return res;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecc_impl.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,275 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dr Vipul Gupta <vipul.gupta@sun.com> and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ECC_IMPL_H
+#define _ECC_IMPL_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include "ecl-exp.h"
+
+/*
+ * Multi-platform definitions
+ */
+#ifdef __linux__
+#define B_FALSE FALSE
+#define B_TRUE TRUE
+typedef unsigned char uint8_t;
+typedef unsigned long ulong_t;
+typedef enum { B_FALSE, B_TRUE } boolean_t;
+#endif /* __linux__ */
+
+#ifdef _WIN32
+typedef unsigned char uint8_t;
+typedef unsigned long ulong_t;
+typedef enum boolean { B_FALSE, B_TRUE } boolean_t;
+#endif /* _WIN32 */
+
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif  /* _KERNEL */
+
+#define EC_MAX_DIGEST_LEN 1024  /* max digest that can be signed */
+#define EC_MAX_POINT_LEN 145    /* max len of DER encoded Q */
+#define EC_MAX_VALUE_LEN 72     /* max len of ANSI X9.62 private value d */
+#define EC_MAX_SIG_LEN 144      /* max signature len for supported curves */
+#define EC_MIN_KEY_LEN  112     /* min key length in bits */
+#define EC_MAX_KEY_LEN  571     /* max key length in bits */
+#define EC_MAX_OID_LEN 10       /* max length of OID buffer */
+
+/*
+ * Various structures and definitions from NSS are here.
+ */
+
+#ifdef _KERNEL
+#define PORT_ArenaAlloc(a, n, f)        kmem_alloc((n), (f))
+#define PORT_ArenaZAlloc(a, n, f)       kmem_zalloc((n), (f))
+#define PORT_ArenaGrow(a, b, c, d)      NULL
+#define PORT_ZAlloc(n, f)               kmem_zalloc((n), (f))
+#define PORT_Alloc(n, f)                kmem_alloc((n), (f))
+#else
+#define PORT_ArenaAlloc(a, n, f)        malloc((n))
+#define PORT_ArenaZAlloc(a, n, f)       calloc(1, (n))
+#define PORT_ArenaGrow(a, b, c, d)      NULL
+#define PORT_ZAlloc(n, f)               calloc(1, (n))
+#define PORT_Alloc(n, f)                malloc((n))
+#endif
+
+#define PORT_NewArena(b)                (char *)12345
+#define PORT_ArenaMark(a)               NULL
+#define PORT_ArenaUnmark(a, b)
+#define PORT_ArenaRelease(a, m)
+#define PORT_FreeArena(a, b)
+#define PORT_Strlen(s)                  strlen((s))
+#define PORT_SetError(e)
+
+#define PRBool                          boolean_t
+#define PR_TRUE                         B_TRUE
+#define PR_FALSE                        B_FALSE
+
+#ifdef _KERNEL
+#define PORT_Assert                     ASSERT
+#define PORT_Memcpy(t, f, l)            bcopy((f), (t), (l))
+#else
+#define PORT_Assert                     assert
+#define PORT_Memcpy(t, f, l)            memcpy((t), (f), (l))
+#endif
+
+#define CHECK_OK(func) if (func == NULL) goto cleanup
+#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
+
+typedef enum {
+        siBuffer = 0,
+        siClearDataBuffer = 1,
+        siCipherDataBuffer = 2,
+        siDERCertBuffer = 3,
+        siEncodedCertBuffer = 4,
+        siDERNameBuffer = 5,
+        siEncodedNameBuffer = 6,
+        siAsciiNameString = 7,
+        siAsciiString = 8,
+        siDEROID = 9,
+        siUnsignedInteger = 10,
+        siUTCTime = 11,
+        siGeneralizedTime = 12
+} SECItemType;
+
+typedef struct SECItemStr SECItem;
+
+struct SECItemStr {
+        SECItemType type;
+        unsigned char *data;
+        unsigned int len;
+};
+
+typedef SECItem SECKEYECParams;
+
+typedef enum { ec_params_explicit,
+               ec_params_named
+} ECParamsType;
+
+typedef enum { ec_field_GFp = 1,
+               ec_field_GF2m
+} ECFieldType;
+
+struct ECFieldIDStr {
+    int         size;   /* field size in bits */
+    ECFieldType type;
+    union {
+        SECItem  prime; /* prime p for (GFp) */
+        SECItem  poly;  /* irreducible binary polynomial for (GF2m) */
+    } u;
+    int         k1;     /* first coefficient of pentanomial or
+                         * the only coefficient of trinomial
+                         */
+    int         k2;     /* two remaining coefficients of pentanomial */
+    int         k3;
+};
+typedef struct ECFieldIDStr ECFieldID;
+
+struct ECCurveStr {
+        SECItem a;      /* contains octet stream encoding of
+                         * field element (X9.62 section 4.3.3)
+                         */
+        SECItem b;
+        SECItem seed;
+};
+typedef struct ECCurveStr ECCurve;
+
+typedef void PRArenaPool;
+
+struct ECParamsStr {
+    PRArenaPool * arena;
+    ECParamsType  type;
+    ECFieldID     fieldID;
+    ECCurve       curve;
+    SECItem       base;
+    SECItem       order;
+    int           cofactor;
+    SECItem       DEREncoding;
+    ECCurveName   name;
+    SECItem       curveOID;
+};
+typedef struct ECParamsStr ECParams;
+
+struct ECPublicKeyStr {
+    ECParams ecParams;
+    SECItem publicValue;   /* elliptic curve point encoded as
+                            * octet stream.
+                            */
+};
+typedef struct ECPublicKeyStr ECPublicKey;
+
+struct ECPrivateKeyStr {
+    ECParams ecParams;
+    SECItem publicValue;   /* encoded ec point */
+    SECItem privateValue;  /* private big integer */
+    SECItem version;       /* As per SEC 1, Appendix C, Section C.4 */
+};
+typedef struct ECPrivateKeyStr ECPrivateKey;
+
+typedef enum _SECStatus {
+        SECBufferTooSmall = -3,
+        SECWouldBlock = -2,
+        SECFailure = -1,
+        SECSuccess = 0
+} SECStatus;
+
+#ifdef _KERNEL
+#define RNG_GenerateGlobalRandomBytes(p,l) ecc_knzero_random_generator((p), (l))
+#else
+/*
+ This function is no longer required because the random bytes are now
+ supplied by the caller. Force a failure.
+*/
+#define RNG_GenerateGlobalRandomBytes(p,l) SECFailure
+#endif
+#define CHECK_MPI_OK(func) if (MP_OKAY > (err = func)) goto cleanup
+#define MP_TO_SEC_ERROR(err)
+
+#define SECITEM_TO_MPINT(it, mp)                                        \
+        CHECK_MPI_OK(mp_read_unsigned_octets((mp), (it).data, (it).len))
+
+extern int ecc_knzero_random_generator(uint8_t *, size_t);
+extern ulong_t soft_nzero_random_generator(uint8_t *, ulong_t);
+
+extern SECStatus EC_DecodeParams(const SECItem *, ECParams **, int);
+extern SECItem * SECITEM_AllocItem(PRArenaPool *, SECItem *, unsigned int, int);
+extern SECStatus SECITEM_CopyItem(PRArenaPool *, SECItem *, const SECItem *,
+    int);
+extern void SECITEM_FreeItem(SECItem *, boolean_t);
+/* This function has been modified to accept an array of random bytes */
+extern SECStatus EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
+    const unsigned char* random, int randomlen, int);
+/* This function has been modified to accept an array of random bytes */
+extern SECStatus ECDSA_SignDigest(ECPrivateKey *, SECItem *, const SECItem *,
+    const unsigned char* random, int randomlen, int);
+extern SECStatus ECDSA_VerifyDigest(ECPublicKey *, const SECItem *,
+    const SECItem *, int);
+extern SECStatus ECDH_Derive(SECItem *, ECParams *, SECItem *, boolean_t,
+    SECItem *, int);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* _ECC_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecdecode.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,632 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Elliptic Curve Cryptography library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dr Vipul Gupta <vipul.gupta@sun.com> and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include <sys/types.h>
+
+#ifndef _WIN32
+#ifndef __linux__
+#include <sys/systm.h>
+#endif /* __linux__ */
+#include <sys/param.h>
+#endif /* _WIN32 */
+
+#ifdef _KERNEL
+#include <sys/kmem.h>
+#else
+#include <string.h>
+#endif
+#include "ec.h"
+#include "ecl-curve.h"
+#include "ecc_impl.h"
+
+#define MAX_ECKEY_LEN           72
+#define SEC_ASN1_OBJECT_ID      0x06
+
+/*
+ * Initializes a SECItem from a hexadecimal string
+ *
+ * Warning: This function ignores leading 00's, so any leading 00's
+ * in the hexadecimal string must be optional.
+ */
+static SECItem *
+hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str,
+    int kmflag)
+{
+    int i = 0;
+    int byteval = 0;
+    int tmp = strlen(str);
+
+    if ((tmp % 2) != 0) return NULL;
+
+    /* skip leading 00's unless the hex string is "00" */
+    while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
+        str += 2;
+        tmp -= 2;
+    }
+
+    item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2, kmflag);
+    if (item->data == NULL) return NULL;
+    item->len = tmp/2;
+
+    while (str[i]) {
+        if ((str[i] >= '0') && (str[i] <= '9'))
+            tmp = str[i] - '0';
+        else if ((str[i] >= 'a') && (str[i] <= 'f'))
+            tmp = str[i] - 'a' + 10;
+        else if ((str[i] >= 'A') && (str[i] <= 'F'))
+            tmp = str[i] - 'A' + 10;
+        else
+            return NULL;
+
+        byteval = byteval * 16 + tmp;
+        if ((i % 2) != 0) {
+            item->data[i/2] = byteval;
+            byteval = 0;
+        }
+        i++;
+    }
+
+    return item;
+}
+
+static SECStatus
+gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params,
+    int kmflag)
+{
+    SECStatus rv = SECFailure;
+    const ECCurveParams *curveParams;
+    /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
+    char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
+
+    if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
+    params->name = name;
+    curveParams = ecCurve_map[params->name];
+    CHECK_OK(curveParams);
+    params->fieldID.size = curveParams->size;
+    params->fieldID.type = field_type;
+    if (field_type == ec_field_GFp) {
+        CHECK_OK(hexString2SECItem(NULL, &params->fieldID.u.prime,
+            curveParams->irr, kmflag));
+    } else {
+        CHECK_OK(hexString2SECItem(NULL, &params->fieldID.u.poly,
+            curveParams->irr, kmflag));
+    }
+    CHECK_OK(hexString2SECItem(NULL, &params->curve.a,
+        curveParams->curvea, kmflag));
+    CHECK_OK(hexString2SECItem(NULL, &params->curve.b,
+        curveParams->curveb, kmflag));
+    genenc[0] = '0';
+    genenc[1] = '4';
+    genenc[2] = '\0';
+    strcat(genenc, curveParams->genx);
+    strcat(genenc, curveParams->geny);
+    CHECK_OK(hexString2SECItem(NULL, &params->base, genenc, kmflag));
+    CHECK_OK(hexString2SECItem(NULL, &params->order,
+        curveParams->order, kmflag));
+    params->cofactor = curveParams->cofactor;
+
+    rv = SECSuccess;
+
+cleanup:
+    return rv;
+}
+
+ECCurveName SECOID_FindOIDTag(const SECItem *);
+
+SECStatus
+EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
+    ECParams *params, int kmflag)
+{
+    SECStatus rv = SECFailure;
+    ECCurveName tag;
+    SECItem oid = { siBuffer, NULL, 0};
+
+#if EC_DEBUG
+    int i;
+
+    printf("Encoded params in EC_DecodeParams: ");
+    for (i = 0; i < encodedParams->len; i++) {
+            printf("%02x:", encodedParams->data[i]);
+    }
+    printf("\n");
+#endif
+
+    if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
+        (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
+            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+            return SECFailure;
+    };
+
+    oid.len = encodedParams->len - 2;
+    oid.data = encodedParams->data + 2;
+    if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
+        ((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) {
+            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+            return SECFailure;
+    }
+
+    params->arena = arena;
+    params->cofactor = 0;
+    params->type = ec_params_named;
+    params->name = ECCurve_noName;
+
+    /* For named curves, fill out curveOID */
+    params->curveOID.len = oid.len;
+    params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len,
+        kmflag);
+    if (params->curveOID.data == NULL) goto cleanup;
+    memcpy(params->curveOID.data, oid.data, oid.len);
+
+#if EC_DEBUG
+#ifndef SECOID_FindOIDTagDescription
+    printf("Curve: %s\n", ecCurve_map[tag]->text);
+#else
+    printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
+#endif
+#endif
+
+    switch (tag) {
+
+    /* Binary curves */
+
+    case ECCurve_X9_62_CHAR2_PNB163V1:
+        /* Populate params for c2pnb163v1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_PNB163V2:
+        /* Populate params for c2pnb163v2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_PNB163V3:
+        /* Populate params for c2pnb163v3 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_PNB176V1:
+        /* Populate params for c2pnb176v1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB191V1:
+        /* Populate params for c2tnb191v1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB191V2:
+        /* Populate params for c2tnb191v2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB191V3:
+        /* Populate params for c2tnb191v3 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_PNB208W1:
+        /* Populate params for c2pnb208w1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB239V1:
+        /* Populate params for c2tnb239v1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB239V2:
+        /* Populate params for c2tnb239v2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB239V3:
+        /* Populate params for c2tnb239v3 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_PNB272W1:
+        /* Populate params for c2pnb272w1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_PNB304W1:
+        /* Populate params for c2pnb304w1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB359V1:
+        /* Populate params for c2tnb359v1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_PNB368W1:
+        /* Populate params for c2pnb368w1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_CHAR2_TNB431R1:
+        /* Populate params for c2tnb431r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_113R1:
+        /* Populate params for sect113r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_113R2:
+        /* Populate params for sect113r2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_131R1:
+        /* Populate params for sect131r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_131R2:
+        /* Populate params for sect131r2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_163K1:
+        /* Populate params for sect163k1
+         * (the NIST K-163 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_163R1:
+        /* Populate params for sect163r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_163R2:
+        /* Populate params for sect163r2
+         * (the NIST B-163 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_193R1:
+        /* Populate params for sect193r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_193R2:
+        /* Populate params for sect193r2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_233K1:
+        /* Populate params for sect233k1
+         * (the NIST K-233 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_233R1:
+        /* Populate params for sect233r1
+         * (the NIST B-233 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_239K1:
+        /* Populate params for sect239k1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_283K1:
+        /* Populate params for sect283k1
+         * (the NIST K-283 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_283R1:
+        /* Populate params for sect283r1
+         * (the NIST B-283 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_409K1:
+        /* Populate params for sect409k1
+         * (the NIST K-409 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_409R1:
+        /* Populate params for sect409r1
+         * (the NIST B-409 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_571K1:
+        /* Populate params for sect571k1
+         * (the NIST K-571 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_CHAR2_571R1:
+        /* Populate params for sect571r1
+         * (the NIST B-571 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
+            params, kmflag) );
+        break;
+
+    /* Prime curves */
+
+    case ECCurve_X9_62_PRIME_192V1:
+        /* Populate params for prime192v1 aka secp192r1
+         * (the NIST P-192 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_PRIME_192V2:
+        /* Populate params for prime192v2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_PRIME_192V3:
+        /* Populate params for prime192v3 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_PRIME_239V1:
+        /* Populate params for prime239v1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_PRIME_239V2:
+        /* Populate params for prime239v2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_PRIME_239V3:
+        /* Populate params for prime239v3 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_X9_62_PRIME_256V1:
+        /* Populate params for prime256v1 aka secp256r1
+         * (the NIST P-256 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_112R1:
+        /* Populate params for secp112r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_112R2:
+        /* Populate params for secp112r2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_128R1:
+        /* Populate params for secp128r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_128R2:
+        /* Populate params for secp128r2 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_160K1:
+        /* Populate params for secp160k1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_160R1:
+        /* Populate params for secp160r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_160R2:
+        /* Populate params for secp160r1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_192K1:
+        /* Populate params for secp192k1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_224K1:
+        /* Populate params for secp224k1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_224R1:
+        /* Populate params for secp224r1
+         * (the NIST P-224 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_256K1:
+        /* Populate params for secp256k1 */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_384R1:
+        /* Populate params for secp384r1
+         * (the NIST P-384 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    case ECCurve_SECG_PRIME_521R1:
+        /* Populate params for secp521r1
+         * (the NIST P-521 curve)
+         */
+        CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
+            params, kmflag) );
+        break;
+
+    default:
+        break;
+    };
+
+cleanup:
+    if (!params->cofactor) {
+        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+#if EC_DEBUG
+        printf("Unrecognized curve, returning NULL params\n");
+#endif
+    }
+
+    return rv;
+}
+
+SECStatus
+EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams, int kmflag)
+{
+    PRArenaPool *arena;
+    ECParams *params;
+    SECStatus rv = SECFailure;
+
+    /* Initialize an arena for the ECParams structure */
+    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
+        return SECFailure;
+
+    params = (ECParams *)PORT_ArenaZAlloc(NULL, sizeof(ECParams), kmflag);
+    if (!params) {
+        PORT_FreeArena(NULL, B_TRUE);
+        return SECFailure;
+    }
+
+    /* Copy the encoded params */
+    SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len,
+        kmflag);
+    memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
+
+    /* Fill out the rest of the ECParams structure based on
+     * the encoded params
+     */
+    rv = EC_FillParams(NULL, encodedParams, params, kmflag);
+    if (rv == SECFailure) {
+        PORT_FreeArena(NULL, B_TRUE);
+        return SECFailure;
+    } else {
+        *ecparams = params;;
+        return SECSuccess;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-curve.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,710 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ECL_CURVE_H
+#define _ECL_CURVE_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecl-exp.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* NIST prime curves */
+static const ECCurveParams ecCurve_NIST_P192 = {
+        "NIST-P192", ECField_GFp, 192,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
+        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+        "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 1
+};
+
+static const ECCurveParams ecCurve_NIST_P224 = {
+        "NIST-P224", ECField_GFp, 224,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1
+};
+
+static const ECCurveParams ecCurve_NIST_P256 = {
+        "NIST-P256", ECField_GFp, 256,
+        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1
+};
+
+static const ECCurveParams ecCurve_NIST_P384 = {
+        "NIST-P384", ECField_GFp, 384,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+        1
+};
+
+static const ECCurveParams ecCurve_NIST_P521 = {
+        "NIST-P521", ECField_GFp, 521,
+        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+        "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+        "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+        "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+        1
+};
+
+/* NIST binary curves */
+static const ECCurveParams ecCurve_NIST_K163 = {
+        "NIST-K163", ECField_GF2m, 163,
+        "0800000000000000000000000000000000000000C9",
+        "000000000000000000000000000000000000000001",
+        "000000000000000000000000000000000000000001",
+        "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
+        "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
+        "04000000000000000000020108A2E0CC0D99F8A5EF", 2
+};
+
+static const ECCurveParams ecCurve_NIST_B163 = {
+        "NIST-B163", ECField_GF2m, 163,
+        "0800000000000000000000000000000000000000C9",
+        "000000000000000000000000000000000000000001",
+        "020A601907B8C953CA1481EB10512F78744A3205FD",
+        "03F0EBA16286A2D57EA0991168D4994637E8343E36",
+        "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
+        "040000000000000000000292FE77E70C12A4234C33", 2
+};
+
+static const ECCurveParams ecCurve_NIST_K233 = {
+        "NIST-K233", ECField_GF2m, 233,
+        "020000000000000000000000000000000000000004000000000000000001",
+        "000000000000000000000000000000000000000000000000000000000000",
+        "000000000000000000000000000000000000000000000000000000000001",
+        "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
+        "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
+        "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4
+};
+
+static const ECCurveParams ecCurve_NIST_B233 = {
+        "NIST-B233", ECField_GF2m, 233,
+        "020000000000000000000000000000000000000004000000000000000001",
+        "000000000000000000000000000000000000000000000000000000000001",
+        "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
+        "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
+        "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
+        "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2
+};
+
+static const ECCurveParams ecCurve_NIST_K283 = {
+        "NIST-K283", ECField_GF2m, 283,
+        "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+        "000000000000000000000000000000000000000000000000000000000000000000000000",
+        "000000000000000000000000000000000000000000000000000000000000000000000001",
+        "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
+        "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
+        "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", 4
+};
+
+static const ECCurveParams ecCurve_NIST_B283 = {
+        "NIST-B283", ECField_GF2m, 283,
+        "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+        "000000000000000000000000000000000000000000000000000000000000000000000001",
+        "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
+        "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
+        "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
+        "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 2
+};
+
+static const ECCurveParams ecCurve_NIST_K409 = {
+        "NIST-K409", ECField_GF2m, 409,
+        "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+        "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
+        "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
+        "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4
+};
+
+static const ECCurveParams ecCurve_NIST_B409 = {
+        "NIST-B409", ECField_GF2m, 409,
+        "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+        "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
+        "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
+        "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
+        "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", 2
+};
+
+static const ECCurveParams ecCurve_NIST_K571 = {
+        "NIST-K571", ECField_GF2m, 571,
+        "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+        "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
+        "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
+        "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", 4
+};
+
+static const ECCurveParams ecCurve_NIST_B571 = {
+        "NIST-B571", ECField_GF2m, 571,
+        "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+        "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
+        "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
+        "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
+        "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", 2
+};
+
+/* ANSI X9.62 prime curves */
+static const ECCurveParams ecCurve_X9_62_PRIME_192V2 = {
+        "X9.62 P-192V2", ECField_GFp, 192,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
+        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
+        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
+        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", 1
+};
+
+static const ECCurveParams ecCurve_X9_62_PRIME_192V3 = {
+        "X9.62 P-192V3", ECField_GFp, 192,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
+        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
+        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
+        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", 1
+};
+
+static const ECCurveParams ecCurve_X9_62_PRIME_239V1 = {
+        "X9.62 P-239V1", ECField_GFp, 239,
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
+        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
+        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", 1
+};
+
+static const ECCurveParams ecCurve_X9_62_PRIME_239V2 = {
+        "X9.62 P-239V2", ECField_GFp, 239,
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
+        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
+        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
+        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", 1
+};
+
+static const ECCurveParams ecCurve_X9_62_PRIME_239V3 = {
+        "X9.62 P-239V3", ECField_GFp, 239,
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
+        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
+        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
+        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", 1
+};
+
+/* ANSI X9.62 binary curves */
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V1 = {
+        "X9.62 C2-PNB163V1", ECField_GF2m, 163,
+        "080000000000000000000000000000000000000107",
+        "072546B5435234A422E0789675F432C89435DE5242",
+        "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
+        "07AF69989546103D79329FCC3D74880F33BBE803CB",
+        "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
+        "0400000000000000000001E60FC8821CC74DAEAFC1", 2
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V2 = {
+        "X9.62 C2-PNB163V2", ECField_GF2m, 163,
+        "080000000000000000000000000000000000000107",
+        "0108B39E77C4B108BED981ED0E890E117C511CF072",
+        "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
+        "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
+        "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
+        "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V3 = {
+        "X9.62 C2-PNB163V3", ECField_GF2m, 163,
+        "080000000000000000000000000000000000000107",
+        "07A526C63D3E25A256A007699F5447E32AE456B50E",
+        "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
+        "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
+        "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
+        "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB176V1 = {
+        "X9.62 C2-PNB176V1", ECField_GF2m, 176,
+        "0100000000000000000000000000000000080000000007",
+        "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
+        "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
+        "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
+        "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
+        "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V1 = {
+        "X9.62 C2-TNB191V1", ECField_GF2m, 191,
+        "800000000000000000000000000000000000000000000201",
+        "2866537B676752636A68F56554E12640276B649EF7526267",
+        "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
+        "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
+        "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
+        "40000000000000000000000004A20E90C39067C893BBB9A5", 2
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V2 = {
+        "X9.62 C2-TNB191V2", ECField_GF2m, 191,
+        "800000000000000000000000000000000000000000000201",
+        "401028774D7777C7B7666D1366EA432071274F89FF01E718",
+        "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
+        "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
+        "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
+        "20000000000000000000000050508CB89F652824E06B8173", 4
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V3 = {
+        "X9.62 C2-TNB191V3", ECField_GF2m, 191,
+        "800000000000000000000000000000000000000000000201",
+        "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
+        "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
+        "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
+        "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
+        "155555555555555555555555610C0B196812BFB6288A3EA3", 6
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB208W1 = {
+        "X9.62 C2-PNB208W1", ECField_GF2m, 208,
+        "010000000000000000000000000000000800000000000000000007",
+        "0000000000000000000000000000000000000000000000000000",
+        "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
+        "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
+        "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
+        "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V1 = {
+        "X9.62 C2-TNB239V1", ECField_GF2m, 239,
+        "800000000000000000000000000000000000000000000000001000000001",
+        "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
+        "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
+        "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
+        "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
+        "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V2 = {
+        "X9.62 C2-TNB239V2", ECField_GF2m, 239,
+        "800000000000000000000000000000000000000000000000001000000001",
+        "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
+        "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
+        "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
+        "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
+        "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V3 = {
+        "X9.62 C2-TNB239V3", ECField_GF2m, 239,
+        "800000000000000000000000000000000000000000000000001000000001",
+        "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
+        "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
+        "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
+        "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
+        "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB272W1 = {
+        "X9.62 C2-PNB272W1", ECField_GF2m, 272,
+        "010000000000000000000000000000000000000000000000000000010000000000000B",
+        "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
+        "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
+        "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
+        "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
+        "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
+        0xFF06
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB304W1 = {
+        "X9.62 C2-PNB304W1", ECField_GF2m, 304,
+        "010000000000000000000000000000000000000000000000000000000000000000000000000807",
+        "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
+        "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
+        "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
+        "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
+        "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 0xFE2E
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB359V1 = {
+        "X9.62 C2-TNB359V1", ECField_GF2m, 359,
+        "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
+        "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
+        "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
+        "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
+        "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
+        "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 0x4C
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB368W1 = {
+        "X9.62 C2-PNB368W1", ECField_GF2m, 368,
+        "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
+        "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
+        "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
+        "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
+        "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
+        "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 0xFF70
+};
+
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB431R1 = {
+        "X9.62 C2-TNB431R1", ECField_GF2m, 431,
+        "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
+        "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
+        "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
+        "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
+        "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
+        "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760
+};
+
+/* SEC2 prime curves */
+static const ECCurveParams ecCurve_SECG_PRIME_112R1 = {
+        "SECP-112R1", ECField_GFp, 112,
+        "DB7C2ABF62E35E668076BEAD208B",
+        "DB7C2ABF62E35E668076BEAD2088",
+        "659EF8BA043916EEDE8911702B22",
+        "09487239995A5EE76B55F9C2F098",
+        "A89CE5AF8724C0A23E0E0FF77500",
+        "DB7C2ABF62E35E7628DFAC6561C5", 1
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_112R2 = {
+        "SECP-112R2", ECField_GFp, 112,
+        "DB7C2ABF62E35E668076BEAD208B",
+        "6127C24C05F38A0AAAF65C0EF02C",
+        "51DEF1815DB5ED74FCC34C85D709",
+        "4BA30AB5E892B4E1649DD0928643",
+        "adcd46f5882e3747def36e956e97",
+        "36DF0AAFD8B8D7597CA10520D04B", 4
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_128R1 = {
+        "SECP-128R1", ECField_GFp, 128,
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
+        "E87579C11079F43DD824993C2CEE5ED3",
+        "161FF7528B899B2D0C28607CA52C5B86",
+        "CF5AC8395BAFEB13C02DA292DDED7A83",
+        "FFFFFFFE0000000075A30D1B9038A115", 1
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_128R2 = {
+        "SECP-128R2", ECField_GFp, 128,
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+        "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
+        "5EEEFCA380D02919DC2C6558BB6D8A5D",
+        "7B6AA5D85E572983E6FB32A7CDEBC140",
+        "27B6916A894D3AEE7106FE805FC34B44",
+        "3FFFFFFF7FFFFFFFBE0024720613B5A3", 4
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_160K1 = {
+        "SECP-160K1", ECField_GFp, 160,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+        "0000000000000000000000000000000000000000",
+        "0000000000000000000000000000000000000007",
+        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
+        "938CF935318FDCED6BC28286531733C3F03C4FEE",
+        "0100000000000000000001B8FA16DFAB9ACA16B6B3", 1
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_160R1 = {
+        "SECP-160R1", ECField_GFp, 160,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
+        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
+        "4A96B5688EF573284664698968C38BB913CBFC82",
+        "23A628553168947D59DCC912042351377AC5FB32",
+        "0100000000000000000001F4C8F927AED3CA752257", 1
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_160R2 = {
+        "SECP-160R2", ECField_GFp, 160,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
+        "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
+        "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
+        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
+        "0100000000000000000000351EE786A818F3A1A16B", 1
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_192K1 = {
+        "SECP-192K1", ECField_GFp, 192,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
+        "000000000000000000000000000000000000000000000000",
+        "000000000000000000000000000000000000000000000003",
+        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
+        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
+        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 1
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_224K1 = {
+        "SECP-224K1", ECField_GFp, 224,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
+        "00000000000000000000000000000000000000000000000000000000",
+        "00000000000000000000000000000000000000000000000000000005",
+        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
+        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
+        "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 1
+};
+
+static const ECCurveParams ecCurve_SECG_PRIME_256K1 = {
+        "SECP-256K1", ECField_GFp, 256,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
+        "0000000000000000000000000000000000000000000000000000000000000000",
+        "0000000000000000000000000000000000000000000000000000000000000007",
+        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
+        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 1
+};
+
+/* SEC2 binary curves */
+static const ECCurveParams ecCurve_SECG_CHAR2_113R1 = {
+        "SECT-113R1", ECField_GF2m, 113,
+        "020000000000000000000000000201",
+        "003088250CA6E7C7FE649CE85820F7",
+        "00E8BEE4D3E2260744188BE0E9C723",
+        "009D73616F35F4AB1407D73562C10F",
+        "00A52830277958EE84D1315ED31886",
+        "0100000000000000D9CCEC8A39E56F", 2
+};
+
+static const ECCurveParams ecCurve_SECG_CHAR2_113R2 = {
+        "SECT-113R2", ECField_GF2m, 113,
+        "020000000000000000000000000201",
+        "00689918DBEC7E5A0DD6DFC0AA55C7",
+        "0095E9A9EC9B297BD4BF36E059184F",
+        "01A57A6A7B26CA5EF52FCDB8164797",
+        "00B3ADC94ED1FE674C06E695BABA1D",
+        "010000000000000108789B2496AF93", 2
+};
+
+static const ECCurveParams ecCurve_SECG_CHAR2_131R1 = {
+        "SECT-131R1", ECField_GF2m, 131,
+        "080000000000000000000000000000010D",
+        "07A11B09A76B562144418FF3FF8C2570B8",
+        "0217C05610884B63B9C6C7291678F9D341",
+        "0081BAF91FDF9833C40F9C181343638399",
+        "078C6E7EA38C001F73C8134B1B4EF9E150",
+        "0400000000000000023123953A9464B54D", 2
+};
+
+static const ECCurveParams ecCurve_SECG_CHAR2_131R2 = {
+        "SECT-131R2", ECField_GF2m, 131,
+        "080000000000000000000000000000010D",
+        "03E5A88919D7CAFCBF415F07C2176573B2",
+        "04B8266A46C55657AC734CE38F018F2192",
+        "0356DCD8F2F95031AD652D23951BB366A8",
+        "0648F06D867940A5366D9E265DE9EB240F",
+        "0400000000000000016954A233049BA98F", 2
+};
+
+static const ECCurveParams ecCurve_SECG_CHAR2_163R1 = {
+        "SECT-163R1", ECField_GF2m, 163,
+        "0800000000000000000000000000000000000000C9",
+        "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
+        "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
+        "0369979697AB43897789566789567F787A7876A654",
+        "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
+        "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2
+};
+
+static const ECCurveParams ecCurve_SECG_CHAR2_193R1 = {
+        "SECT-193R1", ECField_GF2m, 193,
+        "02000000000000000000000000000000000000000000008001",
+        "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
+        "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
+        "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
+        "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
+        "01000000000000000000000000C7F34A778F443ACC920EBA49", 2
+};
+
+static const ECCurveParams ecCurve_SECG_CHAR2_193R2 = {
+        "SECT-193R2", ECField_GF2m, 193,
+        "02000000000000000000000000000000000000000000008001",
+        "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
+        "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
+        "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
+        "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
+        "010000000000000000000000015AAB561B005413CCD4EE99D5", 2
+};
+
+static const ECCurveParams ecCurve_SECG_CHAR2_239K1 = {
+        "SECT-239K1", ECField_GF2m, 239,
+        "800000000000000000004000000000000000000000000000000000000001",
+        "000000000000000000000000000000000000000000000000000000000000",
+        "000000000000000000000000000000000000000000000000000000000001",
+        "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
+        "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
+        "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4
+};
+
+/* WTLS curves */
+static const ECCurveParams ecCurve_WTLS_1 = {
+        "WTLS-1", ECField_GF2m, 113,
+        "020000000000000000000000000201",
+        "000000000000000000000000000001",
+        "000000000000000000000000000001",
+        "01667979A40BA497E5D5C270780617",
+        "00F44B4AF1ECC2630E08785CEBCC15",
+        "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2
+};
+
+static const ECCurveParams ecCurve_WTLS_8 = {
+        "WTLS-8", ECField_GFp, 112,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
+        "0000000000000000000000000000",
+        "0000000000000000000000000003",
+        "0000000000000000000000000001",
+        "0000000000000000000000000002",
+        "0100000000000001ECEA551AD837E9", 1
+};
+
+static const ECCurveParams ecCurve_WTLS_9 = {
+        "WTLS-9", ECField_GFp, 160,
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
+        "0000000000000000000000000000000000000000",
+        "0000000000000000000000000000000000000003",
+        "0000000000000000000000000000000000000001",
+        "0000000000000000000000000000000000000002",
+        "0100000000000000000001CDC98AE0E2DE574ABF33", 1
+};
+
+/* mapping between ECCurveName enum and pointers to ECCurveParams */
+static const ECCurveParams *ecCurve_map[] = {
+    NULL,                               /* ECCurve_noName */
+    &ecCurve_NIST_P192,                 /* ECCurve_NIST_P192 */
+    &ecCurve_NIST_P224,                 /* ECCurve_NIST_P224 */
+    &ecCurve_NIST_P256,                 /* ECCurve_NIST_P256 */
+    &ecCurve_NIST_P384,                 /* ECCurve_NIST_P384 */
+    &ecCurve_NIST_P521,                 /* ECCurve_NIST_P521 */
+    &ecCurve_NIST_K163,                 /* ECCurve_NIST_K163 */
+    &ecCurve_NIST_B163,                 /* ECCurve_NIST_B163 */
+    &ecCurve_NIST_K233,                 /* ECCurve_NIST_K233 */
+    &ecCurve_NIST_B233,                 /* ECCurve_NIST_B233 */
+    &ecCurve_NIST_K283,                 /* ECCurve_NIST_K283 */
+    &ecCurve_NIST_B283,                 /* ECCurve_NIST_B283 */
+    &ecCurve_NIST_K409,                 /* ECCurve_NIST_K409 */
+    &ecCurve_NIST_B409,                 /* ECCurve_NIST_B409 */
+    &ecCurve_NIST_K571,                 /* ECCurve_NIST_K571 */
+    &ecCurve_NIST_B571,                 /* ECCurve_NIST_B571 */
+    &ecCurve_X9_62_PRIME_192V2,         /* ECCurve_X9_62_PRIME_192V2 */
+    &ecCurve_X9_62_PRIME_192V3,         /* ECCurve_X9_62_PRIME_192V3 */
+    &ecCurve_X9_62_PRIME_239V1,         /* ECCurve_X9_62_PRIME_239V1 */
+    &ecCurve_X9_62_PRIME_239V2,         /* ECCurve_X9_62_PRIME_239V2 */
+    &ecCurve_X9_62_PRIME_239V3,         /* ECCurve_X9_62_PRIME_239V3 */
+    &ecCurve_X9_62_CHAR2_PNB163V1,      /* ECCurve_X9_62_CHAR2_PNB163V1 */
+    &ecCurve_X9_62_CHAR2_PNB163V2,      /* ECCurve_X9_62_CHAR2_PNB163V2 */
+    &ecCurve_X9_62_CHAR2_PNB163V3,      /* ECCurve_X9_62_CHAR2_PNB163V3 */
+    &ecCurve_X9_62_CHAR2_PNB176V1,      /* ECCurve_X9_62_CHAR2_PNB176V1 */
+    &ecCurve_X9_62_CHAR2_TNB191V1,      /* ECCurve_X9_62_CHAR2_TNB191V1 */
+    &ecCurve_X9_62_CHAR2_TNB191V2,      /* ECCurve_X9_62_CHAR2_TNB191V2 */
+    &ecCurve_X9_62_CHAR2_TNB191V3,      /* ECCurve_X9_62_CHAR2_TNB191V3 */
+    &ecCurve_X9_62_CHAR2_PNB208W1,      /* ECCurve_X9_62_CHAR2_PNB208W1 */
+    &ecCurve_X9_62_CHAR2_TNB239V1,      /* ECCurve_X9_62_CHAR2_TNB239V1 */
+    &ecCurve_X9_62_CHAR2_TNB239V2,      /* ECCurve_X9_62_CHAR2_TNB239V2 */
+    &ecCurve_X9_62_CHAR2_TNB239V3,      /* ECCurve_X9_62_CHAR2_TNB239V3 */
+    &ecCurve_X9_62_CHAR2_PNB272W1,      /* ECCurve_X9_62_CHAR2_PNB272W1 */
+    &ecCurve_X9_62_CHAR2_PNB304W1,      /* ECCurve_X9_62_CHAR2_PNB304W1 */
+    &ecCurve_X9_62_CHAR2_TNB359V1,      /* ECCurve_X9_62_CHAR2_TNB359V1 */
+    &ecCurve_X9_62_CHAR2_PNB368W1,      /* ECCurve_X9_62_CHAR2_PNB368W1 */
+    &ecCurve_X9_62_CHAR2_TNB431R1,      /* ECCurve_X9_62_CHAR2_TNB431R1 */
+    &ecCurve_SECG_PRIME_112R1,          /* ECCurve_SECG_PRIME_112R1 */
+    &ecCurve_SECG_PRIME_112R2,          /* ECCurve_SECG_PRIME_112R2 */
+    &ecCurve_SECG_PRIME_128R1,          /* ECCurve_SECG_PRIME_128R1 */
+    &ecCurve_SECG_PRIME_128R2,          /* ECCurve_SECG_PRIME_128R2 */
+    &ecCurve_SECG_PRIME_160K1,          /* ECCurve_SECG_PRIME_160K1 */
+    &ecCurve_SECG_PRIME_160R1,          /* ECCurve_SECG_PRIME_160R1 */
+    &ecCurve_SECG_PRIME_160R2,          /* ECCurve_SECG_PRIME_160R2 */
+    &ecCurve_SECG_PRIME_192K1,          /* ECCurve_SECG_PRIME_192K1 */
+    &ecCurve_SECG_PRIME_224K1,          /* ECCurve_SECG_PRIME_224K1 */
+    &ecCurve_SECG_PRIME_256K1,          /* ECCurve_SECG_PRIME_256K1 */
+    &ecCurve_SECG_CHAR2_113R1,          /* ECCurve_SECG_CHAR2_113R1 */
+    &ecCurve_SECG_CHAR2_113R2,          /* ECCurve_SECG_CHAR2_113R2 */
+    &ecCurve_SECG_CHAR2_131R1,          /* ECCurve_SECG_CHAR2_131R1 */
+    &ecCurve_SECG_CHAR2_131R2,          /* ECCurve_SECG_CHAR2_131R2 */
+    &ecCurve_SECG_CHAR2_163R1,          /* ECCurve_SECG_CHAR2_163R1 */
+    &ecCurve_SECG_CHAR2_193R1,          /* ECCurve_SECG_CHAR2_193R1 */
+    &ecCurve_SECG_CHAR2_193R2,          /* ECCurve_SECG_CHAR2_193R2 */
+    &ecCurve_SECG_CHAR2_239K1,          /* ECCurve_SECG_CHAR2_239K1 */
+    &ecCurve_WTLS_1,                    /* ECCurve_WTLS_1 */
+    &ecCurve_WTLS_8,                    /* ECCurve_WTLS_8 */
+    &ecCurve_WTLS_9,                    /* ECCurve_WTLS_9 */
+    NULL                                /* ECCurve_pastLastCurve */
+};
+
+#endif /* _ECL_CURVE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-exp.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,216 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ECL_EXP_H
+#define _ECL_EXP_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* Curve field type */
+typedef enum {
+        ECField_GFp,
+        ECField_GF2m
+} ECField;
+
+/* Hexadecimal encoding of curve parameters */
+struct ECCurveParamsStr {
+        char *text;
+        ECField field;
+        unsigned int size;
+        char *irr;
+        char *curvea;
+        char *curveb;
+        char *genx;
+        char *geny;
+        char *order;
+        int cofactor;
+};
+typedef struct ECCurveParamsStr ECCurveParams;
+
+/* Named curve parameters */
+typedef enum {
+
+        ECCurve_noName = 0,
+
+        /* NIST prime curves */
+        ECCurve_NIST_P192,
+        ECCurve_NIST_P224,
+        ECCurve_NIST_P256,
+        ECCurve_NIST_P384,
+        ECCurve_NIST_P521,
+
+        /* NIST binary curves */
+        ECCurve_NIST_K163,
+        ECCurve_NIST_B163,
+        ECCurve_NIST_K233,
+        ECCurve_NIST_B233,
+        ECCurve_NIST_K283,
+        ECCurve_NIST_B283,
+        ECCurve_NIST_K409,
+        ECCurve_NIST_B409,
+        ECCurve_NIST_K571,
+        ECCurve_NIST_B571,
+
+        /* ANSI X9.62 prime curves */
+        /* ECCurve_X9_62_PRIME_192V1 == ECCurve_NIST_P192 */
+        ECCurve_X9_62_PRIME_192V2,
+        ECCurve_X9_62_PRIME_192V3,
+        ECCurve_X9_62_PRIME_239V1,
+        ECCurve_X9_62_PRIME_239V2,
+        ECCurve_X9_62_PRIME_239V3,
+        /* ECCurve_X9_62_PRIME_256V1 == ECCurve_NIST_P256 */
+
+        /* ANSI X9.62 binary curves */
+        ECCurve_X9_62_CHAR2_PNB163V1,
+        ECCurve_X9_62_CHAR2_PNB163V2,
+        ECCurve_X9_62_CHAR2_PNB163V3,
+        ECCurve_X9_62_CHAR2_PNB176V1,
+        ECCurve_X9_62_CHAR2_TNB191V1,
+        ECCurve_X9_62_CHAR2_TNB191V2,
+        ECCurve_X9_62_CHAR2_TNB191V3,
+        ECCurve_X9_62_CHAR2_PNB208W1,
+        ECCurve_X9_62_CHAR2_TNB239V1,
+        ECCurve_X9_62_CHAR2_TNB239V2,
+        ECCurve_X9_62_CHAR2_TNB239V3,
+        ECCurve_X9_62_CHAR2_PNB272W1,
+        ECCurve_X9_62_CHAR2_PNB304W1,
+        ECCurve_X9_62_CHAR2_TNB359V1,
+        ECCurve_X9_62_CHAR2_PNB368W1,
+        ECCurve_X9_62_CHAR2_TNB431R1,
+
+        /* SEC2 prime curves */
+        ECCurve_SECG_PRIME_112R1,
+        ECCurve_SECG_PRIME_112R2,
+        ECCurve_SECG_PRIME_128R1,
+        ECCurve_SECG_PRIME_128R2,
+        ECCurve_SECG_PRIME_160K1,
+        ECCurve_SECG_PRIME_160R1,
+        ECCurve_SECG_PRIME_160R2,
+        ECCurve_SECG_PRIME_192K1,
+        /* ECCurve_SECG_PRIME_192R1 == ECCurve_NIST_P192 */
+        ECCurve_SECG_PRIME_224K1,
+        /* ECCurve_SECG_PRIME_224R1 == ECCurve_NIST_P224 */
+        ECCurve_SECG_PRIME_256K1,
+        /* ECCurve_SECG_PRIME_256R1 == ECCurve_NIST_P256 */
+        /* ECCurve_SECG_PRIME_384R1 == ECCurve_NIST_P384 */
+        /* ECCurve_SECG_PRIME_521R1 == ECCurve_NIST_P521 */
+
+        /* SEC2 binary curves */
+        ECCurve_SECG_CHAR2_113R1,
+        ECCurve_SECG_CHAR2_113R2,
+        ECCurve_SECG_CHAR2_131R1,
+        ECCurve_SECG_CHAR2_131R2,
+        /* ECCurve_SECG_CHAR2_163K1 == ECCurve_NIST_K163 */
+        ECCurve_SECG_CHAR2_163R1,
+        /* ECCurve_SECG_CHAR2_163R2 == ECCurve_NIST_B163 */
+        ECCurve_SECG_CHAR2_193R1,
+        ECCurve_SECG_CHAR2_193R2,
+        /* ECCurve_SECG_CHAR2_233K1 == ECCurve_NIST_K233 */
+        /* ECCurve_SECG_CHAR2_233R1 == ECCurve_NIST_B233 */
+        ECCurve_SECG_CHAR2_239K1,
+        /* ECCurve_SECG_CHAR2_283K1 == ECCurve_NIST_K283 */
+        /* ECCurve_SECG_CHAR2_283R1 == ECCurve_NIST_B283 */
+        /* ECCurve_SECG_CHAR2_409K1 == ECCurve_NIST_K409 */
+        /* ECCurve_SECG_CHAR2_409R1 == ECCurve_NIST_B409 */
+        /* ECCurve_SECG_CHAR2_571K1 == ECCurve_NIST_K571 */
+        /* ECCurve_SECG_CHAR2_571R1 == ECCurve_NIST_B571 */
+
+        /* WTLS curves */
+        ECCurve_WTLS_1,
+        /* there is no WTLS 2 curve */
+        /* ECCurve_WTLS_3 == ECCurve_NIST_K163 */
+        /* ECCurve_WTLS_4 == ECCurve_SECG_CHAR2_113R1 */
+        /* ECCurve_WTLS_5 == ECCurve_X9_62_CHAR2_PNB163V1 */
+        /* ECCurve_WTLS_6 == ECCurve_SECG_PRIME_112R1 */
+        /* ECCurve_WTLS_7 == ECCurve_SECG_PRIME_160R1 */
+        ECCurve_WTLS_8,
+        ECCurve_WTLS_9,
+        /* ECCurve_WTLS_10 == ECCurve_NIST_K233 */
+        /* ECCurve_WTLS_11 == ECCurve_NIST_B233 */
+        /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */
+
+        ECCurve_pastLastCurve
+} ECCurveName;
+
+/* Aliased named curves */
+
+#define ECCurve_X9_62_PRIME_192V1 ECCurve_NIST_P192
+#define ECCurve_X9_62_PRIME_256V1 ECCurve_NIST_P256
+#define ECCurve_SECG_PRIME_192R1 ECCurve_NIST_P192
+#define ECCurve_SECG_PRIME_224R1 ECCurve_NIST_P224
+#define ECCurve_SECG_PRIME_256R1 ECCurve_NIST_P256
+#define ECCurve_SECG_PRIME_384R1 ECCurve_NIST_P384
+#define ECCurve_SECG_PRIME_521R1 ECCurve_NIST_P521
+#define ECCurve_SECG_CHAR2_163K1 ECCurve_NIST_K163
+#define ECCurve_SECG_CHAR2_163R2 ECCurve_NIST_B163
+#define ECCurve_SECG_CHAR2_233K1 ECCurve_NIST_K233
+#define ECCurve_SECG_CHAR2_233R1 ECCurve_NIST_B233
+#define ECCurve_SECG_CHAR2_283K1 ECCurve_NIST_K283
+#define ECCurve_SECG_CHAR2_283R1 ECCurve_NIST_B283
+#define ECCurve_SECG_CHAR2_409K1 ECCurve_NIST_K409
+#define ECCurve_SECG_CHAR2_409R1 ECCurve_NIST_B409
+#define ECCurve_SECG_CHAR2_571K1 ECCurve_NIST_K571
+#define ECCurve_SECG_CHAR2_571R1 ECCurve_NIST_B571
+#define ECCurve_WTLS_3 ECCurve_NIST_K163
+#define ECCurve_WTLS_4 ECCurve_SECG_CHAR2_113R1
+#define ECCurve_WTLS_5 ECCurve_X9_62_CHAR2_PNB163V1
+#define ECCurve_WTLS_6 ECCurve_SECG_PRIME_112R1
+#define ECCurve_WTLS_7 ECCurve_SECG_PRIME_160R1
+#define ECCurve_WTLS_10 ECCurve_NIST_K233
+#define ECCurve_WTLS_11 ECCurve_NIST_B233
+#define ECCurve_WTLS_12 ECCurve_NIST_P224
+
+#endif /* _ECL_EXP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl-priv.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,304 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Stephen Fung <fungstep@hotmail.com> and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ECL_PRIV_H
+#define _ECL_PRIV_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecl.h"
+#include "mpi.h"
+#include "mplogic.h"
+
+/* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
+/* the following needs to go away... */
+#if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT)
+#define ECL_SIXTY_FOUR_BIT
+#else
+#define ECL_THIRTY_TWO_BIT
+#endif
+
+#define ECL_CURVE_DIGITS(curve_size_in_bits) \
+        (((curve_size_in_bits)+(sizeof(mp_digit)*8-1))/(sizeof(mp_digit)*8))
+#define ECL_BITS (sizeof(mp_digit)*8)
+#define ECL_MAX_FIELD_SIZE_DIGITS (80/sizeof(mp_digit))
+
+/* Gets the i'th bit in the binary representation of a. If i >= length(a),
+ * then return 0. (The above behaviour differs from mpl_get_bit, which
+ * causes an error if i >= length(a).) */
+#define MP_GET_BIT(a, i) \
+        ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
+
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+#define MP_ADD_CARRY(a1, a2, s, cin, cout)   \
+    { mp_word w; \
+    w = ((mp_word)(cin)) + (a1) + (a2); \
+    s = ACCUM(w); \
+    cout = CARRYOUT(w); }
+
+#define MP_SUB_BORROW(a1, a2, s, bin, bout)   \
+    { mp_word w; \
+    w = ((mp_word)(a1)) - (a2) - (bin); \
+    s = ACCUM(w); \
+    bout = (w >> MP_DIGIT_BIT) & 1; }
+
+#else
+/* NOTE,
+ * cin and cout could be the same variable.
+ * bin and bout could be the same variable.
+ * a1 or a2 and s could be the same variable.
+ * don't trash those outputs until their respective inputs have
+ * been read. */
+#define MP_ADD_CARRY(a1, a2, s, cin, cout)   \
+    { mp_digit tmp,sum; \
+    tmp = (a1); \
+    sum = tmp + (a2); \
+    tmp = (sum < tmp);                     /* detect overflow */ \
+    s = sum += (cin); \
+    cout = tmp + (sum < (cin)); }
+
+#define MP_SUB_BORROW(a1, a2, s, bin, bout)   \
+    { mp_digit tmp; \
+    tmp = (a1); \
+    s = tmp - (a2); \
+    tmp = (s > tmp);                    /* detect borrow */ \
+    if ((bin) && !s--) tmp++;   \
+    bout = tmp; }
+#endif
+
+
+struct GFMethodStr;
+typedef struct GFMethodStr GFMethod;
+struct GFMethodStr {
+        /* Indicates whether the structure was constructed from dynamic memory
+         * or statically created. */
+        int constructed;
+        /* Irreducible that defines the field. For prime fields, this is the
+         * prime p. For binary polynomial fields, this is the bitstring
+         * representation of the irreducible polynomial. */
+        mp_int irr;
+        /* For prime fields, the value irr_arr[0] is the number of bits in the
+         * field. For binary polynomial fields, the irreducible polynomial
+         * f(t) is represented as an array of unsigned int[], where f(t) is
+         * of the form: f(t) = t^p[0] + t^p[1] + ... + t^p[4] where m = p[0]
+         * > p[1] > ... > p[4] = 0. */
+        unsigned int irr_arr[5];
+        /* Field arithmetic methods. All methods (except field_enc and
+         * field_dec) are assumed to take field-encoded parameters and return
+         * field-encoded values. All methods (except field_enc and field_dec)
+         * are required to be implemented. */
+        mp_err (*field_add) (const mp_int *a, const mp_int *b, mp_int *r,
+                                                 const GFMethod *meth);
+        mp_err (*field_neg) (const mp_int *a, mp_int *r, const GFMethod *meth);
+        mp_err (*field_sub) (const mp_int *a, const mp_int *b, mp_int *r,
+                                                 const GFMethod *meth);
+        mp_err (*field_mod) (const mp_int *a, mp_int *r, const GFMethod *meth);
+        mp_err (*field_mul) (const mp_int *a, const mp_int *b, mp_int *r,
+                                                 const GFMethod *meth);
+        mp_err (*field_sqr) (const mp_int *a, mp_int *r, const GFMethod *meth);
+        mp_err (*field_div) (const mp_int *a, const mp_int *b, mp_int *r,
+                                                 const GFMethod *meth);
+        mp_err (*field_enc) (const mp_int *a, mp_int *r, const GFMethod *meth);
+        mp_err (*field_dec) (const mp_int *a, mp_int *r, const GFMethod *meth);
+        /* Extra storage for implementation-specific data.  Any memory
+         * allocated to these extra fields will be cleared by extra_free. */
+        void *extra1;
+        void *extra2;
+        void (*extra_free) (GFMethod *meth);
+};
+
+/* Construct generic GFMethods. */
+GFMethod *GFMethod_consGFp(const mp_int *irr);
+GFMethod *GFMethod_consGFp_mont(const mp_int *irr);
+GFMethod *GFMethod_consGF2m(const mp_int *irr,
+                                                        const unsigned int irr_arr[5]);
+/* Free the memory allocated (if any) to a GFMethod object. */
+void GFMethod_free(GFMethod *meth);
+
+struct ECGroupStr {
+        /* Indicates whether the structure was constructed from dynamic memory
+         * or statically created. */
+        int constructed;
+        /* Field definition and arithmetic. */
+        GFMethod *meth;
+        /* Textual representation of curve name, if any. */
+        char *text;
+#ifdef _KERNEL
+        int text_len;
+#endif
+        /* Curve parameters, field-encoded. */
+        mp_int curvea, curveb;
+        /* x and y coordinates of the base point, field-encoded. */
+        mp_int genx, geny;
+        /* Order and cofactor of the base point. */
+        mp_int order;
+        int cofactor;
+        /* Point arithmetic methods. All methods are assumed to take
+         * field-encoded parameters and return field-encoded values. All
+         * methods (except base_point_mul and points_mul) are required to be
+         * implemented. */
+        mp_err (*point_add) (const mp_int *px, const mp_int *py,
+                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
+                                                 mp_int *ry, const ECGroup *group);
+        mp_err (*point_sub) (const mp_int *px, const mp_int *py,
+                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
+                                                 mp_int *ry, const ECGroup *group);
+        mp_err (*point_dbl) (const mp_int *px, const mp_int *py, mp_int *rx,
+                                                 mp_int *ry, const ECGroup *group);
+        mp_err (*point_mul) (const mp_int *n, const mp_int *px,
+                                                 const mp_int *py, mp_int *rx, mp_int *ry,
+                                                 const ECGroup *group);
+        mp_err (*base_point_mul) (const mp_int *n, mp_int *rx, mp_int *ry,
+                                                          const ECGroup *group);
+        mp_err (*points_mul) (const mp_int *k1, const mp_int *k2,
+                                                  const mp_int *px, const mp_int *py, mp_int *rx,
+                                                  mp_int *ry, const ECGroup *group);
+        mp_err (*validate_point) (const mp_int *px, const mp_int *py, const ECGroup *group);
+        /* Extra storage for implementation-specific data.  Any memory
+         * allocated to these extra fields will be cleared by extra_free. */
+        void *extra1;
+        void *extra2;
+        void (*extra_free) (ECGroup *group);
+};
+
+/* Wrapper functions for generic prime field arithmetic. */
+mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+
+/* fixed length in-line adds. Count is in words */
+mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+
+mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+mp_err ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
+                                  const GFMethod *meth);
+/* Wrapper functions for generic binary polynomial field arithmetic. */
+mp_err ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
+                                   const GFMethod *meth);
+mp_err ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                   const GFMethod *meth);
+mp_err ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
+                                   const GFMethod *meth);
+
+/* Montgomery prime field arithmetic. */
+mp_err ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
+                                           const GFMethod *meth);
+mp_err ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
+                                           const GFMethod *meth);
+mp_err ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
+void ec_GFp_extra_free_mont(GFMethod *meth);
+
+/* point multiplication */
+mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
+                                                const mp_int *px, const mp_int *py, mp_int *rx,
+                                                mp_int *ry, const ECGroup *group);
+mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
+                                                   const mp_int *px, const mp_int *py, mp_int *rx,
+                                                   mp_int *ry, const ECGroup *group);
+
+/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
+ * be an array of signed char's to output to, bitsize should be the number
+ * of bits of out, in is the original scalar, and w is the window size.
+ * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
+ * Menezes, "Software implementation of elliptic curve cryptography over
+ * binary fields", Proc. CHES 2000. */
+mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in,
+                                           int w);
+
+/* Optimized field arithmetic */
+mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
+mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName);
+mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName);
+mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName);
+mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName);
+mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name);
+mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name);
+mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
+
+/* Optimized floating-point arithmetic */
+#ifdef ECL_USE_FP
+mp_err ec_group_set_secp160r1_fp(ECGroup *group);
+mp_err ec_group_set_nistp192_fp(ECGroup *group);
+mp_err ec_group_set_nistp224_fp(ECGroup *group);
+#endif
+
+#endif /* _ECL_PRIV_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,475 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mpi.h"
+#include "mplogic.h"
+#include "ecl.h"
+#include "ecl-priv.h"
+#include "ec2.h"
+#include "ecp.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+/* Allocate memory for a new ECGroup object. */
+ECGroup *
+ECGroup_new(int kmflag)
+{
+        mp_err res = MP_OKAY;
+        ECGroup *group;
+#ifdef _KERNEL
+        group = (ECGroup *) kmem_alloc(sizeof(ECGroup), kmflag);
+#else
+        group = (ECGroup *) malloc(sizeof(ECGroup));
+#endif
+        if (group == NULL)
+                return NULL;
+        group->constructed = MP_YES;
+        group->meth = NULL;
+        group->text = NULL;
+        MP_DIGITS(&group->curvea) = 0;
+        MP_DIGITS(&group->curveb) = 0;
+        MP_DIGITS(&group->genx) = 0;
+        MP_DIGITS(&group->geny) = 0;
+        MP_DIGITS(&group->order) = 0;
+        group->base_point_mul = NULL;
+        group->points_mul = NULL;
+        group->validate_point = NULL;
+        group->extra1 = NULL;
+        group->extra2 = NULL;
+        group->extra_free = NULL;
+        MP_CHECKOK(mp_init(&group->curvea, kmflag));
+        MP_CHECKOK(mp_init(&group->curveb, kmflag));
+        MP_CHECKOK(mp_init(&group->genx, kmflag));
+        MP_CHECKOK(mp_init(&group->geny, kmflag));
+        MP_CHECKOK(mp_init(&group->order, kmflag));
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                ECGroup_free(group);
+                return NULL;
+        }
+        return group;
+}
+
+/* Construct a generic ECGroup for elliptic curves over prime fields. */
+ECGroup *
+ECGroup_consGFp(const mp_int *irr, const mp_int *curvea,
+                                const mp_int *curveb, const mp_int *genx,
+                                const mp_int *geny, const mp_int *order, int cofactor)
+{
+        mp_err res = MP_OKAY;
+        ECGroup *group = NULL;
+
+        group = ECGroup_new(FLAG(irr));
+        if (group == NULL)
+                return NULL;
+
+        group->meth = GFMethod_consGFp(irr);
+        if (group->meth == NULL) {
+                res = MP_MEM;
+                goto CLEANUP;
+        }
+        MP_CHECKOK(mp_copy(curvea, &group->curvea));
+        MP_CHECKOK(mp_copy(curveb, &group->curveb));
+        MP_CHECKOK(mp_copy(genx, &group->genx));
+        MP_CHECKOK(mp_copy(geny, &group->geny));
+        MP_CHECKOK(mp_copy(order, &group->order));
+        group->cofactor = cofactor;
+        group->point_add = &ec_GFp_pt_add_aff;
+        group->point_sub = &ec_GFp_pt_sub_aff;
+        group->point_dbl = &ec_GFp_pt_dbl_aff;
+        group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
+        group->base_point_mul = NULL;
+        group->points_mul = &ec_GFp_pts_mul_jac;
+        group->validate_point = &ec_GFp_validate_point;
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                ECGroup_free(group);
+                return NULL;
+        }
+        return group;
+}
+
+/* Construct a generic ECGroup for elliptic curves over prime fields with
+ * field arithmetic implemented in Montgomery coordinates. */
+ECGroup *
+ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
+                                         const mp_int *curveb, const mp_int *genx,
+                                         const mp_int *geny, const mp_int *order, int cofactor)
+{
+        mp_err res = MP_OKAY;
+        ECGroup *group = NULL;
+
+        group = ECGroup_new(FLAG(irr));
+        if (group == NULL)
+                return NULL;
+
+        group->meth = GFMethod_consGFp_mont(irr);
+        if (group->meth == NULL) {
+                res = MP_MEM;
+                goto CLEANUP;
+        }
+        MP_CHECKOK(group->meth->
+                           field_enc(curvea, &group->curvea, group->meth));
+        MP_CHECKOK(group->meth->
+                           field_enc(curveb, &group->curveb, group->meth));
+        MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth));
+        MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth));
+        MP_CHECKOK(mp_copy(order, &group->order));
+        group->cofactor = cofactor;
+        group->point_add = &ec_GFp_pt_add_aff;
+        group->point_sub = &ec_GFp_pt_sub_aff;
+        group->point_dbl = &ec_GFp_pt_dbl_aff;
+        group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
+        group->base_point_mul = NULL;
+        group->points_mul = &ec_GFp_pts_mul_jac;
+        group->validate_point = &ec_GFp_validate_point;
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                ECGroup_free(group);
+                return NULL;
+        }
+        return group;
+}
+
+#ifdef NSS_ECC_MORE_THAN_SUITE_B
+/* Construct a generic ECGroup for elliptic curves over binary polynomial
+ * fields. */
+ECGroup *
+ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
+                                 const mp_int *curvea, const mp_int *curveb,
+                                 const mp_int *genx, const mp_int *geny,
+                                 const mp_int *order, int cofactor)
+{
+        mp_err res = MP_OKAY;
+        ECGroup *group = NULL;
+
+        group = ECGroup_new(FLAG(irr));
+        if (group == NULL)
+                return NULL;
+
+        group->meth = GFMethod_consGF2m(irr, irr_arr);
+        if (group->meth == NULL) {
+                res = MP_MEM;
+                goto CLEANUP;
+        }
+        MP_CHECKOK(mp_copy(curvea, &group->curvea));
+        MP_CHECKOK(mp_copy(curveb, &group->curveb));
+        MP_CHECKOK(mp_copy(genx, &group->genx));
+        MP_CHECKOK(mp_copy(geny, &group->geny));
+        MP_CHECKOK(mp_copy(order, &group->order));
+        group->cofactor = cofactor;
+        group->point_add = &ec_GF2m_pt_add_aff;
+        group->point_sub = &ec_GF2m_pt_sub_aff;
+        group->point_dbl = &ec_GF2m_pt_dbl_aff;
+        group->point_mul = &ec_GF2m_pt_mul_mont;
+        group->base_point_mul = NULL;
+        group->points_mul = &ec_pts_mul_basic;
+        group->validate_point = &ec_GF2m_validate_point;
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                ECGroup_free(group);
+                return NULL;
+        }
+        return group;
+}
+#endif
+
+/* Construct ECGroup from hex parameters and name, if any. Called by
+ * ECGroup_fromHex and ECGroup_fromName. */
+ECGroup *
+ecgroup_fromNameAndHex(const ECCurveName name,
+                                   const ECCurveParams * params, int kmflag)
+{
+        mp_int irr, curvea, curveb, genx, geny, order;
+        int bits;
+        ECGroup *group = NULL;
+        mp_err res = MP_OKAY;
+
+        /* initialize values */
+        MP_DIGITS(&irr) = 0;
+        MP_DIGITS(&curvea) = 0;
+        MP_DIGITS(&curveb) = 0;
+        MP_DIGITS(&genx) = 0;
+        MP_DIGITS(&geny) = 0;
+        MP_DIGITS(&order) = 0;
+        MP_CHECKOK(mp_init(&irr, kmflag));
+        MP_CHECKOK(mp_init(&curvea, kmflag));
+        MP_CHECKOK(mp_init(&curveb, kmflag));
+        MP_CHECKOK(mp_init(&genx, kmflag));
+        MP_CHECKOK(mp_init(&geny, kmflag));
+        MP_CHECKOK(mp_init(&order, kmflag));
+        MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
+        MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
+        MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
+        MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
+        MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
+        MP_CHECKOK(mp_read_radix(&order, params->order, 16));
+
+        /* determine number of bits */
+        bits = mpl_significant_bits(&irr) - 1;
+        if (bits < MP_OKAY) {
+                res = bits;
+                goto CLEANUP;
+        }
+
+        /* determine which optimizations (if any) to use */
+        if (params->field == ECField_GFp) {
+#ifdef NSS_ECC_MORE_THAN_SUITE_B
+            switch (name) {
+#ifdef ECL_USE_FP
+                case ECCurve_SECG_PRIME_160R1:
+                        group =
+                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+                                                                &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                        MP_CHECKOK(ec_group_set_secp160r1_fp(group));
+                        break;
+#endif
+                case ECCurve_SECG_PRIME_192R1:
+#ifdef ECL_USE_FP
+                        group =
+                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+                                                                &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                        MP_CHECKOK(ec_group_set_nistp192_fp(group));
+#else
+                        group =
+                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+                                                                &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                        MP_CHECKOK(ec_group_set_gfp192(group, name));
+#endif
+                        break;
+                case ECCurve_SECG_PRIME_224R1:
+#ifdef ECL_USE_FP
+                        group =
+                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+                                                                &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                        MP_CHECKOK(ec_group_set_nistp224_fp(group));
+#else
+                        group =
+                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+                                                                &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                        MP_CHECKOK(ec_group_set_gfp224(group, name));
+#endif
+                        break;
+                case ECCurve_SECG_PRIME_256R1:
+                        group =
+                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+                                                                &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                        MP_CHECKOK(ec_group_set_gfp256(group, name));
+                        break;
+                case ECCurve_SECG_PRIME_521R1:
+                        group =
+                                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+                                                                &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                        MP_CHECKOK(ec_group_set_gfp521(group, name));
+                        break;
+                default:
+                        /* use generic arithmetic */
+#endif
+                        group =
+                                ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
+                                                                         &order, params->cofactor);
+                        if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+#ifdef NSS_ECC_MORE_THAN_SUITE_B
+                }
+        } else if (params->field == ECField_GF2m) {
+                group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor);
+                if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+                if ((name == ECCurve_NIST_K163) ||
+                    (name == ECCurve_NIST_B163) ||
+                    (name == ECCurve_SECG_CHAR2_163R1)) {
+                        MP_CHECKOK(ec_group_set_gf2m163(group, name));
+                } else if ((name == ECCurve_SECG_CHAR2_193R1) ||
+                           (name == ECCurve_SECG_CHAR2_193R2)) {
+                        MP_CHECKOK(ec_group_set_gf2m193(group, name));
+                } else if ((name == ECCurve_NIST_K233) ||
+                           (name == ECCurve_NIST_B233)) {
+                        MP_CHECKOK(ec_group_set_gf2m233(group, name));
+                }
+#endif
+        } else {
+                res = MP_UNDEF;
+                goto CLEANUP;
+        }
+
+        /* set name, if any */
+        if ((group != NULL) && (params->text != NULL)) {
+#ifdef _KERNEL
+                int n = strlen(params->text) + 1;
+
+                group->text = kmem_alloc(n, kmflag);
+                if (group->text == NULL) {
+                        res = MP_MEM;
+                        goto CLEANUP;
+                }
+                bcopy(params->text, group->text, n);
+                group->text_len = n;
+#else
+                group->text = strdup(params->text);
+                if (group->text == NULL) {
+                        res = MP_MEM;
+                }
+#endif
+        }
+
+  CLEANUP:
+        mp_clear(&irr);
+        mp_clear(&curvea);
+        mp_clear(&curveb);
+        mp_clear(&genx);
+        mp_clear(&geny);
+        mp_clear(&order);
+        if (res != MP_OKAY) {
+                ECGroup_free(group);
+                return NULL;
+        }
+        return group;
+}
+
+/* Construct ECGroup from hexadecimal representations of parameters. */
+ECGroup *
+ECGroup_fromHex(const ECCurveParams * params, int kmflag)
+{
+        return ecgroup_fromNameAndHex(ECCurve_noName, params, kmflag);
+}
+
+/* Construct ECGroup from named parameters. */
+ECGroup *
+ECGroup_fromName(const ECCurveName name, int kmflag)
+{
+        ECGroup *group = NULL;
+        ECCurveParams *params = NULL;
+        mp_err res = MP_OKAY;
+
+        params = EC_GetNamedCurveParams(name, kmflag);
+        if (params == NULL) {
+                res = MP_UNDEF;
+                goto CLEANUP;
+        }
+
+        /* construct actual group */
+        group = ecgroup_fromNameAndHex(name, params, kmflag);
+        if (group == NULL) {
+                res = MP_UNDEF;
+                goto CLEANUP;
+        }
+
+  CLEANUP:
+        EC_FreeCurveParams(params);
+        if (res != MP_OKAY) {
+                ECGroup_free(group);
+                return NULL;
+        }
+        return group;
+}
+
+/* Validates an EC public key as described in Section 5.2.2 of X9.62. */
+mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
+                                        mp_int *py)
+{
+    /* 1: Verify that publicValue is not the point at infinity */
+    /* 2: Verify that the coordinates of publicValue are elements
+     *    of the field.
+     */
+    /* 3: Verify that publicValue is on the curve. */
+    /* 4: Verify that the order of the curve times the publicValue
+     *    is the point at infinity.
+     */
+        return group->validate_point(px, py, group);
+}
+
+/* Free the memory allocated (if any) to an ECGroup object. */
+void
+ECGroup_free(ECGroup *group)
+{
+        if (group == NULL)
+                return;
+        GFMethod_free(group->meth);
+        if (group->constructed == MP_NO)
+                return;
+        mp_clear(&group->curvea);
+        mp_clear(&group->curveb);
+        mp_clear(&group->genx);
+        mp_clear(&group->geny);
+        mp_clear(&group->order);
+        if (group->text != NULL)
+#ifdef _KERNEL
+                kmem_free(group->text, group->text_len);
+#else
+                free(group->text);
+#endif
+        if (group->extra_free != NULL)
+                group->extra_free(group);
+#ifdef _KERNEL
+        kmem_free(group, sizeof (ECGroup));
+#else
+        free(group);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,111 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ECL_H
+#define _ECL_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* Although this is not an exported header file, code which uses elliptic
+ * curve point operations will need to include it. */
+
+#include "ecl-exp.h"
+#include "mpi.h"
+
+struct ECGroupStr;
+typedef struct ECGroupStr ECGroup;
+
+/* Construct ECGroup from hexadecimal representations of parameters. */
+ECGroup *ECGroup_fromHex(const ECCurveParams * params, int kmflag);
+
+/* Construct ECGroup from named parameters. */
+ECGroup *ECGroup_fromName(const ECCurveName name, int kmflag);
+
+/* Free an allocated ECGroup. */
+void ECGroup_free(ECGroup *group);
+
+/* Construct ECCurveParams from an ECCurveName */
+ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name, int kmflag);
+
+/* Duplicates an ECCurveParams */
+ECCurveParams *ECCurveParams_dup(const ECCurveParams * params, int kmflag);
+
+/* Free an allocated ECCurveParams */
+void EC_FreeCurveParams(ECCurveParams * params);
+
+/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x,
+ * y).  If x, y = NULL, then P is assumed to be the generator (base point)
+ * of the group of points on the elliptic curve. Input and output values
+ * are assumed to be NOT field-encoded. */
+mp_err ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
+                                   const mp_int *py, mp_int *qx, mp_int *qy);
+
+/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Input and output values are assumed to
+ * be NOT field-encoded. */
+mp_err ECPoints_mul(const ECGroup *group, const mp_int *k1,
+                                        const mp_int *k2, const mp_int *px, const mp_int *py,
+                                        mp_int *qx, mp_int *qy);
+
+/* Validates an EC public key as described in Section 5.2.2 of X9.62.
+ * Returns MP_YES if the public key is valid, MP_NO if the public key
+ * is invalid, or an error code if the validation could not be
+ * performed. */
+mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
+                                        mp_int *py);
+
+#endif /* _ECL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_curve.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,216 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecl.h"
+#include "ecl-curve.h"
+#include "ecl-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#define CHECK(func) if ((func) == NULL) { res = 0; goto CLEANUP; }
+
+/* Duplicates an ECCurveParams */
+ECCurveParams *
+ECCurveParams_dup(const ECCurveParams * params, int kmflag)
+{
+        int res = 1;
+        ECCurveParams *ret = NULL;
+
+#ifdef _KERNEL
+        ret = (ECCurveParams *) kmem_zalloc(sizeof(ECCurveParams), kmflag);
+#else
+        CHECK(ret = (ECCurveParams *) calloc(1, sizeof(ECCurveParams)));
+#endif
+        if (params->text != NULL) {
+#ifdef _KERNEL
+                ret->text = kmem_alloc(strlen(params->text) + 1, kmflag);
+                bcopy(params->text, ret->text, strlen(params->text) + 1);
+#else
+                CHECK(ret->text = strdup(params->text));
+#endif
+        }
+        ret->field = params->field;
+        ret->size = params->size;
+        if (params->irr != NULL) {
+#ifdef _KERNEL
+                ret->irr = kmem_alloc(strlen(params->irr) + 1, kmflag);
+                bcopy(params->irr, ret->irr, strlen(params->irr) + 1);
+#else
+                CHECK(ret->irr = strdup(params->irr));
+#endif
+        }
+        if (params->curvea != NULL) {
+#ifdef _KERNEL
+                ret->curvea = kmem_alloc(strlen(params->curvea) + 1, kmflag);
+                bcopy(params->curvea, ret->curvea, strlen(params->curvea) + 1);
+#else
+                CHECK(ret->curvea = strdup(params->curvea));
+#endif
+        }
+        if (params->curveb != NULL) {
+#ifdef _KERNEL
+                ret->curveb = kmem_alloc(strlen(params->curveb) + 1, kmflag);
+                bcopy(params->curveb, ret->curveb, strlen(params->curveb) + 1);
+#else
+                CHECK(ret->curveb = strdup(params->curveb));
+#endif
+        }
+        if (params->genx != NULL) {
+#ifdef _KERNEL
+                ret->genx = kmem_alloc(strlen(params->genx) + 1, kmflag);
+                bcopy(params->genx, ret->genx, strlen(params->genx) + 1);
+#else
+                CHECK(ret->genx = strdup(params->genx));
+#endif
+        }
+        if (params->geny != NULL) {
+#ifdef _KERNEL
+                ret->geny = kmem_alloc(strlen(params->geny) + 1, kmflag);
+                bcopy(params->geny, ret->geny, strlen(params->geny) + 1);
+#else
+                CHECK(ret->geny = strdup(params->geny));
+#endif
+        }
+        if (params->order != NULL) {
+#ifdef _KERNEL
+                ret->order = kmem_alloc(strlen(params->order) + 1, kmflag);
+                bcopy(params->order, ret->order, strlen(params->order) + 1);
+#else
+                CHECK(ret->order = strdup(params->order));
+#endif
+        }
+        ret->cofactor = params->cofactor;
+
+  CLEANUP:
+        if (res != 1) {
+                EC_FreeCurveParams(ret);
+                return NULL;
+        }
+        return ret;
+}
+
+#undef CHECK
+
+/* Construct ECCurveParams from an ECCurveName */
+ECCurveParams *
+EC_GetNamedCurveParams(const ECCurveName name, int kmflag)
+{
+        if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) ||
+                                        (ecCurve_map[name] == NULL)) {
+                return NULL;
+        } else {
+                return ECCurveParams_dup(ecCurve_map[name], kmflag);
+        }
+}
+
+/* Free the memory allocated (if any) to an ECCurveParams object. */
+void
+EC_FreeCurveParams(ECCurveParams * params)
+{
+        if (params == NULL)
+                return;
+        if (params->text != NULL)
+#ifdef _KERNEL
+                kmem_free(params->text, strlen(params->text) + 1);
+#else
+                free(params->text);
+#endif
+        if (params->irr != NULL)
+#ifdef _KERNEL
+                kmem_free(params->irr, strlen(params->irr) + 1);
+#else
+                free(params->irr);
+#endif
+        if (params->curvea != NULL)
+#ifdef _KERNEL
+                kmem_free(params->curvea, strlen(params->curvea) + 1);
+#else
+                free(params->curvea);
+#endif
+        if (params->curveb != NULL)
+#ifdef _KERNEL
+                kmem_free(params->curveb, strlen(params->curveb) + 1);
+#else
+                free(params->curveb);
+#endif
+        if (params->genx != NULL)
+#ifdef _KERNEL
+                kmem_free(params->genx, strlen(params->genx) + 1);
+#else
+                free(params->genx);
+#endif
+        if (params->geny != NULL)
+#ifdef _KERNEL
+                kmem_free(params->geny, strlen(params->geny) + 1);
+#else
+                free(params->geny);
+#endif
+        if (params->order != NULL)
+#ifdef _KERNEL
+                kmem_free(params->order, strlen(params->order) + 1);
+#else
+                free(params->order);
+#endif
+#ifdef _KERNEL
+        kmem_free(params, sizeof(ECCurveParams));
+#else
+        free(params);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_gf.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,1062 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Stephen Fung <fungstep@hotmail.com> and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mpi.h"
+#include "mp_gf2m.h"
+#include "ecl-priv.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Allocate memory for a new GFMethod object. */
+GFMethod *
+GFMethod_new(int kmflag)
+{
+        mp_err res = MP_OKAY;
+        GFMethod *meth;
+#ifdef _KERNEL
+        meth = (GFMethod *) kmem_alloc(sizeof(GFMethod), kmflag);
+#else
+        meth = (GFMethod *) malloc(sizeof(GFMethod));
+        if (meth == NULL)
+                return NULL;
+#endif
+        meth->constructed = MP_YES;
+        MP_DIGITS(&meth->irr) = 0;
+        meth->extra_free = NULL;
+        MP_CHECKOK(mp_init(&meth->irr, kmflag));
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                GFMethod_free(meth);
+                return NULL;
+        }
+        return meth;
+}
+
+/* Construct a generic GFMethod for arithmetic over prime fields with
+ * irreducible irr. */
+GFMethod *
+GFMethod_consGFp(const mp_int *irr)
+{
+        mp_err res = MP_OKAY;
+        GFMethod *meth = NULL;
+
+        meth = GFMethod_new(FLAG(irr));
+        if (meth == NULL)
+                return NULL;
+
+        MP_CHECKOK(mp_copy(irr, &meth->irr));
+        meth->irr_arr[0] = mpl_significant_bits(irr);
+        meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] =
+                meth->irr_arr[4] = 0;
+        switch(MP_USED(&meth->irr)) {
+        /* maybe we need 1 and 2 words here as well?*/
+        case 3:
+                meth->field_add = &ec_GFp_add_3;
+                meth->field_sub = &ec_GFp_sub_3;
+                break;
+        case 4:
+                meth->field_add = &ec_GFp_add_4;
+                meth->field_sub = &ec_GFp_sub_4;
+                break;
+        case 5:
+                meth->field_add = &ec_GFp_add_5;
+                meth->field_sub = &ec_GFp_sub_5;
+                break;
+        case 6:
+                meth->field_add = &ec_GFp_add_6;
+                meth->field_sub = &ec_GFp_sub_6;
+                break;
+        default:
+                meth->field_add = &ec_GFp_add;
+                meth->field_sub = &ec_GFp_sub;
+        }
+        meth->field_neg = &ec_GFp_neg;
+        meth->field_mod = &ec_GFp_mod;
+        meth->field_mul = &ec_GFp_mul;
+        meth->field_sqr = &ec_GFp_sqr;
+        meth->field_div = &ec_GFp_div;
+        meth->field_enc = NULL;
+        meth->field_dec = NULL;
+        meth->extra1 = NULL;
+        meth->extra2 = NULL;
+        meth->extra_free = NULL;
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                GFMethod_free(meth);
+                return NULL;
+        }
+        return meth;
+}
+
+/* Construct a generic GFMethod for arithmetic over binary polynomial
+ * fields with irreducible irr that has array representation irr_arr (see
+ * ecl-priv.h for description of the representation).  If irr_arr is NULL,
+ * then it is constructed from the bitstring representation. */
+GFMethod *
+GFMethod_consGF2m(const mp_int *irr, const unsigned int irr_arr[5])
+{
+        mp_err res = MP_OKAY;
+        int ret;
+        GFMethod *meth = NULL;
+
+        meth = GFMethod_new(FLAG(irr));
+        if (meth == NULL)
+                return NULL;
+
+        MP_CHECKOK(mp_copy(irr, &meth->irr));
+        if (irr_arr != NULL) {
+                /* Irreducible polynomials are either trinomials or pentanomials. */
+                meth->irr_arr[0] = irr_arr[0];
+                meth->irr_arr[1] = irr_arr[1];
+                meth->irr_arr[2] = irr_arr[2];
+                if (irr_arr[2] > 0) {
+                        meth->irr_arr[3] = irr_arr[3];
+                        meth->irr_arr[4] = irr_arr[4];
+                } else {
+                        meth->irr_arr[3] = meth->irr_arr[4] = 0;
+                }
+        } else {
+                ret = mp_bpoly2arr(irr, meth->irr_arr, 5);
+                /* Irreducible polynomials are either trinomials or pentanomials. */
+                if ((ret != 5) && (ret != 3)) {
+                        res = MP_UNDEF;
+                        goto CLEANUP;
+                }
+        }
+        meth->field_add = &ec_GF2m_add;
+        meth->field_neg = &ec_GF2m_neg;
+        meth->field_sub = &ec_GF2m_add;
+        meth->field_mod = &ec_GF2m_mod;
+        meth->field_mul = &ec_GF2m_mul;
+        meth->field_sqr = &ec_GF2m_sqr;
+        meth->field_div = &ec_GF2m_div;
+        meth->field_enc = NULL;
+        meth->field_dec = NULL;
+        meth->extra1 = NULL;
+        meth->extra2 = NULL;
+        meth->extra_free = NULL;
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                GFMethod_free(meth);
+                return NULL;
+        }
+        return meth;
+}
+
+/* Free the memory allocated (if any) to a GFMethod object. */
+void
+GFMethod_free(GFMethod *meth)
+{
+        if (meth == NULL)
+                return;
+        if (meth->constructed == MP_NO)
+                return;
+        mp_clear(&meth->irr);
+        if (meth->extra_free != NULL)
+                meth->extra_free(meth);
+#ifdef _KERNEL
+        kmem_free(meth, sizeof(GFMethod));
+#else
+        free(meth);
+#endif
+}
+
+/* Wrapper functions for generic prime field arithmetic. */
+
+/* Add two field elements.  Assumes that 0 <= a, b < meth->irr */
+mp_err
+ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
+                   const GFMethod *meth)
+{
+        /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a + b (mod p) */
+        mp_err res;
+
+        if ((res = mp_add(a, b, r)) != MP_OKAY) {
+                return res;
+        }
+        if (mp_cmp(r, &meth->irr) >= 0) {
+                return mp_sub(r, &meth->irr, r);
+        }
+        return res;
+}
+
+/* Negates a field element.  Assumes that 0 <= a < meth->irr */
+mp_err
+ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        /* PRE: 0 <= a < p = meth->irr POST: 0 <= r < p, r = -a (mod p) */
+
+        if (mp_cmp_z(a) == 0) {
+                mp_zero(r);
+                return MP_OKAY;
+        }
+        return mp_sub(&meth->irr, a, r);
+}
+
+/* Subtracts two field elements.  Assumes that 0 <= a, b < meth->irr */
+mp_err
+ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
+                   const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a - b (mod p) */
+        res = mp_sub(a, b, r);
+        if (res == MP_RANGE) {
+                MP_CHECKOK(mp_sub(b, a, r));
+                if (mp_cmp_z(r) < 0) {
+                        MP_CHECKOK(mp_add(r, &meth->irr, r));
+                }
+                MP_CHECKOK(ec_GFp_neg(r, r, meth));
+        }
+        if (mp_cmp_z(r) < 0) {
+                MP_CHECKOK(mp_add(r, &meth->irr, r));
+        }
+  CLEANUP:
+        return res;
+}
+/*
+ * Inline adds for small curve lengths.
+ */
+/* 3 words */
+mp_err
+ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a0 = 0, a1 = 0, a2 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0;
+        mp_digit carry;
+
+        switch(MP_USED(a)) {
+        case 3:
+                a2 = MP_DIGIT(a,2);
+        case 2:
+                a1 = MP_DIGIT(a,1);
+        case 1:
+                a0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 3:
+                r2 = MP_DIGIT(b,2);
+        case 2:
+                r1 = MP_DIGIT(b,1);
+        case 1:
+                r0 = MP_DIGIT(b,0);
+        }
+
+#ifndef MPI_AMD64_ADD
+        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
+        MP_ADD_CARRY(a1, r1, r1, carry, carry);
+        MP_ADD_CARRY(a2, r2, r2, carry, carry);
+#else
+        __asm__ (
+                "xorq   %3,%3           \n\t"
+                "addq   %4,%0           \n\t"
+                "adcq   %5,%1           \n\t"
+                "adcq   %6,%2           \n\t"
+                "adcq   $0,%3           \n\t"
+                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
+                : "r" (a0), "r" (a1), "r" (a2),
+                  "0" (r0), "1" (r1), "2" (r2)
+                : "%cc" );
+#endif
+
+        MP_CHECKOK(s_mp_pad(r, 3));
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 3;
+
+        /* Do quick 'subract' if we've gone over
+         * (add the 2's complement of the curve field) */
+         a2 = MP_DIGIT(&meth->irr,2);
+        if (carry ||  r2 >  a2 ||
+                ((r2 == a2) && mp_cmp(r,&meth->irr) != MP_LT)) {
+                a1 = MP_DIGIT(&meth->irr,1);
+                a0 = MP_DIGIT(&meth->irr,0);
+#ifndef MPI_AMD64_ADD
+                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a1, r1, carry, carry);
+                MP_SUB_BORROW(r2, a2, r2, carry, carry);
+#else
+                __asm__ (
+                        "subq   %3,%0           \n\t"
+                        "sbbq   %4,%1           \n\t"
+                        "sbbq   %5,%2           \n\t"
+                        : "=r"(r0), "=r"(r1), "=r"(r2)
+                        : "r" (a0), "r" (a1), "r" (a2),
+                          "0" (r0), "1" (r1), "2" (r2)
+                        : "%cc" );
+#endif
+                MP_DIGIT(r, 2) = r2;
+                MP_DIGIT(r, 1) = r1;
+                MP_DIGIT(r, 0) = r0;
+        }
+
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* 4 words */
+mp_err
+ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
+        mp_digit carry;
+
+        switch(MP_USED(a)) {
+        case 4:
+                a3 = MP_DIGIT(a,3);
+        case 3:
+                a2 = MP_DIGIT(a,2);
+        case 2:
+                a1 = MP_DIGIT(a,1);
+        case 1:
+                a0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 4:
+                r3 = MP_DIGIT(b,3);
+        case 3:
+                r2 = MP_DIGIT(b,2);
+        case 2:
+                r1 = MP_DIGIT(b,1);
+        case 1:
+                r0 = MP_DIGIT(b,0);
+        }
+
+#ifndef MPI_AMD64_ADD
+        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
+        MP_ADD_CARRY(a1, r1, r1, carry, carry);
+        MP_ADD_CARRY(a2, r2, r2, carry, carry);
+        MP_ADD_CARRY(a3, r3, r3, carry, carry);
+#else
+        __asm__ (
+                "xorq   %4,%4           \n\t"
+                "addq   %5,%0           \n\t"
+                "adcq   %6,%1           \n\t"
+                "adcq   %7,%2           \n\t"
+                "adcq   %8,%3           \n\t"
+                "adcq   $0,%4           \n\t"
+                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(carry)
+                : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
+                  "0" (r0), "1" (r1), "2" (r2), "3" (r3)
+                : "%cc" );
+#endif
+
+        MP_CHECKOK(s_mp_pad(r, 4));
+        MP_DIGIT(r, 3) = r3;
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 4;
+
+        /* Do quick 'subract' if we've gone over
+         * (add the 2's complement of the curve field) */
+         a3 = MP_DIGIT(&meth->irr,3);
+        if (carry ||  r3 >  a3 ||
+                ((r3 == a3) && mp_cmp(r,&meth->irr) != MP_LT)) {
+                a2 = MP_DIGIT(&meth->irr,2);
+                a1 = MP_DIGIT(&meth->irr,1);
+                a0 = MP_DIGIT(&meth->irr,0);
+#ifndef MPI_AMD64_ADD
+                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a1, r1, carry, carry);
+                MP_SUB_BORROW(r2, a2, r2, carry, carry);
+                MP_SUB_BORROW(r3, a3, r3, carry, carry);
+#else
+                __asm__ (
+                        "subq   %4,%0           \n\t"
+                        "sbbq   %5,%1           \n\t"
+                        "sbbq   %6,%2           \n\t"
+                        "sbbq   %7,%3           \n\t"
+                        : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
+                        : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
+                          "0" (r0), "1" (r1), "2" (r2), "3" (r3)
+                        : "%cc" );
+#endif
+                MP_DIGIT(r, 3) = r3;
+                MP_DIGIT(r, 2) = r2;
+                MP_DIGIT(r, 1) = r1;
+                MP_DIGIT(r, 0) = r0;
+        }
+
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* 5 words */
+mp_err
+ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
+        mp_digit carry;
+
+        switch(MP_USED(a)) {
+        case 5:
+                a4 = MP_DIGIT(a,4);
+        case 4:
+                a3 = MP_DIGIT(a,3);
+        case 3:
+                a2 = MP_DIGIT(a,2);
+        case 2:
+                a1 = MP_DIGIT(a,1);
+        case 1:
+                a0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 5:
+                r4 = MP_DIGIT(b,4);
+        case 4:
+                r3 = MP_DIGIT(b,3);
+        case 3:
+                r2 = MP_DIGIT(b,2);
+        case 2:
+                r1 = MP_DIGIT(b,1);
+        case 1:
+                r0 = MP_DIGIT(b,0);
+        }
+
+        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
+        MP_ADD_CARRY(a1, r1, r1, carry, carry);
+        MP_ADD_CARRY(a2, r2, r2, carry, carry);
+        MP_ADD_CARRY(a3, r3, r3, carry, carry);
+        MP_ADD_CARRY(a4, r4, r4, carry, carry);
+
+        MP_CHECKOK(s_mp_pad(r, 5));
+        MP_DIGIT(r, 4) = r4;
+        MP_DIGIT(r, 3) = r3;
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 5;
+
+        /* Do quick 'subract' if we've gone over
+         * (add the 2's complement of the curve field) */
+         a4 = MP_DIGIT(&meth->irr,4);
+        if (carry ||  r4 >  a4 ||
+                ((r4 == a4) && mp_cmp(r,&meth->irr) != MP_LT)) {
+                a3 = MP_DIGIT(&meth->irr,3);
+                a2 = MP_DIGIT(&meth->irr,2);
+                a1 = MP_DIGIT(&meth->irr,1);
+                a0 = MP_DIGIT(&meth->irr,0);
+                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a1, r1, carry, carry);
+                MP_SUB_BORROW(r2, a2, r2, carry, carry);
+                MP_SUB_BORROW(r3, a3, r3, carry, carry);
+                MP_SUB_BORROW(r4, a4, r4, carry, carry);
+                MP_DIGIT(r, 4) = r4;
+                MP_DIGIT(r, 3) = r3;
+                MP_DIGIT(r, 2) = r2;
+                MP_DIGIT(r, 1) = r1;
+                MP_DIGIT(r, 0) = r0;
+        }
+
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* 6 words */
+mp_err
+ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
+        mp_digit carry;
+
+        switch(MP_USED(a)) {
+        case 6:
+                a5 = MP_DIGIT(a,5);
+        case 5:
+                a4 = MP_DIGIT(a,4);
+        case 4:
+                a3 = MP_DIGIT(a,3);
+        case 3:
+                a2 = MP_DIGIT(a,2);
+        case 2:
+                a1 = MP_DIGIT(a,1);
+        case 1:
+                a0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 6:
+                r5 = MP_DIGIT(b,5);
+        case 5:
+                r4 = MP_DIGIT(b,4);
+        case 4:
+                r3 = MP_DIGIT(b,3);
+        case 3:
+                r2 = MP_DIGIT(b,2);
+        case 2:
+                r1 = MP_DIGIT(b,1);
+        case 1:
+                r0 = MP_DIGIT(b,0);
+        }
+
+        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
+        MP_ADD_CARRY(a1, r1, r1, carry, carry);
+        MP_ADD_CARRY(a2, r2, r2, carry, carry);
+        MP_ADD_CARRY(a3, r3, r3, carry, carry);
+        MP_ADD_CARRY(a4, r4, r4, carry, carry);
+        MP_ADD_CARRY(a5, r5, r5, carry, carry);
+
+        MP_CHECKOK(s_mp_pad(r, 6));
+        MP_DIGIT(r, 5) = r5;
+        MP_DIGIT(r, 4) = r4;
+        MP_DIGIT(r, 3) = r3;
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 6;
+
+        /* Do quick 'subract' if we've gone over
+         * (add the 2's complement of the curve field) */
+        a5 = MP_DIGIT(&meth->irr,5);
+        if (carry ||  r5 >  a5 ||
+                ((r5 == a5) && mp_cmp(r,&meth->irr) != MP_LT)) {
+                a4 = MP_DIGIT(&meth->irr,4);
+                a3 = MP_DIGIT(&meth->irr,3);
+                a2 = MP_DIGIT(&meth->irr,2);
+                a1 = MP_DIGIT(&meth->irr,1);
+                a0 = MP_DIGIT(&meth->irr,0);
+                MP_SUB_BORROW(r0, a0, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a1, r1, carry, carry);
+                MP_SUB_BORROW(r2, a2, r2, carry, carry);
+                MP_SUB_BORROW(r3, a3, r3, carry, carry);
+                MP_SUB_BORROW(r4, a4, r4, carry, carry);
+                MP_SUB_BORROW(r5, a5, r5, carry, carry);
+                MP_DIGIT(r, 5) = r5;
+                MP_DIGIT(r, 4) = r4;
+                MP_DIGIT(r, 3) = r3;
+                MP_DIGIT(r, 2) = r2;
+                MP_DIGIT(r, 1) = r1;
+                MP_DIGIT(r, 0) = r0;
+        }
+
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/*
+ * The following subraction functions do in-line subractions based
+ * on our curve size.
+ *
+ * ... 3 words
+ */
+mp_err
+ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit b0 = 0, b1 = 0, b2 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0;
+        mp_digit borrow;
+
+        switch(MP_USED(a)) {
+        case 3:
+                r2 = MP_DIGIT(a,2);
+        case 2:
+                r1 = MP_DIGIT(a,1);
+        case 1:
+                r0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 3:
+                b2 = MP_DIGIT(b,2);
+        case 2:
+                b1 = MP_DIGIT(b,1);
+        case 1:
+                b0 = MP_DIGIT(b,0);
+        }
+
+#ifndef MPI_AMD64_ADD
+        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
+        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
+        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
+#else
+        __asm__ (
+                "xorq   %3,%3           \n\t"
+                "subq   %4,%0           \n\t"
+                "sbbq   %5,%1           \n\t"
+                "sbbq   %6,%2           \n\t"
+                "adcq   $0,%3           \n\t"
+                : "=r"(r0), "=r"(r1), "=r"(r2), "=r" (borrow)
+                : "r" (b0), "r" (b1), "r" (b2),
+                  "0" (r0), "1" (r1), "2" (r2)
+                : "%cc" );
+#endif
+
+        /* Do quick 'add' if we've gone under 0
+         * (subtract the 2's complement of the curve field) */
+        if (borrow) {
+                b2 = MP_DIGIT(&meth->irr,2);
+                b1 = MP_DIGIT(&meth->irr,1);
+                b0 = MP_DIGIT(&meth->irr,0);
+#ifndef MPI_AMD64_ADD
+                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
+                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
+                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
+#else
+                __asm__ (
+                        "addq   %3,%0           \n\t"
+                        "adcq   %4,%1           \n\t"
+                        "adcq   %5,%2           \n\t"
+                        : "=r"(r0), "=r"(r1), "=r"(r2)
+                        : "r" (b0), "r" (b1), "r" (b2),
+                          "0" (r0), "1" (r1), "2" (r2)
+                        : "%cc" );
+#endif
+        }
+
+#ifdef MPI_AMD64_ADD
+        /* compiler fakeout? */
+        if ((r2 == b0) && (r1 == b0) && (r0 == b0)) {
+                MP_CHECKOK(s_mp_pad(r, 4));
+        }
+#endif
+        MP_CHECKOK(s_mp_pad(r, 3));
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 3;
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* 4 words */
+mp_err
+ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
+        mp_digit borrow;
+
+        switch(MP_USED(a)) {
+        case 4:
+                r3 = MP_DIGIT(a,3);
+        case 3:
+                r2 = MP_DIGIT(a,2);
+        case 2:
+                r1 = MP_DIGIT(a,1);
+        case 1:
+                r0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 4:
+                b3 = MP_DIGIT(b,3);
+        case 3:
+                b2 = MP_DIGIT(b,2);
+        case 2:
+                b1 = MP_DIGIT(b,1);
+        case 1:
+                b0 = MP_DIGIT(b,0);
+        }
+
+#ifndef MPI_AMD64_ADD
+        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
+        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
+        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
+        MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
+#else
+        __asm__ (
+                "xorq   %4,%4           \n\t"
+                "subq   %5,%0           \n\t"
+                "sbbq   %6,%1           \n\t"
+                "sbbq   %7,%2           \n\t"
+                "sbbq   %8,%3           \n\t"
+                "adcq   $0,%4           \n\t"
+                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r" (borrow)
+                : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
+                  "0" (r0), "1" (r1), "2" (r2), "3" (r3)
+                : "%cc" );
+#endif
+
+        /* Do quick 'add' if we've gone under 0
+         * (subtract the 2's complement of the curve field) */
+        if (borrow) {
+                b3 = MP_DIGIT(&meth->irr,3);
+                b2 = MP_DIGIT(&meth->irr,2);
+                b1 = MP_DIGIT(&meth->irr,1);
+                b0 = MP_DIGIT(&meth->irr,0);
+#ifndef MPI_AMD64_ADD
+                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
+                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
+                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
+                MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
+#else
+                __asm__ (
+                        "addq   %4,%0           \n\t"
+                        "adcq   %5,%1           \n\t"
+                        "adcq   %6,%2           \n\t"
+                        "adcq   %7,%3           \n\t"
+                        : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
+                        : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
+                          "0" (r0), "1" (r1), "2" (r2), "3" (r3)
+                        : "%cc" );
+#endif
+        }
+#ifdef MPI_AMD64_ADD
+        /* compiler fakeout? */
+        if ((r3 == b0) && (r1 == b0) && (r0 == b0)) {
+                MP_CHECKOK(s_mp_pad(r, 4));
+        }
+#endif
+        MP_CHECKOK(s_mp_pad(r, 4));
+        MP_DIGIT(r, 3) = r3;
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 4;
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* 5 words */
+mp_err
+ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
+        mp_digit borrow;
+
+        switch(MP_USED(a)) {
+        case 5:
+                r4 = MP_DIGIT(a,4);
+        case 4:
+                r3 = MP_DIGIT(a,3);
+        case 3:
+                r2 = MP_DIGIT(a,2);
+        case 2:
+                r1 = MP_DIGIT(a,1);
+        case 1:
+                r0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 5:
+                b4 = MP_DIGIT(b,4);
+        case 4:
+                b3 = MP_DIGIT(b,3);
+        case 3:
+                b2 = MP_DIGIT(b,2);
+        case 2:
+                b1 = MP_DIGIT(b,1);
+        case 1:
+                b0 = MP_DIGIT(b,0);
+        }
+
+        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
+        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
+        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
+        MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
+        MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
+
+        /* Do quick 'add' if we've gone under 0
+         * (subtract the 2's complement of the curve field) */
+        if (borrow) {
+                b4 = MP_DIGIT(&meth->irr,4);
+                b3 = MP_DIGIT(&meth->irr,3);
+                b2 = MP_DIGIT(&meth->irr,2);
+                b1 = MP_DIGIT(&meth->irr,1);
+                b0 = MP_DIGIT(&meth->irr,0);
+                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
+                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
+                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
+                MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
+        }
+        MP_CHECKOK(s_mp_pad(r, 5));
+        MP_DIGIT(r, 4) = r4;
+        MP_DIGIT(r, 3) = r3;
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 5;
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+/* 6 words */
+mp_err
+ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
+        mp_digit borrow;
+
+        switch(MP_USED(a)) {
+        case 6:
+                r5 = MP_DIGIT(a,5);
+        case 5:
+                r4 = MP_DIGIT(a,4);
+        case 4:
+                r3 = MP_DIGIT(a,3);
+        case 3:
+                r2 = MP_DIGIT(a,2);
+        case 2:
+                r1 = MP_DIGIT(a,1);
+        case 1:
+                r0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 6:
+                b5 = MP_DIGIT(b,5);
+        case 5:
+                b4 = MP_DIGIT(b,4);
+        case 4:
+                b3 = MP_DIGIT(b,3);
+        case 3:
+                b2 = MP_DIGIT(b,2);
+        case 2:
+                b1 = MP_DIGIT(b,1);
+        case 1:
+                b0 = MP_DIGIT(b,0);
+        }
+
+        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
+        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
+        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
+        MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
+        MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
+        MP_SUB_BORROW(r5, b5, r5, borrow, borrow);
+
+        /* Do quick 'add' if we've gone under 0
+         * (subtract the 2's complement of the curve field) */
+        if (borrow) {
+                b5 = MP_DIGIT(&meth->irr,5);
+                b4 = MP_DIGIT(&meth->irr,4);
+                b3 = MP_DIGIT(&meth->irr,3);
+                b2 = MP_DIGIT(&meth->irr,2);
+                b1 = MP_DIGIT(&meth->irr,1);
+                b0 = MP_DIGIT(&meth->irr,0);
+                MP_ADD_CARRY(b0, r0, r0, 0,      borrow);
+                MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
+                MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
+                MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
+                MP_ADD_CARRY(b4, r4, r4, borrow, borrow);
+        }
+
+        MP_CHECKOK(s_mp_pad(r, 6));
+        MP_DIGIT(r, 5) = r5;
+        MP_DIGIT(r, 4) = r4;
+        MP_DIGIT(r, 3) = r3;
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 6;
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+
+/* Reduces an integer to a field element. */
+mp_err
+ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        return mp_mod(a, &meth->irr, r);
+}
+
+/* Multiplies two field elements. */
+mp_err
+ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                   const GFMethod *meth)
+{
+        return mp_mulmod(a, b, &meth->irr, r);
+}
+
+/* Squares a field element. */
+mp_err
+ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        return mp_sqrmod(a, &meth->irr, r);
+}
+
+/* Divides two field elements. If a is NULL, then returns the inverse of
+ * b. */
+mp_err
+ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
+                   const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_int t;
+
+        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
+        if (a == NULL) {
+                return mp_invmod(b, &meth->irr, r);
+        } else {
+                /* MPI doesn't support divmod, so we implement it using invmod and
+                 * mulmod. */
+                MP_CHECKOK(mp_init(&t, FLAG(b)));
+                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
+                MP_CHECKOK(mp_mulmod(a, &t, &meth->irr, r));
+          CLEANUP:
+                mp_clear(&t);
+                return res;
+        }
+}
+
+/* Wrapper functions for generic binary polynomial field arithmetic. */
+
+/* Adds two field elements. */
+mp_err
+ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        return mp_badd(a, b, r);
+}
+
+/* Negates a field element. Note that for binary polynomial fields, the
+ * negation of a field element is the field element itself. */
+mp_err
+ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        if (a == r) {
+                return MP_OKAY;
+        } else {
+                return mp_copy(a, r);
+        }
+}
+
+/* Reduces a binary polynomial to a field element. */
+mp_err
+ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        return mp_bmod(a, meth->irr_arr, r);
+}
+
+/* Multiplies two field elements. */
+mp_err
+ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        return mp_bmulmod(a, b, meth->irr_arr, r);
+}
+
+/* Squares a field element. */
+mp_err
+ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        return mp_bsqrmod(a, meth->irr_arr, r);
+}
+
+/* Divides two field elements. If a is NULL, then returns the inverse of
+ * b. */
+mp_err
+ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_int t;
+
+        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
+        if (a == NULL) {
+                /* The GF(2^m) portion of MPI doesn't support invmod, so we
+                 * compute 1/b. */
+                MP_CHECKOK(mp_init(&t, FLAG(b)));
+                MP_CHECKOK(mp_set_int(&t, 1));
+                MP_CHECKOK(mp_bdivmod(&t, b, &meth->irr, meth->irr_arr, r));
+          CLEANUP:
+                mp_clear(&t);
+                return res;
+        } else {
+                return mp_bdivmod(a, b, &meth->irr, meth->irr_arr, r);
+        }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecl_mult.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,378 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mpi.h"
+#include "mplogic.h"
+#include "ecl.h"
+#include "ecl-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x,
+ * y).  If x, y = NULL, then P is assumed to be the generator (base point)
+ * of the group of points on the elliptic curve. Input and output values
+ * are assumed to be NOT field-encoded. */
+mp_err
+ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
+                        const mp_int *py, mp_int *rx, mp_int *ry)
+{
+        mp_err res = MP_OKAY;
+        mp_int kt;
+
+        ARGCHK((k != NULL) && (group != NULL), MP_BADARG);
+        MP_DIGITS(&kt) = 0;
+
+        /* want scalar to be less than or equal to group order */
+        if (mp_cmp(k, &group->order) > 0) {
+                MP_CHECKOK(mp_init(&kt, FLAG(k)));
+                MP_CHECKOK(mp_mod(k, &group->order, &kt));
+        } else {
+                MP_SIGN(&kt) = MP_ZPOS;
+                MP_USED(&kt) = MP_USED(k);
+                MP_ALLOC(&kt) = MP_ALLOC(k);
+                MP_DIGITS(&kt) = MP_DIGITS(k);
+        }
+
+        if ((px == NULL) || (py == NULL)) {
+                if (group->base_point_mul) {
+                        MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group));
+                } else {
+                        MP_CHECKOK(group->
+                                           point_mul(&kt, &group->genx, &group->geny, rx, ry,
+                                                                 group));
+                }
+        } else {
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
+                        MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
+                        MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
+                } else {
+                        MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
+                }
+        }
+        if (group->meth->field_dec) {
+                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+        }
+
+  CLEANUP:
+        if (MP_DIGITS(&kt) != MP_DIGITS(k)) {
+                mp_clear(&kt);
+        }
+        return res;
+}
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Input and output values are assumed to be NOT field-encoded. */
+mp_err
+ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
+                                 const mp_int *py, mp_int *rx, mp_int *ry,
+                                 const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int sx, sy;
+
+        ARGCHK(group != NULL, MP_BADARG);
+        ARGCHK(!((k1 == NULL)
+                         && ((k2 == NULL) || (px == NULL)
+                                 || (py == NULL))), MP_BADARG);
+
+        /* if some arguments are not defined used ECPoint_mul */
+        if (k1 == NULL) {
+                return ECPoint_mul(group, k2, px, py, rx, ry);
+        } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
+                return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
+        }
+
+        MP_DIGITS(&sx) = 0;
+        MP_DIGITS(&sy) = 0;
+        MP_CHECKOK(mp_init(&sx, FLAG(k1)));
+        MP_CHECKOK(mp_init(&sy, FLAG(k1)));
+
+        MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy));
+        MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry));
+
+        if (group->meth->field_enc) {
+                MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth));
+                MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth));
+                MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth));
+                MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth));
+        }
+
+        MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group));
+
+        if (group->meth->field_dec) {
+                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+        }
+
+  CLEANUP:
+        mp_clear(&sx);
+        mp_clear(&sy);
+        return res;
+}
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Input and output values are assumed to be NOT field-encoded. Uses
+ * algorithm 15 (simultaneous multiple point multiplication) from Brown,
+ * Hankerson, Lopez, Menezes. Software Implementation of the NIST
+ * Elliptic Curves over Prime Fields. */
+mp_err
+ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
+                                        const mp_int *py, mp_int *rx, mp_int *ry,
+                                        const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int precomp[4][4][2];
+        const mp_int *a, *b;
+        int i, j;
+        int ai, bi, d;
+
+        ARGCHK(group != NULL, MP_BADARG);
+        ARGCHK(!((k1 == NULL)
+                         && ((k2 == NULL) || (px == NULL)
+                                 || (py == NULL))), MP_BADARG);
+
+        /* if some arguments are not defined used ECPoint_mul */
+        if (k1 == NULL) {
+                return ECPoint_mul(group, k2, px, py, rx, ry);
+        } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
+                return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
+        }
+
+        /* initialize precomputation table */
+        for (i = 0; i < 4; i++) {
+                for (j = 0; j < 4; j++) {
+                        MP_DIGITS(&precomp[i][j][0]) = 0;
+                        MP_DIGITS(&precomp[i][j][1]) = 0;
+                }
+        }
+        for (i = 0; i < 4; i++) {
+                for (j = 0; j < 4; j++) {
+                         MP_CHECKOK( mp_init_size(&precomp[i][j][0],
+                                         ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) );
+                         MP_CHECKOK( mp_init_size(&precomp[i][j][1],
+                                         ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) );
+                }
+        }
+
+        /* fill precomputation table */
+        /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
+        if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
+                a = k2;
+                b = k1;
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->
+                                           field_enc(px, &precomp[1][0][0], group->meth));
+                        MP_CHECKOK(group->meth->
+                                           field_enc(py, &precomp[1][0][1], group->meth));
+                } else {
+                        MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
+                        MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
+                }
+                MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
+                MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
+        } else {
+                a = k1;
+                b = k2;
+                MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
+                MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->
+                                           field_enc(px, &precomp[0][1][0], group->meth));
+                        MP_CHECKOK(group->meth->
+                                           field_enc(py, &precomp[0][1][1], group->meth));
+                } else {
+                        MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
+                        MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
+                }
+        }
+        /* precompute [*][0][*] */
+        mp_zero(&precomp[0][0][0]);
+        mp_zero(&precomp[0][0][1]);
+        MP_CHECKOK(group->
+                           point_dbl(&precomp[1][0][0], &precomp[1][0][1],
+                                                 &precomp[2][0][0], &precomp[2][0][1], group));
+        MP_CHECKOK(group->
+                           point_add(&precomp[1][0][0], &precomp[1][0][1],
+                                                 &precomp[2][0][0], &precomp[2][0][1],
+                                                 &precomp[3][0][0], &precomp[3][0][1], group));
+        /* precompute [*][1][*] */
+        for (i = 1; i < 4; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[0][1][0], &precomp[0][1][1],
+                                                         &precomp[i][0][0], &precomp[i][0][1],
+                                                         &precomp[i][1][0], &precomp[i][1][1], group));
+        }
+        /* precompute [*][2][*] */
+        MP_CHECKOK(group->
+                           point_dbl(&precomp[0][1][0], &precomp[0][1][1],
+                                                 &precomp[0][2][0], &precomp[0][2][1], group));
+        for (i = 1; i < 4; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[0][2][0], &precomp[0][2][1],
+                                                         &precomp[i][0][0], &precomp[i][0][1],
+                                                         &precomp[i][2][0], &precomp[i][2][1], group));
+        }
+        /* precompute [*][3][*] */
+        MP_CHECKOK(group->
+                           point_add(&precomp[0][1][0], &precomp[0][1][1],
+                                                 &precomp[0][2][0], &precomp[0][2][1],
+                                                 &precomp[0][3][0], &precomp[0][3][1], group));
+        for (i = 1; i < 4; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[0][3][0], &precomp[0][3][1],
+                                                         &precomp[i][0][0], &precomp[i][0][1],
+                                                         &precomp[i][3][0], &precomp[i][3][1], group));
+        }
+
+        d = (mpl_significant_bits(a) + 1) / 2;
+
+        /* R = inf */
+        mp_zero(rx);
+        mp_zero(ry);
+
+        for (i = d - 1; i >= 0; i--) {
+                ai = MP_GET_BIT(a, 2 * i + 1);
+                ai <<= 1;
+                ai |= MP_GET_BIT(a, 2 * i);
+                bi = MP_GET_BIT(b, 2 * i + 1);
+                bi <<= 1;
+                bi |= MP_GET_BIT(b, 2 * i);
+                /* R = 2^2 * R */
+                MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
+                MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
+                /* R = R + (ai * A + bi * B) */
+                MP_CHECKOK(group->
+                                   point_add(rx, ry, &precomp[ai][bi][0],
+                                                         &precomp[ai][bi][1], rx, ry, group));
+        }
+
+        if (group->meth->field_dec) {
+                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+        }
+
+  CLEANUP:
+        for (i = 0; i < 4; i++) {
+                for (j = 0; j < 4; j++) {
+                        mp_clear(&precomp[i][j][0]);
+                        mp_clear(&precomp[i][j][1]);
+                }
+        }
+        return res;
+}
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Input and output values are assumed to be NOT field-encoded. */
+mp_err
+ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
+                         const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry)
+{
+        mp_err res = MP_OKAY;
+        mp_int k1t, k2t;
+        const mp_int *k1p, *k2p;
+
+        MP_DIGITS(&k1t) = 0;
+        MP_DIGITS(&k2t) = 0;
+
+        ARGCHK(group != NULL, MP_BADARG);
+
+        /* want scalar to be less than or equal to group order */
+        if (k1 != NULL) {
+                if (mp_cmp(k1, &group->order) >= 0) {
+                        MP_CHECKOK(mp_init(&k1t, FLAG(k1)));
+                        MP_CHECKOK(mp_mod(k1, &group->order, &k1t));
+                        k1p = &k1t;
+                } else {
+                        k1p = k1;
+                }
+        } else {
+                k1p = k1;
+        }
+        if (k2 != NULL) {
+                if (mp_cmp(k2, &group->order) >= 0) {
+                        MP_CHECKOK(mp_init(&k2t, FLAG(k2)));
+                        MP_CHECKOK(mp_mod(k2, &group->order, &k2t));
+                        k2p = &k2t;
+                } else {
+                        k2p = k2;
+                }
+        } else {
+                k2p = k2;
+        }
+
+        /* if points_mul is defined, then use it */
+        if (group->points_mul) {
+                res = group->points_mul(k1p, k2p, px, py, rx, ry, group);
+        } else {
+                res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
+        }
+
+  CLEANUP:
+        mp_clear(&k1t);
+        mp_clear(&k2t);
+        return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,160 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ECP_H
+#define _ECP_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecl-priv.h"
+
+/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
+mp_err ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py);
+
+/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
+mp_err ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py);
+
+/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
+ * qy). Uses affine coordinates. */
+mp_err ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py,
+                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
+                                                 mp_int *ry, const ECGroup *group);
+
+/* Computes R = P - Q.  Uses affine coordinates. */
+mp_err ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py,
+                                                 const mp_int *qx, const mp_int *qy, mp_int *rx,
+                                                 mp_int *ry, const ECGroup *group);
+
+/* Computes R = 2P.  Uses affine coordinates. */
+mp_err ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+                                                 mp_int *ry, const ECGroup *group);
+
+/* Validates a point on a GFp curve. */
+mp_err ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
+
+#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp.  Uses affine coordinates. */
+mp_err ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px,
+                                                 const mp_int *py, mp_int *rx, mp_int *ry,
+                                                 const ECGroup *group);
+#endif
+
+/* Converts a point P(px, py) from affine coordinates to Jacobian
+ * projective coordinates R(rx, ry, rz). */
+mp_err ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
+                                                 mp_int *ry, mp_int *rz, const ECGroup *group);
+
+/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
+ * affine coordinates R(rx, ry). */
+mp_err ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py,
+                                                 const mp_int *pz, mp_int *rx, mp_int *ry,
+                                                 const ECGroup *group);
+
+/* Checks if point P(px, py, pz) is at infinity.  Uses Jacobian
+ * coordinates. */
+mp_err ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py,
+                                                        const mp_int *pz);
+
+/* Sets P(px, py, pz) to be the point at infinity.  Uses Jacobian
+ * coordinates. */
+mp_err ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz);
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, qz).  Uses Jacobian coordinates. */
+mp_err ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py,
+                                                         const mp_int *pz, const mp_int *qx,
+                                                         const mp_int *qy, mp_int *rx, mp_int *ry,
+                                                         mp_int *rz, const ECGroup *group);
+
+/* Computes R = 2P.  Uses Jacobian coordinates. */
+mp_err ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py,
+                                                 const mp_int *pz, mp_int *rx, mp_int *ry,
+                                                 mp_int *rz, const ECGroup *group);
+
+#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp.  Uses Jacobian coordinates. */
+mp_err ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px,
+                                                 const mp_int *py, mp_int *rx, mp_int *ry,
+                                                 const ECGroup *group);
+#endif
+
+/* Computes R(x, y) = k1 * G + k2 * P(x, y), where G is the generator
+ * (base point) of the group of points on the elliptic curve. Allows k1 =
+ * NULL or { k2, P } = NULL.  Implemented using mixed Jacobian-affine
+ * coordinates. Input and output values are assumed to be NOT
+ * field-encoded and are in affine form. */
+mp_err
+ ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
+                                        const mp_int *py, mp_int *rx, mp_int *ry,
+                                        const ECGroup *group);
+
+/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
+ * curve points P and R can be identical. Uses mixed Modified-Jacobian
+ * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
+ * additions. Assumes input is already field-encoded using field_enc, and
+ * returns output that is still field-encoded. Uses 5-bit window NAF
+ * method (algorithm 11) for scalar-point multiplication from Brown,
+ * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
+ * Curves Over Prime Fields. */
+mp_err
+ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
+                                           mp_int *rx, mp_int *ry, const ECGroup *group);
+
+#endif /* _ECP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_192.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,538 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+#define ECP192_DIGITS ECL_CURVE_DIGITS(192)
+
+/* Fast modular reduction for p192 = 2^192 - 2^64 - 1.  a can be r. Uses
+ * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
+ * Implementation of the NIST Elliptic Curves over Prime Fields. */
+mp_err
+ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_size a_used = MP_USED(a);
+        mp_digit r3;
+#ifndef MPI_AMD64_ADD
+        mp_digit carry;
+#endif
+#ifdef ECL_THIRTY_TWO_BIT
+        mp_digit a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
+        mp_digit r0a, r0b, r1a, r1b, r2a, r2b;
+#else
+        mp_digit a5 = 0, a4 = 0, a3 = 0;
+        mp_digit r0, r1, r2;
+#endif
+
+        /* reduction not needed if a is not larger than field size */
+        if (a_used < ECP192_DIGITS) {
+                if (a == r) {
+                        return MP_OKAY;
+                }
+                return mp_copy(a, r);
+        }
+
+        /* for polynomials larger than twice the field size, use regular
+         * reduction */
+        if (a_used > ECP192_DIGITS*2) {
+                MP_CHECKOK(mp_mod(a, &meth->irr, r));
+        } else {
+                /* copy out upper words of a */
+
+#ifdef ECL_THIRTY_TWO_BIT
+
+                /* in all the math below,
+                 * nXb is most signifiant, nXa is least significant */
+                switch (a_used) {
+                case 12:
+                        a5b = MP_DIGIT(a, 11);
+                case 11:
+                        a5a = MP_DIGIT(a, 10);
+                case 10:
+                        a4b = MP_DIGIT(a, 9);
+                case 9:
+                        a4a = MP_DIGIT(a, 8);
+                case 8:
+                        a3b = MP_DIGIT(a, 7);
+                case 7:
+                        a3a = MP_DIGIT(a, 6);
+                }
+
+
+                r2b= MP_DIGIT(a, 5);
+                r2a= MP_DIGIT(a, 4);
+                r1b = MP_DIGIT(a, 3);
+                r1a = MP_DIGIT(a, 2);
+                r0b = MP_DIGIT(a, 1);
+                r0a = MP_DIGIT(a, 0);
+
+                /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
+                MP_ADD_CARRY(r0a, a3a, r0a, 0,    carry);
+                MP_ADD_CARRY(r0b, a3b, r0b, carry, carry);
+                MP_ADD_CARRY(r1a, a3a, r1a, carry, carry);
+                MP_ADD_CARRY(r1b, a3b, r1b, carry, carry);
+                MP_ADD_CARRY(r2a, a4a, r2a, carry, carry);
+                MP_ADD_CARRY(r2b, a4b, r2b, carry, carry);
+                r3 = carry; carry = 0;
+                MP_ADD_CARRY(r0a, a5a, r0a, 0,     carry);
+                MP_ADD_CARRY(r0b, a5b, r0b, carry, carry);
+                MP_ADD_CARRY(r1a, a5a, r1a, carry, carry);
+                MP_ADD_CARRY(r1b, a5b, r1b, carry, carry);
+                MP_ADD_CARRY(r2a, a5a, r2a, carry, carry);
+                MP_ADD_CARRY(r2b, a5b, r2b, carry, carry);
+                r3 += carry;
+                MP_ADD_CARRY(r1a, a4a, r1a, 0,     carry);
+                MP_ADD_CARRY(r1b, a4b, r1b, carry, carry);
+                MP_ADD_CARRY(r2a,   0, r2a, carry, carry);
+                MP_ADD_CARRY(r2b,   0, r2b, carry, carry);
+                r3 += carry;
+
+                /* reduce out the carry */
+                while (r3) {
+                        MP_ADD_CARRY(r0a, r3, r0a, 0,     carry);
+                        MP_ADD_CARRY(r0b,  0, r0b, carry, carry);
+                        MP_ADD_CARRY(r1a, r3, r1a, carry, carry);
+                        MP_ADD_CARRY(r1b,  0, r1b, carry, carry);
+                        MP_ADD_CARRY(r2a,  0, r2a, carry, carry);
+                        MP_ADD_CARRY(r2b,  0, r2b, carry, carry);
+                        r3 = carry;
+                }
+
+                /* check for final reduction */
+                /*
+                 * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
+                 * 0xffffffffffffffff. That means we can only be over and need
+                 * one more reduction
+                 *  if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
+                 *     and
+                 *     r1 == 0xffffffffffffffffff   or
+                 *     r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
+                 * In all cases, we subtract the field (or add the 2's
+                 * complement value (1,1,0)).  (r0, r1, r2)
+                 */
+                if (((r2b == 0xffffffff) && (r2a == 0xffffffff)
+                        && (r1b == 0xffffffff) ) &&
+                           ((r1a == 0xffffffff) ||
+                            (r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
+                                        (r0b == 0xffffffff)) ) {
+                        /* do a quick subtract */
+                        MP_ADD_CARRY(r0a, 1, r0a, 0, carry);
+                        r0b += carry;
+                        r1a = r1b = r2a = r2b = 0;
+                }
+
+                /* set the lower words of r */
+                if (a != r) {
+                        MP_CHECKOK(s_mp_pad(r, 6));
+                }
+                MP_DIGIT(r, 5) = r2b;
+                MP_DIGIT(r, 4) = r2a;
+                MP_DIGIT(r, 3) = r1b;
+                MP_DIGIT(r, 2) = r1a;
+                MP_DIGIT(r, 1) = r0b;
+                MP_DIGIT(r, 0) = r0a;
+                MP_USED(r) = 6;
+#else
+                switch (a_used) {
+                case 6:
+                        a5 = MP_DIGIT(a, 5);
+                case 5:
+                        a4 = MP_DIGIT(a, 4);
+                case 4:
+                        a3 = MP_DIGIT(a, 3);
+                }
+
+                r2 = MP_DIGIT(a, 2);
+                r1 = MP_DIGIT(a, 1);
+                r0 = MP_DIGIT(a, 0);
+
+                /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
+#ifndef MPI_AMD64_ADD
+                MP_ADD_CARRY(r0, a3, r0, 0,     carry);
+                MP_ADD_CARRY(r1, a3, r1, carry, carry);
+                MP_ADD_CARRY(r2, a4, r2, carry, carry);
+                r3 = carry;
+                MP_ADD_CARRY(r0, a5, r0, 0,     carry);
+                MP_ADD_CARRY(r1, a5, r1, carry, carry);
+                MP_ADD_CARRY(r2, a5, r2, carry, carry);
+                r3 += carry;
+                MP_ADD_CARRY(r1, a4, r1, 0,     carry);
+                MP_ADD_CARRY(r2,  0, r2, carry, carry);
+                r3 += carry;
+
+#else
+                r2 = MP_DIGIT(a, 2);
+                r1 = MP_DIGIT(a, 1);
+                r0 = MP_DIGIT(a, 0);
+
+                /* set the lower words of r */
+                __asm__ (
+                "xorq   %3,%3           \n\t"
+                "addq   %4,%0           \n\t"
+                "adcq   %4,%1           \n\t"
+                "adcq   %5,%2           \n\t"
+                "adcq   $0,%3           \n\t"
+                "addq   %6,%0           \n\t"
+                "adcq   %6,%1           \n\t"
+                "adcq   %6,%2           \n\t"
+                "adcq   $0,%3           \n\t"
+                "addq   %5,%1           \n\t"
+                "adcq   $0,%2           \n\t"
+                "adcq   $0,%3           \n\t"
+                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3),
+                  "=r"(a4), "=r"(a5)
+                : "0" (r0), "1" (r1), "2" (r2), "3" (r3),
+                  "4" (a3), "5" (a4), "6"(a5)
+                : "%cc" );
+#endif
+
+                /* reduce out the carry */
+                while (r3) {
+#ifndef MPI_AMD64_ADD
+                        MP_ADD_CARRY(r0, r3, r0, 0,     carry);
+                        MP_ADD_CARRY(r1, r3, r1, carry, carry);
+                        MP_ADD_CARRY(r2,  0, r2, carry, carry);
+                        r3 = carry;
+#else
+                        a3=r3;
+                        __asm__ (
+                        "xorq   %3,%3           \n\t"
+                        "addq   %4,%0           \n\t"
+                        "adcq   %4,%1           \n\t"
+                        "adcq   $0,%2           \n\t"
+                        "adcq   $0,%3           \n\t"
+                        : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3)
+                        : "0" (r0), "1" (r1), "2" (r2), "3" (r3), "4"(a3)
+                        : "%cc" );
+#endif
+                }
+
+                /* check for final reduction */
+                /*
+                 * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
+                 * 0xffffffffffffffff. That means we can only be over and need
+                 * one more reduction
+                 *  if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
+                 *     and
+                 *     r1 == 0xffffffffffffffffff   or
+                 *     r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
+                 * In all cases, we subtract the field (or add the 2's
+                 * complement value (1,1,0)).  (r0, r1, r2)
+                 */
+                if (r3 || ((r2 == MP_DIGIT_MAX) &&
+                      ((r1 == MP_DIGIT_MAX) ||
+                        ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
+                        /* do a quick subtract */
+                        r0++;
+                        r1 = r2 = 0;
+                }
+                /* set the lower words of r */
+                if (a != r) {
+                        MP_CHECKOK(s_mp_pad(r, 3));
+                }
+                MP_DIGIT(r, 2) = r2;
+                MP_DIGIT(r, 1) = r1;
+                MP_DIGIT(r, 0) = r0;
+                MP_USED(r) = 3;
+#endif
+        }
+
+  CLEANUP:
+        return res;
+}
+
+#ifndef ECL_THIRTY_TWO_BIT
+/* Compute the sum of 192 bit curves. Do the work in-line since the
+ * number of words are so small, we don't want to overhead of mp function
+ * calls.  Uses optimized modular reduction for p192.
+ */
+mp_err
+ec_GFp_nistp192_add(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit a0 = 0, a1 = 0, a2 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0;
+        mp_digit carry;
+
+        switch(MP_USED(a)) {
+        case 3:
+                a2 = MP_DIGIT(a,2);
+        case 2:
+                a1 = MP_DIGIT(a,1);
+        case 1:
+                a0 = MP_DIGIT(a,0);
+        }
+        switch(MP_USED(b)) {
+        case 3:
+                r2 = MP_DIGIT(b,2);
+        case 2:
+                r1 = MP_DIGIT(b,1);
+        case 1:
+                r0 = MP_DIGIT(b,0);
+        }
+
+#ifndef MPI_AMD64_ADD
+        MP_ADD_CARRY(a0, r0, r0, 0,     carry);
+        MP_ADD_CARRY(a1, r1, r1, carry, carry);
+        MP_ADD_CARRY(a2, r2, r2, carry, carry);
+#else
+        __asm__ (
+                "xorq   %3,%3           \n\t"
+                "addq   %4,%0           \n\t"
+                "adcq   %5,%1           \n\t"
+                "adcq   %6,%2           \n\t"
+                "adcq   $0,%3           \n\t"
+                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
+                : "r" (a0), "r" (a1), "r" (a2), "0" (r0),
+                  "1" (r1), "2" (r2)
+                : "%cc" );
+#endif
+
+        /* Do quick 'subract' if we've gone over
+         * (add the 2's complement of the curve field) */
+        if (carry || ((r2 == MP_DIGIT_MAX) &&
+                      ((r1 == MP_DIGIT_MAX) ||
+                        ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
+#ifndef MPI_AMD64_ADD
+                MP_ADD_CARRY(r0, 1, r0, 0,     carry);
+                MP_ADD_CARRY(r1, 1, r1, carry, carry);
+                MP_ADD_CARRY(r2, 0, r2, carry, carry);
+#else
+                __asm__ (
+                        "addq   $1,%0           \n\t"
+                        "adcq   $1,%1           \n\t"
+                        "adcq   $0,%2           \n\t"
+                        : "=r"(r0), "=r"(r1), "=r"(r2)
+                        : "0" (r0), "1" (r1), "2" (r2)
+                        : "%cc" );
+#endif
+        }
+
+
+        MP_CHECKOK(s_mp_pad(r, 3));
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 3;
+        s_mp_clamp(r);
+
+
+  CLEANUP:
+        return res;
+}
+
+/* Compute the diff of 192 bit curves. Do the work in-line since the
+ * number of words are so small, we don't want to overhead of mp function
+ * calls.  Uses optimized modular reduction for p192.
+ */
+mp_err
+ec_GFp_nistp192_sub(const mp_int *a, const mp_int *b, mp_int *r,
+                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_digit b0 = 0, b1 = 0, b2 = 0;
+        mp_digit r0 = 0, r1 = 0, r2 = 0;
+        mp_digit borrow;
+
+        switch(MP_USED(a)) {
+        case 3:
+                r2 = MP_DIGIT(a,2);
+        case 2:
+                r1 = MP_DIGIT(a,1);
+        case 1:
+                r0 = MP_DIGIT(a,0);
+        }
+
+        switch(MP_USED(b)) {
+        case 3:
+                b2 = MP_DIGIT(b,2);
+        case 2:
+                b1 = MP_DIGIT(b,1);
+        case 1:
+                b0 = MP_DIGIT(b,0);
+        }
+
+#ifndef MPI_AMD64_ADD
+        MP_SUB_BORROW(r0, b0, r0, 0,     borrow);
+        MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
+        MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
+#else
+        __asm__ (
+                "xorq   %3,%3           \n\t"
+                "subq   %4,%0           \n\t"
+                "sbbq   %5,%1           \n\t"
+                "sbbq   %6,%2           \n\t"
+                "adcq   $0,%3           \n\t"
+                : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(borrow)
+                : "r" (b0), "r" (b1), "r" (b2), "0" (r0),
+                  "1" (r1), "2" (r2)
+                : "%cc" );
+#endif
+
+        /* Do quick 'add' if we've gone under 0
+         * (subtract the 2's complement of the curve field) */
+        if (borrow) {
+#ifndef MPI_AMD64_ADD
+                MP_SUB_BORROW(r0, 1, r0, 0,     borrow);
+                MP_SUB_BORROW(r1, 1, r1, borrow, borrow);
+                MP_SUB_BORROW(r2,  0, r2, borrow, borrow);
+#else
+                __asm__ (
+                        "subq   $1,%0           \n\t"
+                        "sbbq   $1,%1           \n\t"
+                        "sbbq   $0,%2           \n\t"
+                        : "=r"(r0), "=r"(r1), "=r"(r2)
+                        : "0" (r0), "1" (r1), "2" (r2)
+                        : "%cc" );
+#endif
+        }
+
+        MP_CHECKOK(s_mp_pad(r, 3));
+        MP_DIGIT(r, 2) = r2;
+        MP_DIGIT(r, 1) = r1;
+        MP_DIGIT(r, 0) = r0;
+        MP_SIGN(r) = MP_ZPOS;
+        MP_USED(r) = 3;
+        s_mp_clamp(r);
+
+  CLEANUP:
+        return res;
+}
+
+#endif
+
+/* Compute the square of polynomial a, reduce modulo p192. Store the
+ * result in r.  r could be a.  Uses optimized modular reduction for p192.
+ */
+mp_err
+ec_GFp_nistp192_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_sqr(a, r));
+        MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p192.
+ * Store the result in r.  r could be a or b; a could be b.  Uses
+ * optimized modular reduction for p192. */
+mp_err
+ec_GFp_nistp192_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_mul(a, b, r));
+        MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Divides two field elements. If a is NULL, then returns the inverse of
+ * b. */
+mp_err
+ec_GFp_nistp192_div(const mp_int *a, const mp_int *b, mp_int *r,
+                   const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_int t;
+
+        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
+        if (a == NULL) {
+                return  mp_invmod(b, &meth->irr, r);
+        } else {
+                /* MPI doesn't support divmod, so we implement it using invmod and
+                 * mulmod. */
+                MP_CHECKOK(mp_init(&t, FLAG(b)));
+                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
+                MP_CHECKOK(mp_mul(a, &t, r));
+                MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
+          CLEANUP:
+                mp_clear(&t);
+                return res;
+        }
+}
+
+/* Wire in fast field arithmetic and precomputation of base point for
+ * named curves. */
+mp_err
+ec_group_set_gfp192(ECGroup *group, ECCurveName name)
+{
+        if (name == ECCurve_NIST_P192) {
+                group->meth->field_mod = &ec_GFp_nistp192_mod;
+                group->meth->field_mul = &ec_GFp_nistp192_mul;
+                group->meth->field_sqr = &ec_GFp_nistp192_sqr;
+                group->meth->field_div = &ec_GFp_nistp192_div;
+#ifndef ECL_THIRTY_TWO_BIT
+                group->meth->field_add = &ec_GFp_nistp192_add;
+                group->meth->field_sub = &ec_GFp_nistp192_sub;
+#endif
+        }
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_224.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,394 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+#define ECP224_DIGITS ECL_CURVE_DIGITS(224)
+
+/* Fast modular reduction for p224 = 2^224 - 2^96 + 1.  a can be r. Uses
+ * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
+ * Implementation of the NIST Elliptic Curves over Prime Fields. */
+mp_err
+ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_size a_used = MP_USED(a);
+
+        int    r3b;
+        mp_digit carry;
+#ifdef ECL_THIRTY_TWO_BIT
+        mp_digit a6a = 0, a6b = 0,
+                a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
+        mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a;
+#else
+        mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0;
+        mp_digit a6b = 0, a6a_a5b = 0, a5b = 0, a5a_a4b = 0, a4a_a3b = 0;
+        mp_digit r0, r1, r2, r3;
+#endif
+
+        /* reduction not needed if a is not larger than field size */
+        if (a_used < ECP224_DIGITS) {
+                if (a == r) return MP_OKAY;
+                return mp_copy(a, r);
+        }
+        /* for polynomials larger than twice the field size, use regular
+         * reduction */
+        if (a_used > ECL_CURVE_DIGITS(224*2)) {
+                MP_CHECKOK(mp_mod(a, &meth->irr, r));
+        } else {
+#ifdef ECL_THIRTY_TWO_BIT
+                /* copy out upper words of a */
+                switch (a_used) {
+                case 14:
+                        a6b = MP_DIGIT(a, 13);
+                case 13:
+                        a6a = MP_DIGIT(a, 12);
+                case 12:
+                        a5b = MP_DIGIT(a, 11);
+                case 11:
+                        a5a = MP_DIGIT(a, 10);
+                case 10:
+                        a4b = MP_DIGIT(a, 9);
+                case 9:
+                        a4a = MP_DIGIT(a, 8);
+                case 8:
+                        a3b = MP_DIGIT(a, 7);
+                }
+                r3a = MP_DIGIT(a, 6);
+                r2b= MP_DIGIT(a, 5);
+                r2a= MP_DIGIT(a, 4);
+                r1b = MP_DIGIT(a, 3);
+                r1a = MP_DIGIT(a, 2);
+                r0b = MP_DIGIT(a, 1);
+                r0a = MP_DIGIT(a, 0);
+
+
+                /* implement r = (a3a,a2,a1,a0)
+                        +(a5a, a4,a3b,  0)
+                        +(  0, a6,a5b,  0)
+                        -(  0    0,    0|a6b, a6a|a5b )
+                        -(  a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
+                MP_ADD_CARRY (r1b, a3b, r1b, 0,     carry);
+                MP_ADD_CARRY (r2a, a4a, r2a, carry, carry);
+                MP_ADD_CARRY (r2b, a4b, r2b, carry, carry);
+                MP_ADD_CARRY (r3a, a5a, r3a, carry, carry);
+                r3b = carry;
+                MP_ADD_CARRY (r1b, a5b, r1b, 0,     carry);
+                MP_ADD_CARRY (r2a, a6a, r2a, carry, carry);
+                MP_ADD_CARRY (r2b, a6b, r2b, carry, carry);
+                MP_ADD_CARRY (r3a,   0, r3a, carry, carry);
+                r3b += carry;
+                MP_SUB_BORROW(r0a, a3b, r0a, 0,     carry);
+                MP_SUB_BORROW(r0b, a4a, r0b, carry, carry);
+                MP_SUB_BORROW(r1a, a4b, r1a, carry, carry);
+                MP_SUB_BORROW(r1b, a5a, r1b, carry, carry);
+                MP_SUB_BORROW(r2a, a5b, r2a, carry, carry);
+                MP_SUB_BORROW(r2b, a6a, r2b, carry, carry);
+                MP_SUB_BORROW(r3a, a6b, r3a, carry, carry);
+                r3b -= carry;
+                MP_SUB_BORROW(r0a, a5b, r0a, 0,     carry);
+                MP_SUB_BORROW(r0b, a6a, r0b, carry, carry);
+                MP_SUB_BORROW(r1a, a6b, r1a, carry, carry);
+                if (carry) {
+                        MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
+                        MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
+                        MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
+                        MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
+                        r3b -= carry;
+                }
+
+                while (r3b > 0) {
+                        int tmp;
+                        MP_ADD_CARRY(r1b, r3b, r1b, 0,     carry);
+                        if (carry) {
+                                MP_ADD_CARRY(r2a,  0, r2a, carry, carry);
+                                MP_ADD_CARRY(r2b,  0, r2b, carry, carry);
+                                MP_ADD_CARRY(r3a,  0, r3a, carry, carry);
+                        }
+                        tmp = carry;
+                        MP_SUB_BORROW(r0a, r3b, r0a, 0,     carry);
+                        if (carry) {
+                                MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
+                                MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
+                                MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
+                                MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
+                                MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
+                                MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
+                                tmp -= carry;
+                        }
+                        r3b = tmp;
+                }
+
+                while (r3b < 0) {
+                        mp_digit maxInt = MP_DIGIT_MAX;
+                        MP_ADD_CARRY (r0a, 1, r0a, 0,     carry);
+                        MP_ADD_CARRY (r0b, 0, r0b, carry, carry);
+                        MP_ADD_CARRY (r1a, 0, r1a, carry, carry);
+                        MP_ADD_CARRY (r1b, maxInt, r1b, carry, carry);
+                        MP_ADD_CARRY (r2a, maxInt, r2a, carry, carry);
+                        MP_ADD_CARRY (r2b, maxInt, r2b, carry, carry);
+                        MP_ADD_CARRY (r3a, maxInt, r3a, carry, carry);
+                        r3b += carry;
+                }
+                /* check for final reduction */
+                /* now the only way we are over is if the top 4 words are all ones */
+                if ((r3a == MP_DIGIT_MAX) && (r2b == MP_DIGIT_MAX)
+                        && (r2a == MP_DIGIT_MAX) && (r1b == MP_DIGIT_MAX) &&
+                         ((r1a != 0) || (r0b != 0) || (r0a != 0)) ) {
+                        /* one last subraction */
+                        MP_SUB_BORROW(r0a, 1, r0a, 0,     carry);
+                        MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
+                        MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
+                        r1b = r2a = r2b = r3a = 0;
+                }
+
+
+                if (a != r) {
+                        MP_CHECKOK(s_mp_pad(r, 7));
+                }
+                /* set the lower words of r */
+                MP_SIGN(r) = MP_ZPOS;
+                MP_USED(r) = 7;
+                MP_DIGIT(r, 6) = r3a;
+                MP_DIGIT(r, 5) = r2b;
+                MP_DIGIT(r, 4) = r2a;
+                MP_DIGIT(r, 3) = r1b;
+                MP_DIGIT(r, 2) = r1a;
+                MP_DIGIT(r, 1) = r0b;
+                MP_DIGIT(r, 0) = r0a;
+#else
+                /* copy out upper words of a */
+                switch (a_used) {
+                case 7:
+                        a6 = MP_DIGIT(a, 6);
+                        a6b = a6 >> 32;
+                        a6a_a5b = a6 << 32;
+                case 6:
+                        a5 = MP_DIGIT(a, 5);
+                        a5b = a5 >> 32;
+                        a6a_a5b |= a5b;
+                        a5b = a5b << 32;
+                        a5a_a4b = a5 << 32;
+                        a5a = a5 & 0xffffffff;
+                case 5:
+                        a4 = MP_DIGIT(a, 4);
+                        a5a_a4b |= a4 >> 32;
+                        a4a_a3b = a4 << 32;
+                case 4:
+                        a3b = MP_DIGIT(a, 3) >> 32;
+                        a4a_a3b |= a3b;
+                        a3b = a3b << 32;
+                }
+
+                r3 = MP_DIGIT(a, 3) & 0xffffffff;
+                r2 = MP_DIGIT(a, 2);
+                r1 = MP_DIGIT(a, 1);
+                r0 = MP_DIGIT(a, 0);
+
+                /* implement r = (a3a,a2,a1,a0)
+                        +(a5a, a4,a3b,  0)
+                        +(  0, a6,a5b,  0)
+                        -(  0    0,    0|a6b, a6a|a5b )
+                        -(  a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
+                MP_ADD_CARRY (r1, a3b, r1, 0,     carry);
+                MP_ADD_CARRY (r2, a4 , r2, carry, carry);
+                MP_ADD_CARRY (r3, a5a, r3, carry, carry);
+                MP_ADD_CARRY (r1, a5b, r1, 0,     carry);
+                MP_ADD_CARRY (r2, a6 , r2, carry, carry);
+                MP_ADD_CARRY (r3,   0, r3, carry, carry);
+
+                MP_SUB_BORROW(r0, a4a_a3b, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a5a_a4b, r1, carry, carry);
+                MP_SUB_BORROW(r2, a6a_a5b, r2, carry, carry);
+                MP_SUB_BORROW(r3, a6b    , r3, carry, carry);
+                MP_SUB_BORROW(r0, a6a_a5b, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a6b    , r1, carry, carry);
+                if (carry) {
+                        MP_SUB_BORROW(r2, 0, r2, carry, carry);
+                        MP_SUB_BORROW(r3, 0, r3, carry, carry);
+                }
+
+
+                /* if the value is negative, r3 has a 2's complement
+                 * high value */
+                r3b = (int)(r3 >>32);
+                while (r3b > 0) {
+                        r3 &= 0xffffffff;
+                        MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry);
+                        if (carry) {
+                                MP_ADD_CARRY(r2,  0, r2, carry, carry);
+                                MP_ADD_CARRY(r3,  0, r3, carry, carry);
+                        }
+                        MP_SUB_BORROW(r0, r3b, r0, 0, carry);
+                        if (carry) {
+                                MP_SUB_BORROW(r1, 0, r1, carry, carry);
+                                MP_SUB_BORROW(r2, 0, r2, carry, carry);
+                                MP_SUB_BORROW(r3, 0, r3, carry, carry);
+                        }
+                        r3b = (int)(r3 >>32);
+                }
+
+                while (r3b < 0) {
+                        MP_ADD_CARRY (r0, 1, r0, 0,     carry);
+                        MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry);
+                        MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry);
+                        MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry);
+                        r3b = (int)(r3 >>32);
+                }
+                /* check for final reduction */
+                /* now the only way we are over is if the top 4 words are all ones */
+                if ((r3 == (MP_DIGIT_MAX >> 32)) && (r2 == MP_DIGIT_MAX)
+                        && ((r1 & MP_DIGIT_MAX << 32)== MP_DIGIT_MAX << 32) &&
+                         ((r1 != MP_DIGIT_MAX << 32 ) || (r0 != 0)) ) {
+                        /* one last subraction */
+                        MP_SUB_BORROW(r0, 1, r0, 0,     carry);
+                        MP_SUB_BORROW(r1, 0, r1, carry, carry);
+                        r2 = r3 = 0;
+                }
+
+
+                if (a != r) {
+                        MP_CHECKOK(s_mp_pad(r, 4));
+                }
+                /* set the lower words of r */
+                MP_SIGN(r) = MP_ZPOS;
+                MP_USED(r) = 4;
+                MP_DIGIT(r, 3) = r3;
+                MP_DIGIT(r, 2) = r2;
+                MP_DIGIT(r, 1) = r1;
+                MP_DIGIT(r, 0) = r0;
+#endif
+        }
+
+  CLEANUP:
+        return res;
+}
+
+/* Compute the square of polynomial a, reduce modulo p224. Store the
+ * result in r.  r could be a.  Uses optimized modular reduction for p224.
+ */
+mp_err
+ec_GFp_nistp224_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_sqr(a, r));
+        MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p224.
+ * Store the result in r.  r could be a or b; a could be b.  Uses
+ * optimized modular reduction for p224. */
+mp_err
+ec_GFp_nistp224_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_mul(a, b, r));
+        MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Divides two field elements. If a is NULL, then returns the inverse of
+ * b. */
+mp_err
+ec_GFp_nistp224_div(const mp_int *a, const mp_int *b, mp_int *r,
+                   const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_int t;
+
+        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
+        if (a == NULL) {
+                return  mp_invmod(b, &meth->irr, r);
+        } else {
+                /* MPI doesn't support divmod, so we implement it using invmod and
+                 * mulmod. */
+                MP_CHECKOK(mp_init(&t, FLAG(b)));
+                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
+                MP_CHECKOK(mp_mul(a, &t, r));
+                MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
+          CLEANUP:
+                mp_clear(&t);
+                return res;
+        }
+}
+
+/* Wire in fast field arithmetic and precomputation of base point for
+ * named curves. */
+mp_err
+ec_group_set_gfp224(ECGroup *group, ECCurveName name)
+{
+        if (name == ECCurve_NIST_P224) {
+                group->meth->field_mod = &ec_GFp_nistp224_mod;
+                group->meth->field_mul = &ec_GFp_nistp224_mul;
+                group->meth->field_sqr = &ec_GFp_nistp224_sqr;
+                group->meth->field_div = &ec_GFp_nistp224_div;
+        }
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_256.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,451 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Fast modular reduction for p256 = 2^256 - 2^224 + 2^192+ 2^96 - 1.  a can be r.
+ * Uses algorithm 2.29 from Hankerson, Menezes, Vanstone. Guide to
+ * Elliptic Curve Cryptography. */
+mp_err
+ec_GFp_nistp256_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_size a_used = MP_USED(a);
+        int a_bits = mpl_significant_bits(a);
+        mp_digit carry;
+
+#ifdef ECL_THIRTY_TWO_BIT
+        mp_digit a8=0, a9=0, a10=0, a11=0, a12=0, a13=0, a14=0, a15=0;
+        mp_digit r0, r1, r2, r3, r4, r5, r6, r7;
+        int r8; /* must be a signed value ! */
+#else
+        mp_digit a4=0, a5=0, a6=0, a7=0;
+        mp_digit a4h, a4l, a5h, a5l, a6h, a6l, a7h, a7l;
+        mp_digit r0, r1, r2, r3;
+        int r4; /* must be a signed value ! */
+#endif
+        /* for polynomials larger than twice the field size
+         * use regular reduction */
+        if (a_bits < 256) {
+                if (a == r) return MP_OKAY;
+                return mp_copy(a,r);
+        }
+        if (a_bits > 512)  {
+                MP_CHECKOK(mp_mod(a, &meth->irr, r));
+        } else {
+
+#ifdef ECL_THIRTY_TWO_BIT
+                switch (a_used) {
+                case 16:
+                        a15 = MP_DIGIT(a,15);
+                case 15:
+                        a14 = MP_DIGIT(a,14);
+                case 14:
+                        a13 = MP_DIGIT(a,13);
+                case 13:
+                        a12 = MP_DIGIT(a,12);
+                case 12:
+                        a11 = MP_DIGIT(a,11);
+                case 11:
+                        a10 = MP_DIGIT(a,10);
+                case 10:
+                        a9 = MP_DIGIT(a,9);
+                case 9:
+                        a8 = MP_DIGIT(a,8);
+                }
+
+                r0 = MP_DIGIT(a,0);
+                r1 = MP_DIGIT(a,1);
+                r2 = MP_DIGIT(a,2);
+                r3 = MP_DIGIT(a,3);
+                r4 = MP_DIGIT(a,4);
+                r5 = MP_DIGIT(a,5);
+                r6 = MP_DIGIT(a,6);
+                r7 = MP_DIGIT(a,7);
+
+                /* sum 1 */
+                MP_ADD_CARRY(r3, a11, r3, 0,     carry);
+                MP_ADD_CARRY(r4, a12, r4, carry, carry);
+                MP_ADD_CARRY(r5, a13, r5, carry, carry);
+                MP_ADD_CARRY(r6, a14, r6, carry, carry);
+                MP_ADD_CARRY(r7, a15, r7, carry, carry);
+                r8 = carry;
+                MP_ADD_CARRY(r3, a11, r3, 0,     carry);
+                MP_ADD_CARRY(r4, a12, r4, carry, carry);
+                MP_ADD_CARRY(r5, a13, r5, carry, carry);
+                MP_ADD_CARRY(r6, a14, r6, carry, carry);
+                MP_ADD_CARRY(r7, a15, r7, carry, carry);
+                r8 += carry;
+                /* sum 2 */
+                MP_ADD_CARRY(r3, a12, r3, 0,     carry);
+                MP_ADD_CARRY(r4, a13, r4, carry, carry);
+                MP_ADD_CARRY(r5, a14, r5, carry, carry);
+                MP_ADD_CARRY(r6, a15, r6, carry, carry);
+                MP_ADD_CARRY(r7,   0, r7, carry, carry);
+                r8 += carry;
+                /* combine last bottom of sum 3 with second sum 2 */
+                MP_ADD_CARRY(r0, a8,  r0, 0,     carry);
+                MP_ADD_CARRY(r1, a9,  r1, carry, carry);
+                MP_ADD_CARRY(r2, a10, r2, carry, carry);
+                MP_ADD_CARRY(r3, a12, r3, carry, carry);
+                MP_ADD_CARRY(r4, a13, r4, carry, carry);
+                MP_ADD_CARRY(r5, a14, r5, carry, carry);
+                MP_ADD_CARRY(r6, a15, r6, carry, carry);
+                MP_ADD_CARRY(r7, a15, r7, carry, carry); /* from sum 3 */
+                r8 += carry;
+                /* sum 3 (rest of it)*/
+                MP_ADD_CARRY(r6, a14, r6, 0,     carry);
+                MP_ADD_CARRY(r7,   0, r7, carry, carry);
+                r8 += carry;
+                /* sum 4 (rest of it)*/
+                MP_ADD_CARRY(r0, a9,  r0, 0,     carry);
+                MP_ADD_CARRY(r1, a10, r1, carry, carry);
+                MP_ADD_CARRY(r2, a11, r2, carry, carry);
+                MP_ADD_CARRY(r3, a13, r3, carry, carry);
+                MP_ADD_CARRY(r4, a14, r4, carry, carry);
+                MP_ADD_CARRY(r5, a15, r5, carry, carry);
+                MP_ADD_CARRY(r6, a13, r6, carry, carry);
+                MP_ADD_CARRY(r7, a8,  r7, carry, carry);
+                r8 += carry;
+                /* diff 5 */
+                MP_SUB_BORROW(r0, a11, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a12, r1, carry, carry);
+                MP_SUB_BORROW(r2, a13, r2, carry, carry);
+                MP_SUB_BORROW(r3,   0, r3, carry, carry);
+                MP_SUB_BORROW(r4,   0, r4, carry, carry);
+                MP_SUB_BORROW(r5,   0, r5, carry, carry);
+                MP_SUB_BORROW(r6, a8,  r6, carry, carry);
+                MP_SUB_BORROW(r7, a10, r7, carry, carry);
+                r8 -= carry;
+                /* diff 6 */
+                MP_SUB_BORROW(r0, a12, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a13, r1, carry, carry);
+                MP_SUB_BORROW(r2, a14, r2, carry, carry);
+                MP_SUB_BORROW(r3, a15, r3, carry, carry);
+                MP_SUB_BORROW(r4,   0, r4, carry, carry);
+                MP_SUB_BORROW(r5,   0, r5, carry, carry);
+                MP_SUB_BORROW(r6, a9,  r6, carry, carry);
+                MP_SUB_BORROW(r7, a11, r7, carry, carry);
+                r8 -= carry;
+                /* diff 7 */
+                MP_SUB_BORROW(r0, a13, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a14, r1, carry, carry);
+                MP_SUB_BORROW(r2, a15, r2, carry, carry);
+                MP_SUB_BORROW(r3, a8,  r3, carry, carry);
+                MP_SUB_BORROW(r4, a9,  r4, carry, carry);
+                MP_SUB_BORROW(r5, a10, r5, carry, carry);
+                MP_SUB_BORROW(r6, 0,   r6, carry, carry);
+                MP_SUB_BORROW(r7, a12, r7, carry, carry);
+                r8 -= carry;
+                /* diff 8 */
+                MP_SUB_BORROW(r0, a14, r0, 0,     carry);
+                MP_SUB_BORROW(r1, a15, r1, carry, carry);
+                MP_SUB_BORROW(r2, 0,   r2, carry, carry);
+                MP_SUB_BORROW(r3, a9,  r3, carry, carry);
+                MP_SUB_BORROW(r4, a10, r4, carry, carry);
+                MP_SUB_BORROW(r5, a11, r5, carry, carry);
+                MP_SUB_BORROW(r6, 0,   r6, carry, carry);
+                MP_SUB_BORROW(r7, a13, r7, carry, carry);
+                r8 -= carry;
+
+                /* reduce the overflows */
+                while (r8 > 0) {
+                        mp_digit r8_d = r8;
+                        MP_ADD_CARRY(r0, r8_d,         r0, 0,     carry);
+                        MP_ADD_CARRY(r1, 0,            r1, carry, carry);
+                        MP_ADD_CARRY(r2, 0,            r2, carry, carry);
+                        MP_ADD_CARRY(r3, -r8_d,        r3, carry, carry);
+                        MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry, carry);
+                        MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry, carry);
+                        MP_ADD_CARRY(r6, -(r8_d+1),    r6, carry, carry);
+                        MP_ADD_CARRY(r7, (r8_d-1),     r7, carry, carry);
+                        r8 = carry;
+                }
+
+                /* reduce the underflows */
+                while (r8 < 0) {
+                        mp_digit r8_d = -r8;
+                        MP_SUB_BORROW(r0, r8_d,         r0, 0,     carry);
+                        MP_SUB_BORROW(r1, 0,            r1, carry, carry);
+                        MP_SUB_BORROW(r2, 0,            r2, carry, carry);
+                        MP_SUB_BORROW(r3, -r8_d,        r3, carry, carry);
+                        MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry, carry);
+                        MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry, carry);
+                        MP_SUB_BORROW(r6, -(r8_d+1),    r6, carry, carry);
+                        MP_SUB_BORROW(r7, (r8_d-1),     r7, carry, carry);
+                        r8 = -carry;
+                }
+                if (a != r) {
+                        MP_CHECKOK(s_mp_pad(r,8));
+                }
+                MP_SIGN(r) = MP_ZPOS;
+                MP_USED(r) = 8;
+
+                MP_DIGIT(r,7) = r7;
+                MP_DIGIT(r,6) = r6;
+                MP_DIGIT(r,5) = r5;
+                MP_DIGIT(r,4) = r4;
+                MP_DIGIT(r,3) = r3;
+                MP_DIGIT(r,2) = r2;
+                MP_DIGIT(r,1) = r1;
+                MP_DIGIT(r,0) = r0;
+
+                /* final reduction if necessary */
+                if ((r7 == MP_DIGIT_MAX) &&
+                        ((r6 > 1) || ((r6 == 1) &&
+                        (r5 || r4 || r3 ||
+                                ((r2 == MP_DIGIT_MAX) && (r1 == MP_DIGIT_MAX)
+                                  && (r0 == MP_DIGIT_MAX)))))) {
+                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
+                }
+#ifdef notdef
+
+
+                /* smooth the negatives */
+                while (MP_SIGN(r) != MP_ZPOS) {
+                        MP_CHECKOK(mp_add(r, &meth->irr, r));
+                }
+                while (MP_USED(r) > 8) {
+                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
+                }
+
+                /* final reduction if necessary */
+                if (MP_DIGIT(r,7) >= MP_DIGIT(&meth->irr,7)) {
+                    if (mp_cmp(r,&meth->irr) != MP_LT) {
+                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
+                    }
+                }
+#endif
+                s_mp_clamp(r);
+#else
+                switch (a_used) {
+                case 8:
+                        a7 = MP_DIGIT(a,7);
+                case 7:
+                        a6 = MP_DIGIT(a,6);
+                case 6:
+                        a5 = MP_DIGIT(a,5);
+                case 5:
+                        a4 = MP_DIGIT(a,4);
+                }
+                a7l = a7 << 32;
+                a7h = a7 >> 32;
+                a6l = a6 << 32;
+                a6h = a6 >> 32;
+                a5l = a5 << 32;
+                a5h = a5 >> 32;
+                a4l = a4 << 32;
+                a4h = a4 >> 32;
+                r3 = MP_DIGIT(a,3);
+                r2 = MP_DIGIT(a,2);
+                r1 = MP_DIGIT(a,1);
+                r0 = MP_DIGIT(a,0);
+
+                /* sum 1 */
+                MP_ADD_CARRY(r1, a5h << 32, r1, 0,     carry);
+                MP_ADD_CARRY(r2, a6,        r2, carry, carry);
+                MP_ADD_CARRY(r3, a7,        r3, carry, carry);
+                r4 = carry;
+                MP_ADD_CARRY(r1, a5h << 32, r1, 0,     carry);
+                MP_ADD_CARRY(r2, a6,        r2, carry, carry);
+                MP_ADD_CARRY(r3, a7,        r3, carry, carry);
+                r4 += carry;
+                /* sum 2 */
+                MP_ADD_CARRY(r1, a6l,       r1, 0,     carry);
+                MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
+                MP_ADD_CARRY(r3, a7h,       r3, carry, carry);
+                r4 += carry;
+                MP_ADD_CARRY(r1, a6l,       r1, 0,     carry);
+                MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
+                MP_ADD_CARRY(r3, a7h,       r3, carry, carry);
+                r4 += carry;
+
+                /* sum 3 */
+                MP_ADD_CARRY(r0, a4,        r0, 0,     carry);
+                MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry);
+                MP_ADD_CARRY(r2, 0,         r2, carry, carry);
+                MP_ADD_CARRY(r3, a7,        r3, carry, carry);
+                r4 += carry;
+                /* sum 4 */
+                MP_ADD_CARRY(r0, a4h | a5l,     r0, 0,     carry);
+                MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry);
+                MP_ADD_CARRY(r2, a7,            r2, carry, carry);
+                MP_ADD_CARRY(r3, a6h | a4l,     r3, carry, carry);
+                r4 += carry;
+                /* diff 5 */
+                MP_SUB_BORROW(r0, a5h | a6l,    r0, 0,     carry);
+                MP_SUB_BORROW(r1, a6h,          r1, carry, carry);
+                MP_SUB_BORROW(r2, 0,            r2, carry, carry);
+                MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry, carry);
+                r4 -= carry;
+                /* diff 6 */
+                MP_SUB_BORROW(r0, a6,           r0, 0,     carry);
+                MP_SUB_BORROW(r1, a7,           r1, carry, carry);
+                MP_SUB_BORROW(r2, 0,            r2, carry, carry);
+                MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry, carry);
+                r4 -= carry;
+                /* diff 7 */
+                MP_SUB_BORROW(r0, a6h|a7l,      r0, 0,     carry);
+                MP_SUB_BORROW(r1, a7h|a4l,      r1, carry, carry);
+                MP_SUB_BORROW(r2, a4h|a5l,      r2, carry, carry);
+                MP_SUB_BORROW(r3, a6l,          r3, carry, carry);
+                r4 -= carry;
+                /* diff 8 */
+                MP_SUB_BORROW(r0, a7,           r0, 0,     carry);
+                MP_SUB_BORROW(r1, a4h<<32,      r1, carry, carry);
+                MP_SUB_BORROW(r2, a5,           r2, carry, carry);
+                MP_SUB_BORROW(r3, a6h<<32,      r3, carry, carry);
+                r4 -= carry;
+
+                /* reduce the overflows */
+                while (r4 > 0) {
+                        mp_digit r4_long = r4;
+                        mp_digit r4l = (r4_long << 32);
+                        MP_ADD_CARRY(r0, r4_long,      r0, 0,     carry);
+                        MP_ADD_CARRY(r1, -r4l,         r1, carry, carry);
+                        MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry);
+                        MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry);
+                        r4 = carry;
+                }
+
+                /* reduce the underflows */
+                while (r4 < 0) {
+                        mp_digit r4_long = -r4;
+                        mp_digit r4l = (r4_long << 32);
+                        MP_SUB_BORROW(r0, r4_long,      r0, 0,     carry);
+                        MP_SUB_BORROW(r1, -r4l,         r1, carry, carry);
+                        MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry, carry);
+                        MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry, carry);
+                        r4 = -carry;
+                }
+
+                if (a != r) {
+                        MP_CHECKOK(s_mp_pad(r,4));
+                }
+                MP_SIGN(r) = MP_ZPOS;
+                MP_USED(r) = 4;
+
+                MP_DIGIT(r,3) = r3;
+                MP_DIGIT(r,2) = r2;
+                MP_DIGIT(r,1) = r1;
+                MP_DIGIT(r,0) = r0;
+
+                /* final reduction if necessary */
+                if ((r3 > 0xFFFFFFFF00000001ULL) ||
+                        ((r3 == 0xFFFFFFFF00000001ULL) &&
+                        (r2 || (r1 >> 32)||
+                               (r1 == 0xFFFFFFFFULL && r0 == MP_DIGIT_MAX)))) {
+                        /* very rare, just use mp_sub */
+                        MP_CHECKOK(mp_sub(r, &meth->irr, r));
+                }
+
+                s_mp_clamp(r);
+#endif
+        }
+
+  CLEANUP:
+        return res;
+}
+
+/* Compute the square of polynomial a, reduce modulo p256. Store the
+ * result in r.  r could be a.  Uses optimized modular reduction for p256.
+ */
+mp_err
+ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_sqr(a, r));
+        MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p256.
+ * Store the result in r.  r could be a or b; a could be b.  Uses
+ * optimized modular reduction for p256. */
+mp_err
+ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_mul(a, b, r));
+        MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Wire in fast field arithmetic and precomputation of base point for
+ * named curves. */
+mp_err
+ec_group_set_gfp256(ECGroup *group, ECCurveName name)
+{
+        if (name == ECCurve_NIST_P256) {
+                group->meth->field_mod = &ec_GFp_nistp256_mod;
+                group->meth->field_mul = &ec_GFp_nistp256_mul;
+                group->meth->field_sqr = &ec_GFp_nistp256_sqr;
+        }
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_384.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,315 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1.  a can be r.
+ * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to
+ * Elliptic Curve Cryptography. */
+mp_err
+ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        int a_bits = mpl_significant_bits(a);
+        int i;
+
+        /* m1, m2 are statically-allocated mp_int of exactly the size we need */
+        mp_int m[10];
+
+#ifdef ECL_THIRTY_TWO_BIT
+        mp_digit s[10][12];
+        for (i = 0; i < 10; i++) {
+                MP_SIGN(&m[i]) = MP_ZPOS;
+                MP_ALLOC(&m[i]) = 12;
+                MP_USED(&m[i]) = 12;
+                MP_DIGITS(&m[i]) = s[i];
+        }
+#else
+        mp_digit s[10][6];
+        for (i = 0; i < 10; i++) {
+                MP_SIGN(&m[i]) = MP_ZPOS;
+                MP_ALLOC(&m[i]) = 6;
+                MP_USED(&m[i]) = 6;
+                MP_DIGITS(&m[i]) = s[i];
+        }
+#endif
+
+#ifdef ECL_THIRTY_TWO_BIT
+        /* for polynomials larger than twice the field size or polynomials
+         * not using all words, use regular reduction */
+        if ((a_bits > 768) || (a_bits <= 736)) {
+                MP_CHECKOK(mp_mod(a, &meth->irr, r));
+        } else {
+                for (i = 0; i < 12; i++) {
+                        s[0][i] = MP_DIGIT(a, i);
+                }
+                s[1][0] = 0;
+                s[1][1] = 0;
+                s[1][2] = 0;
+                s[1][3] = 0;
+                s[1][4] = MP_DIGIT(a, 21);
+                s[1][5] = MP_DIGIT(a, 22);
+                s[1][6] = MP_DIGIT(a, 23);
+                s[1][7] = 0;
+                s[1][8] = 0;
+                s[1][9] = 0;
+                s[1][10] = 0;
+                s[1][11] = 0;
+                for (i = 0; i < 12; i++) {
+                        s[2][i] = MP_DIGIT(a, i+12);
+                }
+                s[3][0] = MP_DIGIT(a, 21);
+                s[3][1] = MP_DIGIT(a, 22);
+                s[3][2] = MP_DIGIT(a, 23);
+                for (i = 3; i < 12; i++) {
+                        s[3][i] = MP_DIGIT(a, i+9);
+                }
+                s[4][0] = 0;
+                s[4][1] = MP_DIGIT(a, 23);
+                s[4][2] = 0;
+                s[4][3] = MP_DIGIT(a, 20);
+                for (i = 4; i < 12; i++) {
+                        s[4][i] = MP_DIGIT(a, i+8);
+                }
+                s[5][0] = 0;
+                s[5][1] = 0;
+                s[5][2] = 0;
+                s[5][3] = 0;
+                s[5][4] = MP_DIGIT(a, 20);
+                s[5][5] = MP_DIGIT(a, 21);
+                s[5][6] = MP_DIGIT(a, 22);
+                s[5][7] = MP_DIGIT(a, 23);
+                s[5][8] = 0;
+                s[5][9] = 0;
+                s[5][10] = 0;
+                s[5][11] = 0;
+                s[6][0] = MP_DIGIT(a, 20);
+                s[6][1] = 0;
+                s[6][2] = 0;
+                s[6][3] = MP_DIGIT(a, 21);
+                s[6][4] = MP_DIGIT(a, 22);
+                s[6][5] = MP_DIGIT(a, 23);
+                s[6][6] = 0;
+                s[6][7] = 0;
+                s[6][8] = 0;
+                s[6][9] = 0;
+                s[6][10] = 0;
+                s[6][11] = 0;
+                s[7][0] = MP_DIGIT(a, 23);
+                for (i = 1; i < 12; i++) {
+                        s[7][i] = MP_DIGIT(a, i+11);
+                }
+                s[8][0] = 0;
+                s[8][1] = MP_DIGIT(a, 20);
+                s[8][2] = MP_DIGIT(a, 21);
+                s[8][3] = MP_DIGIT(a, 22);
+                s[8][4] = MP_DIGIT(a, 23);
+                s[8][5] = 0;
+                s[8][6] = 0;
+                s[8][7] = 0;
+                s[8][8] = 0;
+                s[8][9] = 0;
+                s[8][10] = 0;
+                s[8][11] = 0;
+                s[9][0] = 0;
+                s[9][1] = 0;
+                s[9][2] = 0;
+                s[9][3] = MP_DIGIT(a, 23);
+                s[9][4] = MP_DIGIT(a, 23);
+                s[9][5] = 0;
+                s[9][6] = 0;
+                s[9][7] = 0;
+                s[9][8] = 0;
+                s[9][9] = 0;
+                s[9][10] = 0;
+                s[9][11] = 0;
+
+                MP_CHECKOK(mp_add(&m[0], &m[1], r));
+                MP_CHECKOK(mp_add(r, &m[1], r));
+                MP_CHECKOK(mp_add(r, &m[2], r));
+                MP_CHECKOK(mp_add(r, &m[3], r));
+                MP_CHECKOK(mp_add(r, &m[4], r));
+                MP_CHECKOK(mp_add(r, &m[5], r));
+                MP_CHECKOK(mp_add(r, &m[6], r));
+                MP_CHECKOK(mp_sub(r, &m[7], r));
+                MP_CHECKOK(mp_sub(r, &m[8], r));
+                MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
+                s_mp_clamp(r);
+        }
+#else
+        /* for polynomials larger than twice the field size or polynomials
+         * not using all words, use regular reduction */
+        if ((a_bits > 768) || (a_bits <= 736)) {
+                MP_CHECKOK(mp_mod(a, &meth->irr, r));
+        } else {
+                for (i = 0; i < 6; i++) {
+                        s[0][i] = MP_DIGIT(a, i);
+                }
+                s[1][0] = 0;
+                s[1][1] = 0;
+                s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
+                s[1][3] = MP_DIGIT(a, 11) >> 32;
+                s[1][4] = 0;
+                s[1][5] = 0;
+                for (i = 0; i < 6; i++) {
+                        s[2][i] = MP_DIGIT(a, i+6);
+                }
+                s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
+                s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
+                for (i = 2; i < 6; i++) {
+                        s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32);
+                }
+                s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32;
+                s[4][1] = MP_DIGIT(a, 10) << 32;
+                for (i = 2; i < 6; i++) {
+                        s[4][i] = MP_DIGIT(a, i+4);
+                }
+                s[5][0] = 0;
+                s[5][1] = 0;
+                s[5][2] = MP_DIGIT(a, 10);
+                s[5][3] = MP_DIGIT(a, 11);
+                s[5][4] = 0;
+                s[5][5] = 0;
+                s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32;
+                s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32;
+                s[6][2] = MP_DIGIT(a, 11);
+                s[6][3] = 0;
+                s[6][4] = 0;
+                s[6][5] = 0;
+                s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
+                for (i = 1; i < 6; i++) {
+                        s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32);
+                }
+                s[8][0] = MP_DIGIT(a, 10) << 32;
+                s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
+                s[8][2] = MP_DIGIT(a, 11) >> 32;
+                s[8][3] = 0;
+                s[8][4] = 0;
+                s[8][5] = 0;
+                s[9][0] = 0;
+                s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32;
+                s[9][2] = MP_DIGIT(a, 11) >> 32;
+                s[9][3] = 0;
+                s[9][4] = 0;
+                s[9][5] = 0;
+
+                MP_CHECKOK(mp_add(&m[0], &m[1], r));
+                MP_CHECKOK(mp_add(r, &m[1], r));
+                MP_CHECKOK(mp_add(r, &m[2], r));
+                MP_CHECKOK(mp_add(r, &m[3], r));
+                MP_CHECKOK(mp_add(r, &m[4], r));
+                MP_CHECKOK(mp_add(r, &m[5], r));
+                MP_CHECKOK(mp_add(r, &m[6], r));
+                MP_CHECKOK(mp_sub(r, &m[7], r));
+                MP_CHECKOK(mp_sub(r, &m[8], r));
+                MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
+                s_mp_clamp(r);
+        }
+#endif
+
+  CLEANUP:
+        return res;
+}
+
+/* Compute the square of polynomial a, reduce modulo p384. Store the
+ * result in r.  r could be a.  Uses optimized modular reduction for p384.
+ */
+mp_err
+ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_sqr(a, r));
+        MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p384.
+ * Store the result in r.  r could be a or b; a could be b.  Uses
+ * optimized modular reduction for p384. */
+mp_err
+ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_mul(a, b, r));
+        MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Wire in fast field arithmetic and precomputation of base point for
+ * named curves. */
+mp_err
+ec_group_set_gfp384(ECGroup *group, ECCurveName name)
+{
+        if (name == ECCurve_NIST_P384) {
+                group->meth->field_mod = &ec_GFp_nistp384_mod;
+                group->meth->field_mul = &ec_GFp_nistp384_mul;
+                group->meth->field_sqr = &ec_GFp_nistp384_sqr;
+        }
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_521.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,192 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+#define ECP521_DIGITS ECL_CURVE_DIGITS(521)
+
+/* Fast modular reduction for p521 = 2^521 - 1.  a can be r. Uses
+ * algorithm 2.31 from Hankerson, Menezes, Vanstone. Guide to
+ * Elliptic Curve Cryptography. */
+mp_err
+ec_GFp_nistp521_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        int a_bits = mpl_significant_bits(a);
+        int i;
+
+        /* m1, m2 are statically-allocated mp_int of exactly the size we need */
+        mp_int m1;
+
+        mp_digit s1[ECP521_DIGITS] = { 0 };
+
+        MP_SIGN(&m1) = MP_ZPOS;
+        MP_ALLOC(&m1) = ECP521_DIGITS;
+        MP_USED(&m1) = ECP521_DIGITS;
+        MP_DIGITS(&m1) = s1;
+
+        if (a_bits < 521) {
+                if (a==r) return MP_OKAY;
+                return mp_copy(a, r);
+        }
+        /* for polynomials larger than twice the field size or polynomials
+         * not using all words, use regular reduction */
+        if (a_bits > (521*2)) {
+                MP_CHECKOK(mp_mod(a, &meth->irr, r));
+        } else {
+#define FIRST_DIGIT (ECP521_DIGITS-1)
+                for (i = FIRST_DIGIT; i < MP_USED(a)-1; i++) {
+                        s1[i-FIRST_DIGIT] = (MP_DIGIT(a, i) >> 9)
+                                | (MP_DIGIT(a, 1+i) << (MP_DIGIT_BIT-9));
+                }
+                s1[i-FIRST_DIGIT] = MP_DIGIT(a, i) >> 9;
+
+                if ( a != r ) {
+                        MP_CHECKOK(s_mp_pad(r,ECP521_DIGITS));
+                        for (i = 0; i < ECP521_DIGITS; i++) {
+                                MP_DIGIT(r,i) = MP_DIGIT(a, i);
+                        }
+                }
+                MP_USED(r) = ECP521_DIGITS;
+                MP_DIGIT(r,FIRST_DIGIT) &=  0x1FF;
+
+                MP_CHECKOK(s_mp_add(r, &m1));
+                if (MP_DIGIT(r, FIRST_DIGIT) & 0x200) {
+                        MP_CHECKOK(s_mp_add_d(r,1));
+                        MP_DIGIT(r,FIRST_DIGIT) &=  0x1FF;
+                }
+                s_mp_clamp(r);
+        }
+
+  CLEANUP:
+        return res;
+}
+
+/* Compute the square of polynomial a, reduce modulo p521. Store the
+ * result in r.  r could be a.  Uses optimized modular reduction for p521.
+ */
+mp_err
+ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_sqr(a, r));
+        MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p521.
+ * Store the result in r.  r could be a or b; a could be b.  Uses
+ * optimized modular reduction for p521. */
+mp_err
+ec_GFp_nistp521_mul(const mp_int *a, const mp_int *b, mp_int *r,
+                                        const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        MP_CHECKOK(mp_mul(a, b, r));
+        MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
+  CLEANUP:
+        return res;
+}
+
+/* Divides two field elements. If a is NULL, then returns the inverse of
+ * b. */
+mp_err
+ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r,
+                   const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+        mp_int t;
+
+        /* If a is NULL, then return the inverse of b, otherwise return a/b. */
+        if (a == NULL) {
+                return mp_invmod(b, &meth->irr, r);
+        } else {
+                /* MPI doesn't support divmod, so we implement it using invmod and
+                 * mulmod. */
+                MP_CHECKOK(mp_init(&t, FLAG(b)));
+                MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
+                MP_CHECKOK(mp_mul(a, &t, r));
+                MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
+          CLEANUP:
+                mp_clear(&t);
+                return res;
+        }
+}
+
+/* Wire in fast field arithmetic and precomputation of base point for
+ * named curves. */
+mp_err
+ec_group_set_gfp521(ECGroup *group, ECCurveName name)
+{
+        if (name == ECCurve_NIST_P521) {
+                group->meth->field_mod = &ec_GFp_nistp521_mod;
+                group->meth->field_mul = &ec_GFp_nistp521_mul;
+                group->meth->field_sqr = &ec_GFp_nistp521_sqr;
+                group->meth->field_div = &ec_GFp_nistp521_div;
+        }
+        return MP_OKAY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_aff.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,379 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ *   Stephen Fung <fungstep@hotmail.com>, and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *   Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
+ *   Nils Larsch <nla@trustcenter.de>, and
+ *   Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "mplogic.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+/* Checks if point P(px, py) is at infinity.  Uses affine coordinates. */
+mp_err
+ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py)
+{
+
+        if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
+                return MP_YES;
+        } else {
+                return MP_NO;
+        }
+
+}
+
+/* Sets P(px, py) to be the point at infinity.  Uses affine coordinates. */
+mp_err
+ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py)
+{
+        mp_zero(px);
+        mp_zero(py);
+        return MP_OKAY;
+}
+
+/* Computes R = P + Q based on IEEE P1363 A.10.1. Elliptic curve points P,
+ * Q, and R can all be identical. Uses affine coordinates. Assumes input
+ * is already field-encoded using field_enc, and returns output that is
+ * still field-encoded. */
+mp_err
+ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+                                  const mp_int *qy, mp_int *rx, mp_int *ry,
+                                  const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int lambda, temp, tempx, tempy;
+
+        MP_DIGITS(&lambda) = 0;
+        MP_DIGITS(&temp) = 0;
+        MP_DIGITS(&tempx) = 0;
+        MP_DIGITS(&tempy) = 0;
+        MP_CHECKOK(mp_init(&lambda, FLAG(px)));
+        MP_CHECKOK(mp_init(&temp, FLAG(px)));
+        MP_CHECKOK(mp_init(&tempx, FLAG(px)));
+        MP_CHECKOK(mp_init(&tempy, FLAG(px)));
+        /* if P = inf, then R = Q */
+        if (ec_GFp_pt_is_inf_aff(px, py) == 0) {
+                MP_CHECKOK(mp_copy(qx, rx));
+                MP_CHECKOK(mp_copy(qy, ry));
+                res = MP_OKAY;
+                goto CLEANUP;
+        }
+        /* if Q = inf, then R = P */
+        if (ec_GFp_pt_is_inf_aff(qx, qy) == 0) {
+                MP_CHECKOK(mp_copy(px, rx));
+                MP_CHECKOK(mp_copy(py, ry));
+                res = MP_OKAY;
+                goto CLEANUP;
+        }
+        /* if px != qx, then lambda = (py-qy) / (px-qx) */
+        if (mp_cmp(px, qx) != 0) {
+                MP_CHECKOK(group->meth->field_sub(py, qy, &tempy, group->meth));
+                MP_CHECKOK(group->meth->field_sub(px, qx, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_div(&tempy, &tempx, &lambda, group->meth));
+        } else {
+                /* if py != qy or qy = 0, then R = inf */
+                if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
+                        mp_zero(rx);
+                        mp_zero(ry);
+                        res = MP_OKAY;
+                        goto CLEANUP;
+                }
+                /* lambda = (3qx^2+a) / (2qy) */
+                MP_CHECKOK(group->meth->field_sqr(qx, &tempx, group->meth));
+                MP_CHECKOK(mp_set_int(&temp, 3));
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
+                }
+                MP_CHECKOK(group->meth->
+                                   field_mul(&tempx, &temp, &tempx, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&tempx, &group->curvea, &tempx, group->meth));
+                MP_CHECKOK(mp_set_int(&temp, 2));
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
+                }
+                MP_CHECKOK(group->meth->field_mul(qy, &temp, &tempy, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_div(&tempx, &tempy, &lambda, group->meth));
+        }
+        /* rx = lambda^2 - px - qx */
+        MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
+        MP_CHECKOK(group->meth->field_sub(&tempx, px, &tempx, group->meth));
+        MP_CHECKOK(group->meth->field_sub(&tempx, qx, &tempx, group->meth));
+        /* ry = (x1-x2) * lambda - y1 */
+        MP_CHECKOK(group->meth->field_sub(qx, &tempx, &tempy, group->meth));
+        MP_CHECKOK(group->meth->
+                           field_mul(&tempy, &lambda, &tempy, group->meth));
+        MP_CHECKOK(group->meth->field_sub(&tempy, qy, &tempy, group->meth));
+        MP_CHECKOK(mp_copy(&tempx, rx));
+        MP_CHECKOK(mp_copy(&tempy, ry));
+
+  CLEANUP:
+        mp_clear(&lambda);
+        mp_clear(&temp);
+        mp_clear(&tempx);
+        mp_clear(&tempy);
+        return res;
+}
+
+/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
+ * identical. Uses affine coordinates. Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+                                  const mp_int *qy, mp_int *rx, mp_int *ry,
+                                  const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int nqy;
+
+        MP_DIGITS(&nqy) = 0;
+        MP_CHECKOK(mp_init(&nqy, FLAG(px)));
+        /* nqy = -qy */
+        MP_CHECKOK(group->meth->field_neg(qy, &nqy, group->meth));
+        res = group->point_add(px, py, qx, &nqy, rx, ry, group);
+  CLEANUP:
+        mp_clear(&nqy);
+        return res;
+}
+
+/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+ * affine coordinates. Assumes input is already field-encoded using
+ * field_enc, and returns output that is still field-encoded. */
+mp_err
+ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+                                  mp_int *ry, const ECGroup *group)
+{
+        return ec_GFp_pt_add_aff(px, py, px, py, rx, ry, group);
+}
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
+/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
+ * R can be identical. Uses affine coordinates. Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
+                                  mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int k, k3, qx, qy, sx, sy;
+        int b1, b3, i, l;
+
+        MP_DIGITS(&k) = 0;
+        MP_DIGITS(&k3) = 0;
+        MP_DIGITS(&qx) = 0;
+        MP_DIGITS(&qy) = 0;
+        MP_DIGITS(&sx) = 0;
+        MP_DIGITS(&sy) = 0;
+        MP_CHECKOK(mp_init(&k));
+        MP_CHECKOK(mp_init(&k3));
+        MP_CHECKOK(mp_init(&qx));
+        MP_CHECKOK(mp_init(&qy));
+        MP_CHECKOK(mp_init(&sx));
+        MP_CHECKOK(mp_init(&sy));
+
+        /* if n = 0 then r = inf */
+        if (mp_cmp_z(n) == 0) {
+                mp_zero(rx);
+                mp_zero(ry);
+                res = MP_OKAY;
+                goto CLEANUP;
+        }
+        /* Q = P, k = n */
+        MP_CHECKOK(mp_copy(px, &qx));
+        MP_CHECKOK(mp_copy(py, &qy));
+        MP_CHECKOK(mp_copy(n, &k));
+        /* if n < 0 then Q = -Q, k = -k */
+        if (mp_cmp_z(n) < 0) {
+                MP_CHECKOK(group->meth->field_neg(&qy, &qy, group->meth));
+                MP_CHECKOK(mp_neg(&k, &k));
+        }
+#ifdef ECL_DEBUG                                /* basic double and add method */
+        l = mpl_significant_bits(&k) - 1;
+        MP_CHECKOK(mp_copy(&qx, &sx));
+        MP_CHECKOK(mp_copy(&qy, &sy));
+        for (i = l - 1; i >= 0; i--) {
+                /* S = 2S */
+                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+                /* if k_i = 1, then S = S + Q */
+                if (mpl_get_bit(&k, i) != 0) {
+                        MP_CHECKOK(group->
+                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+                }
+        }
+#else                                                   /* double and add/subtract method from
+                                                                 * standard */
+        /* k3 = 3 * k */
+        MP_CHECKOK(mp_set_int(&k3, 3));
+        MP_CHECKOK(mp_mul(&k, &k3, &k3));
+        /* S = Q */
+        MP_CHECKOK(mp_copy(&qx, &sx));
+        MP_CHECKOK(mp_copy(&qy, &sy));
+        /* l = index of high order bit in binary representation of 3*k */
+        l = mpl_significant_bits(&k3) - 1;
+        /* for i = l-1 downto 1 */
+        for (i = l - 1; i >= 1; i--) {
+                /* S = 2S */
+                MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+                b3 = MP_GET_BIT(&k3, i);
+                b1 = MP_GET_BIT(&k, i);
+                /* if k3_i = 1 and k_i = 0, then S = S + Q */
+                if ((b3 == 1) && (b1 == 0)) {
+                        MP_CHECKOK(group->
+                                           point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+                        /* if k3_i = 0 and k_i = 1, then S = S - Q */
+                } else if ((b3 == 0) && (b1 == 1)) {
+                        MP_CHECKOK(group->
+                                           point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
+                }
+        }
+#endif
+        /* output S */
+        MP_CHECKOK(mp_copy(&sx, rx));
+        MP_CHECKOK(mp_copy(&sy, ry));
+
+  CLEANUP:
+        mp_clear(&k);
+        mp_clear(&k3);
+        mp_clear(&qx);
+        mp_clear(&qy);
+        mp_clear(&sx);
+        mp_clear(&sy);
+        return res;
+}
+#endif
+
+/* Validates a point on a GFp curve. */
+mp_err
+ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
+{
+        mp_err res = MP_NO;
+        mp_int accl, accr, tmp, pxt, pyt;
+
+        MP_DIGITS(&accl) = 0;
+        MP_DIGITS(&accr) = 0;
+        MP_DIGITS(&tmp) = 0;
+        MP_DIGITS(&pxt) = 0;
+        MP_DIGITS(&pyt) = 0;
+        MP_CHECKOK(mp_init(&accl, FLAG(px)));
+        MP_CHECKOK(mp_init(&accr, FLAG(px)));
+        MP_CHECKOK(mp_init(&tmp, FLAG(px)));
+        MP_CHECKOK(mp_init(&pxt, FLAG(px)));
+        MP_CHECKOK(mp_init(&pyt, FLAG(px)));
+
+    /* 1: Verify that publicValue is not the point at infinity */
+        if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+    /* 2: Verify that the coordinates of publicValue are elements
+     *    of the field.
+     */
+        if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
+                (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+    /* 3: Verify that publicValue is on the curve. */
+        if (group->meth->field_enc) {
+                group->meth->field_enc(px, &pxt, group->meth);
+                group->meth->field_enc(py, &pyt, group->meth);
+        } else {
+                mp_copy(px, &pxt);
+                mp_copy(py, &pyt);
+        }
+        /* left-hand side: y^2  */
+        MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
+        /* right-hand side: x^3 + a*x + b */
+        MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
+        MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
+        MP_CHECKOK( group->meth->field_mul(&group->curvea, &pxt, &tmp, group->meth) );
+        MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
+        MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
+        /* check LHS - RHS == 0 */
+        MP_CHECKOK( group->meth->field_sub(&accl, &accr, &accr, group->meth) );
+        if (mp_cmp_z(&accr) != 0) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+    /* 4: Verify that the order of the curve times the publicValue
+     *    is the point at infinity.
+     */
+        MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
+        if (ec_GFp_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
+                res = MP_NO;
+                goto CLEANUP;
+        }
+
+        res = MP_YES;
+
+CLEANUP:
+        mp_clear(&accl);
+        mp_clear(&accr);
+        mp_clear(&tmp);
+        mp_clear(&pxt);
+        mp_clear(&pyt);
+        return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_jac.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,575 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ *   Stephen Fung <fungstep@hotmail.com>, and
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *   Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
+ *   Nils Larsch <nla@trustcenter.de>, and
+ *   Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "mplogic.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+#ifdef ECL_DEBUG
+#include <assert.h>
+#endif
+
+/* Converts a point P(px, py) from affine coordinates to Jacobian
+ * projective coordinates R(rx, ry, rz). Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
+                                  mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+
+        if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
+                MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
+        } else {
+                MP_CHECKOK(mp_copy(px, rx));
+                MP_CHECKOK(mp_copy(py, ry));
+                MP_CHECKOK(mp_set_int(rz, 1));
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
+                }
+        }
+  CLEANUP:
+        return res;
+}
+
+/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
+ * affine coordinates R(rx, ry).  P and R can share x and y coordinates.
+ * Assumes input is already field-encoded using field_enc, and returns
+ * output that is still field-encoded. */
+mp_err
+ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
+                                  mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int z1, z2, z3;
+
+        MP_DIGITS(&z1) = 0;
+        MP_DIGITS(&z2) = 0;
+        MP_DIGITS(&z3) = 0;
+        MP_CHECKOK(mp_init(&z1, FLAG(px)));
+        MP_CHECKOK(mp_init(&z2, FLAG(px)));
+        MP_CHECKOK(mp_init(&z3, FLAG(px)));
+
+        /* if point at infinity, then set point at infinity and exit */
+        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+                MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
+                goto CLEANUP;
+        }
+
+        /* transform (px, py, pz) into (px / pz^2, py / pz^3) */
+        if (mp_cmp_d(pz, 1) == 0) {
+                MP_CHECKOK(mp_copy(px, rx));
+                MP_CHECKOK(mp_copy(py, ry));
+        } else {
+                MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
+                MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
+                MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
+                MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
+                MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
+        }
+
+  CLEANUP:
+        mp_clear(&z1);
+        mp_clear(&z2);
+        mp_clear(&z3);
+        return res;
+}
+
+/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
+ * coordinates. */
+mp_err
+ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
+{
+        return mp_cmp_z(pz);
+}
+
+/* Sets P(px, py, pz) to be the point at infinity.  Uses Jacobian
+ * coordinates. */
+mp_err
+ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
+{
+        mp_zero(pz);
+        return MP_OKAY;
+}
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, 1).  Elliptic curve points P, Q, and R can all be identical.
+ * Uses mixed Jacobian-affine coordinates. Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. Uses equation (2) from Brown, Hankerson, Lopez, and
+ * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
+ * Fields. */
+mp_err
+ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
+                                          const mp_int *qx, const mp_int *qy, mp_int *rx,
+                                          mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int A, B, C, D, C2, C3;
+
+        MP_DIGITS(&A) = 0;
+        MP_DIGITS(&B) = 0;
+        MP_DIGITS(&C) = 0;
+        MP_DIGITS(&D) = 0;
+        MP_DIGITS(&C2) = 0;
+        MP_DIGITS(&C3) = 0;
+        MP_CHECKOK(mp_init(&A, FLAG(px)));
+        MP_CHECKOK(mp_init(&B, FLAG(px)));
+        MP_CHECKOK(mp_init(&C, FLAG(px)));
+        MP_CHECKOK(mp_init(&D, FLAG(px)));
+        MP_CHECKOK(mp_init(&C2, FLAG(px)));
+        MP_CHECKOK(mp_init(&C3, FLAG(px)));
+
+        /* If either P or Q is the point at infinity, then return the other
+         * point */
+        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+                MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
+                goto CLEANUP;
+        }
+        if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
+                MP_CHECKOK(mp_copy(px, rx));
+                MP_CHECKOK(mp_copy(py, ry));
+                MP_CHECKOK(mp_copy(pz, rz));
+                goto CLEANUP;
+        }
+
+        /* A = qx * pz^2, B = qy * pz^3 */
+        MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
+
+        /* C = A - px, D = B - py */
+        MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
+        MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
+
+        /* C2 = C^2, C3 = C^3 */
+        MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
+
+        /* rz = pz * C */
+        MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
+
+        /* C = px * C^2 */
+        MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
+        /* A = D^2 */
+        MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));
+
+        /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
+        MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
+        MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
+        MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));
+
+        /* C3 = py * C^3 */
+        MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));
+
+        /* ry = D * (px * C^2 - rx) - py * C^3 */
+        MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
+        MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));
+
+  CLEANUP:
+        mp_clear(&A);
+        mp_clear(&B);
+        mp_clear(&C);
+        mp_clear(&D);
+        mp_clear(&C2);
+        mp_clear(&C3);
+        return res;
+}
+
+/* Computes R = 2P.  Elliptic curve points P and R can be identical.  Uses
+ * Jacobian coordinates.
+ *
+ * Assumes input is already field-encoded using field_enc, and returns
+ * output that is still field-encoded.
+ *
+ * This routine implements Point Doubling in the Jacobian Projective
+ * space as described in the paper "Efficient elliptic curve exponentiation
+ * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
+ */
+mp_err
+ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
+                                  mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int t0, t1, M, S;
+
+        MP_DIGITS(&t0) = 0;
+        MP_DIGITS(&t1) = 0;
+        MP_DIGITS(&M) = 0;
+        MP_DIGITS(&S) = 0;
+        MP_CHECKOK(mp_init(&t0, FLAG(px)));
+        MP_CHECKOK(mp_init(&t1, FLAG(px)));
+        MP_CHECKOK(mp_init(&M, FLAG(px)));
+        MP_CHECKOK(mp_init(&S, FLAG(px)));
+
+        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+                MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
+                goto CLEANUP;
+        }
+
+        if (mp_cmp_d(pz, 1) == 0) {
+                /* M = 3 * px^2 + a */
+                MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
+                MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
+                MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_add(&t0, &group->curvea, &M, group->meth));
+        } else if (mp_cmp_int(&group->curvea, -3, FLAG(px)) == 0) {
+                /* M = 3 * (px + pz^2) * (px - pz^2) */
+                MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
+                MP_CHECKOK(group->meth->field_add(px, &M, &t0, group->meth));
+                MP_CHECKOK(group->meth->field_sub(px, &M, &t1, group->meth));
+                MP_CHECKOK(group->meth->field_mul(&t0, &t1, &M, group->meth));
+                MP_CHECKOK(group->meth->field_add(&M, &M, &t0, group->meth));
+                MP_CHECKOK(group->meth->field_add(&t0, &M, &M, group->meth));
+        } else {
+                /* M = 3 * (px^2) + a * (pz^4) */
+                MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
+                MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
+                MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
+                MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
+                MP_CHECKOK(group->meth->field_sqr(&M, &M, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_mul(&M, &group->curvea, &M, group->meth));
+                MP_CHECKOK(group->meth->field_add(&M, &t0, &M, group->meth));
+        }
+
+        /* rz = 2 * py * pz */
+        /* t0 = 4 * py^2 */
+        if (mp_cmp_d(pz, 1) == 0) {
+                MP_CHECKOK(group->meth->field_add(py, py, rz, group->meth));
+                MP_CHECKOK(group->meth->field_sqr(rz, &t0, group->meth));
+        } else {
+                MP_CHECKOK(group->meth->field_add(py, py, &t0, group->meth));
+                MP_CHECKOK(group->meth->field_mul(&t0, pz, rz, group->meth));
+                MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
+        }
+
+        /* S = 4 * px * py^2 = px * (2 * py)^2 */
+        MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));
+
+        /* rx = M^2 - 2 * S */
+        MP_CHECKOK(group->meth->field_add(&S, &S, &t1, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
+        MP_CHECKOK(group->meth->field_sub(rx, &t1, rx, group->meth));
+
+        /* ry = M * (S - rx) - 8 * py^4 */
+        MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
+        if (mp_isodd(&t1)) {
+                MP_CHECKOK(mp_add(&t1, &group->meth->irr, &t1));
+        }
+        MP_CHECKOK(mp_div_2(&t1, &t1));
+        MP_CHECKOK(group->meth->field_sub(&S, rx, &S, group->meth));
+        MP_CHECKOK(group->meth->field_mul(&M, &S, &M, group->meth));
+        MP_CHECKOK(group->meth->field_sub(&M, &t1, ry, group->meth));
+
+  CLEANUP:
+        mp_clear(&t0);
+        mp_clear(&t1);
+        mp_clear(&M);
+        mp_clear(&S);
+        return res;
+}
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp.  Elliptic curve points P and R can be
+ * identical.  Uses mixed Jacobian-affine coordinates. Assumes input is
+ * already field-encoded using field_enc, and returns output that is still
+ * field-encoded. Uses 4-bit window method. */
+mp_err
+ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
+                                  mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int precomp[16][2], rz;
+        int i, ni, d;
+
+        MP_DIGITS(&rz) = 0;
+        for (i = 0; i < 16; i++) {
+                MP_DIGITS(&precomp[i][0]) = 0;
+                MP_DIGITS(&precomp[i][1]) = 0;
+        }
+
+        ARGCHK(group != NULL, MP_BADARG);
+        ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
+
+        /* initialize precomputation table */
+        for (i = 0; i < 16; i++) {
+                MP_CHECKOK(mp_init(&precomp[i][0]));
+                MP_CHECKOK(mp_init(&precomp[i][1]));
+        }
+
+        /* fill precomputation table */
+        mp_zero(&precomp[0][0]);
+        mp_zero(&precomp[0][1]);
+        MP_CHECKOK(mp_copy(px, &precomp[1][0]));
+        MP_CHECKOK(mp_copy(py, &precomp[1][1]));
+        for (i = 2; i < 16; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[1][0], &precomp[1][1],
+                                                         &precomp[i - 1][0], &precomp[i - 1][1],
+                                                         &precomp[i][0], &precomp[i][1], group));
+        }
+
+        d = (mpl_significant_bits(n) + 3) / 4;
+
+        /* R = inf */
+        MP_CHECKOK(mp_init(&rz));
+        MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
+
+        for (i = d - 1; i >= 0; i--) {
+                /* compute window ni */
+                ni = MP_GET_BIT(n, 4 * i + 3);
+                ni <<= 1;
+                ni |= MP_GET_BIT(n, 4 * i + 2);
+                ni <<= 1;
+                ni |= MP_GET_BIT(n, 4 * i + 1);
+                ni <<= 1;
+                ni |= MP_GET_BIT(n, 4 * i);
+                /* R = 2^4 * R */
+                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+                /* R = R + (ni * P) */
+                MP_CHECKOK(ec_GFp_pt_add_jac_aff
+                                   (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
+                                        &rz, group));
+        }
+
+        /* convert result S to affine coordinates */
+        MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
+
+  CLEANUP:
+        mp_clear(&rz);
+        for (i = 0; i < 16; i++) {
+                mp_clear(&precomp[i][0]);
+                mp_clear(&precomp[i][1]);
+        }
+        return res;
+}
+#endif
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Uses mixed Jacobian-affine coordinates. Input and output values are
+ * assumed to be NOT field-encoded. Uses algorithm 15 (simultaneous
+ * multiple point multiplication) from Brown, Hankerson, Lopez, Menezes.
+ * Software Implementation of the NIST Elliptic Curves over Prime Fields. */
+mp_err
+ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
+                                   const mp_int *py, mp_int *rx, mp_int *ry,
+                                   const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int precomp[4][4][2];
+        mp_int rz;
+        const mp_int *a, *b;
+        int i, j;
+        int ai, bi, d;
+
+        for (i = 0; i < 4; i++) {
+                for (j = 0; j < 4; j++) {
+                        MP_DIGITS(&precomp[i][j][0]) = 0;
+                        MP_DIGITS(&precomp[i][j][1]) = 0;
+                }
+        }
+        MP_DIGITS(&rz) = 0;
+
+        ARGCHK(group != NULL, MP_BADARG);
+        ARGCHK(!((k1 == NULL)
+                         && ((k2 == NULL) || (px == NULL)
+                                 || (py == NULL))), MP_BADARG);
+
+        /* if some arguments are not defined used ECPoint_mul */
+        if (k1 == NULL) {
+                return ECPoint_mul(group, k2, px, py, rx, ry);
+        } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
+                return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
+        }
+
+        /* initialize precomputation table */
+        for (i = 0; i < 4; i++) {
+                for (j = 0; j < 4; j++) {
+                        MP_CHECKOK(mp_init(&precomp[i][j][0], FLAG(k1)));
+                        MP_CHECKOK(mp_init(&precomp[i][j][1], FLAG(k1)));
+                }
+        }
+
+        /* fill precomputation table */
+        /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
+        if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
+                a = k2;
+                b = k1;
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->
+                                           field_enc(px, &precomp[1][0][0], group->meth));
+                        MP_CHECKOK(group->meth->
+                                           field_enc(py, &precomp[1][0][1], group->meth));
+                } else {
+                        MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
+                        MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
+                }
+                MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
+                MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
+        } else {
+                a = k1;
+                b = k2;
+                MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
+                MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
+                if (group->meth->field_enc) {
+                        MP_CHECKOK(group->meth->
+                                           field_enc(px, &precomp[0][1][0], group->meth));
+                        MP_CHECKOK(group->meth->
+                                           field_enc(py, &precomp[0][1][1], group->meth));
+                } else {
+                        MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
+                        MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
+                }
+        }
+        /* precompute [*][0][*] */
+        mp_zero(&precomp[0][0][0]);
+        mp_zero(&precomp[0][0][1]);
+        MP_CHECKOK(group->
+                           point_dbl(&precomp[1][0][0], &precomp[1][0][1],
+                                                 &precomp[2][0][0], &precomp[2][0][1], group));
+        MP_CHECKOK(group->
+                           point_add(&precomp[1][0][0], &precomp[1][0][1],
+                                                 &precomp[2][0][0], &precomp[2][0][1],
+                                                 &precomp[3][0][0], &precomp[3][0][1], group));
+        /* precompute [*][1][*] */
+        for (i = 1; i < 4; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[0][1][0], &precomp[0][1][1],
+                                                         &precomp[i][0][0], &precomp[i][0][1],
+                                                         &precomp[i][1][0], &precomp[i][1][1], group));
+        }
+        /* precompute [*][2][*] */
+        MP_CHECKOK(group->
+                           point_dbl(&precomp[0][1][0], &precomp[0][1][1],
+                                                 &precomp[0][2][0], &precomp[0][2][1], group));
+        for (i = 1; i < 4; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[0][2][0], &precomp[0][2][1],
+                                                         &precomp[i][0][0], &precomp[i][0][1],
+                                                         &precomp[i][2][0], &precomp[i][2][1], group));
+        }
+        /* precompute [*][3][*] */
+        MP_CHECKOK(group->
+                           point_add(&precomp[0][1][0], &precomp[0][1][1],
+                                                 &precomp[0][2][0], &precomp[0][2][1],
+                                                 &precomp[0][3][0], &precomp[0][3][1], group));
+        for (i = 1; i < 4; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[0][3][0], &precomp[0][3][1],
+                                                         &precomp[i][0][0], &precomp[i][0][1],
+                                                         &precomp[i][3][0], &precomp[i][3][1], group));
+        }
+
+        d = (mpl_significant_bits(a) + 1) / 2;
+
+        /* R = inf */
+        MP_CHECKOK(mp_init(&rz, FLAG(k1)));
+        MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
+
+        for (i = d - 1; i >= 0; i--) {
+                ai = MP_GET_BIT(a, 2 * i + 1);
+                ai <<= 1;
+                ai |= MP_GET_BIT(a, 2 * i);
+                bi = MP_GET_BIT(b, 2 * i + 1);
+                bi <<= 1;
+                bi |= MP_GET_BIT(b, 2 * i);
+                /* R = 2^2 * R */
+                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+                MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+                /* R = R + (ai * A + bi * B) */
+                MP_CHECKOK(ec_GFp_pt_add_jac_aff
+                                   (rx, ry, &rz, &precomp[ai][bi][0], &precomp[ai][bi][1],
+                                        rx, ry, &rz, group));
+        }
+
+        MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
+
+        if (group->meth->field_dec) {
+                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+        }
+
+  CLEANUP:
+        mp_clear(&rz);
+        for (i = 0; i < 4; i++) {
+                for (j = 0; j < 4; j++) {
+                        mp_clear(&precomp[i][j][0]);
+                        mp_clear(&precomp[i][j][1]);
+                }
+        }
+        return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_jm.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,353 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library for prime field curves.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "ecp.h"
+#include "ecl-priv.h"
+#include "mplogic.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+#define MAX_SCRATCH 6
+
+/* Computes R = 2P.  Elliptic curve points P and R can be identical.  Uses
+ * Modified Jacobian coordinates.
+ *
+ * Assumes input is already field-encoded using field_enc, and returns
+ * output that is still field-encoded.
+ *
+ */
+mp_err
+ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
+                                 const mp_int *paz4, mp_int *rx, mp_int *ry, mp_int *rz,
+                                 mp_int *raz4, mp_int scratch[], const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int *t0, *t1, *M, *S;
+
+        t0 = &scratch[0];
+        t1 = &scratch[1];
+        M = &scratch[2];
+        S = &scratch[3];
+
+#if MAX_SCRATCH < 4
+#error "Scratch array defined too small "
+#endif
+
+        /* Check for point at infinity */
+        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+                /* Set r = pt at infinity by setting rz = 0 */
+
+                MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
+                goto CLEANUP;
+        }
+
+        /* M = 3 (px^2) + a*(pz^4) */
+        MP_CHECKOK(group->meth->field_sqr(px, t0, group->meth));
+        MP_CHECKOK(group->meth->field_add(t0, t0, M, group->meth));
+        MP_CHECKOK(group->meth->field_add(t0, M, t0, group->meth));
+        MP_CHECKOK(group->meth->field_add(t0, paz4, M, group->meth));
+
+        /* rz = 2 * py * pz */
+        MP_CHECKOK(group->meth->field_mul(py, pz, S, group->meth));
+        MP_CHECKOK(group->meth->field_add(S, S, rz, group->meth));
+
+        /* t0 = 2y^2 , t1 = 8y^4 */
+        MP_CHECKOK(group->meth->field_sqr(py, t0, group->meth));
+        MP_CHECKOK(group->meth->field_add(t0, t0, t0, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(t0, t1, group->meth));
+        MP_CHECKOK(group->meth->field_add(t1, t1, t1, group->meth));
+
+        /* S = 4 * px * py^2 = 2 * px * t0 */
+        MP_CHECKOK(group->meth->field_mul(px, t0, S, group->meth));
+        MP_CHECKOK(group->meth->field_add(S, S, S, group->meth));
+
+
+        /* rx = M^2 - 2S */
+        MP_CHECKOK(group->meth->field_sqr(M, rx, group->meth));
+        MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
+        MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
+
+        /* ry = M * (S - rx) - t1 */
+        MP_CHECKOK(group->meth->field_sub(S, rx, S, group->meth));
+        MP_CHECKOK(group->meth->field_mul(S, M, ry, group->meth));
+        MP_CHECKOK(group->meth->field_sub(ry, t1, ry, group->meth));
+
+        /* ra*z^4 = 2*t1*(apz4) */
+        MP_CHECKOK(group->meth->field_mul(paz4, t1, raz4, group->meth));
+        MP_CHECKOK(group->meth->field_add(raz4, raz4, raz4, group->meth));
+
+
+  CLEANUP:
+        return res;
+}
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, 1).  Elliptic curve points P, Q, and R can all be identical.
+ * Uses mixed Modified_Jacobian-affine coordinates. Assumes input is
+ * already field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
+                                         const mp_int *paz4, const mp_int *qx,
+                                         const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz,
+                                         mp_int *raz4, mp_int scratch[], const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int *A, *B, *C, *D, *C2, *C3;
+
+        A = &scratch[0];
+        B = &scratch[1];
+        C = &scratch[2];
+        D = &scratch[3];
+        C2 = &scratch[4];
+        C3 = &scratch[5];
+
+#if MAX_SCRATCH < 6
+#error "Scratch array defined too small "
+#endif
+
+        /* If either P or Q is the point at infinity, then return the other
+         * point */
+        if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+                MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
+                MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
+                MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
+                MP_CHECKOK(group->meth->
+                                   field_mul(raz4, &group->curvea, raz4, group->meth));
+                goto CLEANUP;
+        }
+        if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
+                MP_CHECKOK(mp_copy(px, rx));
+                MP_CHECKOK(mp_copy(py, ry));
+                MP_CHECKOK(mp_copy(pz, rz));
+                MP_CHECKOK(mp_copy(paz4, raz4));
+                goto CLEANUP;
+        }
+
+        /* A = qx * pz^2, B = qy * pz^3 */
+        MP_CHECKOK(group->meth->field_sqr(pz, A, group->meth));
+        MP_CHECKOK(group->meth->field_mul(A, pz, B, group->meth));
+        MP_CHECKOK(group->meth->field_mul(A, qx, A, group->meth));
+        MP_CHECKOK(group->meth->field_mul(B, qy, B, group->meth));
+
+        /* C = A - px, D = B - py */
+        MP_CHECKOK(group->meth->field_sub(A, px, C, group->meth));
+        MP_CHECKOK(group->meth->field_sub(B, py, D, group->meth));
+
+        /* C2 = C^2, C3 = C^3 */
+        MP_CHECKOK(group->meth->field_sqr(C, C2, group->meth));
+        MP_CHECKOK(group->meth->field_mul(C, C2, C3, group->meth));
+
+        /* rz = pz * C */
+        MP_CHECKOK(group->meth->field_mul(pz, C, rz, group->meth));
+
+        /* C = px * C^2 */
+        MP_CHECKOK(group->meth->field_mul(px, C2, C, group->meth));
+        /* A = D^2 */
+        MP_CHECKOK(group->meth->field_sqr(D, A, group->meth));
+
+        /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
+        MP_CHECKOK(group->meth->field_add(C, C, rx, group->meth));
+        MP_CHECKOK(group->meth->field_add(C3, rx, rx, group->meth));
+        MP_CHECKOK(group->meth->field_sub(A, rx, rx, group->meth));
+
+        /* C3 = py * C^3 */
+        MP_CHECKOK(group->meth->field_mul(py, C3, C3, group->meth));
+
+        /* ry = D * (px * C^2 - rx) - py * C^3 */
+        MP_CHECKOK(group->meth->field_sub(C, rx, ry, group->meth));
+        MP_CHECKOK(group->meth->field_mul(D, ry, ry, group->meth));
+        MP_CHECKOK(group->meth->field_sub(ry, C3, ry, group->meth));
+
+        /* raz4 = a * rz^4 */
+        MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
+        MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
+        MP_CHECKOK(group->meth->
+                           field_mul(raz4, &group->curvea, raz4, group->meth));
+CLEANUP:
+        return res;
+}
+
+/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
+ * curve points P and R can be identical. Uses mixed Modified-Jacobian
+ * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
+ * additions. Assumes input is already field-encoded using field_enc, and
+ * returns output that is still field-encoded. Uses 5-bit window NAF
+ * method (algorithm 11) for scalar-point multiplication from Brown,
+ * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
+ * Curves Over Prime Fields. */
+mp_err
+ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
+                                          mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+        mp_err res = MP_OKAY;
+        mp_int precomp[16][2], rz, tpx, tpy;
+        mp_int raz4;
+        mp_int scratch[MAX_SCRATCH];
+        signed char *naf = NULL;
+        int i, orderBitSize;
+
+        MP_DIGITS(&rz) = 0;
+        MP_DIGITS(&raz4) = 0;
+        MP_DIGITS(&tpx) = 0;
+        MP_DIGITS(&tpy) = 0;
+        for (i = 0; i < 16; i++) {
+                MP_DIGITS(&precomp[i][0]) = 0;
+                MP_DIGITS(&precomp[i][1]) = 0;
+        }
+        for (i = 0; i < MAX_SCRATCH; i++) {
+                MP_DIGITS(&scratch[i]) = 0;
+        }
+
+        ARGCHK(group != NULL, MP_BADARG);
+        ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
+
+        /* initialize precomputation table */
+        MP_CHECKOK(mp_init(&tpx, FLAG(n)));
+        MP_CHECKOK(mp_init(&tpy, FLAG(n)));;
+        MP_CHECKOK(mp_init(&rz, FLAG(n)));
+        MP_CHECKOK(mp_init(&raz4, FLAG(n)));
+
+        for (i = 0; i < 16; i++) {
+                MP_CHECKOK(mp_init(&precomp[i][0], FLAG(n)));
+                MP_CHECKOK(mp_init(&precomp[i][1], FLAG(n)));
+        }
+        for (i = 0; i < MAX_SCRATCH; i++) {
+                MP_CHECKOK(mp_init(&scratch[i], FLAG(n)));
+        }
+
+        /* Set out[8] = P */
+        MP_CHECKOK(mp_copy(px, &precomp[8][0]));
+        MP_CHECKOK(mp_copy(py, &precomp[8][1]));
+
+        /* Set (tpx, tpy) = 2P */
+        MP_CHECKOK(group->
+                           point_dbl(&precomp[8][0], &precomp[8][1], &tpx, &tpy,
+                                                 group));
+
+        /* Set 3P, 5P, ..., 15P */
+        for (i = 8; i < 15; i++) {
+                MP_CHECKOK(group->
+                                   point_add(&precomp[i][0], &precomp[i][1], &tpx, &tpy,
+                                                         &precomp[i + 1][0], &precomp[i + 1][1],
+                                                         group));
+        }
+
+        /* Set -15P, -13P, ..., -P */
+        for (i = 0; i < 8; i++) {
+                MP_CHECKOK(mp_copy(&precomp[15 - i][0], &precomp[i][0]));
+                MP_CHECKOK(group->meth->
+                                   field_neg(&precomp[15 - i][1], &precomp[i][1],
+                                                         group->meth));
+        }
+
+        /* R = inf */
+        MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
+
+        orderBitSize = mpl_significant_bits(&group->order);
+
+        /* Allocate memory for NAF */
+#ifdef _KERNEL
+        naf = (signed char *) kmem_alloc((orderBitSize + 1), FLAG(n));
+#else
+        naf = (signed char *) malloc(sizeof(signed char) * (orderBitSize + 1));
+        if (naf == NULL) {
+                res = MP_MEM;
+                goto CLEANUP;
+        }
+#endif
+
+        /* Compute 5NAF */
+        ec_compute_wNAF(naf, orderBitSize, n, 5);
+
+        /* wNAF method */
+        for (i = orderBitSize; i >= 0; i--) {
+                /* R = 2R */
+                ec_GFp_pt_dbl_jm(rx, ry, &rz, &raz4, rx, ry, &rz,
+                                             &raz4, scratch, group);
+                if (naf[i] != 0) {
+                        ec_GFp_pt_add_jm_aff(rx, ry, &rz, &raz4,
+                                                                 &precomp[(naf[i] + 15) / 2][0],
+                                                                 &precomp[(naf[i] + 15) / 2][1], rx, ry,
+                                                                 &rz, &raz4, scratch, group);
+                }
+        }
+
+        /* convert result S to affine coordinates */
+        MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
+
+  CLEANUP:
+        for (i = 0; i < MAX_SCRATCH; i++) {
+                mp_clear(&scratch[i]);
+        }
+        for (i = 0; i < 16; i++) {
+                mp_clear(&precomp[i][0]);
+                mp_clear(&precomp[i][1]);
+        }
+        mp_clear(&tpx);
+        mp_clear(&tpy);
+        mp_clear(&rz);
+        mp_clear(&raz4);
+#ifdef _KERNEL
+        kmem_free(naf, (orderBitSize + 1));
+#else
+        free(naf);
+#endif
+        return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/ecp_mont.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,223 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* Uses Montgomery reduction for field arithmetic.  See mpi/mpmontg.c for
+ * code implementation. */
+
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#include "ecl-priv.h"
+#include "ecp.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#include <stdio.h>
+#endif
+
+/* Construct a generic GFMethod for arithmetic over prime fields with
+ * irreducible irr. */
+GFMethod *
+GFMethod_consGFp_mont(const mp_int *irr)
+{
+        mp_err res = MP_OKAY;
+        int i;
+        GFMethod *meth = NULL;
+        mp_mont_modulus *mmm;
+
+        meth = GFMethod_consGFp(irr);
+        if (meth == NULL)
+                return NULL;
+
+#ifdef _KERNEL
+        mmm = (mp_mont_modulus *) kmem_alloc(sizeof(mp_mont_modulus),
+            FLAG(irr));
+#else
+        mmm = (mp_mont_modulus *) malloc(sizeof(mp_mont_modulus));
+#endif
+        if (mmm == NULL) {
+                res = MP_MEM;
+                goto CLEANUP;
+        }
+
+        meth->field_mul = &ec_GFp_mul_mont;
+        meth->field_sqr = &ec_GFp_sqr_mont;
+        meth->field_div = &ec_GFp_div_mont;
+        meth->field_enc = &ec_GFp_enc_mont;
+        meth->field_dec = &ec_GFp_dec_mont;
+        meth->extra1 = mmm;
+        meth->extra2 = NULL;
+        meth->extra_free = &ec_GFp_extra_free_mont;
+
+        mmm->N = meth->irr;
+        i = mpl_significant_bits(&meth->irr);
+        i += MP_DIGIT_BIT - 1;
+        mmm->b = i - i % MP_DIGIT_BIT;
+        mmm->n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(&meth->irr, 0));
+
+  CLEANUP:
+        if (res != MP_OKAY) {
+                GFMethod_free(meth);
+                return NULL;
+        }
+        return meth;
+}
+
+/* Wrapper functions for generic prime field arithmetic. */
+
+/* Field multiplication using Montgomery reduction. */
+mp_err
+ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
+                                const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+#ifdef MP_MONT_USE_MP_MUL
+        /* if MP_MONT_USE_MP_MUL is defined, then the function s_mp_mul_mont
+         * is not implemented and we have to use mp_mul and s_mp_redc directly
+         */
+        MP_CHECKOK(mp_mul(a, b, r));
+        MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
+#else
+        mp_int s;
+
+        MP_DIGITS(&s) = 0;
+        /* s_mp_mul_mont doesn't allow source and destination to be the same */
+        if ((a == r) || (b == r)) {
+                MP_CHECKOK(mp_init(&s, FLAG(a)));
+                MP_CHECKOK(s_mp_mul_mont
+                                   (a, b, &s, (mp_mont_modulus *) meth->extra1));
+                MP_CHECKOK(mp_copy(&s, r));
+                mp_clear(&s);
+        } else {
+                return s_mp_mul_mont(a, b, r, (mp_mont_modulus *) meth->extra1);
+        }
+#endif
+  CLEANUP:
+        return res;
+}
+
+/* Field squaring using Montgomery reduction. */
+mp_err
+ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        return ec_GFp_mul_mont(a, a, r, meth);
+}
+
+/* Field division using Montgomery reduction. */
+mp_err
+ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
+                                const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        /* if A=aZ represents a encoded in montgomery coordinates with Z and #
+         * and \ respectively represent multiplication and division in
+         * montgomery coordinates, then A\B = (a/b)Z = (A/B)Z and Binv =
+         * (1/b)Z = (1/B)(Z^2) where B # Binv = Z */
+        MP_CHECKOK(ec_GFp_div(a, b, r, meth));
+        MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
+        if (a == NULL) {
+                MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
+        }
+  CLEANUP:
+        return res;
+}
+
+/* Encode a field element in Montgomery form. See s_mp_to_mont in
+ * mpi/mpmontg.c */
+mp_err
+ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_mont_modulus *mmm;
+        mp_err res = MP_OKAY;
+
+        mmm = (mp_mont_modulus *) meth->extra1;
+        MP_CHECKOK(mpl_lsh(a, r, mmm->b));
+        MP_CHECKOK(mp_mod(r, &mmm->N, r));
+  CLEANUP:
+        return res;
+}
+
+/* Decode a field element from Montgomery form. */
+mp_err
+ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+        mp_err res = MP_OKAY;
+
+        if (a != r) {
+                MP_CHECKOK(mp_copy(a, r));
+        }
+        MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
+  CLEANUP:
+        return res;
+}
+
+/* Free the memory allocated to the extra fields of Montgomery GFMethod
+ * object. */
+void
+ec_GFp_extra_free_mont(GFMethod *meth)
+{
+        if (meth->extra1 != NULL) {
+#ifdef _KERNEL
+                kmem_free(meth->extra1, sizeof(mp_mont_modulus));
+#else
+                free(meth->extra1);
+#endif
+                meth->extra1 = NULL;
+        }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/logtab.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,82 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LOGTAB_H
+#define _LOGTAB_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+const float s_logv_2[] = {
+   0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f,  /*  0  1  2  3 */
+   0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f,  /*  4  5  6  7 */
+   0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f,  /*  8  9 10 11 */
+   0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f,  /* 12 13 14 15 */
+   0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f,  /* 16 17 18 19 */
+   0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f,  /* 20 21 22 23 */
+   0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f,  /* 24 25 26 27 */
+   0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f,  /* 28 29 30 31 */
+   0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f,  /* 32 33 34 35 */
+   0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f,  /* 36 37 38 39 */
+   0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f,  /* 40 41 42 43 */
+   0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f,  /* 44 45 46 47 */
+   0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f,  /* 48 49 50 51 */
+   0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f,  /* 52 53 54 55 */
+   0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f,  /* 56 57 58 59 */
+   0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f,  /* 60 61 62 63 */
+   0.166666667f
+};
+
+#endif /* _LOGTAB_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m-priv.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,122 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang Shantz <sheueling.chang@sun.com> and
+ *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MP_GF2M_PRIV_H_
+#define _MP_GF2M_PRIV_H_
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mpi-priv.h"
+
+extern const mp_digit mp_gf2m_sqr_tb[16];
+
+#if defined(MP_USE_UINT_DIGIT)
+#define MP_DIGIT_BITS 32
+#else
+#define MP_DIGIT_BITS 64
+#endif
+
+/* Platform-specific macros for fast binary polynomial squaring. */
+#if MP_DIGIT_BITS == 32
+#define gf2m_SQR1(w) \
+    mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 16 | \
+    mp_gf2m_sqr_tb[(w) >> 20 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF]
+#define gf2m_SQR0(w) \
+    mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >>  8 & 0xF] << 16 | \
+    mp_gf2m_sqr_tb[(w) >>  4 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w)       & 0xF]
+#else
+#define gf2m_SQR1(w) \
+    mp_gf2m_sqr_tb[(w) >> 60 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 56 & 0xF] << 48 | \
+    mp_gf2m_sqr_tb[(w) >> 52 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 48 & 0xF] << 32 | \
+    mp_gf2m_sqr_tb[(w) >> 44 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 40 & 0xF] << 16 | \
+    mp_gf2m_sqr_tb[(w) >> 36 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w) >> 32 & 0xF]
+#define gf2m_SQR0(w) \
+    mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 48 | \
+    mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] << 32 | \
+    mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >>  8 & 0xF] << 16 | \
+    mp_gf2m_sqr_tb[(w) >>  4 & 0xF] <<  8 | mp_gf2m_sqr_tb[(w)       & 0xF]
+#endif
+
+/* Multiply two binary polynomials mp_digits a, b.
+ * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
+ * Output in two mp_digits rh, rl.
+ */
+void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b);
+
+/* Compute xor-multiply of two binary polynomials  (a1, a0) x (b1, b0)
+ * result is a binary polynomial in 4 mp_digits r[4].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
+        const mp_digit b0);
+
+/* Compute xor-multiply of two binary polynomials  (a2, a1, a0) x (b2, b1, b0)
+ * result is a binary polynomial in 6 mp_digits r[6].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
+        const mp_digit b2, const mp_digit b1, const mp_digit b0);
+
+/* Compute xor-multiply of two binary polynomials  (a3, a2, a1, a0) x (b3, b2, b1, b0)
+ * result is a binary polynomial in 8 mp_digits r[8].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
+        const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
+        const mp_digit b0);
+
+#endif /* _MP_GF2M_PRIV_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,624 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang Shantz <sheueling.chang@sun.com> and
+ *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mp_gf2m.h"
+#include "mp_gf2m-priv.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+
+const mp_digit mp_gf2m_sqr_tb[16] =
+{
+      0,     1,     4,     5,    16,    17,    20,    21,
+     64,    65,    68,    69,    80,    81,    84,    85
+};
+
+/* Multiply two binary polynomials mp_digits a, b.
+ * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
+ * Output in two mp_digits rh, rl.
+ */
+#if MP_DIGIT_BITS == 32
+void
+s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
+{
+    register mp_digit h, l, s;
+    mp_digit tab[8], top2b = a >> 30;
+    register mp_digit a1, a2, a4;
+
+    a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
+
+    tab[0] =  0; tab[1] = a1;    tab[2] = a2;    tab[3] = a1^a2;
+    tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
+
+    s = tab[b       & 0x7]; l  = s;
+    s = tab[b >>  3 & 0x7]; l ^= s <<  3; h  = s >> 29;
+    s = tab[b >>  6 & 0x7]; l ^= s <<  6; h ^= s >> 26;
+    s = tab[b >>  9 & 0x7]; l ^= s <<  9; h ^= s >> 23;
+    s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
+    s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
+    s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
+    s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
+    s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >>  8;
+    s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >>  5;
+    s = tab[b >> 30      ]; l ^= s << 30; h ^= s >>  2;
+
+    /* compensate for the top two bits of a */
+
+    if (top2b & 01) { l ^= b << 30; h ^= b >> 2; }
+    if (top2b & 02) { l ^= b << 31; h ^= b >> 1; }
+
+    *rh = h; *rl = l;
+}
+#else
+void
+s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
+{
+    register mp_digit h, l, s;
+    mp_digit tab[16], top3b = a >> 61;
+    register mp_digit a1, a2, a4, a8;
+
+    a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1;
+    a4 = a2 << 1; a8 = a4 << 1;
+    tab[ 0] = 0;     tab[ 1] = a1;       tab[ 2] = a2;       tab[ 3] = a1^a2;
+    tab[ 4] = a4;    tab[ 5] = a1^a4;    tab[ 6] = a2^a4;    tab[ 7] = a1^a2^a4;
+    tab[ 8] = a8;    tab[ 9] = a1^a8;    tab[10] = a2^a8;    tab[11] = a1^a2^a8;
+    tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
+
+    s = tab[b       & 0xF]; l  = s;
+    s = tab[b >>  4 & 0xF]; l ^= s <<  4; h  = s >> 60;
+    s = tab[b >>  8 & 0xF]; l ^= s <<  8; h ^= s >> 56;
+    s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
+    s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
+    s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
+    s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
+    s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
+    s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
+    s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
+    s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
+    s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
+    s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
+    s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
+    s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >>  8;
+    s = tab[b >> 60      ]; l ^= s << 60; h ^= s >>  4;
+
+    /* compensate for the top three bits of a */
+
+    if (top3b & 01) { l ^= b << 61; h ^= b >> 3; }
+    if (top3b & 02) { l ^= b << 62; h ^= b >> 2; }
+    if (top3b & 04) { l ^= b << 63; h ^= b >> 1; }
+
+    *rh = h; *rl = l;
+}
+#endif
+
+/* Compute xor-multiply of two binary polynomials  (a1, a0) x (b1, b0)
+ * result is a binary polynomial in 4 mp_digits r[4].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void
+s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
+           const mp_digit b0)
+{
+    mp_digit m1, m0;
+    /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
+    s_bmul_1x1(r+3, r+2, a1, b1);
+    s_bmul_1x1(r+1, r, a0, b0);
+    s_bmul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
+    /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
+    r[2] ^= m1 ^ r[1] ^ r[3];  /* h0 ^= m1 ^ l1 ^ h1; */
+    r[1]  = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0;  /* l1 ^= l0 ^ h0 ^ m0; */
+}
+
+/* Compute xor-multiply of two binary polynomials  (a2, a1, a0) x (b2, b1, b0)
+ * result is a binary polynomial in 6 mp_digits r[6].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void
+s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
+        const mp_digit b2, const mp_digit b1, const mp_digit b0)
+{
+        mp_digit zm[4];
+
+        s_bmul_1x1(r+5, r+4, a2, b2);         /* fill top 2 words */
+        s_bmul_2x2(zm, a1, a2^a0, b1, b2^b0); /* fill middle 4 words */
+        s_bmul_2x2(r, a1, a0, b1, b0);        /* fill bottom 4 words */
+
+        zm[3] ^= r[3];
+        zm[2] ^= r[2];
+        zm[1] ^= r[1] ^ r[5];
+        zm[0] ^= r[0] ^ r[4];
+
+        r[5]  ^= zm[3];
+        r[4]  ^= zm[2];
+        r[3]  ^= zm[1];
+        r[2]  ^= zm[0];
+}
+
+/* Compute xor-multiply of two binary polynomials  (a3, a2, a1, a0) x (b3, b2, b1, b0)
+ * result is a binary polynomial in 8 mp_digits r[8].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
+        const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
+        const mp_digit b0)
+{
+        mp_digit zm[4];
+
+        s_bmul_2x2(r+4, a3, a2, b3, b2);            /* fill top 4 words */
+        s_bmul_2x2(zm, a3^a1, a2^a0, b3^b1, b2^b0); /* fill middle 4 words */
+        s_bmul_2x2(r, a1, a0, b1, b0);              /* fill bottom 4 words */
+
+        zm[3] ^= r[3] ^ r[7];
+        zm[2] ^= r[2] ^ r[6];
+        zm[1] ^= r[1] ^ r[5];
+        zm[0] ^= r[0] ^ r[4];
+
+        r[5]  ^= zm[3];
+        r[4]  ^= zm[2];
+        r[3]  ^= zm[1];
+        r[2]  ^= zm[0];
+}
+
+/* Compute addition of two binary polynomials a and b,
+ * store result in c; c could be a or b, a and b could be equal;
+ * c is the bitwise XOR of a and b.
+ */
+mp_err
+mp_badd(const mp_int *a, const mp_int *b, mp_int *c)
+{
+    mp_digit *pa, *pb, *pc;
+    mp_size ix;
+    mp_size used_pa, used_pb;
+    mp_err res = MP_OKAY;
+
+    /* Add all digits up to the precision of b.  If b had more
+     * precision than a initially, swap a, b first
+     */
+    if (MP_USED(a) >= MP_USED(b)) {
+        pa = MP_DIGITS(a);
+        pb = MP_DIGITS(b);
+        used_pa = MP_USED(a);
+        used_pb = MP_USED(b);
+    } else {
+        pa = MP_DIGITS(b);
+        pb = MP_DIGITS(a);
+        used_pa = MP_USED(b);
+        used_pb = MP_USED(a);
+    }
+
+    /* Make sure c has enough precision for the output value */
+    MP_CHECKOK( s_mp_pad(c, used_pa) );
+
+    /* Do word-by-word xor */
+    pc = MP_DIGITS(c);
+    for (ix = 0; ix < used_pb; ix++) {
+        (*pc++) = (*pa++) ^ (*pb++);
+    }
+
+    /* Finish the rest of digits until we're actually done */
+    for (; ix < used_pa; ++ix) {
+        *pc++ = *pa++;
+    }
+
+    MP_USED(c) = used_pa;
+    MP_SIGN(c) = ZPOS;
+    s_mp_clamp(c);
+
+CLEANUP:
+    return res;
+}
+
+#define s_mp_div2(a) MP_CHECKOK( mpl_rsh((a), (a), 1) );
+
+/* Compute binary polynomial multiply d = a * b */
+static void
+s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
+{
+    mp_digit a_i, a0b0, a1b1, carry = 0;
+    while (a_len--) {
+        a_i = *a++;
+        s_bmul_1x1(&a1b1, &a0b0, a_i, b);
+        *d++ = a0b0 ^ carry;
+        carry = a1b1;
+    }
+    *d = carry;
+}
+
+/* Compute binary polynomial xor multiply accumulate d ^= a * b */
+static void
+s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
+{
+    mp_digit a_i, a0b0, a1b1, carry = 0;
+    while (a_len--) {
+        a_i = *a++;
+        s_bmul_1x1(&a1b1, &a0b0, a_i, b);
+        *d++ ^= a0b0 ^ carry;
+        carry = a1b1;
+    }
+    *d ^= carry;
+}
+
+/* Compute binary polynomial xor multiply c = a * b.
+ * All parameters may be identical.
+ */
+mp_err
+mp_bmul(const mp_int *a, const mp_int *b, mp_int *c)
+{
+    mp_digit *pb, b_i;
+    mp_int tmp;
+    mp_size ib, a_used, b_used;
+    mp_err res = MP_OKAY;
+
+    MP_DIGITS(&tmp) = 0;
+
+    ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+    if (a == c) {
+        MP_CHECKOK( mp_init_copy(&tmp, a) );
+        if (a == b)
+            b = &tmp;
+        a = &tmp;
+    } else if (b == c) {
+        MP_CHECKOK( mp_init_copy(&tmp, b) );
+        b = &tmp;
+    }
+
+    if (MP_USED(a) < MP_USED(b)) {
+        const mp_int *xch = b;      /* switch a and b if b longer */
+        b = a;
+        a = xch;
+    }
+
+    MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
+    MP_CHECKOK( s_mp_pad(c, USED(a) + USED(b)) );
+
+    pb = MP_DIGITS(b);
+    s_bmul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
+
+    /* Outer loop:  Digits of b */
+    a_used = MP_USED(a);
+    b_used = MP_USED(b);
+        MP_USED(c) = a_used + b_used;
+    for (ib = 1; ib < b_used; ib++) {
+        b_i = *pb++;
+
+        /* Inner product:  Digits of a */
+        if (b_i)
+            s_bmul_d_add(MP_DIGITS(a), a_used, b_i, MP_DIGITS(c) + ib);
+        else
+            MP_DIGIT(c, ib + a_used) = b_i;
+    }
+
+    s_mp_clamp(c);
+
+    SIGN(c) = ZPOS;
+
+CLEANUP:
+    mp_clear(&tmp);
+    return res;
+}
+
+
+/* Compute modular reduction of a and store result in r.
+ * r could be a.
+ * For modular arithmetic, the irreducible polynomial f(t) is represented
+ * as an array of int[], where f(t) is of the form:
+ *     f(t) = t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+mp_err
+mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
+{
+    int j, k;
+    int n, dN, d0, d1;
+    mp_digit zz, *z, tmp;
+    mp_size used;
+    mp_err res = MP_OKAY;
+
+    /* The algorithm does the reduction in place in r,
+     * if a != r, copy a into r first so reduction can be done in r
+     */
+    if (a != r) {
+        MP_CHECKOK( mp_copy(a, r) );
+    }
+    z = MP_DIGITS(r);
+
+    /* start reduction */
+    dN = p[0] / MP_DIGIT_BITS;
+    used = MP_USED(r);
+
+    for (j = used - 1; j > dN;) {
+
+        zz = z[j];
+        if (zz == 0) {
+            j--; continue;
+        }
+        z[j] = 0;
+
+        for (k = 1; p[k] > 0; k++) {
+            /* reducing component t^p[k] */
+            n = p[0] - p[k];
+            d0 = n % MP_DIGIT_BITS;
+            d1 = MP_DIGIT_BITS - d0;
+            n /= MP_DIGIT_BITS;
+            z[j-n] ^= (zz>>d0);
+            if (d0)
+                z[j-n-1] ^= (zz<<d1);
+        }
+
+        /* reducing component t^0 */
+        n = dN;
+        d0 = p[0] % MP_DIGIT_BITS;
+        d1 = MP_DIGIT_BITS - d0;
+        z[j-n] ^= (zz >> d0);
+        if (d0)
+            z[j-n-1] ^= (zz << d1);
+
+    }
+
+    /* final round of reduction */
+    while (j == dN) {
+
+        d0 = p[0] % MP_DIGIT_BITS;
+        zz = z[dN] >> d0;
+        if (zz == 0) break;
+        d1 = MP_DIGIT_BITS - d0;
+
+        /* clear up the top d1 bits */
+        if (d0) z[dN] = (z[dN] << d1) >> d1;
+        *z ^= zz; /* reduction t^0 component */
+
+        for (k = 1; p[k] > 0; k++) {
+            /* reducing component t^p[k]*/
+            n = p[k] / MP_DIGIT_BITS;
+            d0 = p[k] % MP_DIGIT_BITS;
+            d1 = MP_DIGIT_BITS - d0;
+            z[n] ^= (zz << d0);
+            tmp = zz >> d1;
+            if (d0 && tmp)
+                z[n+1] ^= tmp;
+        }
+    }
+
+    s_mp_clamp(r);
+CLEANUP:
+    return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p,
+ * Store the result in r.  r could be a or b; a could be b.
+ */
+mp_err
+mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], mp_int *r)
+{
+    mp_err res;
+
+    if (a == b) return mp_bsqrmod(a, p, r);
+    if ((res = mp_bmul(a, b, r) ) != MP_OKAY)
+        return res;
+    return mp_bmod(r, p, r);
+}
+
+/* Compute binary polynomial squaring c = a*a mod p .
+ * Parameter r and a can be identical.
+ */
+
+mp_err
+mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
+{
+    mp_digit *pa, *pr, a_i;
+    mp_int tmp;
+    mp_size ia, a_used;
+    mp_err res;
+
+    ARGCHK(a != NULL && r != NULL, MP_BADARG);
+    MP_DIGITS(&tmp) = 0;
+
+    if (a == r) {
+        MP_CHECKOK( mp_init_copy(&tmp, a) );
+        a = &tmp;
+    }
+
+    MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
+    MP_CHECKOK( s_mp_pad(r, 2*USED(a)) );
+
+    pa = MP_DIGITS(a);
+    pr = MP_DIGITS(r);
+    a_used = MP_USED(a);
+        MP_USED(r) = 2 * a_used;
+
+    for (ia = 0; ia < a_used; ia++) {
+        a_i = *pa++;
+        *pr++ = gf2m_SQR0(a_i);
+        *pr++ = gf2m_SQR1(a_i);
+    }
+
+    MP_CHECKOK( mp_bmod(r, p, r) );
+    s_mp_clamp(r);
+    SIGN(r) = ZPOS;
+
+CLEANUP:
+    mp_clear(&tmp);
+    return res;
+}
+
+/* Compute binary polynomial y/x mod p, y divided by x, reduce modulo p.
+ * Store the result in r. r could be x or y, and x could equal y.
+ * Uses algorithm Modular_Division_GF(2^m) from
+ *     Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to
+ *     the Great Divide".
+ */
+int
+mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
+    const unsigned int p[], mp_int *r)
+{
+    mp_int aa, bb, uu;
+    mp_int *a, *b, *u, *v;
+    mp_err res = MP_OKAY;
+
+    MP_DIGITS(&aa) = 0;
+    MP_DIGITS(&bb) = 0;
+    MP_DIGITS(&uu) = 0;
+
+    MP_CHECKOK( mp_init_copy(&aa, x) );
+    MP_CHECKOK( mp_init_copy(&uu, y) );
+    MP_CHECKOK( mp_init_copy(&bb, pp) );
+    MP_CHECKOK( s_mp_pad(r, USED(pp)) );
+    MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
+
+    a = &aa; b= &bb; u=&uu; v=r;
+    /* reduce x and y mod p */
+    MP_CHECKOK( mp_bmod(a, p, a) );
+    MP_CHECKOK( mp_bmod(u, p, u) );
+
+    while (!mp_isodd(a)) {
+        s_mp_div2(a);
+        if (mp_isodd(u)) {
+            MP_CHECKOK( mp_badd(u, pp, u) );
+        }
+        s_mp_div2(u);
+    }
+
+    do {
+        if (mp_cmp_mag(b, a) > 0) {
+            MP_CHECKOK( mp_badd(b, a, b) );
+            MP_CHECKOK( mp_badd(v, u, v) );
+            do {
+                s_mp_div2(b);
+                if (mp_isodd(v)) {
+                    MP_CHECKOK( mp_badd(v, pp, v) );
+                }
+                s_mp_div2(v);
+            } while (!mp_isodd(b));
+        }
+        else if ((MP_DIGIT(a,0) == 1) && (MP_USED(a) == 1))
+            break;
+        else {
+            MP_CHECKOK( mp_badd(a, b, a) );
+            MP_CHECKOK( mp_badd(u, v, u) );
+            do {
+                s_mp_div2(a);
+                if (mp_isodd(u)) {
+                    MP_CHECKOK( mp_badd(u, pp, u) );
+                }
+                s_mp_div2(u);
+            } while (!mp_isodd(a));
+        }
+    } while (1);
+
+    MP_CHECKOK( mp_copy(u, r) );
+
+CLEANUP:
+    /* XXX this appears to be a memory leak in the NSS code */
+    mp_clear(&aa);
+    mp_clear(&bb);
+    mp_clear(&uu);
+    return res;
+
+}
+
+/* Convert the bit-string representation of a polynomial a into an array
+ * of integers corresponding to the bits with non-zero coefficient.
+ * Up to max elements of the array will be filled.  Return value is total
+ * number of coefficients that would be extracted if array was large enough.
+ */
+int
+mp_bpoly2arr(const mp_int *a, unsigned int p[], int max)
+{
+    int i, j, k;
+    mp_digit top_bit, mask;
+
+    top_bit = 1;
+    top_bit <<= MP_DIGIT_BIT - 1;
+
+    for (k = 0; k < max; k++) p[k] = 0;
+    k = 0;
+
+    for (i = MP_USED(a) - 1; i >= 0; i--) {
+        mask = top_bit;
+        for (j = MP_DIGIT_BIT - 1; j >= 0; j--) {
+            if (MP_DIGITS(a)[i] & mask) {
+                if (k < max) p[k] = MP_DIGIT_BIT * i + j;
+                k++;
+            }
+            mask >>= 1;
+        }
+    }
+
+    return k;
+}
+
+/* Convert the coefficient array representation of a polynomial to a
+ * bit-string.  The array must be terminated by 0.
+ */
+mp_err
+mp_barr2poly(const unsigned int p[], mp_int *a)
+{
+
+    mp_err res = MP_OKAY;
+    int i;
+
+    mp_zero(a);
+    for (i = 0; p[i] > 0; i++) {
+        MP_CHECKOK( mpl_set_bit(a, p[i], 1) );
+    }
+    MP_CHECKOK( mpl_set_bit(a, 0, 1) );
+
+CLEANUP:
+    return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mp_gf2m.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,83 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Multi-precision Binary Polynomial Arithmetic Library.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang Shantz <sheueling.chang@sun.com> and
+ *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MP_GF2M_H_
+#define _MP_GF2M_H_
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mpi.h"
+
+mp_err mp_badd(const mp_int *a, const mp_int *b, mp_int *c);
+mp_err mp_bmul(const mp_int *a, const mp_int *b, mp_int *c);
+
+/* For modular arithmetic, the irreducible polynomial f(t) is represented
+ * as an array of int[], where f(t) is of the form:
+ *     f(t) = t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+mp_err mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r);
+mp_err mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[],
+    mp_int *r);
+mp_err mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r);
+mp_err mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
+    const unsigned int p[], mp_int *r);
+
+int mp_bpoly2arr(const mp_int *a, unsigned int p[], int max);
+mp_err mp_barr2poly(const unsigned int p[], mp_int *a);
+
+#endif /* _MP_GF2M_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi-config.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,130 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael J. Fromberger.
+ * Portions created by the Initial Developer are Copyright (C) 1997
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Netscape Communications Corporation
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MPI_CONFIG_H
+#define _MPI_CONFIG_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* $Id: mpi-config.h,v 1.5 2004/04/25 15:03:10 gerv%gerv.net Exp $ */
+
+/*
+  For boolean options,
+  0 = no
+  1 = yes
+
+  Other options are documented individually.
+
+ */
+
+#ifndef MP_IOFUNC
+#define MP_IOFUNC     0  /* include mp_print() ?                */
+#endif
+
+#ifndef MP_MODARITH
+#define MP_MODARITH   1  /* include modular arithmetic ?        */
+#endif
+
+#ifndef MP_NUMTH
+#define MP_NUMTH      1  /* include number theoretic functions? */
+#endif
+
+#ifndef MP_LOGTAB
+#define MP_LOGTAB     1  /* use table of logs instead of log()? */
+#endif
+
+#ifndef MP_MEMSET
+#define MP_MEMSET     1  /* use memset() to zero buffers?       */
+#endif
+
+#ifndef MP_MEMCPY
+#define MP_MEMCPY     1  /* use memcpy() to copy buffers?       */
+#endif
+
+#ifndef MP_CRYPTO
+#define MP_CRYPTO     1  /* erase memory on free?               */
+#endif
+
+#ifndef MP_ARGCHK
+/*
+  0 = no parameter checks
+  1 = runtime checks, continue execution and return an error to caller
+  2 = assertions; dump core on parameter errors
+ */
+#ifdef DEBUG
+#define MP_ARGCHK     2  /* how to check input arguments        */
+#else
+#define MP_ARGCHK     1  /* how to check input arguments        */
+#endif
+#endif
+
+#ifndef MP_DEBUG
+#define MP_DEBUG      0  /* print diagnostic output?            */
+#endif
+
+#ifndef MP_DEFPREC
+#define MP_DEFPREC    64 /* default precision, in digits        */
+#endif
+
+#ifndef MP_MACRO
+#define MP_MACRO      0  /* use macros for frequent calls?      */
+#endif
+
+#ifndef MP_SQUARE
+#define MP_SQUARE     1  /* use separate squaring code?         */
+#endif
+
+#endif /* _MPI_CONFIG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi-priv.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,340 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ *  Arbitrary precision integer arithmetic library
+ *
+ *  NOTE WELL: the content of this header file is NOT part of the "public"
+ *  API for the MPI library, and may change at any time.
+ *  Application programs that use libmpi should NOT include this header file.
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael J. Fromberger.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Netscape Communications Corporation
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MPI_PRIV_H
+#define _MPI_PRIV_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* $Id: mpi-priv.h,v 1.20 2005/11/22 07:16:43 relyea%netscape.com Exp $ */
+
+#include "mpi.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#endif /* _KERNEL */
+
+#if MP_DEBUG
+#include <stdio.h>
+
+#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
+#else
+#define DIAG(T,V)
+#endif
+
+/* If we aren't using a wired-in logarithm table, we need to include
+   the math library to get the log() function
+ */
+
+/* {{{ s_logv_2[] - log table for 2 in various bases */
+
+#if MP_LOGTAB
+/*
+  A table of the logs of 2 for various bases (the 0 and 1 entries of
+  this table are meaningless and should not be referenced).
+
+  This table is used to compute output lengths for the mp_toradix()
+  function.  Since a number n in radix r takes up about log_r(n)
+  digits, we estimate the output size by taking the least integer
+  greater than log_r(n), where:
+
+  log_r(n) = log_2(n) * log_r(2)
+
+  This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
+  which are the output bases supported.
+ */
+
+extern const float s_logv_2[];
+#define LOG_V_2(R)  s_logv_2[(R)]
+
+#else
+
+/*
+   If MP_LOGTAB is not defined, use the math library to compute the
+   logarithms on the fly.  Otherwise, use the table.
+   Pick which works best for your system.
+ */
+
+#include <math.h>
+#define LOG_V_2(R)  (log(2.0)/log(R))
+
+#endif /* if MP_LOGTAB */
+
+/* }}} */
+
+/* {{{ Digit arithmetic macros */
+
+/*
+  When adding and multiplying digits, the results can be larger than
+  can be contained in an mp_digit.  Thus, an mp_word is used.  These
+  macros mask off the upper and lower digits of the mp_word (the
+  mp_word may be more than 2 mp_digits wide, but we only concern
+  ourselves with the low-order 2 mp_digits)
+ */
+
+#define  CARRYOUT(W)  (mp_digit)((W)>>DIGIT_BIT)
+#define  ACCUM(W)     (mp_digit)(W)
+
+#define MP_MIN(a,b)   (((a) < (b)) ? (a) : (b))
+#define MP_MAX(a,b)   (((a) > (b)) ? (a) : (b))
+#define MP_HOWMANY(a,b) (((a) + (b) - 1)/(b))
+#define MP_ROUNDUP(a,b) (MP_HOWMANY(a,b) * (b))
+
+/* }}} */
+
+/* {{{ Comparison constants */
+
+#define  MP_LT       -1
+#define  MP_EQ        0
+#define  MP_GT        1
+
+/* }}} */
+
+/* {{{ private function declarations */
+
+/*
+   If MP_MACRO is false, these will be defined as actual functions;
+   otherwise, suitable macro definitions will be used.  This works
+   around the fact that ANSI C89 doesn't support an 'inline' keyword
+   (although I hear C9x will ... about bloody time).  At present, the
+   macro definitions are identical to the function bodies, but they'll
+   expand in place, instead of generating a function call.
+
+   I chose these particular functions to be made into macros because
+   some profiling showed they are called a lot on a typical workload,
+   and yet they are primarily housekeeping.
+ */
+#if MP_MACRO == 0
+ void     s_mp_setz(mp_digit *dp, mp_size count); /* zero digits           */
+ void     s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count); /* copy */
+ void    *s_mp_alloc(size_t nb, size_t ni, int flag); /* general allocator    */
+ void     s_mp_free(void *ptr, mp_size);          /* general free function */
+extern unsigned long mp_allocs;
+extern unsigned long mp_frees;
+extern unsigned long mp_copies;
+#else
+
+ /* Even if these are defined as macros, we need to respect the settings
+    of the MP_MEMSET and MP_MEMCPY configuration options...
+  */
+ #if MP_MEMSET == 0
+  #define  s_mp_setz(dp, count) \
+       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
+ #else
+  #define  s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
+ #endif /* MP_MEMSET */
+
+ #if MP_MEMCPY == 0
+  #define  s_mp_copy(sp, dp, count) \
+       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
+ #else
+  #define  s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
+ #endif /* MP_MEMCPY */
+
+ #define  s_mp_alloc(nb, ni)  calloc(nb, ni)
+ #define  s_mp_free(ptr) {if(ptr) free(ptr);}
+#endif /* MP_MACRO */
+
+mp_err   s_mp_grow(mp_int *mp, mp_size min);   /* increase allocated size */
+mp_err   s_mp_pad(mp_int *mp, mp_size min);    /* left pad with zeroes    */
+
+#if MP_MACRO == 0
+ void     s_mp_clamp(mp_int *mp);               /* clip leading zeroes     */
+#else
+ #define  s_mp_clamp(mp)\
+  { mp_size used = MP_USED(mp); \
+    while (used > 1 && DIGIT(mp, used - 1) == 0) --used; \
+    MP_USED(mp) = used; \
+  }
+#endif /* MP_MACRO */
+
+void     s_mp_exch(mp_int *a, mp_int *b);      /* swap a and b in place   */
+
+mp_err   s_mp_lshd(mp_int *mp, mp_size p);     /* left-shift by p digits  */
+void     s_mp_rshd(mp_int *mp, mp_size p);     /* right-shift by p digits */
+mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d);  /* multiply by 2^d in place */
+void     s_mp_div_2d(mp_int *mp, mp_digit d);  /* divide by 2^d in place  */
+void     s_mp_mod_2d(mp_int *mp, mp_digit d);  /* modulo 2^d in place     */
+void     s_mp_div_2(mp_int *mp);               /* divide by 2 in place    */
+mp_err   s_mp_mul_2(mp_int *mp);               /* multiply by 2 in place  */
+mp_err   s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd);
+                                               /* normalize for division  */
+mp_err   s_mp_add_d(mp_int *mp, mp_digit d);   /* unsigned digit addition */
+mp_err   s_mp_sub_d(mp_int *mp, mp_digit d);   /* unsigned digit subtract */
+mp_err   s_mp_mul_d(mp_int *mp, mp_digit d);   /* unsigned digit multiply */
+mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
+                                               /* unsigned digit divide   */
+mp_err   s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
+                                               /* Barrett reduction       */
+mp_err   s_mp_add(mp_int *a, const mp_int *b); /* magnitude addition      */
+mp_err   s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c);
+mp_err   s_mp_sub(mp_int *a, const mp_int *b); /* magnitude subtract      */
+mp_err   s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c);
+mp_err   s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset);
+                                               /* a += b * RADIX^offset   */
+mp_err   s_mp_mul(mp_int *a, const mp_int *b); /* magnitude multiply      */
+#if MP_SQUARE
+mp_err   s_mp_sqr(mp_int *a);                  /* magnitude square        */
+#else
+#define  s_mp_sqr(a) s_mp_mul(a, a)
+#endif
+mp_err   s_mp_div(mp_int *rem, mp_int *div, mp_int *quot); /* magnitude div */
+mp_err   s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
+mp_err   s_mp_2expt(mp_int *a, mp_digit k);    /* a = 2^k                 */
+int      s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */
+int      s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */
+int      s_mp_ispow2(const mp_int *v);         /* is v a power of 2?      */
+int      s_mp_ispow2d(mp_digit d);             /* is d a power of 2?      */
+
+int      s_mp_tovalue(char ch, int r);          /* convert ch to value    */
+char     s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */
+int      s_mp_outlen(int bits, int r);          /* output length in bytes */
+mp_digit s_mp_invmod_radix(mp_digit P);   /* returns (P ** -1) mod RADIX */
+mp_err   s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c);
+mp_err   s_mp_invmod_2d(    const mp_int *a, mp_size k,       mp_int *c);
+mp_err   s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
+
+#ifdef NSS_USE_COMBA
+
+#define IS_POWER_OF_2(a) ((a) && !((a) & ((a)-1)))
+
+void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C);
+void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C);
+void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C);
+void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C);
+
+void s_mp_sqr_comba_4(const mp_int *A, mp_int *B);
+void s_mp_sqr_comba_8(const mp_int *A, mp_int *B);
+void s_mp_sqr_comba_16(const mp_int *A, mp_int *B);
+void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
+
+#endif /* end NSS_USE_COMBA */
+
+/* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */
+#if defined (__OS2__) && defined (__IBMC__)
+#define MPI_ASM_DECL __cdecl
+#else
+#define MPI_ASM_DECL
+#endif
+
+#ifdef MPI_AMD64
+
+mp_digit MPI_ASM_DECL s_mpv_mul_set_vec64(mp_digit*, mp_digit *, mp_size, mp_digit);
+mp_digit MPI_ASM_DECL s_mpv_mul_add_vec64(mp_digit*, const mp_digit*, mp_size, mp_digit);
+
+/* c = a * b */
+#define s_mpv_mul_d(a, a_len, b, c) \
+        ((unsigned long*)c)[a_len] = s_mpv_mul_set_vec64(c, a, a_len, b)
+
+/* c += a * b */
+#define s_mpv_mul_d_add(a, a_len, b, c) \
+        ((unsigned long*)c)[a_len] = s_mpv_mul_add_vec64(c, a, a_len, b)
+
+#else
+
+void     MPI_ASM_DECL s_mpv_mul_d(const mp_digit *a, mp_size a_len,
+                                        mp_digit b, mp_digit *c);
+void     MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len,
+                                            mp_digit b, mp_digit *c);
+
+#endif
+
+void     MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a,
+                                                mp_size a_len, mp_digit b,
+                                                mp_digit *c);
+void     MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a,
+                                                mp_size a_len,
+                                                mp_digit *sqrs);
+
+mp_err   MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo,
+                            mp_digit divisor, mp_digit *quot, mp_digit *rem);
+
+/* c += a * b * (MP_RADIX ** offset);  */
+#define s_mp_mul_d_add_offset(a, b, c, off) \
+(s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off), MP_OKAY)
+
+typedef struct {
+  mp_int       N;       /* modulus N */
+  mp_digit     n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */
+  mp_size      b;       /* R == 2 ** b,  also b = # significant bits in N */
+} mp_mont_modulus;
+
+mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
+                       mp_mont_modulus *mmm);
+mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm);
+
+/*
+ * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
+ * if a cache exists, or zero if there is no cache. If more than one
+ * cache line exists, it should return the smallest line size (which is
+ * usually the L1 cache).
+ *
+ * mp_modexp uses this information to make sure that private key information
+ * isn't being leaked through the cache.
+ *
+ * see mpcpucache.c for the implementation.
+ */
+unsigned long s_mpi_getProcessorLineSize();
+
+/* }}} */
+#endif /* _MPI_PRIV_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,4886 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ *
+ *  Arbitrary precision integer arithmetic library
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael J. Fromberger.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Netscape Communications Corporation
+ *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* $Id: mpi.c,v 1.45 2006/09/29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */
+
+#include "mpi-priv.h"
+#if defined(OSF1)
+#include <c_asm.h>
+#endif
+
+#if MP_LOGTAB
+/*
+  A table of the logs of 2 for various bases (the 0 and 1 entries of
+  this table are meaningless and should not be referenced).
+
+  This table is used to compute output lengths for the mp_toradix()
+  function.  Since a number n in radix r takes up about log_r(n)
+  digits, we estimate the output size by taking the least integer
+  greater than log_r(n), where:
+
+  log_r(n) = log_2(n) * log_r(2)
+
+  This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
+  which are the output bases supported.
+ */
+#include "logtab.h"
+#endif
+
+/* {{{ Constant strings */
+
+/* Constant strings returned by mp_strerror() */
+static const char *mp_err_string[] = {
+  "unknown result code",     /* say what?            */
+  "boolean true",            /* MP_OKAY, MP_YES      */
+  "boolean false",           /* MP_NO                */
+  "out of memory",           /* MP_MEM               */
+  "argument out of range",   /* MP_RANGE             */
+  "invalid input parameter", /* MP_BADARG            */
+  "result is undefined"      /* MP_UNDEF             */
+};
+
+/* Value to digit maps for radix conversion   */
+
+/* s_dmap_1 - standard digits and letters */
+static const char *s_dmap_1 =
+  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+
+/* }}} */
+
+unsigned long mp_allocs;
+unsigned long mp_frees;
+unsigned long mp_copies;
+
+/* {{{ Default precision manipulation */
+
+/* Default precision for newly created mp_int's      */
+static mp_size s_mp_defprec = MP_DEFPREC;
+
+mp_size mp_get_prec(void)
+{
+  return s_mp_defprec;
+
+} /* end mp_get_prec() */
+
+void         mp_set_prec(mp_size prec)
+{
+  if(prec == 0)
+    s_mp_defprec = MP_DEFPREC;
+  else
+    s_mp_defprec = prec;
+
+} /* end mp_set_prec() */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ mp_init(mp, kmflag) */
+
+/*
+  mp_init(mp, kmflag)
+
+  Initialize a new zero-valued mp_int.  Returns MP_OKAY if successful,
+  MP_MEM if memory could not be allocated for the structure.
+ */
+
+mp_err mp_init(mp_int *mp, int kmflag)
+{
+  return mp_init_size(mp, s_mp_defprec, kmflag);
+
+} /* end mp_init() */
+
+/* }}} */
+
+/* {{{ mp_init_size(mp, prec, kmflag) */
+
+/*
+  mp_init_size(mp, prec, kmflag)
+
+  Initialize a new zero-valued mp_int with at least the given
+  precision; returns MP_OKAY if successful, or MP_MEM if memory could
+  not be allocated for the structure.
+ */
+
+mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag)
+{
+  ARGCHK(mp != NULL && prec > 0, MP_BADARG);
+
+  prec = MP_ROUNDUP(prec, s_mp_defprec);
+  if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit), kmflag)) == NULL)
+    return MP_MEM;
+
+  SIGN(mp) = ZPOS;
+  USED(mp) = 1;
+  ALLOC(mp) = prec;
+
+  return MP_OKAY;
+
+} /* end mp_init_size() */
+
+/* }}} */
+
+/* {{{ mp_init_copy(mp, from) */
+
+/*
+  mp_init_copy(mp, from)
+
+  Initialize mp as an exact copy of from.  Returns MP_OKAY if
+  successful, MP_MEM if memory could not be allocated for the new
+  structure.
+ */
+
+mp_err mp_init_copy(mp_int *mp, const mp_int *from)
+{
+  ARGCHK(mp != NULL && from != NULL, MP_BADARG);
+
+  if(mp == from)
+    return MP_OKAY;
+
+  if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
+    return MP_MEM;
+
+  s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
+  USED(mp) = USED(from);
+  ALLOC(mp) = ALLOC(from);
+  SIGN(mp) = SIGN(from);
+
+#ifndef _WIN32
+  FLAG(mp) = FLAG(from);
+#endif /* _WIN32 */
+
+  return MP_OKAY;
+
+} /* end mp_init_copy() */
+
+/* }}} */
+
+/* {{{ mp_copy(from, to) */
+
+/*
+  mp_copy(from, to)
+
+  Copies the mp_int 'from' to the mp_int 'to'.  It is presumed that
+  'to' has already been initialized (if not, use mp_init_copy()
+  instead). If 'from' and 'to' are identical, nothing happens.
+ */
+
+mp_err mp_copy(const mp_int *from, mp_int *to)
+{
+  ARGCHK(from != NULL && to != NULL, MP_BADARG);
+
+  if(from == to)
+    return MP_OKAY;
+
+  ++mp_copies;
+  { /* copy */
+    mp_digit   *tmp;
+
+    /*
+      If the allocated buffer in 'to' already has enough space to hold
+      all the used digits of 'from', we'll re-use it to avoid hitting
+      the memory allocater more than necessary; otherwise, we'd have
+      to grow anyway, so we just allocate a hunk and make the copy as
+      usual
+     */
+    if(ALLOC(to) >= USED(from)) {
+      s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
+      s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
+
+    } else {
+      if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
+        return MP_MEM;
+
+      s_mp_copy(DIGITS(from), tmp, USED(from));
+
+      if(DIGITS(to) != NULL) {
+#if MP_CRYPTO
+        s_mp_setz(DIGITS(to), ALLOC(to));
+#endif
+        s_mp_free(DIGITS(to), ALLOC(to));
+      }
+
+      DIGITS(to) = tmp;
+      ALLOC(to) = ALLOC(from);
+    }
+
+    /* Copy the precision and sign from the original */
+    USED(to) = USED(from);
+    SIGN(to) = SIGN(from);
+  } /* end copy */
+
+  return MP_OKAY;
+
+} /* end mp_copy() */
+
+/* }}} */
+
+/* {{{ mp_exch(mp1, mp2) */
+
+/*
+  mp_exch(mp1, mp2)
+
+  Exchange mp1 and mp2 without allocating any intermediate memory
+  (well, unless you count the stack space needed for this call and the
+  locals it creates...).  This cannot fail.
+ */
+
+void mp_exch(mp_int *mp1, mp_int *mp2)
+{
+#if MP_ARGCHK == 2
+  assert(mp1 != NULL && mp2 != NULL);
+#else
+  if(mp1 == NULL || mp2 == NULL)
+    return;
+#endif
+
+  s_mp_exch(mp1, mp2);
+
+} /* end mp_exch() */
+
+/* }}} */
+
+/* {{{ mp_clear(mp) */
+
+/*
+  mp_clear(mp)
+
+  Release the storage used by an mp_int, and void its fields so that
+  if someone calls mp_clear() again for the same int later, we won't
+  get tollchocked.
+ */
+
+void   mp_clear(mp_int *mp)
+{
+  if(mp == NULL)
+    return;
+
+  if(DIGITS(mp) != NULL) {
+#if MP_CRYPTO
+    s_mp_setz(DIGITS(mp), ALLOC(mp));
+#endif
+    s_mp_free(DIGITS(mp), ALLOC(mp));
+    DIGITS(mp) = NULL;
+  }
+
+  USED(mp) = 0;
+  ALLOC(mp) = 0;
+
+} /* end mp_clear() */
+
+/* }}} */
+
+/* {{{ mp_zero(mp) */
+
+/*
+  mp_zero(mp)
+
+  Set mp to zero.  Does not change the allocated size of the structure,
+  and therefore cannot fail (except on a bad argument, which we ignore)
+ */
+void   mp_zero(mp_int *mp)
+{
+  if(mp == NULL)
+    return;
+
+  s_mp_setz(DIGITS(mp), ALLOC(mp));
+  USED(mp) = 1;
+  SIGN(mp) = ZPOS;
+
+} /* end mp_zero() */
+
+/* }}} */
+
+/* {{{ mp_set(mp, d) */
+
+void   mp_set(mp_int *mp, mp_digit d)
+{
+  if(mp == NULL)
+    return;
+
+  mp_zero(mp);
+  DIGIT(mp, 0) = d;
+
+} /* end mp_set() */
+
+/* }}} */
+
+/* {{{ mp_set_int(mp, z) */
+
+mp_err mp_set_int(mp_int *mp, long z)
+{
+  int            ix;
+  unsigned long  v = labs(z);
+  mp_err         res;
+
+  ARGCHK(mp != NULL, MP_BADARG);
+
+  mp_zero(mp);
+  if(z == 0)
+    return MP_OKAY;  /* shortcut for zero */
+
+  if (sizeof v <= sizeof(mp_digit)) {
+    DIGIT(mp,0) = v;
+  } else {
+    for (ix = sizeof(long) - 1; ix >= 0; ix--) {
+      if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
+        return res;
+
+      res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
+      if (res != MP_OKAY)
+        return res;
+    }
+  }
+  if(z < 0)
+    SIGN(mp) = NEG;
+
+  return MP_OKAY;
+
+} /* end mp_set_int() */
+
+/* }}} */
+
+/* {{{ mp_set_ulong(mp, z) */
+
+mp_err mp_set_ulong(mp_int *mp, unsigned long z)
+{
+  int            ix;
+  mp_err         res;
+
+  ARGCHK(mp != NULL, MP_BADARG);
+
+  mp_zero(mp);
+  if(z == 0)
+    return MP_OKAY;  /* shortcut for zero */
+
+  if (sizeof z <= sizeof(mp_digit)) {
+    DIGIT(mp,0) = z;
+  } else {
+    for (ix = sizeof(long) - 1; ix >= 0; ix--) {
+      if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
+        return res;
+
+      res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));
+      if (res != MP_OKAY)
+        return res;
+    }
+  }
+  return MP_OKAY;
+} /* end mp_set_ulong() */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Digit arithmetic */
+
+/* {{{ mp_add_d(a, d, b) */
+
+/*
+  mp_add_d(a, d, b)
+
+  Compute the sum b = a + d, for a single digit d.  Respects the sign of
+  its primary addend (single digits are unsigned anyway).
+ */
+
+mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
+{
+  mp_int   tmp;
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+    return res;
+
+  if(SIGN(&tmp) == ZPOS) {
+    if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
+      goto CLEANUP;
+  } else if(s_mp_cmp_d(&tmp, d) >= 0) {
+    if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
+      goto CLEANUP;
+  } else {
+    mp_neg(&tmp, &tmp);
+
+    DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
+  }
+
+  if(s_mp_cmp_d(&tmp, 0) == 0)
+    SIGN(&tmp) = ZPOS;
+
+  s_mp_exch(&tmp, b);
+
+CLEANUP:
+  mp_clear(&tmp);
+  return res;
+
+} /* end mp_add_d() */
+
+/* }}} */
+
+/* {{{ mp_sub_d(a, d, b) */
+
+/*
+  mp_sub_d(a, d, b)
+
+  Compute the difference b = a - d, for a single digit d.  Respects the
+  sign of its subtrahend (single digits are unsigned anyway).
+ */
+
+mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)
+{
+  mp_int   tmp;
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+    return res;
+
+  if(SIGN(&tmp) == NEG) {
+    if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
+      goto CLEANUP;
+  } else if(s_mp_cmp_d(&tmp, d) >= 0) {
+    if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
+      goto CLEANUP;
+  } else {
+    mp_neg(&tmp, &tmp);
+
+    DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
+    SIGN(&tmp) = NEG;
+  }
+
+  if(s_mp_cmp_d(&tmp, 0) == 0)
+    SIGN(&tmp) = ZPOS;
+
+  s_mp_exch(&tmp, b);
+
+CLEANUP:
+  mp_clear(&tmp);
+  return res;
+
+} /* end mp_sub_d() */
+
+/* }}} */
+
+/* {{{ mp_mul_d(a, d, b) */
+
+/*
+  mp_mul_d(a, d, b)
+
+  Compute the product b = a * d, for a single digit d.  Respects the sign
+  of its multiplicand (single digits are unsigned anyway)
+ */
+
+mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if(d == 0) {
+    mp_zero(b);
+    return MP_OKAY;
+  }
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  res = s_mp_mul_d(b, d);
+
+  return res;
+
+} /* end mp_mul_d() */
+
+/* }}} */
+
+/* {{{ mp_mul_2(a, c) */
+
+mp_err mp_mul_2(const mp_int *a, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, c)) != MP_OKAY)
+    return res;
+
+  return s_mp_mul_2(c);
+
+} /* end mp_mul_2() */
+
+/* }}} */
+
+/* {{{ mp_div_d(a, d, q, r) */
+
+/*
+  mp_div_d(a, d, q, r)
+
+  Compute the quotient q = a / d and remainder r = a mod d, for a
+  single digit d.  Respects the sign of its divisor (single digits are
+  unsigned anyway).
+ */
+
+mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
+{
+  mp_err   res;
+  mp_int   qp;
+  mp_digit rem;
+  int      pow;
+
+  ARGCHK(a != NULL, MP_BADARG);
+
+  if(d == 0)
+    return MP_RANGE;
+
+  /* Shortcut for powers of two ... */
+  if((pow = s_mp_ispow2d(d)) >= 0) {
+    mp_digit  mask;
+
+    mask = ((mp_digit)1 << pow) - 1;
+    rem = DIGIT(a, 0) & mask;
+
+    if(q) {
+      mp_copy(a, q);
+      s_mp_div_2d(q, pow);
+    }
+
+    if(r)
+      *r = rem;
+
+    return MP_OKAY;
+  }
+
+  if((res = mp_init_copy(&qp, a)) != MP_OKAY)
+    return res;
+
+  res = s_mp_div_d(&qp, d, &rem);
+
+  if(s_mp_cmp_d(&qp, 0) == 0)
+    SIGN(q) = ZPOS;
+
+  if(r)
+    *r = rem;
+
+  if(q)
+    s_mp_exch(&qp, q);
+
+  mp_clear(&qp);
+  return res;
+
+} /* end mp_div_d() */
+
+/* }}} */
+
+/* {{{ mp_div_2(a, c) */
+
+/*
+  mp_div_2(a, c)
+
+  Compute c = a / 2, disregarding the remainder.
+ */
+
+mp_err mp_div_2(const mp_int *a, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, c)) != MP_OKAY)
+    return res;
+
+  s_mp_div_2(c);
+
+  return MP_OKAY;
+
+} /* end mp_div_2() */
+
+/* }}} */
+
+/* {{{ mp_expt_d(a, d, b) */
+
+mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
+{
+  mp_int   s, x;
+  mp_err   res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+  DIGIT(&s, 0) = 1;
+
+  while(d != 0) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+        goto CLEANUP;
+    }
+
+    d /= 2;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  s_mp_exch(&s, c);
+
+CLEANUP:
+  mp_clear(&x);
+X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end mp_expt_d() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Full arithmetic */
+
+/* {{{ mp_abs(a, b) */
+
+/*
+  mp_abs(a, b)
+
+  Compute b = |a|.  'a' and 'b' may be identical.
+ */
+
+mp_err mp_abs(const mp_int *a, mp_int *b)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  SIGN(b) = ZPOS;
+
+  return MP_OKAY;
+
+} /* end mp_abs() */
+
+/* }}} */
+
+/* {{{ mp_neg(a, b) */
+
+/*
+  mp_neg(a, b)
+
+  Compute b = -a.  'a' and 'b' may be identical.
+ */
+
+mp_err mp_neg(const mp_int *a, mp_int *b)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  if(s_mp_cmp_d(b, 0) == MP_EQ)
+    SIGN(b) = ZPOS;
+  else
+    SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
+
+  return MP_OKAY;
+
+} /* end mp_neg() */
+
+/* }}} */
+
+/* {{{ mp_add(a, b, c) */
+
+/*
+  mp_add(a, b, c)
+
+  Compute c = a + b.  All parameters may be identical.
+ */
+
+mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(SIGN(a) == SIGN(b)) { /* same sign:  add values, keep sign */
+    MP_CHECKOK( s_mp_add_3arg(a, b, c) );
+  } else if(s_mp_cmp(a, b) >= 0) {  /* different sign: |a| >= |b|   */
+    MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
+  } else {                          /* different sign: |a|  < |b|   */
+    MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
+  }
+
+  if (s_mp_cmp_d(c, 0) == MP_EQ)
+    SIGN(c) = ZPOS;
+
+CLEANUP:
+  return res;
+
+} /* end mp_add() */
+
+/* }}} */
+
+/* {{{ mp_sub(a, b, c) */
+
+/*
+  mp_sub(a, b, c)
+
+  Compute c = a - b.  All parameters may be identical.
+ */
+
+mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
+{
+  mp_err  res;
+  int     magDiff;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if (a == b) {
+    mp_zero(c);
+    return MP_OKAY;
+  }
+
+  if (MP_SIGN(a) != MP_SIGN(b)) {
+    MP_CHECKOK( s_mp_add_3arg(a, b, c) );
+  } else if (!(magDiff = s_mp_cmp(a, b))) {
+    mp_zero(c);
+    res = MP_OKAY;
+  } else if (magDiff > 0) {
+    MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
+  } else {
+    MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
+    MP_SIGN(c) = !MP_SIGN(a);
+  }
+
+  if (s_mp_cmp_d(c, 0) == MP_EQ)
+    MP_SIGN(c) = MP_ZPOS;
+
+CLEANUP:
+  return res;
+
+} /* end mp_sub() */
+
+/* }}} */
+
+/* {{{ mp_mul(a, b, c) */
+
+/*
+  mp_mul(a, b, c)
+
+  Compute c = a * b.  All parameters may be identical.
+ */
+mp_err   mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
+{
+  mp_digit *pb;
+  mp_int   tmp;
+  mp_err   res;
+  mp_size  ib;
+  mp_size  useda, usedb;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if (a == c) {
+    if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+      return res;
+    if (a == b)
+      b = &tmp;
+    a = &tmp;
+  } else if (b == c) {
+    if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)
+      return res;
+    b = &tmp;
+  } else {
+    MP_DIGITS(&tmp) = 0;
+  }
+
+  if (MP_USED(a) < MP_USED(b)) {
+    const mp_int *xch = b;      /* switch a and b, to do fewer outer loops */
+    b = a;
+    a = xch;
+  }
+
+  MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
+  if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
+    goto CLEANUP;
+
+#ifdef NSS_USE_COMBA
+  if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
+      if (MP_USED(a) == 4) {
+          s_mp_mul_comba_4(a, b, c);
+          goto CLEANUP;
+      }
+      if (MP_USED(a) == 8) {
+          s_mp_mul_comba_8(a, b, c);
+          goto CLEANUP;
+      }
+      if (MP_USED(a) == 16) {
+          s_mp_mul_comba_16(a, b, c);
+          goto CLEANUP;
+      }
+      if (MP_USED(a) == 32) {
+          s_mp_mul_comba_32(a, b, c);
+          goto CLEANUP;
+      }
+  }
+#endif
+
+  pb = MP_DIGITS(b);
+  s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
+
+  /* Outer loop:  Digits of b */
+  useda = MP_USED(a);
+  usedb = MP_USED(b);
+  for (ib = 1; ib < usedb; ib++) {
+    mp_digit b_i    = *pb++;
+
+    /* Inner product:  Digits of a */
+    if (b_i)
+      s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
+    else
+      MP_DIGIT(c, ib + useda) = b_i;
+  }
+
+  s_mp_clamp(c);
+
+  if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
+    SIGN(c) = ZPOS;
+  else
+    SIGN(c) = NEG;
+
+CLEANUP:
+  mp_clear(&tmp);
+  return res;
+} /* end mp_mul() */
+
+/* }}} */
+
+/* {{{ mp_sqr(a, sqr) */
+
+#if MP_SQUARE
+/*
+  Computes the square of a.  This can be done more
+  efficiently than a general multiplication, because many of the
+  computation steps are redundant when squaring.  The inner product
+  step is a bit more complicated, but we save a fair number of
+  iterations of the multiplication loop.
+ */
+
+/* sqr = a^2;   Caller provides both a and tmp; */
+mp_err   mp_sqr(const mp_int *a, mp_int *sqr)
+{
+  mp_digit *pa;
+  mp_digit d;
+  mp_err   res;
+  mp_size  ix;
+  mp_int   tmp;
+  int      count;
+
+  ARGCHK(a != NULL && sqr != NULL, MP_BADARG);
+
+  if (a == sqr) {
+    if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+      return res;
+    a = &tmp;
+  } else {
+    DIGITS(&tmp) = 0;
+    res = MP_OKAY;
+  }
+
+  ix = 2 * MP_USED(a);
+  if (ix > MP_ALLOC(sqr)) {
+    MP_USED(sqr) = 1;
+    MP_CHECKOK( s_mp_grow(sqr, ix) );
+  }
+  MP_USED(sqr) = ix;
+  MP_DIGIT(sqr, 0) = 0;
+
+#ifdef NSS_USE_COMBA
+  if (IS_POWER_OF_2(MP_USED(a))) {
+      if (MP_USED(a) == 4) {
+          s_mp_sqr_comba_4(a, sqr);
+          goto CLEANUP;
+      }
+      if (MP_USED(a) == 8) {
+          s_mp_sqr_comba_8(a, sqr);
+          goto CLEANUP;
+      }
+      if (MP_USED(a) == 16) {
+          s_mp_sqr_comba_16(a, sqr);
+          goto CLEANUP;
+      }
+      if (MP_USED(a) == 32) {
+          s_mp_sqr_comba_32(a, sqr);
+          goto CLEANUP;
+      }
+  }
+#endif
+
+  pa = MP_DIGITS(a);
+  count = MP_USED(a) - 1;
+  if (count > 0) {
+    d = *pa++;
+    s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);
+    for (ix = 3; --count > 0; ix += 2) {
+      d = *pa++;
+      s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);
+    } /* for(ix ...) */
+    MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */
+
+    /* now sqr *= 2 */
+    s_mp_mul_2(sqr);
+  } else {
+    MP_DIGIT(sqr, 1) = 0;
+  }
+
+  /* now add the squares of the digits of a to sqr. */
+  s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));
+
+  SIGN(sqr) = ZPOS;
+  s_mp_clamp(sqr);
+
+CLEANUP:
+  mp_clear(&tmp);
+  return res;
+
+} /* end mp_sqr() */
+#endif
+
+/* }}} */
+
+/* {{{ mp_div(a, b, q, r) */
+
+/*
+  mp_div(a, b, q, r)
+
+  Compute q = a / b and r = a mod b.  Input parameters may be re-used
+  as output parameters.  If q or r is NULL, that portion of the
+  computation will be discarded (although it will still be computed)
+ */
+mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
+{
+  mp_err   res;
+  mp_int   *pQ, *pR;
+  mp_int   qtmp, rtmp, btmp;
+  int      cmp;
+  mp_sign  signA;
+  mp_sign  signB;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  signA = MP_SIGN(a);
+  signB = MP_SIGN(b);
+
+  if(mp_cmp_z(b) == MP_EQ)
+    return MP_RANGE;
+
+  DIGITS(&qtmp) = 0;
+  DIGITS(&rtmp) = 0;
+  DIGITS(&btmp) = 0;
+
+  /* Set up some temporaries... */
+  if (!r || r == a || r == b) {
+    MP_CHECKOK( mp_init_copy(&rtmp, a) );
+    pR = &rtmp;
+  } else {
+    MP_CHECKOK( mp_copy(a, r) );
+    pR = r;
+  }
+
+  if (!q || q == a || q == b) {
+    MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a), FLAG(a)) );
+    pQ = &qtmp;
+  } else {
+    MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );
+    pQ = q;
+    mp_zero(pQ);
+  }
+
+  /*
+    If |a| <= |b|, we can compute the solution without division;
+    otherwise, we actually do the work required.
+   */
+  if ((cmp = s_mp_cmp(a, b)) <= 0) {
+    if (cmp) {
+      /* r was set to a above. */
+      mp_zero(pQ);
+    } else {
+      mp_set(pQ, 1);
+      mp_zero(pR);
+    }
+  } else {
+    MP_CHECKOK( mp_init_copy(&btmp, b) );
+    MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );
+  }
+
+  /* Compute the signs for the output  */
+  MP_SIGN(pR) = signA;   /* Sr = Sa              */
+  /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */
+  MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;
+
+  if(s_mp_cmp_d(pQ, 0) == MP_EQ)
+    SIGN(pQ) = ZPOS;
+  if(s_mp_cmp_d(pR, 0) == MP_EQ)
+    SIGN(pR) = ZPOS;
+
+  /* Copy output, if it is needed      */
+  if(q && q != pQ)
+    s_mp_exch(pQ, q);
+
+  if(r && r != pR)
+    s_mp_exch(pR, r);
+
+CLEANUP:
+  mp_clear(&btmp);
+  mp_clear(&rtmp);
+  mp_clear(&qtmp);
+
+  return res;
+
+} /* end mp_div() */
+
+/* }}} */
+
+/* {{{ mp_div_2d(a, d, q, r) */
+
+mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL, MP_BADARG);
+
+  if(q) {
+    if((res = mp_copy(a, q)) != MP_OKAY)
+      return res;
+  }
+  if(r) {
+    if((res = mp_copy(a, r)) != MP_OKAY)
+      return res;
+  }
+  if(q) {
+    s_mp_div_2d(q, d);
+  }
+  if(r) {
+    s_mp_mod_2d(r, d);
+  }
+
+  return MP_OKAY;
+
+} /* end mp_div_2d() */
+
+/* }}} */
+
+/* {{{ mp_expt(a, b, c) */
+
+/*
+  mp_expt(a, b, c)
+
+  Compute c = a ** b, that is, raise a to the b power.  Uses a
+  standard iterative square-and-multiply technique.
+ */
+
+mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_int   s, x;
+  mp_err   res;
+  mp_digit d;
+  int      dig, bit;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(mp_cmp_z(b) < 0)
+    return MP_RANGE;
+
+  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
+    return res;
+
+  mp_set(&s, 1);
+
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+  /* Loop over low-order digits in ascending order */
+  for(dig = 0; dig < (USED(b) - 1); dig++) {
+    d = DIGIT(b, dig);
+
+    /* Loop over bits of each non-maximal digit */
+    for(bit = 0; bit < DIGIT_BIT; bit++) {
+      if(d & 1) {
+        if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+          goto CLEANUP;
+      }
+
+      d >>= 1;
+
+      if((res = s_mp_sqr(&x)) != MP_OKAY)
+        goto CLEANUP;
+    }
+  }
+
+  /* Consider now the last digit... */
+  d = DIGIT(b, dig);
+
+  while(d) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+        goto CLEANUP;
+    }
+
+    d >>= 1;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  if(mp_iseven(b))
+    SIGN(&s) = SIGN(a);
+
+  res = mp_copy(&s, c);
+
+CLEANUP:
+  mp_clear(&x);
+X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end mp_expt() */
+
+/* }}} */
+
+/* {{{ mp_2expt(a, k) */
+
+/* Compute a = 2^k */
+
+mp_err mp_2expt(mp_int *a, mp_digit k)
+{
+  ARGCHK(a != NULL, MP_BADARG);
+
+  return s_mp_2expt(a, k);
+
+} /* end mp_2expt() */
+
+/* }}} */
+
+/* {{{ mp_mod(a, m, c) */
+
+/*
+  mp_mod(a, m, c)
+
+  Compute c = a (mod m).  Result will always be 0 <= c < m.
+ */
+
+mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
+{
+  mp_err  res;
+  int     mag;
+
+  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if(SIGN(m) == NEG)
+    return MP_RANGE;
+
+  /*
+     If |a| > m, we need to divide to get the remainder and take the
+     absolute value.
+
+     If |a| < m, we don't need to do any division, just copy and adjust
+     the sign (if a is negative).
+
+     If |a| == m, we can simply set the result to zero.
+
+     This order is intended to minimize the average path length of the
+     comparison chain on common workloads -- the most frequent cases are
+     that |a| != m, so we do those first.
+   */
+  if((mag = s_mp_cmp(a, m)) > 0) {
+    if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
+      return res;
+
+    if(SIGN(c) == NEG) {
+      if((res = mp_add(c, m, c)) != MP_OKAY)
+        return res;
+    }
+
+  } else if(mag < 0) {
+    if((res = mp_copy(a, c)) != MP_OKAY)
+      return res;
+
+    if(mp_cmp_z(a) < 0) {
+      if((res = mp_add(c, m, c)) != MP_OKAY)
+        return res;
+
+    }
+
+  } else {
+    mp_zero(c);
+
+  }
+
+  return MP_OKAY;
+
+} /* end mp_mod() */
+
+/* }}} */
+
+/* {{{ mp_mod_d(a, d, c) */
+
+/*
+  mp_mod_d(a, d, c)
+
+  Compute c = a (mod d).  Result will always be 0 <= c < d
+ */
+mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
+{
+  mp_err   res;
+  mp_digit rem;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if(s_mp_cmp_d(a, d) > 0) {
+    if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
+      return res;
+
+  } else {
+    if(SIGN(a) == NEG)
+      rem = d - DIGIT(a, 0);
+    else
+      rem = DIGIT(a, 0);
+  }
+
+  if(c)
+    *c = rem;
+
+  return MP_OKAY;
+
+} /* end mp_mod_d() */
+
+/* }}} */
+
+/* {{{ mp_sqrt(a, b) */
+
+/*
+  mp_sqrt(a, b)
+
+  Compute the integer square root of a, and store the result in b.
+  Uses an integer-arithmetic version of Newton's iterative linear
+  approximation technique to determine this value; the result has the
+  following two properties:
+
+     b^2 <= a
+     (b+1)^2 >= a
+
+  It is a range error to pass a negative value.
+ */
+mp_err mp_sqrt(const mp_int *a, mp_int *b)
+{
+  mp_int   x, t;
+  mp_err   res;
+  mp_size  used;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  /* Cannot take square root of a negative value */
+  if(SIGN(a) == NEG)
+    return MP_RANGE;
+
+  /* Special cases for zero and one, trivial     */
+  if(mp_cmp_d(a, 1) <= 0)
+    return mp_copy(a, b);
+
+  /* Initialize the temporaries we'll use below  */
+  if((res = mp_init_size(&t, USED(a), FLAG(a))) != MP_OKAY)
+    return res;
+
+  /* Compute an initial guess for the iteration as a itself */
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+  used = MP_USED(&x);
+  if (used > 1) {
+    s_mp_rshd(&x, used / 2);
+  }
+
+  for(;;) {
+    /* t = (x * x) - a */
+    mp_copy(&x, &t);      /* can't fail, t is big enough for original x */
+    if((res = mp_sqr(&t, &t)) != MP_OKAY ||
+       (res = mp_sub(&t, a, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+    /* t = t / 2x       */
+    s_mp_mul_2(&x);
+    if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
+      goto CLEANUP;
+    s_mp_div_2(&x);
+
+    /* Terminate the loop, if the quotient is zero */
+    if(mp_cmp_z(&t) == MP_EQ)
+      break;
+
+    /* x = x - t       */
+    if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
+      goto CLEANUP;
+
+  }
+
+  /* Copy result to output parameter */
+  mp_sub_d(&x, 1, &x);
+  s_mp_exch(&x, b);
+
+ CLEANUP:
+  mp_clear(&x);
+ X:
+  mp_clear(&t);
+
+  return res;
+
+} /* end mp_sqrt() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Modular arithmetic */
+
+#if MP_MODARITH
+/* {{{ mp_addmod(a, b, m, c) */
+
+/*
+  mp_addmod(a, b, m, c)
+
+  Compute c = (a + b) mod m
+ */
+
+mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_add(a, b, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_submod(a, b, m, c) */
+
+/*
+  mp_submod(a, b, m, c)
+
+  Compute c = (a - b) mod m
+ */
+
+mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_sub(a, b, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_mulmod(a, b, m, c) */
+
+/*
+  mp_mulmod(a, b, m, c)
+
+  Compute c = (a * b) mod m
+ */
+
+mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_mul(a, b, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_sqrmod(a, m, c) */
+
+#if MP_SQUARE
+mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_sqr(a, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+} /* end mp_sqrmod() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_exptmod(a, b, m, c) */
+
+/*
+  s_mp_exptmod(a, b, m, c)
+
+  Compute c = (a ** b) mod m.  Uses a standard square-and-multiply
+  method with modular reductions at each step. (This is basically the
+  same code as mp_expt(), except for the addition of the reductions)
+
+  The modular reductions are done using Barrett's algorithm (see
+  s_mp_reduce() below for details)
+ */
+
+mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
+{
+  mp_int   s, x, mu;
+  mp_err   res;
+  mp_digit d;
+  int      dig, bit;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
+    return MP_RANGE;
+
+  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&x, a)) != MP_OKAY ||
+     (res = mp_mod(&x, m, &x)) != MP_OKAY)
+    goto X;
+  if((res = mp_init(&mu, FLAG(a))) != MP_OKAY)
+    goto MU;
+
+  mp_set(&s, 1);
+
+  /* mu = b^2k / m */
+  s_mp_add_d(&mu, 1);
+  s_mp_lshd(&mu, 2 * USED(m));
+  if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
+    goto CLEANUP;
+
+  /* Loop over digits of b in ascending order, except highest order */
+  for(dig = 0; dig < (USED(b) - 1); dig++) {
+    d = DIGIT(b, dig);
+
+    /* Loop over the bits of the lower-order digits */
+    for(bit = 0; bit < DIGIT_BIT; bit++) {
+      if(d & 1) {
+        if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+          goto CLEANUP;
+        if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
+          goto CLEANUP;
+      }
+
+      d >>= 1;
+
+      if((res = s_mp_sqr(&x)) != MP_OKAY)
+        goto CLEANUP;
+      if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
+        goto CLEANUP;
+    }
+  }
+
+  /* Now do the last digit... */
+  d = DIGIT(b, dig);
+
+  while(d) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+        goto CLEANUP;
+      if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
+        goto CLEANUP;
+    }
+
+    d >>= 1;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY)
+      goto CLEANUP;
+    if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  s_mp_exch(&s, c);
+
+ CLEANUP:
+  mp_clear(&mu);
+ MU:
+  mp_clear(&x);
+ X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end s_mp_exptmod() */
+
+/* }}} */
+
+/* {{{ mp_exptmod_d(a, d, m, c) */
+
+mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
+{
+  mp_int   s, x;
+  mp_err   res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+  mp_set(&s, 1);
+
+  while(d != 0) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
+         (res = mp_mod(&s, m, &s)) != MP_OKAY)
+        goto CLEANUP;
+    }
+
+    d /= 2;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY ||
+       (res = mp_mod(&x, m, &x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  s_mp_exch(&s, c);
+
+CLEANUP:
+  mp_clear(&x);
+X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end mp_exptmod_d() */
+
+/* }}} */
+#endif /* if MP_MODARITH */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Comparison functions */
+
+/* {{{ mp_cmp_z(a) */
+
+/*
+  mp_cmp_z(a)
+
+  Compare a <=> 0.  Returns <0 if a<0, 0 if a=0, >0 if a>0.
+ */
+
+int    mp_cmp_z(const mp_int *a)
+{
+  if(SIGN(a) == NEG)
+    return MP_LT;
+  else if(USED(a) == 1 && DIGIT(a, 0) == 0)
+    return MP_EQ;
+  else
+    return MP_GT;
+
+} /* end mp_cmp_z() */
+
+/* }}} */
+
+/* {{{ mp_cmp_d(a, d) */
+
+/*
+  mp_cmp_d(a, d)
+
+  Compare a <=> d.  Returns <0 if a<d, 0 if a=d, >0 if a>d
+ */
+
+int    mp_cmp_d(const mp_int *a, mp_digit d)
+{
+  ARGCHK(a != NULL, MP_EQ);
+
+  if(SIGN(a) == NEG)
+    return MP_LT;
+
+  return s_mp_cmp_d(a, d);
+
+} /* end mp_cmp_d() */
+
+/* }}} */
+
+/* {{{ mp_cmp(a, b) */
+
+int    mp_cmp(const mp_int *a, const mp_int *b)
+{
+  ARGCHK(a != NULL && b != NULL, MP_EQ);
+
+  if(SIGN(a) == SIGN(b)) {
+    int  mag;
+
+    if((mag = s_mp_cmp(a, b)) == MP_EQ)
+      return MP_EQ;
+
+    if(SIGN(a) == ZPOS)
+      return mag;
+    else
+      return -mag;
+
+  } else if(SIGN(a) == ZPOS) {
+    return MP_GT;
+  } else {
+    return MP_LT;
+  }
+
+} /* end mp_cmp() */
+
+/* }}} */
+
+/* {{{ mp_cmp_mag(a, b) */
+
+/*
+  mp_cmp_mag(a, b)
+
+  Compares |a| <=> |b|, and returns an appropriate comparison result
+ */
+
+int    mp_cmp_mag(mp_int *a, mp_int *b)
+{
+  ARGCHK(a != NULL && b != NULL, MP_EQ);
+
+  return s_mp_cmp(a, b);
+
+} /* end mp_cmp_mag() */
+
+/* }}} */
+
+/* {{{ mp_cmp_int(a, z, kmflag) */
+
+/*
+  This just converts z to an mp_int, and uses the existing comparison
+  routines.  This is sort of inefficient, but it's not clear to me how
+  frequently this wil get used anyway.  For small positive constants,
+  you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
+ */
+int    mp_cmp_int(const mp_int *a, long z, int kmflag)
+{
+  mp_int  tmp;
+  int     out;
+
+  ARGCHK(a != NULL, MP_EQ);
+
+  mp_init(&tmp, kmflag); mp_set_int(&tmp, z);
+  out = mp_cmp(a, &tmp);
+  mp_clear(&tmp);
+
+  return out;
+
+} /* end mp_cmp_int() */
+
+/* }}} */
+
+/* {{{ mp_isodd(a) */
+
+/*
+  mp_isodd(a)
+
+  Returns a true (non-zero) value if a is odd, false (zero) otherwise.
+ */
+int    mp_isodd(const mp_int *a)
+{
+  ARGCHK(a != NULL, 0);
+
+  return (int)(DIGIT(a, 0) & 1);
+
+} /* end mp_isodd() */
+
+/* }}} */
+
+/* {{{ mp_iseven(a) */
+
+int    mp_iseven(const mp_int *a)
+{
+  return !mp_isodd(a);
+
+} /* end mp_iseven() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Number theoretic functions */
+
+#if MP_NUMTH
+/* {{{ mp_gcd(a, b, c) */
+
+/*
+  Like the old mp_gcd() function, except computes the GCD using the
+  binary algorithm due to Josef Stein in 1961 (via Knuth).
+ */
+mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_err   res;
+  mp_int   u, v, t;
+  mp_size  k = 0;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
+      return MP_RANGE;
+  if(mp_cmp_z(a) == MP_EQ) {
+    return mp_copy(b, c);
+  } else if(mp_cmp_z(b) == MP_EQ) {
+    return mp_copy(a, c);
+  }
+
+  if((res = mp_init(&t, FLAG(a))) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&u, a)) != MP_OKAY)
+    goto U;
+  if((res = mp_init_copy(&v, b)) != MP_OKAY)
+    goto V;
+
+  SIGN(&u) = ZPOS;
+  SIGN(&v) = ZPOS;
+
+  /* Divide out common factors of 2 until at least 1 of a, b is even */
+  while(mp_iseven(&u) && mp_iseven(&v)) {
+    s_mp_div_2(&u);
+    s_mp_div_2(&v);
+    ++k;
+  }
+
+  /* Initialize t */
+  if(mp_isodd(&u)) {
+    if((res = mp_copy(&v, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+    /* t = -v */
+    if(SIGN(&v) == ZPOS)
+      SIGN(&t) = NEG;
+    else
+      SIGN(&t) = ZPOS;
+
+  } else {
+    if((res = mp_copy(&u, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+  }
+
+  for(;;) {
+    while(mp_iseven(&t)) {
+      s_mp_div_2(&t);
+    }
+
+    if(mp_cmp_z(&t) == MP_GT) {
+      if((res = mp_copy(&t, &u)) != MP_OKAY)
+        goto CLEANUP;
+
+    } else {
+      if((res = mp_copy(&t, &v)) != MP_OKAY)
+        goto CLEANUP;
+
+      /* v = -t */
+      if(SIGN(&t) == ZPOS)
+        SIGN(&v) = NEG;
+      else
+        SIGN(&v) = ZPOS;
+    }
+
+    if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+    if(s_mp_cmp_d(&t, 0) == MP_EQ)
+      break;
+  }
+
+  s_mp_2expt(&v, k);       /* v = 2^k   */
+  res = mp_mul(&u, &v, c); /* c = u * v */
+
+ CLEANUP:
+  mp_clear(&v);
+ V:
+  mp_clear(&u);
+ U:
+  mp_clear(&t);
+
+  return res;
+
+} /* end mp_gcd() */
+
+/* }}} */
+
+/* {{{ mp_lcm(a, b, c) */
+
+/* We compute the least common multiple using the rule:
+
+   ab = [a, b](a, b)
+
+   ... by computing the product, and dividing out the gcd.
+ */
+
+mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_int  gcd, prod;
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  /* Set up temporaries */
+  if((res = mp_init(&gcd, FLAG(a))) != MP_OKAY)
+    return res;
+  if((res = mp_init(&prod, FLAG(a))) != MP_OKAY)
+    goto GCD;
+
+  if((res = mp_mul(a, b, &prod)) != MP_OKAY)
+    goto CLEANUP;
+  if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
+    goto CLEANUP;
+
+  res = mp_div(&prod, &gcd, c, NULL);
+
+ CLEANUP:
+  mp_clear(&prod);
+ GCD:
+  mp_clear(&gcd);
+
+  return res;
+
+} /* end mp_lcm() */
+
+/* }}} */
+
+/* {{{ mp_xgcd(a, b, g, x, y) */
+
+/*
+  mp_xgcd(a, b, g, x, y)
+
+  Compute g = (a, b) and values x and y satisfying Bezout's identity
+  (that is, ax + by = g).  This uses the binary extended GCD algorithm
+  based on the Stein algorithm used for mp_gcd()
+  See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
+ */
+
+mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)
+{
+  mp_int   gx, xc, yc, u, v, A, B, C, D;
+  mp_int  *clean[9];
+  mp_err   res;
+  int      last = -1;
+
+  if(mp_cmp_z(b) == 0)
+    return MP_RANGE;
+
+  /* Initialize all these variables we need */
+  MP_CHECKOK( mp_init(&u, FLAG(a)) );
+  clean[++last] = &u;
+  MP_CHECKOK( mp_init(&v, FLAG(a)) );
+  clean[++last] = &v;
+  MP_CHECKOK( mp_init(&gx, FLAG(a)) );
+  clean[++last] = &gx;
+  MP_CHECKOK( mp_init(&A, FLAG(a)) );
+  clean[++last] = &A;
+  MP_CHECKOK( mp_init(&B, FLAG(a)) );
+  clean[++last] = &B;
+  MP_CHECKOK( mp_init(&C, FLAG(a)) );
+  clean[++last] = &C;
+  MP_CHECKOK( mp_init(&D, FLAG(a)) );
+  clean[++last] = &D;
+  MP_CHECKOK( mp_init_copy(&xc, a) );
+  clean[++last] = &xc;
+  mp_abs(&xc, &xc);
+  MP_CHECKOK( mp_init_copy(&yc, b) );
+  clean[++last] = &yc;
+  mp_abs(&yc, &yc);
+
+  mp_set(&gx, 1);
+
+  /* Divide by two until at least one of them is odd */
+  while(mp_iseven(&xc) && mp_iseven(&yc)) {
+    mp_size nx = mp_trailing_zeros(&xc);
+    mp_size ny = mp_trailing_zeros(&yc);
+    mp_size n  = MP_MIN(nx, ny);
+    s_mp_div_2d(&xc,n);
+    s_mp_div_2d(&yc,n);
+    MP_CHECKOK( s_mp_mul_2d(&gx,n) );
+  }
+
+  mp_copy(&xc, &u);
+  mp_copy(&yc, &v);
+  mp_set(&A, 1); mp_set(&D, 1);
+
+  /* Loop through binary GCD algorithm */
+  do {
+    while(mp_iseven(&u)) {
+      s_mp_div_2(&u);
+
+      if(mp_iseven(&A) && mp_iseven(&B)) {
+        s_mp_div_2(&A); s_mp_div_2(&B);
+      } else {
+        MP_CHECKOK( mp_add(&A, &yc, &A) );
+        s_mp_div_2(&A);
+        MP_CHECKOK( mp_sub(&B, &xc, &B) );
+        s_mp_div_2(&B);
+      }
+    }
+
+    while(mp_iseven(&v)) {
+      s_mp_div_2(&v);
+
+      if(mp_iseven(&C) && mp_iseven(&D)) {
+        s_mp_div_2(&C); s_mp_div_2(&D);
+      } else {
+        MP_CHECKOK( mp_add(&C, &yc, &C) );
+        s_mp_div_2(&C);
+        MP_CHECKOK( mp_sub(&D, &xc, &D) );
+        s_mp_div_2(&D);
+      }
+    }
+
+    if(mp_cmp(&u, &v) >= 0) {
+      MP_CHECKOK( mp_sub(&u, &v, &u) );
+      MP_CHECKOK( mp_sub(&A, &C, &A) );
+      MP_CHECKOK( mp_sub(&B, &D, &B) );
+    } else {
+      MP_CHECKOK( mp_sub(&v, &u, &v) );
+      MP_CHECKOK( mp_sub(&C, &A, &C) );
+      MP_CHECKOK( mp_sub(&D, &B, &D) );
+    }
+  } while (mp_cmp_z(&u) != 0);
+
+  /* copy results to output */
+  if(x)
+    MP_CHECKOK( mp_copy(&C, x) );
+
+  if(y)
+    MP_CHECKOK( mp_copy(&D, y) );
+
+  if(g)
+    MP_CHECKOK( mp_mul(&gx, &v, g) );
+
+ CLEANUP:
+  while(last >= 0)
+    mp_clear(clean[last--]);
+
+  return res;
+
+} /* end mp_xgcd() */
+
+/* }}} */
+
+mp_size mp_trailing_zeros(const mp_int *mp)
+{
+  mp_digit d;
+  mp_size  n = 0;
+  int      ix;
+
+  if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
+    return n;
+
+  for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
+    n += MP_DIGIT_BIT;
+  if (!d)
+    return 0;   /* shouldn't happen, but ... */
+#if !defined(MP_USE_UINT_DIGIT)
+  if (!(d & 0xffffffffU)) {
+    d >>= 32;
+    n  += 32;
+  }
+#endif
+  if (!(d & 0xffffU)) {
+    d >>= 16;
+    n  += 16;
+  }
+  if (!(d & 0xffU)) {
+    d >>= 8;
+    n  += 8;
+  }
+  if (!(d & 0xfU)) {
+    d >>= 4;
+    n  += 4;
+  }
+  if (!(d & 0x3U)) {
+    d >>= 2;
+    n  += 2;
+  }
+  if (!(d & 0x1U)) {
+    d >>= 1;
+    n  += 1;
+  }
+#if MP_ARGCHK == 2
+  assert(0 != (d & 1));
+#endif
+  return n;
+}
+
+/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
+** Returns k (positive) or error (negative).
+** This technique from the paper "Fast Modular Reciprocals" (unpublished)
+** by Richard Schroeppel (a.k.a. Captain Nemo).
+*/
+mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
+{
+  mp_err res;
+  mp_err k    = 0;
+  mp_int d, f, g;
+
+  ARGCHK(a && p && c, MP_BADARG);
+
+  MP_DIGITS(&d) = 0;
+  MP_DIGITS(&f) = 0;
+  MP_DIGITS(&g) = 0;
+  MP_CHECKOK( mp_init(&d, FLAG(a)) );
+  MP_CHECKOK( mp_init_copy(&f, a) );    /* f = a */
+  MP_CHECKOK( mp_init_copy(&g, p) );    /* g = p */
+
+  mp_set(c, 1);
+  mp_zero(&d);
+
+  if (mp_cmp_z(&f) == 0) {
+    res = MP_UNDEF;
+  } else
+  for (;;) {
+    int diff_sign;
+    while (mp_iseven(&f)) {
+      mp_size n = mp_trailing_zeros(&f);
+      if (!n) {
+        res = MP_UNDEF;
+        goto CLEANUP;
+      }
+      s_mp_div_2d(&f, n);
+      MP_CHECKOK( s_mp_mul_2d(&d, n) );
+      k += n;
+    }
+    if (mp_cmp_d(&f, 1) == MP_EQ) {     /* f == 1 */
+      res = k;
+      break;
+    }
+    diff_sign = mp_cmp(&f, &g);
+    if (diff_sign < 0) {                /* f < g */
+      s_mp_exch(&f, &g);
+      s_mp_exch(c, &d);
+    } else if (diff_sign == 0) {                /* f == g */
+      res = MP_UNDEF;           /* a and p are not relatively prime */
+      break;
+    }
+    if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {
+      MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */
+      MP_CHECKOK( mp_sub(c,  &d,  c) ); /* c = c - d */
+    } else {
+      MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */
+      MP_CHECKOK( mp_add(c,  &d,  c) ); /* c = c + d */
+    }
+  }
+  if (res >= 0) {
+    while (MP_SIGN(c) != MP_ZPOS) {
+      MP_CHECKOK( mp_add(c, p, c) );
+    }
+    res = k;
+  }
+
+CLEANUP:
+  mp_clear(&d);
+  mp_clear(&f);
+  mp_clear(&g);
+  return res;
+}
+
+/* Compute T = (P ** -1) mod MP_RADIX.  Also works for 16-bit mp_digits.
+** This technique from the paper "Fast Modular Reciprocals" (unpublished)
+** by Richard Schroeppel (a.k.a. Captain Nemo).
+*/
+mp_digit  s_mp_invmod_radix(mp_digit P)
+{
+  mp_digit T = P;
+  T *= 2 - (P * T);
+  T *= 2 - (P * T);
+  T *= 2 - (P * T);
+  T *= 2 - (P * T);
+#if !defined(MP_USE_UINT_DIGIT)
+  T *= 2 - (P * T);
+  T *= 2 - (P * T);
+#endif
+  return T;
+}
+
+/* Given c, k, and prime p, where a*c == 2**k (mod p),
+** Compute x = (a ** -1) mod p.  This is similar to Montgomery reduction.
+** This technique from the paper "Fast Modular Reciprocals" (unpublished)
+** by Richard Schroeppel (a.k.a. Captain Nemo).
+*/
+mp_err  s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x)
+{
+  int      k_orig = k;
+  mp_digit r;
+  mp_size  ix;
+  mp_err   res;
+
+  if (mp_cmp_z(c) < 0) {                /* c < 0 */
+    MP_CHECKOK( mp_add(c, p, x) );      /* x = c + p */
+  } else {
+    MP_CHECKOK( mp_copy(c, x) );        /* x = c */
+  }
+
+  /* make sure x is large enough */
+  ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;
+  ix = MP_MAX(ix, MP_USED(x));
+  MP_CHECKOK( s_mp_pad(x, ix) );
+
+  r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));
+
+  for (ix = 0; k > 0; ix++) {
+    int      j = MP_MIN(k, MP_DIGIT_BIT);
+    mp_digit v = r * MP_DIGIT(x, ix);
+    if (j < MP_DIGIT_BIT) {
+      v &= ((mp_digit)1 << j) - 1;      /* v = v mod (2 ** j) */
+    }
+    s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */
+    k -= j;
+  }
+  s_mp_clamp(x);
+  s_mp_div_2d(x, k_orig);
+  res = MP_OKAY;
+
+CLEANUP:
+  return res;
+}
+
+/* compute mod inverse using Schroeppel's method, only if m is odd */
+mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
+{
+  int k;
+  mp_err  res;
+  mp_int  x;
+
+  ARGCHK(a && m && c, MP_BADARG);
+
+  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+    return MP_RANGE;
+  if (mp_iseven(m))
+    return MP_UNDEF;
+
+  MP_DIGITS(&x) = 0;
+
+  if (a == c) {
+    if ((res = mp_init_copy(&x, a)) != MP_OKAY)
+      return res;
+    if (a == m)
+      m = &x;
+    a = &x;
+  } else if (m == c) {
+    if ((res = mp_init_copy(&x, m)) != MP_OKAY)
+      return res;
+    m = &x;
+  } else {
+    MP_DIGITS(&x) = 0;
+  }
+
+  MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
+  k = res;
+  MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
+CLEANUP:
+  mp_clear(&x);
+  return res;
+}
+
+/* Known good algorithm for computing modular inverse.  But slow. */
+mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
+{
+  mp_int  g, x;
+  mp_err  res;
+
+  ARGCHK(a && m && c, MP_BADARG);
+
+  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+    return MP_RANGE;
+
+  MP_DIGITS(&g) = 0;
+  MP_DIGITS(&x) = 0;
+  MP_CHECKOK( mp_init(&x, FLAG(a)) );
+  MP_CHECKOK( mp_init(&g, FLAG(a)) );
+
+  MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
+
+  if (mp_cmp_d(&g, 1) != MP_EQ) {
+    res = MP_UNDEF;
+    goto CLEANUP;
+  }
+
+  res = mp_mod(&x, m, c);
+  SIGN(c) = SIGN(a);
+
+CLEANUP:
+  mp_clear(&x);
+  mp_clear(&g);
+
+  return res;
+}
+
+/* modular inverse where modulus is 2**k. */
+/* c = a**-1 mod 2**k */
+mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
+{
+  mp_err res;
+  mp_size ix = k + 4;
+  mp_int t0, t1, val, tmp, two2k;
+
+  static const mp_digit d2 = 2;
+  static const mp_int two = { 0, MP_ZPOS, 1, 1, (mp_digit *)&d2 };
+
+  if (mp_iseven(a))
+    return MP_UNDEF;
+  if (k <= MP_DIGIT_BIT) {
+    mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
+    if (k < MP_DIGIT_BIT)
+      i &= ((mp_digit)1 << k) - (mp_digit)1;
+    mp_set(c, i);
+    return MP_OKAY;
+  }
+  MP_DIGITS(&t0) = 0;
+  MP_DIGITS(&t1) = 0;
+  MP_DIGITS(&val) = 0;
+  MP_DIGITS(&tmp) = 0;
+  MP_DIGITS(&two2k) = 0;
+  MP_CHECKOK( mp_init_copy(&val, a) );
+  s_mp_mod_2d(&val, k);
+  MP_CHECKOK( mp_init_copy(&t0, &val) );
+  MP_CHECKOK( mp_init_copy(&t1, &t0)  );
+  MP_CHECKOK( mp_init(&tmp, FLAG(a)) );
+  MP_CHECKOK( mp_init(&two2k, FLAG(a)) );
+  MP_CHECKOK( s_mp_2expt(&two2k, k) );
+  do {
+    MP_CHECKOK( mp_mul(&val, &t1, &tmp)  );
+    MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
+    MP_CHECKOK( mp_mul(&t1, &tmp, &t1)   );
+    s_mp_mod_2d(&t1, k);
+    while (MP_SIGN(&t1) != MP_ZPOS) {
+      MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
+    }
+    if (mp_cmp(&t1, &t0) == MP_EQ)
+      break;
+    MP_CHECKOK( mp_copy(&t1, &t0) );
+  } while (--ix > 0);
+  if (!ix) {
+    res = MP_UNDEF;
+  } else {
+    mp_exch(c, &t1);
+  }
+
+CLEANUP:
+  mp_clear(&t0);
+  mp_clear(&t1);
+  mp_clear(&val);
+  mp_clear(&tmp);
+  mp_clear(&two2k);
+  return res;
+}
+
+mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
+{
+  mp_err res;
+  mp_size k;
+  mp_int oddFactor, evenFactor; /* factors of the modulus */
+  mp_int oddPart, evenPart;     /* parts to combine via CRT. */
+  mp_int C2, tmp1, tmp2;
+
+  /*static const mp_digit d1 = 1; */
+  /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
+
+  if ((res = s_mp_ispow2(m)) >= 0) {
+    k = res;
+    return s_mp_invmod_2d(a, k, c);
+  }
+  MP_DIGITS(&oddFactor) = 0;
+  MP_DIGITS(&evenFactor) = 0;
+  MP_DIGITS(&oddPart) = 0;
+  MP_DIGITS(&evenPart) = 0;
+  MP_DIGITS(&C2)     = 0;
+  MP_DIGITS(&tmp1)   = 0;
+  MP_DIGITS(&tmp2)   = 0;
+
+  MP_CHECKOK( mp_init_copy(&oddFactor, m) );    /* oddFactor = m */
+  MP_CHECKOK( mp_init(&evenFactor, FLAG(m)) );
+  MP_CHECKOK( mp_init(&oddPart, FLAG(m)) );
+  MP_CHECKOK( mp_init(&evenPart, FLAG(m)) );
+  MP_CHECKOK( mp_init(&C2, FLAG(m))     );
+  MP_CHECKOK( mp_init(&tmp1, FLAG(m))   );
+  MP_CHECKOK( mp_init(&tmp2, FLAG(m))   );
+
+  k = mp_trailing_zeros(m);
+  s_mp_div_2d(&oddFactor, k);
+  MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
+
+  /* compute a**-1 mod oddFactor. */
+  MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
+  /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
+  MP_CHECKOK( s_mp_invmod_2d(   a,       k,    &evenPart) );
+
+  /* Use Chinese Remainer theorem to compute a**-1 mod m. */
+  /* let m1 = oddFactor,  v1 = oddPart,
+   * let m2 = evenFactor, v2 = evenPart.
+   */
+
+  /* Compute C2 = m1**-1 mod m2. */
+  MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k,    &C2) );
+
+  /* compute u = (v2 - v1)*C2 mod m2 */
+  MP_CHECKOK( mp_sub(&evenPart, &oddPart,   &tmp1) );
+  MP_CHECKOK( mp_mul(&tmp1,     &C2,        &tmp2) );
+  s_mp_mod_2d(&tmp2, k);
+  while (MP_SIGN(&tmp2) != MP_ZPOS) {
+    MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
+  }
+
+  /* compute answer = v1 + u*m1 */
+  MP_CHECKOK( mp_mul(&tmp2,     &oddFactor, c) );
+  MP_CHECKOK( mp_add(&oddPart,  c,          c) );
+  /* not sure this is necessary, but it's low cost if not. */
+  MP_CHECKOK( mp_mod(c,         m,          c) );
+
+CLEANUP:
+  mp_clear(&oddFactor);
+  mp_clear(&evenFactor);
+  mp_clear(&oddPart);
+  mp_clear(&evenPart);
+  mp_clear(&C2);
+  mp_clear(&tmp1);
+  mp_clear(&tmp2);
+  return res;
+}
+
+
+/* {{{ mp_invmod(a, m, c) */
+
+/*
+  mp_invmod(a, m, c)
+
+  Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
+  This is equivalent to the question of whether (a, m) = 1.  If not,
+  MP_UNDEF is returned, and there is no inverse.
+ */
+
+mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
+{
+
+  ARGCHK(a && m && c, MP_BADARG);
+
+  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+    return MP_RANGE;
+
+  if (mp_isodd(m)) {
+    return s_mp_invmod_odd_m(a, m, c);
+  }
+  if (mp_iseven(a))
+    return MP_UNDEF;    /* not invertable */
+
+  return s_mp_invmod_even_m(a, m, c);
+
+} /* end mp_invmod() */
+
+/* }}} */
+#endif /* if MP_NUMTH */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ mp_print(mp, ofp) */
+
+#if MP_IOFUNC
+/*
+  mp_print(mp, ofp)
+
+  Print a textual representation of the given mp_int on the output
+  stream 'ofp'.  Output is generated using the internal radix.
+ */
+
+void   mp_print(mp_int *mp, FILE *ofp)
+{
+  int   ix;
+
+  if(mp == NULL || ofp == NULL)
+    return;
+
+  fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
+
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
+  }
+
+} /* end mp_print() */
+
+#endif /* if MP_IOFUNC */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ More I/O Functions */
+
+/* {{{ mp_read_raw(mp, str, len) */
+
+/*
+   mp_read_raw(mp, str, len)
+
+   Read in a raw value (base 256) into the given mp_int
+ */
+
+mp_err  mp_read_raw(mp_int *mp, char *str, int len)
+{
+  int            ix;
+  mp_err         res;
+  unsigned char *ustr = (unsigned char *)str;
+
+  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
+
+  mp_zero(mp);
+
+  /* Get sign from first byte */
+  if(ustr[0])
+    SIGN(mp) = NEG;
+  else
+    SIGN(mp) = ZPOS;
+
+  /* Read the rest of the digits */
+  for(ix = 1; ix < len; ix++) {
+    if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
+      return res;
+    if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)
+      return res;
+  }
+
+  return MP_OKAY;
+
+} /* end mp_read_raw() */
+
+/* }}} */
+
+/* {{{ mp_raw_size(mp) */
+
+int    mp_raw_size(mp_int *mp)
+{
+  ARGCHK(mp != NULL, 0);
+
+  return (USED(mp) * sizeof(mp_digit)) + 1;
+
+} /* end mp_raw_size() */
+
+/* }}} */
+
+/* {{{ mp_toraw(mp, str) */
+
+mp_err mp_toraw(mp_int *mp, char *str)
+{
+  int  ix, jx, pos = 1;
+
+  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+
+  str[0] = (char)SIGN(mp);
+
+  /* Iterate over each digit... */
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    mp_digit  d = DIGIT(mp, ix);
+
+    /* Unpack digit bytes, high order first */
+    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
+      str[pos++] = (char)(d >> (jx * CHAR_BIT));
+    }
+  }
+
+  return MP_OKAY;
+
+} /* end mp_toraw() */
+
+/* }}} */
+
+/* {{{ mp_read_radix(mp, str, radix) */
+
+/*
+  mp_read_radix(mp, str, radix)
+
+  Read an integer from the given string, and set mp to the resulting
+  value.  The input is presumed to be in base 10.  Leading non-digit
+  characters are ignored, and the function reads until a non-digit
+  character or the end of the string.
+ */
+
+mp_err  mp_read_radix(mp_int *mp, const char *str, int radix)
+{
+  int     ix = 0, val = 0;
+  mp_err  res;
+  mp_sign sig = ZPOS;
+
+  ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
+         MP_BADARG);
+
+  mp_zero(mp);
+
+  /* Skip leading non-digit characters until a digit or '-' or '+' */
+  while(str[ix] &&
+        (s_mp_tovalue(str[ix], radix) < 0) &&
+        str[ix] != '-' &&
+        str[ix] != '+') {
+    ++ix;
+  }
+
+  if(str[ix] == '-') {
+    sig = NEG;
+    ++ix;
+  } else if(str[ix] == '+') {
+    sig = ZPOS; /* this is the default anyway... */
+    ++ix;
+  }
+
+  while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
+    if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
+      return res;
+    if((res = s_mp_add_d(mp, val)) != MP_OKAY)
+      return res;
+    ++ix;
+  }
+
+  if(s_mp_cmp_d(mp, 0) == MP_EQ)
+    SIGN(mp) = ZPOS;
+  else
+    SIGN(mp) = sig;
+
+  return MP_OKAY;
+
+} /* end mp_read_radix() */
+
+mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)
+{
+  int     radix = default_radix;
+  int     cx;
+  mp_sign sig   = ZPOS;
+  mp_err  res;
+
+  /* Skip leading non-digit characters until a digit or '-' or '+' */
+  while ((cx = *str) != 0 &&
+        (s_mp_tovalue(cx, radix) < 0) &&
+        cx != '-' &&
+        cx != '+') {
+    ++str;
+  }
+
+  if (cx == '-') {
+    sig = NEG;
+    ++str;
+  } else if (cx == '+') {
+    sig = ZPOS; /* this is the default anyway... */
+    ++str;
+  }
+
+  if (str[0] == '0') {
+    if ((str[1] | 0x20) == 'x') {
+      radix = 16;
+      str += 2;
+    } else {
+      radix = 8;
+      str++;
+    }
+  }
+  res = mp_read_radix(a, str, radix);
+  if (res == MP_OKAY) {
+    MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;
+  }
+  return res;
+}
+
+/* }}} */
+
+/* {{{ mp_radix_size(mp, radix) */
+
+int    mp_radix_size(mp_int *mp, int radix)
+{
+  int  bits;
+
+  if(!mp || radix < 2 || radix > MAX_RADIX)
+    return 0;
+
+  bits = USED(mp) * DIGIT_BIT - 1;
+
+  return s_mp_outlen(bits, radix);
+
+} /* end mp_radix_size() */
+
+/* }}} */
+
+/* {{{ mp_toradix(mp, str, radix) */
+
+mp_err mp_toradix(mp_int *mp, char *str, int radix)
+{
+  int  ix, pos = 0;
+
+  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+  ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
+
+  if(mp_cmp_z(mp) == MP_EQ) {
+    str[0] = '0';
+    str[1] = '\0';
+  } else {
+    mp_err   res;
+    mp_int   tmp;
+    mp_sign  sgn;
+    mp_digit rem, rdx = (mp_digit)radix;
+    char     ch;
+
+    if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
+      return res;
+
+    /* Save sign for later, and take absolute value */
+    sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;
+
+    /* Generate output digits in reverse order      */
+    while(mp_cmp_z(&tmp) != 0) {
+      if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {
+        mp_clear(&tmp);
+        return res;
+      }
+
+      /* Generate digits, use capital letters */
+      ch = s_mp_todigit(rem, radix, 0);
+
+      str[pos++] = ch;
+    }
+
+    /* Add - sign if original value was negative */
+    if(sgn == NEG)
+      str[pos++] = '-';
+
+    /* Add trailing NUL to end the string        */
+    str[pos--] = '\0';
+
+    /* Reverse the digits and sign indicator     */
+    ix = 0;
+    while(ix < pos) {
+      char tmp = str[ix];
+
+      str[ix] = str[pos];
+      str[pos] = tmp;
+      ++ix;
+      --pos;
+    }
+
+    mp_clear(&tmp);
+  }
+
+  return MP_OKAY;
+
+} /* end mp_toradix() */
+
+/* }}} */
+
+/* {{{ mp_tovalue(ch, r) */
+
+int    mp_tovalue(char ch, int r)
+{
+  return s_mp_tovalue(ch, r);
+
+} /* end mp_tovalue() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ mp_strerror(ec) */
+
+/*
+  mp_strerror(ec)
+
+  Return a string describing the meaning of error code 'ec'.  The
+  string returned is allocated in static memory, so the caller should
+  not attempt to modify or free the memory associated with this
+  string.
+ */
+const char  *mp_strerror(mp_err ec)
+{
+  int   aec = (ec < 0) ? -ec : ec;
+
+  /* Code values are negative, so the senses of these comparisons
+     are accurate */
+  if(ec < MP_LAST_CODE || ec > MP_OKAY) {
+    return mp_err_string[0];  /* unknown error code */
+  } else {
+    return mp_err_string[aec + 1];
+  }
+
+} /* end mp_strerror() */
+
+/* }}} */
+
+/*========================================================================*/
+/*------------------------------------------------------------------------*/
+/* Static function definitions (internal use only)                        */
+
+/* {{{ Memory management */
+
+/* {{{ s_mp_grow(mp, min) */
+
+/* Make sure there are at least 'min' digits allocated to mp              */
+mp_err   s_mp_grow(mp_int *mp, mp_size min)
+{
+  if(min > ALLOC(mp)) {
+    mp_digit   *tmp;
+
+    /* Set min to next nearest default precision block size */
+    min = MP_ROUNDUP(min, s_mp_defprec);
+
+    if((tmp = s_mp_alloc(min, sizeof(mp_digit), FLAG(mp))) == NULL)
+      return MP_MEM;
+
+    s_mp_copy(DIGITS(mp), tmp, USED(mp));
+
+#if MP_CRYPTO
+    s_mp_setz(DIGITS(mp), ALLOC(mp));
+#endif
+    s_mp_free(DIGITS(mp), ALLOC(mp));
+    DIGITS(mp) = tmp;
+    ALLOC(mp) = min;
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_grow() */
+
+/* }}} */
+
+/* {{{ s_mp_pad(mp, min) */
+
+/* Make sure the used size of mp is at least 'min', growing if needed     */
+mp_err   s_mp_pad(mp_int *mp, mp_size min)
+{
+  if(min > USED(mp)) {
+    mp_err  res;
+
+    /* Make sure there is room to increase precision  */
+    if (min > ALLOC(mp)) {
+      if ((res = s_mp_grow(mp, min)) != MP_OKAY)
+        return res;
+    } else {
+      s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));
+    }
+
+    /* Increase precision; should already be 0-filled */
+    USED(mp) = min;
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_pad() */
+
+/* }}} */
+
+/* {{{ s_mp_setz(dp, count) */
+
+#if MP_MACRO == 0
+/* Set 'count' digits pointed to by dp to be zeroes                       */
+void s_mp_setz(mp_digit *dp, mp_size count)
+{
+#if MP_MEMSET == 0
+  int  ix;
+
+  for(ix = 0; ix < count; ix++)
+    dp[ix] = 0;
+#else
+  memset(dp, 0, count * sizeof(mp_digit));
+#endif
+
+} /* end s_mp_setz() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_copy(sp, dp, count) */
+
+#if MP_MACRO == 0
+/* Copy 'count' digits from sp to dp                                      */
+void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
+{
+#if MP_MEMCPY == 0
+  int  ix;
+
+  for(ix = 0; ix < count; ix++)
+    dp[ix] = sp[ix];
+#else
+  memcpy(dp, sp, count * sizeof(mp_digit));
+#endif
+
+} /* end s_mp_copy() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_alloc(nb, ni, kmflag) */
+
+#if MP_MACRO == 0
+/* Allocate ni records of nb bytes each, and return a pointer to that     */
+void    *s_mp_alloc(size_t nb, size_t ni, int kmflag)
+{
+  mp_int *mp;
+  ++mp_allocs;
+#ifdef _KERNEL
+  mp = kmem_zalloc(nb * ni, kmflag);
+  if (mp != NULL)
+    FLAG(mp) = kmflag;
+  return (mp);
+#else
+  return calloc(nb, ni);
+#endif
+
+} /* end s_mp_alloc() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_free(ptr) */
+
+#if MP_MACRO == 0
+/* Free the memory pointed to by ptr                                      */
+void     s_mp_free(void *ptr, mp_size alloc)
+{
+  if(ptr) {
+    ++mp_frees;
+#ifdef _KERNEL
+    kmem_free(ptr, alloc * sizeof (mp_digit));
+#else
+    free(ptr);
+#endif
+  }
+} /* end s_mp_free() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_clamp(mp) */
+
+#if MP_MACRO == 0
+/* Remove leading zeroes from the given value                             */
+void     s_mp_clamp(mp_int *mp)
+{
+  mp_size used = MP_USED(mp);
+  while (used > 1 && DIGIT(mp, used - 1) == 0)
+    --used;
+  MP_USED(mp) = used;
+} /* end s_mp_clamp() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_exch(a, b) */
+
+/* Exchange the data for a and b; (b, a) = (a, b)                         */
+void     s_mp_exch(mp_int *a, mp_int *b)
+{
+  mp_int   tmp;
+
+  tmp = *a;
+  *a = *b;
+  *b = tmp;
+
+} /* end s_mp_exch() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Arithmetic helpers */
+
+/* {{{ s_mp_lshd(mp, p) */
+
+/*
+   Shift mp leftward by p digits, growing if needed, and zero-filling
+   the in-shifted digits at the right end.  This is a convenient
+   alternative to multiplication by powers of the radix
+   The value of USED(mp) must already have been set to the value for
+   the shifted result.
+ */
+
+mp_err   s_mp_lshd(mp_int *mp, mp_size p)
+{
+  mp_err  res;
+  mp_size pos;
+  int     ix;
+
+  if(p == 0)
+    return MP_OKAY;
+
+  if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
+    return MP_OKAY;
+
+  if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
+    return res;
+
+  pos = USED(mp) - 1;
+
+  /* Shift all the significant figures over as needed */
+  for(ix = pos - p; ix >= 0; ix--)
+    DIGIT(mp, ix + p) = DIGIT(mp, ix);
+
+  /* Fill the bottom digits with zeroes */
+  for(ix = 0; ix < p; ix++)
+    DIGIT(mp, ix) = 0;
+
+  return MP_OKAY;
+
+} /* end s_mp_lshd() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_2d(mp, d) */
+
+/*
+  Multiply the integer by 2^d, where d is a number of bits.  This
+  amounts to a bitwise shift of the value.
+ */
+mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d)
+{
+  mp_err   res;
+  mp_digit dshift, bshift;
+  mp_digit mask;
+
+  ARGCHK(mp != NULL,  MP_BADARG);
+
+  dshift = d / MP_DIGIT_BIT;
+  bshift = d % MP_DIGIT_BIT;
+  /* bits to be shifted out of the top word */
+  mask   = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));
+  mask  &= MP_DIGIT(mp, MP_USED(mp) - 1);
+
+  if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
+    return res;
+
+  if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))
+    return res;
+
+  if (bshift) {
+    mp_digit *pa = MP_DIGITS(mp);
+    mp_digit *alim = pa + MP_USED(mp);
+    mp_digit  prev = 0;
+
+    for (pa += dshift; pa < alim; ) {
+      mp_digit x = *pa;
+      *pa++ = (x << bshift) | prev;
+      prev = x >> (DIGIT_BIT - bshift);
+    }
+  }
+
+  s_mp_clamp(mp);
+  return MP_OKAY;
+} /* end s_mp_mul_2d() */
+
+/* {{{ s_mp_rshd(mp, p) */
+
+/*
+   Shift mp rightward by p digits.  Maintains the invariant that
+   digits above the precision are all zero.  Digits shifted off the
+   end are lost.  Cannot fail.
+ */
+
+void     s_mp_rshd(mp_int *mp, mp_size p)
+{
+  mp_size  ix;
+  mp_digit *src, *dst;
+
+  if(p == 0)
+    return;
+
+  /* Shortcut when all digits are to be shifted off */
+  if(p >= USED(mp)) {
+    s_mp_setz(DIGITS(mp), ALLOC(mp));
+    USED(mp) = 1;
+    SIGN(mp) = ZPOS;
+    return;
+  }
+
+  /* Shift all the significant figures over as needed */
+  dst = MP_DIGITS(mp);
+  src = dst + p;
+  for (ix = USED(mp) - p; ix > 0; ix--)
+    *dst++ = *src++;
+
+  MP_USED(mp) -= p;
+  /* Fill the top digits with zeroes */
+  while (p-- > 0)
+    *dst++ = 0;
+
+#if 0
+  /* Strip off any leading zeroes    */
+  s_mp_clamp(mp);
+#endif
+
+} /* end s_mp_rshd() */
+
+/* }}} */
+
+/* {{{ s_mp_div_2(mp) */
+
+/* Divide by two -- take advantage of radix properties to do it fast      */
+void     s_mp_div_2(mp_int *mp)
+{
+  s_mp_div_2d(mp, 1);
+
+} /* end s_mp_div_2() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_2(mp) */
+
+mp_err s_mp_mul_2(mp_int *mp)
+{
+  mp_digit *pd;
+  int      ix, used;
+  mp_digit kin = 0;
+
+  /* Shift digits leftward by 1 bit */
+  used = MP_USED(mp);
+  pd = MP_DIGITS(mp);
+  for (ix = 0; ix < used; ix++) {
+    mp_digit d = *pd;
+    *pd++ = (d << 1) | kin;
+    kin = (d >> (DIGIT_BIT - 1));
+  }
+
+  /* Deal with rollover from last digit */
+  if (kin) {
+    if (ix >= ALLOC(mp)) {
+      mp_err res;
+      if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
+        return res;
+    }
+
+    DIGIT(mp, ix) = kin;
+    USED(mp) += 1;
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_mul_2() */
+
+/* }}} */
+
+/* {{{ s_mp_mod_2d(mp, d) */
+
+/*
+  Remainder the integer by 2^d, where d is a number of bits.  This
+  amounts to a bitwise AND of the value, and does not require the full
+  division code
+ */
+void     s_mp_mod_2d(mp_int *mp, mp_digit d)
+{
+  mp_size  ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
+  mp_size  ix;
+  mp_digit dmask;
+
+  if(ndig >= USED(mp))
+    return;
+
+  /* Flush all the bits above 2^d in its digit */
+  dmask = ((mp_digit)1 << nbit) - 1;
+  DIGIT(mp, ndig) &= dmask;
+
+  /* Flush all digits above the one with 2^d in it */
+  for(ix = ndig + 1; ix < USED(mp); ix++)
+    DIGIT(mp, ix) = 0;
+
+  s_mp_clamp(mp);
+
+} /* end s_mp_mod_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_div_2d(mp, d) */
+
+/*
+  Divide the integer by 2^d, where d is a number of bits.  This
+  amounts to a bitwise shift of the value, and does not require the
+  full division code (used in Barrett reduction, see below)
+ */
+void     s_mp_div_2d(mp_int *mp, mp_digit d)
+{
+  int       ix;
+  mp_digit  save, next, mask;
+
+  s_mp_rshd(mp, d / DIGIT_BIT);
+  d %= DIGIT_BIT;
+  if (d) {
+    mask = ((mp_digit)1 << d) - 1;
+    save = 0;
+    for(ix = USED(mp) - 1; ix >= 0; ix--) {
+      next = DIGIT(mp, ix) & mask;
+      DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));
+      save = next;
+    }
+  }
+  s_mp_clamp(mp);
+
+} /* end s_mp_div_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_norm(a, b, *d) */
+
+/*
+  s_mp_norm(a, b, *d)
+
+  Normalize a and b for division, where b is the divisor.  In order
+  that we might make good guesses for quotient digits, we want the
+  leading digit of b to be at least half the radix, which we
+  accomplish by multiplying a and b by a power of 2.  The exponent
+  (shift count) is placed in *pd, so that the remainder can be shifted
+  back at the end of the division process.
+ */
+
+mp_err   s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
+{
+  mp_digit  d;
+  mp_digit  mask;
+  mp_digit  b_msd;
+  mp_err    res    = MP_OKAY;
+
+  d = 0;
+  mask  = DIGIT_MAX & ~(DIGIT_MAX >> 1);        /* mask is msb of digit */
+  b_msd = DIGIT(b, USED(b) - 1);
+  while (!(b_msd & mask)) {
+    b_msd <<= 1;
+    ++d;
+  }
+
+  if (d) {
+    MP_CHECKOK( s_mp_mul_2d(a, d) );
+    MP_CHECKOK( s_mp_mul_2d(b, d) );
+  }
+
+  *pd = d;
+CLEANUP:
+  return res;
+
+} /* end s_mp_norm() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive digit arithmetic */
+
+/* {{{ s_mp_add_d(mp, d) */
+
+/* Add d to |mp| in place                                                 */
+mp_err   s_mp_add_d(mp_int *mp, mp_digit d)    /* unsigned digit addition */
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  mp_word   w, k = 0;
+  mp_size   ix = 1;
+
+  w = (mp_word)DIGIT(mp, 0) + d;
+  DIGIT(mp, 0) = ACCUM(w);
+  k = CARRYOUT(w);
+
+  while(ix < USED(mp) && k) {
+    w = (mp_word)DIGIT(mp, ix) + k;
+    DIGIT(mp, ix) = ACCUM(w);
+    k = CARRYOUT(w);
+    ++ix;
+  }
+
+  if(k != 0) {
+    mp_err  res;
+
+    if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(mp, ix) = (mp_digit)k;
+  }
+
+  return MP_OKAY;
+#else
+  mp_digit * pmp = MP_DIGITS(mp);
+  mp_digit sum, mp_i, carry = 0;
+  mp_err   res = MP_OKAY;
+  int used = (int)MP_USED(mp);
+
+  mp_i = *pmp;
+  *pmp++ = sum = d + mp_i;
+  carry = (sum < d);
+  while (carry && --used > 0) {
+    mp_i = *pmp;
+    *pmp++ = sum = carry + mp_i;
+    carry = !sum;
+  }
+  if (carry && !used) {
+    /* mp is growing */
+    used = MP_USED(mp);
+    MP_CHECKOK( s_mp_pad(mp, used + 1) );
+    MP_DIGIT(mp, used) = carry;
+  }
+CLEANUP:
+  return res;
+#endif
+} /* end s_mp_add_d() */
+
+/* }}} */
+
+/* {{{ s_mp_sub_d(mp, d) */
+
+/* Subtract d from |mp| in place, assumes |mp| > d                        */
+mp_err   s_mp_sub_d(mp_int *mp, mp_digit d)    /* unsigned digit subtract */
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+  mp_word   w, b = 0;
+  mp_size   ix = 1;
+
+  /* Compute initial subtraction    */
+  w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
+  b = CARRYOUT(w) ? 0 : 1;
+  DIGIT(mp, 0) = ACCUM(w);
+
+  /* Propagate borrows leftward     */
+  while(b && ix < USED(mp)) {
+    w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
+    b = CARRYOUT(w) ? 0 : 1;
+    DIGIT(mp, ix) = ACCUM(w);
+    ++ix;
+  }
+
+  /* Remove leading zeroes          */
+  s_mp_clamp(mp);
+
+  /* If we have a borrow out, it's a violation of the input invariant */
+  if(b)
+    return MP_RANGE;
+  else
+    return MP_OKAY;
+#else
+  mp_digit *pmp = MP_DIGITS(mp);
+  mp_digit mp_i, diff, borrow;
+  mp_size  used = MP_USED(mp);
+
+  mp_i = *pmp;
+  *pmp++ = diff = mp_i - d;
+  borrow = (diff > mp_i);
+  while (borrow && --used) {
+    mp_i = *pmp;
+    *pmp++ = diff = mp_i - borrow;
+    borrow = (diff > mp_i);
+  }
+  s_mp_clamp(mp);
+  return (borrow && !used) ? MP_RANGE : MP_OKAY;
+#endif
+} /* end s_mp_sub_d() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_d(a, d) */
+
+/* Compute a = a * d, single digit multiplication                         */
+mp_err   s_mp_mul_d(mp_int *a, mp_digit d)
+{
+  mp_err  res;
+  mp_size used;
+  int     pow;
+
+  if (!d) {
+    mp_zero(a);
+    return MP_OKAY;
+  }
+  if (d == 1)
+    return MP_OKAY;
+  if (0 <= (pow = s_mp_ispow2d(d))) {
+    return s_mp_mul_2d(a, (mp_digit)pow);
+  }
+
+  used = MP_USED(a);
+  MP_CHECKOK( s_mp_pad(a, used + 1) );
+
+  s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
+
+  s_mp_clamp(a);
+
+CLEANUP:
+  return res;
+
+} /* end s_mp_mul_d() */
+
+/* }}} */
+
+/* {{{ s_mp_div_d(mp, d, r) */
+
+/*
+  s_mp_div_d(mp, d, r)
+
+  Compute the quotient mp = mp / d and remainder r = mp mod d, for a
+  single digit d.  If r is null, the remainder will be discarded.
+ */
+
+mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
+  mp_word   w = 0, q;
+#else
+  mp_digit  w, q;
+#endif
+  int       ix;
+  mp_err    res;
+  mp_int    quot;
+  mp_int    rem;
+
+  if(d == 0)
+    return MP_RANGE;
+  if (d == 1) {
+    if (r)
+      *r = 0;
+    return MP_OKAY;
+  }
+  /* could check for power of 2 here, but mp_div_d does that. */
+  if (MP_USED(mp) == 1) {
+    mp_digit n   = MP_DIGIT(mp,0);
+    mp_digit rem;
+
+    q   = n / d;
+    rem = n % d;
+    MP_DIGIT(mp,0) = q;
+    if (r)
+      *r = rem;
+    return MP_OKAY;
+  }
+
+  MP_DIGITS(&rem)  = 0;
+  MP_DIGITS(&quot) = 0;
+  /* Make room for the quotient */
+  MP_CHECKOK( mp_init_size(&quot, USED(mp), FLAG(mp)) );
+
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    w = (w << DIGIT_BIT) | DIGIT(mp, ix);
+
+    if(w >= d) {
+      q = w / d;
+      w = w % d;
+    } else {
+      q = 0;
+    }
+
+    s_mp_lshd(&quot, 1);
+    DIGIT(&quot, 0) = (mp_digit)q;
+  }
+#else
+  {
+    mp_digit p;
+#if !defined(MP_ASSEMBLY_DIV_2DX1D)
+    mp_digit norm;
+#endif
+
+    MP_CHECKOK( mp_init_copy(&rem, mp) );
+
+#if !defined(MP_ASSEMBLY_DIV_2DX1D)
+    MP_DIGIT(&quot, 0) = d;
+    MP_CHECKOK( s_mp_norm(&rem, &quot, &norm) );
+    if (norm)
+      d <<= norm;
+    MP_DIGIT(&quot, 0) = 0;
+#endif
+
+    p = 0;
+    for (ix = USED(&rem) - 1; ix >= 0; ix--) {
+      w = DIGIT(&rem, ix);
+
+      if (p) {
+        MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );
+      } else if (w >= d) {
+        q = w / d;
+        w = w % d;
+      } else {
+        q = 0;
+      }
+
+      MP_CHECKOK( s_mp_lshd(&quot, 1) );
+      DIGIT(&quot, 0) = q;
+      p = w;
+    }
+#if !defined(MP_ASSEMBLY_DIV_2DX1D)
+    if (norm)
+      w >>= norm;
+#endif
+  }
+#endif
+
+  /* Deliver the remainder, if desired */
+  if(r)
+    *r = (mp_digit)w;
+
+  s_mp_clamp(&quot);
+  mp_exch(&quot, mp);
+CLEANUP:
+  mp_clear(&quot);
+  mp_clear(&rem);
+
+  return res;
+} /* end s_mp_div_d() */
+
+/* }}} */
+
+
+/* }}} */
+
+/* {{{ Primitive full arithmetic */
+
+/* {{{ s_mp_add(a, b) */
+
+/* Compute a = |a| + |b|                                                  */
+mp_err   s_mp_add(mp_int *a, const mp_int *b)  /* magnitude addition      */
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  mp_word   w = 0;
+#else
+  mp_digit  d, sum, carry = 0;
+#endif
+  mp_digit *pa, *pb;
+  mp_size   ix;
+  mp_size   used;
+  mp_err    res;
+
+  /* Make sure a has enough precision for the output value */
+  if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)
+    return res;
+
+  /*
+    Add up all digits up to the precision of b.  If b had initially
+    the same precision as a, or greater, we took care of it by the
+    padding step above, so there is no problem.  If b had initially
+    less precision, we'll have to make sure the carry out is duly
+    propagated upward among the higher-order digits of the sum.
+   */
+  pa = MP_DIGITS(a);
+  pb = MP_DIGITS(b);
+  used = MP_USED(b);
+  for(ix = 0; ix < used; ix++) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+    w = w + *pa + *pb++;
+    *pa++ = ACCUM(w);
+    w = CARRYOUT(w);
+#else
+    d = *pa;
+    sum = d + *pb++;
+    d = (sum < d);                      /* detect overflow */
+    *pa++ = sum += carry;
+    carry = d + (sum < carry);          /* detect overflow */
+#endif
+  }
+
+  /* If we run out of 'b' digits before we're actually done, make
+     sure the carries get propagated upward...
+   */
+  used = MP_USED(a);
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  while (w && ix < used) {
+    w = w + *pa;
+    *pa++ = ACCUM(w);
+    w = CARRYOUT(w);
+    ++ix;
+  }
+#else
+  while (carry && ix < used) {
+    sum = carry + *pa;
+    *pa++ = sum;
+    carry = !sum;
+    ++ix;
+  }
+#endif
+
+  /* If there's an overall carry out, increase precision and include
+     it.  We could have done this initially, but why touch the memory
+     allocator unless we're sure we have to?
+   */
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  if (w) {
+    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(a, ix) = (mp_digit)w;
+  }
+#else
+  if (carry) {
+    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(a, used) = carry;
+  }
+#endif
+
+  return MP_OKAY;
+} /* end s_mp_add() */
+
+/* }}} */
+
+/* Compute c = |a| + |b|         */ /* magnitude addition      */
+mp_err   s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
+{
+  mp_digit *pa, *pb, *pc;
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  mp_word   w = 0;
+#else
+  mp_digit  sum, carry = 0, d;
+#endif
+  mp_size   ix;
+  mp_size   used;
+  mp_err    res;
+
+  MP_SIGN(c) = MP_SIGN(a);
+  if (MP_USED(a) < MP_USED(b)) {
+    const mp_int *xch = a;
+    a = b;
+    b = xch;
+  }
+
+  /* Make sure a has enough precision for the output value */
+  if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
+    return res;
+
+  /*
+    Add up all digits up to the precision of b.  If b had initially
+    the same precision as a, or greater, we took care of it by the
+    exchange step above, so there is no problem.  If b had initially
+    less precision, we'll have to make sure the carry out is duly
+    propagated upward among the higher-order digits of the sum.
+   */
+  pa = MP_DIGITS(a);
+  pb = MP_DIGITS(b);
+  pc = MP_DIGITS(c);
+  used = MP_USED(b);
+  for (ix = 0; ix < used; ix++) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+    w = w + *pa++ + *pb++;
+    *pc++ = ACCUM(w);
+    w = CARRYOUT(w);
+#else
+    d = *pa++;
+    sum = d + *pb++;
+    d = (sum < d);                      /* detect overflow */
+    *pc++ = sum += carry;
+    carry = d + (sum < carry);          /* detect overflow */
+#endif
+  }
+
+  /* If we run out of 'b' digits before we're actually done, make
+     sure the carries get propagated upward...
+   */
+  for (used = MP_USED(a); ix < used; ++ix) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+    w = w + *pa++;
+    *pc++ = ACCUM(w);
+    w = CARRYOUT(w);
+#else
+    *pc++ = sum = carry + *pa++;
+    carry = (sum < carry);
+#endif
+  }
+
+  /* If there's an overall carry out, increase precision and include
+     it.  We could have done this initially, but why touch the memory
+     allocator unless we're sure we have to?
+   */
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  if (w) {
+    if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(c, used) = (mp_digit)w;
+    ++used;
+  }
+#else
+  if (carry) {
+    if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(c, used) = carry;
+    ++used;
+  }
+#endif
+  MP_USED(c) = used;
+  return MP_OKAY;
+}
+/* {{{ s_mp_add_offset(a, b, offset) */
+
+/* Compute a = |a| + ( |b| * (RADIX ** offset) )             */
+mp_err   s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  mp_word   w, k = 0;
+#else
+  mp_digit  d, sum, carry = 0;
+#endif
+  mp_size   ib;
+  mp_size   ia;
+  mp_size   lim;
+  mp_err    res;
+
+  /* Make sure a has enough precision for the output value */
+  lim = MP_USED(b) + offset;
+  if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)
+    return res;
+
+  /*
+    Add up all digits up to the precision of b.  If b had initially
+    the same precision as a, or greater, we took care of it by the
+    padding step above, so there is no problem.  If b had initially
+    less precision, we'll have to make sure the carry out is duly
+    propagated upward among the higher-order digits of the sum.
+   */
+  lim = USED(b);
+  for(ib = 0, ia = offset; ib < lim; ib++, ia++) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+    w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;
+    DIGIT(a, ia) = ACCUM(w);
+    k = CARRYOUT(w);
+#else
+    d = MP_DIGIT(a, ia);
+    sum = d + MP_DIGIT(b, ib);
+    d = (sum < d);
+    MP_DIGIT(a,ia) = sum += carry;
+    carry = d + (sum < carry);
+#endif
+  }
+
+  /* If we run out of 'b' digits before we're actually done, make
+     sure the carries get propagated upward...
+   */
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  for (lim = MP_USED(a); k && (ia < lim); ++ia) {
+    w = (mp_word)DIGIT(a, ia) + k;
+    DIGIT(a, ia) = ACCUM(w);
+    k = CARRYOUT(w);
+  }
+#else
+  for (lim = MP_USED(a); carry && (ia < lim); ++ia) {
+    d = MP_DIGIT(a, ia);
+    MP_DIGIT(a,ia) = sum = d + carry;
+    carry = (sum < d);
+  }
+#endif
+
+  /* If there's an overall carry out, increase precision and include
+     it.  We could have done this initially, but why touch the memory
+     allocator unless we're sure we have to?
+   */
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
+  if(k) {
+    if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(a, ia) = (mp_digit)k;
+  }
+#else
+  if (carry) {
+    if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(a, lim) = carry;
+  }
+#endif
+  s_mp_clamp(a);
+
+  return MP_OKAY;
+
+} /* end s_mp_add_offset() */
+
+/* }}} */
+
+/* {{{ s_mp_sub(a, b) */
+
+/* Compute a = |a| - |b|, assumes |a| >= |b|                              */
+mp_err   s_mp_sub(mp_int *a, const mp_int *b)  /* magnitude subtract      */
+{
+  mp_digit *pa, *pb, *limit;
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+  mp_sword  w = 0;
+#else
+  mp_digit  d, diff, borrow = 0;
+#endif
+
+  /*
+    Subtract and propagate borrow.  Up to the precision of b, this
+    accounts for the digits of b; after that, we just make sure the
+    carries get to the right place.  This saves having to pad b out to
+    the precision of a just to make the loops work right...
+   */
+  pa = MP_DIGITS(a);
+  pb = MP_DIGITS(b);
+  limit = pb + MP_USED(b);
+  while (pb < limit) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+    w = w + *pa - *pb++;
+    *pa++ = ACCUM(w);
+    w >>= MP_DIGIT_BIT;
+#else
+    d = *pa;
+    diff = d - *pb++;
+    d = (diff > d);                             /* detect borrow */
+    if (borrow && --diff == MP_DIGIT_MAX)
+      ++d;
+    *pa++ = diff;
+    borrow = d;
+#endif
+  }
+  limit = MP_DIGITS(a) + MP_USED(a);
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+  while (w && pa < limit) {
+    w = w + *pa;
+    *pa++ = ACCUM(w);
+    w >>= MP_DIGIT_BIT;
+  }
+#else
+  while (borrow && pa < limit) {
+    d = *pa;
+    *pa++ = diff = d - borrow;
+    borrow = (diff > d);
+  }
+#endif
+
+  /* Clobber any leading zeroes we created    */
+  s_mp_clamp(a);
+
+  /*
+     If there was a borrow out, then |b| > |a| in violation
+     of our input invariant.  We've already done the work,
+     but we'll at least complain about it...
+   */
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+  return w ? MP_RANGE : MP_OKAY;
+#else
+  return borrow ? MP_RANGE : MP_OKAY;
+#endif
+} /* end s_mp_sub() */
+
+/* }}} */
+
+/* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract      */
+mp_err   s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
+{
+  mp_digit *pa, *pb, *pc;
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+  mp_sword  w = 0;
+#else
+  mp_digit  d, diff, borrow = 0;
+#endif
+  int       ix, limit;
+  mp_err    res;
+
+  MP_SIGN(c) = MP_SIGN(a);
+
+  /* Make sure a has enough precision for the output value */
+  if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
+    return res;
+
+  /*
+    Subtract and propagate borrow.  Up to the precision of b, this
+    accounts for the digits of b; after that, we just make sure the
+    carries get to the right place.  This saves having to pad b out to
+    the precision of a just to make the loops work right...
+   */
+  pa = MP_DIGITS(a);
+  pb = MP_DIGITS(b);
+  pc = MP_DIGITS(c);
+  limit = MP_USED(b);
+  for (ix = 0; ix < limit; ++ix) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+    w = w + *pa++ - *pb++;
+    *pc++ = ACCUM(w);
+    w >>= MP_DIGIT_BIT;
+#else
+    d = *pa++;
+    diff = d - *pb++;
+    d = (diff > d);
+    if (borrow && --diff == MP_DIGIT_MAX)
+      ++d;
+    *pc++ = diff;
+    borrow = d;
+#endif
+  }
+  for (limit = MP_USED(a); ix < limit; ++ix) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+    w = w + *pa++;
+    *pc++ = ACCUM(w);
+    w >>= MP_DIGIT_BIT;
+#else
+    d = *pa++;
+    *pc++ = diff = d - borrow;
+    borrow = (diff > d);
+#endif
+  }
+
+  /* Clobber any leading zeroes we created    */
+  MP_USED(c) = ix;
+  s_mp_clamp(c);
+
+  /*
+     If there was a borrow out, then |b| > |a| in violation
+     of our input invariant.  We've already done the work,
+     but we'll at least complain about it...
+   */
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
+  return w ? MP_RANGE : MP_OKAY;
+#else
+  return borrow ? MP_RANGE : MP_OKAY;
+#endif
+}
+/* {{{ s_mp_mul(a, b) */
+
+/* Compute a = |a| * |b|                                                  */
+mp_err   s_mp_mul(mp_int *a, const mp_int *b)
+{
+  return mp_mul(a, b, a);
+} /* end s_mp_mul() */
+
+/* }}} */
+
+#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
+/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
+#define MP_MUL_DxD(a, b, Phi, Plo) \
+  { unsigned long long product = (unsigned long long)a * b; \
+    Plo = (mp_digit)product; \
+    Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
+#elif defined(OSF1)
+#define MP_MUL_DxD(a, b, Phi, Plo) \
+  { Plo = asm ("mulq %a0, %a1, %v0", a, b);\
+    Phi = asm ("umulh %a0, %a1, %v0", a, b); }
+#else
+#define MP_MUL_DxD(a, b, Phi, Plo) \
+  { mp_digit a0b1, a1b0; \
+    Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \
+    Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \
+    a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \
+    a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
+    a1b0 += a0b1; \
+    Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
+    if (a1b0 < a0b1)  \
+      Phi += MP_HALF_RADIX; \
+    a1b0 <<= MP_HALF_DIGIT_BIT; \
+    Plo += a1b0; \
+    if (Plo < a1b0) \
+      ++Phi; \
+  }
+#endif
+
+#if !defined(MP_ASSEMBLY_MULTIPLY)
+/* c = a * b */
+void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
+  mp_digit   d = 0;
+
+  /* Inner product:  Digits of a */
+  while (a_len--) {
+    mp_word w = ((mp_word)b * *a++) + d;
+    *c++ = ACCUM(w);
+    d = CARRYOUT(w);
+  }
+  *c = d;
+#else
+  mp_digit carry = 0;
+  while (a_len--) {
+    mp_digit a_i = *a++;
+    mp_digit a0b0, a1b1;
+
+    MP_MUL_DxD(a_i, b, a1b1, a0b0);
+
+    a0b0 += carry;
+    if (a0b0 < carry)
+      ++a1b1;
+    *c++ = a0b0;
+    carry = a1b1;
+  }
+  *c = carry;
+#endif
+}
+
+/* c += a * b */
+void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
+                              mp_digit *c)
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
+  mp_digit   d = 0;
+
+  /* Inner product:  Digits of a */
+  while (a_len--) {
+    mp_word w = ((mp_word)b * *a++) + *c + d;
+    *c++ = ACCUM(w);
+    d = CARRYOUT(w);
+  }
+  *c = d;
+#else
+  mp_digit carry = 0;
+  while (a_len--) {
+    mp_digit a_i = *a++;
+    mp_digit a0b0, a1b1;
+
+    MP_MUL_DxD(a_i, b, a1b1, a0b0);
+
+    a0b0 += carry;
+    if (a0b0 < carry)
+      ++a1b1;
+    a0b0 += a_i = *c;
+    if (a0b0 < a_i)
+      ++a1b1;
+    *c++ = a0b0;
+    carry = a1b1;
+  }
+  *c = carry;
+#endif
+}
+
+/* Presently, this is only used by the Montgomery arithmetic code. */
+/* c += a * b */
+void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
+  mp_digit   d = 0;
+
+  /* Inner product:  Digits of a */
+  while (a_len--) {
+    mp_word w = ((mp_word)b * *a++) + *c + d;
+    *c++ = ACCUM(w);
+    d = CARRYOUT(w);
+  }
+
+  while (d) {
+    mp_word w = (mp_word)*c + d;
+    *c++ = ACCUM(w);
+    d = CARRYOUT(w);
+  }
+#else
+  mp_digit carry = 0;
+  while (a_len--) {
+    mp_digit a_i = *a++;
+    mp_digit a0b0, a1b1;
+
+    MP_MUL_DxD(a_i, b, a1b1, a0b0);
+
+    a0b0 += carry;
+    if (a0b0 < carry)
+      ++a1b1;
+
+    a0b0 += a_i = *c;
+    if (a0b0 < a_i)
+      ++a1b1;
+
+    *c++ = a0b0;
+    carry = a1b1;
+  }
+  while (carry) {
+    mp_digit c_i = *c;
+    carry += c_i;
+    *c++ = carry;
+    carry = carry < c_i;
+  }
+#endif
+}
+#endif
+
+#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
+/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
+#define MP_SQR_D(a, Phi, Plo) \
+  { unsigned long long square = (unsigned long long)a * a; \
+    Plo = (mp_digit)square; \
+    Phi = (mp_digit)(square >> MP_DIGIT_BIT); }
+#elif defined(OSF1)
+#define MP_SQR_D(a, Phi, Plo) \
+  { Plo = asm ("mulq  %a0, %a0, %v0", a);\
+    Phi = asm ("umulh %a0, %a0, %v0", a); }
+#else
+#define MP_SQR_D(a, Phi, Plo) \
+  { mp_digit Pmid; \
+    Plo  = (a  & MP_HALF_DIGIT_MAX) * (a  & MP_HALF_DIGIT_MAX); \
+    Phi  = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \
+    Pmid = (a  & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \
+    Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1);  \
+    Pmid <<= (MP_HALF_DIGIT_BIT + 1);  \
+    Plo += Pmid;  \
+    if (Plo < Pmid)  \
+      ++Phi;  \
+  }
+#endif
+
+#if !defined(MP_ASSEMBLY_SQUARE)
+/* Add the squares of the digits of a to the digits of b. */
+void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
+{
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
+  mp_word  w;
+  mp_digit d;
+  mp_size  ix;
+
+  w  = 0;
+#define ADD_SQUARE(n) \
+    d = pa[n]; \
+    w += (d * (mp_word)d) + ps[2*n]; \
+    ps[2*n] = ACCUM(w); \
+    w = (w >> DIGIT_BIT) + ps[2*n+1]; \
+    ps[2*n+1] = ACCUM(w); \
+    w = (w >> DIGIT_BIT)
+
+  for (ix = a_len; ix >= 4; ix -= 4) {
+    ADD_SQUARE(0);
+    ADD_SQUARE(1);
+    ADD_SQUARE(2);
+    ADD_SQUARE(3);
+    pa += 4;
+    ps += 8;
+  }
+  if (ix) {
+    ps += 2*ix;
+    pa += ix;
+    switch (ix) {
+    case 3: ADD_SQUARE(-3); /* FALLTHRU */
+    case 2: ADD_SQUARE(-2); /* FALLTHRU */
+    case 1: ADD_SQUARE(-1); /* FALLTHRU */
+    case 0: break;
+    }
+  }
+  while (w) {
+    w += *ps;
+    *ps++ = ACCUM(w);
+    w = (w >> DIGIT_BIT);
+  }
+#else
+  mp_digit carry = 0;
+  while (a_len--) {
+    mp_digit a_i = *pa++;
+    mp_digit a0a0, a1a1;
+
+    MP_SQR_D(a_i, a1a1, a0a0);
+
+    /* here a1a1 and a0a0 constitute a_i ** 2 */
+    a0a0 += carry;
+    if (a0a0 < carry)
+      ++a1a1;
+
+    /* now add to ps */
+    a0a0 += a_i = *ps;
+    if (a0a0 < a_i)
+      ++a1a1;
+    *ps++ = a0a0;
+    a1a1 += a_i = *ps;
+    carry = (a1a1 < a_i);
+    *ps++ = a1a1;
+  }
+  while (carry) {
+    mp_digit s_i = *ps;
+    carry += s_i;
+    *ps++ = carry;
+    carry = carry < s_i;
+  }
+#endif
+}
+#endif
+
+#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \
+&& !defined(MP_ASSEMBLY_DIV_2DX1D)
+/*
+** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
+** so its high bit is 1.   This code is from NSPR.
+*/
+mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
+                       mp_digit *qp, mp_digit *rp)
+{
+    mp_digit d1, d0, q1, q0;
+    mp_digit r1, r0, m;
+
+    d1 = divisor >> MP_HALF_DIGIT_BIT;
+    d0 = divisor & MP_HALF_DIGIT_MAX;
+    r1 = Nhi % d1;
+    q1 = Nhi / d1;
+    m = q1 * d0;
+    r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);
+    if (r1 < m) {
+        q1--, r1 += divisor;
+        if (r1 >= divisor && r1 < m) {
+            q1--, r1 += divisor;
+        }
+    }
+    r1 -= m;
+    r0 = r1 % d1;
+    q0 = r1 / d1;
+    m = q0 * d0;
+    r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);
+    if (r0 < m) {
+        q0--, r0 += divisor;
+        if (r0 >= divisor && r0 < m) {
+            q0--, r0 += divisor;
+        }
+    }
+    if (qp)
+        *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
+    if (rp)
+        *rp = r0 - m;
+    return MP_OKAY;
+}
+#endif
+
+#if MP_SQUARE
+/* {{{ s_mp_sqr(a) */
+
+mp_err   s_mp_sqr(mp_int *a)
+{
+  mp_err   res;
+  mp_int   tmp;
+
+  if((res = mp_init_size(&tmp, 2 * USED(a), FLAG(a))) != MP_OKAY)
+    return res;
+  res = mp_sqr(a, &tmp);
+  if (res == MP_OKAY) {
+    s_mp_exch(&tmp, a);
+  }
+  mp_clear(&tmp);
+  return res;
+}
+
+/* }}} */
+#endif
+
+/* {{{ s_mp_div(a, b) */
+
+/*
+  s_mp_div(a, b)
+
+  Compute a = a / b and b = a mod b.  Assumes b > a.
+ */
+
+mp_err   s_mp_div(mp_int *rem,  /* i: dividend, o: remainder */
+                  mp_int *div,  /* i: divisor                */
+                  mp_int *quot) /* i: 0;        o: quotient  */
+{
+  mp_int   part, t;
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
+  mp_word  q_msd;
+#else
+  mp_digit q_msd;
+#endif
+  mp_err   res;
+  mp_digit d;
+  mp_digit div_msd;
+  int      ix;
+
+  if(mp_cmp_z(div) == 0)
+    return MP_RANGE;
+
+  /* Shortcut if divisor is power of two */
+  if((ix = s_mp_ispow2(div)) >= 0) {
+    MP_CHECKOK( mp_copy(rem, quot) );
+    s_mp_div_2d(quot, (mp_digit)ix);
+    s_mp_mod_2d(rem,  (mp_digit)ix);
+
+    return MP_OKAY;
+  }
+
+  DIGITS(&t) = 0;
+  MP_SIGN(rem) = ZPOS;
+  MP_SIGN(div) = ZPOS;
+
+  /* A working temporary for division     */
+  MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem), FLAG(rem)));
+
+  /* Normalize to optimize guessing       */
+  MP_CHECKOK( s_mp_norm(rem, div, &d) );
+
+  part = *rem;
+
+  /* Perform the division itself...woo!   */
+  MP_USED(quot) = MP_ALLOC(quot);
+
+  /* Find a partial substring of rem which is at least div */
+  /* If we didn't find one, we're finished dividing    */
+  while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
+    int i;
+    int unusedRem;
+
+    unusedRem = MP_USED(rem) - MP_USED(div);
+    MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
+    MP_ALLOC(&part)  = MP_ALLOC(rem)  - unusedRem;
+    MP_USED(&part)   = MP_USED(div);
+    if (s_mp_cmp(&part, div) < 0) {
+      -- unusedRem;
+#if MP_ARGCHK == 2
+      assert(unusedRem >= 0);
+#endif
+      -- MP_DIGITS(&part);
+      ++ MP_USED(&part);
+      ++ MP_ALLOC(&part);
+    }
+
+    /* Compute a guess for the next quotient digit       */
+    q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
+    div_msd = MP_DIGIT(div, MP_USED(div) - 1);
+    if (q_msd >= div_msd) {
+      q_msd = 1;
+    } else if (MP_USED(&part) > 1) {
+#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
+      q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
+      q_msd /= div_msd;
+      if (q_msd == RADIX)
+        --q_msd;
+#else
+      mp_digit r;
+      MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
+                                  div_msd, &q_msd, &r) );
+#endif
+    } else {
+      q_msd = 0;
+    }
+#if MP_ARGCHK == 2
+    assert(q_msd > 0); /* This case should never occur any more. */
+#endif
+    if (q_msd <= 0)
+      break;
+
+    /* See what that multiplies out to                   */
+    mp_copy(div, &t);
+    MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );
+
+    /*
+       If it's too big, back it off.  We should not have to do this
+       more than once, or, in rare cases, twice.  Knuth describes a
+       method by which this could be reduced to a maximum of once, but
+       I didn't implement that here.
+     * When using s_mpv_div_2dx1d, we may have to do this 3 times.
+     */
+    for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
+      --q_msd;
+      s_mp_sub(&t, div);        /* t -= div */
+    }
+    if (i < 0) {
+      res = MP_RANGE;
+      goto CLEANUP;
+    }
+
+    /* At this point, q_msd should be the right next digit   */
+    MP_CHECKOK( s_mp_sub(&part, &t) );  /* part -= t */
+    s_mp_clamp(rem);
+
+    /*
+      Include the digit in the quotient.  We allocated enough memory
+      for any quotient we could ever possibly get, so we should not
+      have to check for failures here
+     */
+    MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
+  }
+
+  /* Denormalize remainder                */
+  if (d) {
+    s_mp_div_2d(rem, d);
+  }
+
+  s_mp_clamp(quot);
+
+CLEANUP:
+  mp_clear(&t);
+
+  return res;
+
+} /* end s_mp_div() */
+
+
+/* }}} */
+
+/* {{{ s_mp_2expt(a, k) */
+
+mp_err   s_mp_2expt(mp_int *a, mp_digit k)
+{
+  mp_err    res;
+  mp_size   dig, bit;
+
+  dig = k / DIGIT_BIT;
+  bit = k % DIGIT_BIT;
+
+  mp_zero(a);
+  if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
+    return res;
+
+  DIGIT(a, dig) |= ((mp_digit)1 << bit);
+
+  return MP_OKAY;
+
+} /* end s_mp_2expt() */
+
+/* }}} */
+
+/* {{{ s_mp_reduce(x, m, mu) */
+
+/*
+  Compute Barrett reduction, x (mod m), given a precomputed value for
+  mu = b^2k / m, where b = RADIX and k = #digits(m).  This should be
+  faster than straight division, when many reductions by the same
+  value of m are required (such as in modular exponentiation).  This
+  can nearly halve the time required to do modular exponentiation,
+  as compared to using the full integer divide to reduce.
+
+  This algorithm was derived from the _Handbook of Applied
+  Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
+  pp. 603-604.
+ */
+
+mp_err   s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
+{
+  mp_int   q;
+  mp_err   res;
+
+  if((res = mp_init_copy(&q, x)) != MP_OKAY)
+    return res;
+
+  s_mp_rshd(&q, USED(m) - 1);  /* q1 = x / b^(k-1)  */
+  s_mp_mul(&q, mu);            /* q2 = q1 * mu      */
+  s_mp_rshd(&q, USED(m) + 1);  /* q3 = q2 / b^(k+1) */
+
+  /* x = x mod b^(k+1), quick (no division) */
+  s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));
+
+  /* q = q * m mod b^(k+1), quick (no division) */
+  s_mp_mul(&q, m);
+  s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));
+
+  /* x = x - q */
+  if((res = mp_sub(x, &q, x)) != MP_OKAY)
+    goto CLEANUP;
+
+  /* If x < 0, add b^(k+1) to it */
+  if(mp_cmp_z(x) < 0) {
+    mp_set(&q, 1);
+    if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)
+      goto CLEANUP;
+    if((res = mp_add(x, &q, x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  /* Back off if it's too big */
+  while(mp_cmp(x, m) >= 0) {
+    if((res = s_mp_sub(x, m)) != MP_OKAY)
+      break;
+  }
+
+ CLEANUP:
+  mp_clear(&q);
+
+  return res;
+
+} /* end s_mp_reduce() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive comparisons */
+
+/* {{{ s_mp_cmp(a, b) */
+
+/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b           */
+int      s_mp_cmp(const mp_int *a, const mp_int *b)
+{
+  mp_size used_a = MP_USED(a);
+  {
+    mp_size used_b = MP_USED(b);
+
+    if (used_a > used_b)
+      goto IS_GT;
+    if (used_a < used_b)
+      goto IS_LT;
+  }
+  {
+    mp_digit *pa, *pb;
+    mp_digit da = 0, db = 0;
+
+#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done
+
+    pa = MP_DIGITS(a) + used_a;
+    pb = MP_DIGITS(b) + used_a;
+    while (used_a >= 4) {
+      pa     -= 4;
+      pb     -= 4;
+      used_a -= 4;
+      CMP_AB(3);
+      CMP_AB(2);
+      CMP_AB(1);
+      CMP_AB(0);
+    }
+    while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))
+      /* do nothing */;
+done:
+    if (da > db)
+      goto IS_GT;
+    if (da < db)
+      goto IS_LT;
+  }
+  return MP_EQ;
+IS_LT:
+  return MP_LT;
+IS_GT:
+  return MP_GT;
+} /* end s_mp_cmp() */
+
+/* }}} */
+
+/* {{{ s_mp_cmp_d(a, d) */
+
+/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d             */
+int      s_mp_cmp_d(const mp_int *a, mp_digit d)
+{
+  if(USED(a) > 1)
+    return MP_GT;
+
+  if(DIGIT(a, 0) < d)
+    return MP_LT;
+  else if(DIGIT(a, 0) > d)
+    return MP_GT;
+  else
+    return MP_EQ;
+
+} /* end s_mp_cmp_d() */
+
+/* }}} */
+
+/* {{{ s_mp_ispow2(v) */
+
+/*
+  Returns -1 if the value is not a power of two; otherwise, it returns
+  k such that v = 2^k, i.e. lg(v).
+ */
+int      s_mp_ispow2(const mp_int *v)
+{
+  mp_digit d;
+  int      extra = 0, ix;
+
+  ix = MP_USED(v) - 1;
+  d = MP_DIGIT(v, ix); /* most significant digit of v */
+
+  extra = s_mp_ispow2d(d);
+  if (extra < 0 || ix == 0)
+    return extra;
+
+  while (--ix >= 0) {
+    if (DIGIT(v, ix) != 0)
+      return -1; /* not a power of two */
+    extra += MP_DIGIT_BIT;
+  }
+
+  return extra;
+
+} /* end s_mp_ispow2() */
+
+/* }}} */
+
+/* {{{ s_mp_ispow2d(d) */
+
+int      s_mp_ispow2d(mp_digit d)
+{
+  if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */
+    int pow = 0;
+#if defined (MP_USE_UINT_DIGIT)
+    if (d & 0xffff0000U)
+      pow += 16;
+    if (d & 0xff00ff00U)
+      pow += 8;
+    if (d & 0xf0f0f0f0U)
+      pow += 4;
+    if (d & 0xccccccccU)
+      pow += 2;
+    if (d & 0xaaaaaaaaU)
+      pow += 1;
+#elif defined(MP_USE_LONG_LONG_DIGIT)
+    if (d & 0xffffffff00000000ULL)
+      pow += 32;
+    if (d & 0xffff0000ffff0000ULL)
+      pow += 16;
+    if (d & 0xff00ff00ff00ff00ULL)
+      pow += 8;
+    if (d & 0xf0f0f0f0f0f0f0f0ULL)
+      pow += 4;
+    if (d & 0xccccccccccccccccULL)
+      pow += 2;
+    if (d & 0xaaaaaaaaaaaaaaaaULL)
+      pow += 1;
+#elif defined(MP_USE_LONG_DIGIT)
+    if (d & 0xffffffff00000000UL)
+      pow += 32;
+    if (d & 0xffff0000ffff0000UL)
+      pow += 16;
+    if (d & 0xff00ff00ff00ff00UL)
+      pow += 8;
+    if (d & 0xf0f0f0f0f0f0f0f0UL)
+      pow += 4;
+    if (d & 0xccccccccccccccccUL)
+      pow += 2;
+    if (d & 0xaaaaaaaaaaaaaaaaUL)
+      pow += 1;
+#else
+#error "unknown type for mp_digit"
+#endif
+    return pow;
+  }
+  return -1;
+
+} /* end s_mp_ispow2d() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive I/O helpers */
+
+/* {{{ s_mp_tovalue(ch, r) */
+
+/*
+  Convert the given character to its digit value, in the given radix.
+  If the given character is not understood in the given radix, -1 is
+  returned.  Otherwise the digit's numeric value is returned.
+
+  The results will be odd if you use a radix < 2 or > 62, you are
+  expected to know what you're up to.
+ */
+int      s_mp_tovalue(char ch, int r)
+{
+  int    val, xch;
+
+  if(r > 36)
+    xch = ch;
+  else
+    xch = toupper(ch);
+
+  if(isdigit(xch))
+    val = xch - '0';
+  else if(isupper(xch))
+    val = xch - 'A' + 10;
+  else if(islower(xch))
+    val = xch - 'a' + 36;
+  else if(xch == '+')
+    val = 62;
+  else if(xch == '/')
+    val = 63;
+  else
+    return -1;
+
+  if(val < 0 || val >= r)
+    return -1;
+
+  return val;
+
+} /* end s_mp_tovalue() */
+
+/* }}} */
+
+/* {{{ s_mp_todigit(val, r, low) */
+
+/*
+  Convert val to a radix-r digit, if possible.  If val is out of range
+  for r, returns zero.  Otherwise, returns an ASCII character denoting
+  the value in the given radix.
+
+  The results may be odd if you use a radix < 2 or > 64, you are
+  expected to know what you're doing.
+ */
+
+char     s_mp_todigit(mp_digit val, int r, int low)
+{
+  char   ch;
+
+  if(val >= r)
+    return 0;
+
+  ch = s_dmap_1[val];
+
+  if(r <= 36 && low)
+    ch = tolower(ch);
+
+  return ch;
+
+} /* end s_mp_todigit() */
+
+/* }}} */
+
+/* {{{ s_mp_outlen(bits, radix) */
+
+/*
+   Return an estimate for how long a string is needed to hold a radix
+   r representation of a number with 'bits' significant bits, plus an
+   extra for a zero terminator (assuming C style strings here)
+ */
+int      s_mp_outlen(int bits, int r)
+{
+  return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
+
+} /* end s_mp_outlen() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ mp_read_unsigned_octets(mp, str, len) */
+/* mp_read_unsigned_octets(mp, str, len)
+   Read in a raw value (base 256) into the given mp_int
+   No sign bit, number is positive.  Leading zeros ignored.
+ */
+
+mp_err
+mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
+{
+  int            count;
+  mp_err         res;
+  mp_digit       d;
+
+  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
+
+  mp_zero(mp);
+
+  count = len % sizeof(mp_digit);
+  if (count) {
+    for (d = 0; count-- > 0; --len) {
+      d = (d << 8) | *str++;
+    }
+    MP_DIGIT(mp, 0) = d;
+  }
+
+  /* Read the rest of the digits */
+  for(; len > 0; len -= sizeof(mp_digit)) {
+    for (d = 0, count = sizeof(mp_digit); count > 0; --count) {
+      d = (d << 8) | *str++;
+    }
+    if (MP_EQ == mp_cmp_z(mp)) {
+      if (!d)
+        continue;
+    } else {
+      if((res = s_mp_lshd(mp, 1)) != MP_OKAY)
+        return res;
+    }
+    MP_DIGIT(mp, 0) = d;
+  }
+  return MP_OKAY;
+} /* end mp_read_unsigned_octets() */
+/* }}} */
+
+/* {{{ mp_unsigned_octet_size(mp) */
+int
+mp_unsigned_octet_size(const mp_int *mp)
+{
+  int  bytes;
+  int  ix;
+  mp_digit  d = 0;
+
+  ARGCHK(mp != NULL, MP_BADARG);
+  ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);
+
+  bytes = (USED(mp) * sizeof(mp_digit));
+
+  /* subtract leading zeros. */
+  /* Iterate over each digit... */
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    d = DIGIT(mp, ix);
+    if (d)
+        break;
+    bytes -= sizeof(d);
+  }
+  if (!bytes)
+    return 1;
+
+  /* Have MSD, check digit bytes, high order first */
+  for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {
+    unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));
+    if (x)
+        break;
+    --bytes;
+  }
+  return bytes;
+} /* end mp_unsigned_octet_size() */
+/* }}} */
+
+/* {{{ mp_to_unsigned_octets(mp, str) */
+/* output a buffer of big endian octets no longer than specified. */
+mp_err
+mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
+{
+  int  ix, pos = 0;
+  int  bytes;
+
+  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
+
+  bytes = mp_unsigned_octet_size(mp);
+  ARGCHK(bytes <= maxlen, MP_BADARG);
+
+  /* Iterate over each digit... */
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    mp_digit  d = DIGIT(mp, ix);
+    int       jx;
+
+    /* Unpack digit bytes, high order first */
+    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
+      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
+      if (!pos && !x)   /* suppress leading zeros */
+        continue;
+      str[pos++] = x;
+    }
+  }
+  if (!pos)
+    str[pos++] = 0;
+  return pos;
+} /* end mp_to_unsigned_octets() */
+/* }}} */
+
+/* {{{ mp_to_signed_octets(mp, str) */
+/* output a buffer of big endian octets no longer than specified. */
+mp_err
+mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
+{
+  int  ix, pos = 0;
+  int  bytes;
+
+  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
+
+  bytes = mp_unsigned_octet_size(mp);
+  ARGCHK(bytes <= maxlen, MP_BADARG);
+
+  /* Iterate over each digit... */
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    mp_digit  d = DIGIT(mp, ix);
+    int       jx;
+
+    /* Unpack digit bytes, high order first */
+    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
+      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
+      if (!pos) {
+        if (!x)         /* suppress leading zeros */
+          continue;
+        if (x & 0x80) { /* add one leading zero to make output positive.  */
+          ARGCHK(bytes + 1 <= maxlen, MP_BADARG);
+          if (bytes + 1 > maxlen)
+            return MP_BADARG;
+          str[pos++] = 0;
+        }
+      }
+      str[pos++] = x;
+    }
+  }
+  if (!pos)
+    str[pos++] = 0;
+  return pos;
+} /* end mp_to_signed_octets() */
+/* }}} */
+
+/* {{{ mp_to_fixlen_octets(mp, str) */
+/* output a buffer of big endian octets exactly as long as requested. */
+mp_err
+mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
+{
+  int  ix, pos = 0;
+  int  bytes;
+
+  ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
+
+  bytes = mp_unsigned_octet_size(mp);
+  ARGCHK(bytes <= length, MP_BADARG);
+
+  /* place any needed leading zeros */
+  for (;length > bytes; --length) {
+        *str++ = 0;
+  }
+
+  /* Iterate over each digit... */
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    mp_digit  d = DIGIT(mp, ix);
+    int       jx;
+
+    /* Unpack digit bytes, high order first */
+    for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
+      unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
+      if (!pos && !x)   /* suppress leading zeros */
+        continue;
+      str[pos++] = x;
+    }
+  }
+  if (!pos)
+    str[pos++] = 0;
+  return MP_OKAY;
+} /* end mp_to_fixlen_octets() */
+/* }}} */
+
+
+/*------------------------------------------------------------------------*/
+/* HERE THERE BE DRAGONS                                                  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mpi.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,409 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ *
+ *  Arbitrary precision integer arithmetic library
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael J. Fromberger.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Netscape Communications Corporation
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MPI_H
+#define _MPI_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* $Id: mpi.h,v 1.22 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
+
+#include "mpi-config.h"
+
+#ifndef _WIN32
+#include <sys/param.h>
+#endif /* _WIN32 */
+
+#ifdef _KERNEL
+#include <sys/debug.h>
+#include <sys/systm.h>
+#define assert ASSERT
+#define labs(a) (a >= 0 ? a : -a)
+#define UCHAR_MAX 255
+#define memset(s, c, n) bzero(s, n)
+#define memcpy(a,b,c) bcopy((caddr_t)b, (caddr_t)a, c)
+/*
+ * Generic #define's to cover missing things in the kernel
+ */
+#ifndef isdigit
+#define isdigit(x)      ((x) >= '0' && (x) <= '9')
+#endif
+#ifndef isupper
+#define isupper(x)      (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z'))
+#endif
+#ifndef islower
+#define islower(x)      (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z'))
+#endif
+#ifndef isalpha
+#define isalpha(x)      (isupper(x) || islower(x))
+#endif
+#ifndef toupper
+#define toupper(x)      (islower(x) ? (x) - 'a' + 'A' : (x))
+#endif
+#ifndef tolower
+#define tolower(x)      (isupper(x) ? (x) + 'a' - 'A' : (x))
+#endif
+#ifndef isspace
+#define isspace(x)      (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \
+                         ((x) == '\t') || ((x) == '\b'))
+#endif
+#endif /* _KERNEL */
+
+#if MP_DEBUG
+#undef MP_IOFUNC
+#define MP_IOFUNC 1
+#endif
+
+#if MP_IOFUNC
+#include <stdio.h>
+#include <ctype.h>
+#endif
+
+#ifndef _KERNEL
+#include <limits.h>
+#endif
+
+#if defined(BSDI)
+#undef ULLONG_MAX
+#endif
+
+#if defined( macintosh )
+#include <Types.h>
+#elif defined( _WIN32_WCE)
+/* #include <sys/types.h> What do we need here ?? */
+#else
+#include <sys/types.h>
+#endif
+
+#define  MP_NEG    1
+#define  MP_ZPOS   0
+
+#define  MP_OKAY          0 /* no error, all is well */
+#define  MP_YES           0 /* yes (boolean result)  */
+#define  MP_NO           -1 /* no (boolean result)   */
+#define  MP_MEM          -2 /* out of memory         */
+#define  MP_RANGE        -3 /* argument out of range */
+#define  MP_BADARG       -4 /* invalid parameter     */
+#define  MP_UNDEF        -5 /* answer is undefined   */
+#define  MP_LAST_CODE    MP_UNDEF
+
+typedef unsigned int      mp_sign;
+typedef unsigned int      mp_size;
+typedef int               mp_err;
+typedef int               mp_flag;
+
+#define MP_32BIT_MAX 4294967295U
+
+#if !defined(ULONG_MAX)
+#error "ULONG_MAX not defined"
+#elif !defined(UINT_MAX)
+#error "UINT_MAX not defined"
+#elif !defined(USHRT_MAX)
+#error "USHRT_MAX not defined"
+#endif
+
+#if defined(ULONG_LONG_MAX)                     /* GCC, HPUX */
+#define MP_ULONG_LONG_MAX ULONG_LONG_MAX
+#elif defined(ULLONG_MAX)                       /* Solaris */
+#define MP_ULONG_LONG_MAX ULLONG_MAX
+/* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */
+#elif defined(ULONGLONG_MAX)                    /* IRIX, AIX */
+#define MP_ULONG_LONG_MAX ULONGLONG_MAX
+#endif
+
+/* We only use unsigned long for mp_digit iff long is more than 32 bits. */
+#if !defined(MP_USE_UINT_DIGIT) && ULONG_MAX > MP_32BIT_MAX
+typedef unsigned long     mp_digit;
+#define MP_DIGIT_MAX      ULONG_MAX
+#define MP_DIGIT_FMT      "%016lX"   /* printf() format for 1 digit */
+#define MP_HALF_DIGIT_MAX UINT_MAX
+#undef  MP_NO_MP_WORD
+#define MP_NO_MP_WORD 1
+#undef  MP_USE_LONG_DIGIT
+#define MP_USE_LONG_DIGIT 1
+#undef  MP_USE_LONG_LONG_DIGIT
+
+#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX)
+typedef unsigned long long mp_digit;
+#define MP_DIGIT_MAX       MP_ULONG_LONG_MAX
+#define MP_DIGIT_FMT      "%016llX"  /* printf() format for 1 digit */
+#define MP_HALF_DIGIT_MAX  UINT_MAX
+#undef  MP_NO_MP_WORD
+#define MP_NO_MP_WORD 1
+#undef  MP_USE_LONG_LONG_DIGIT
+#define MP_USE_LONG_LONG_DIGIT 1
+#undef  MP_USE_LONG_DIGIT
+
+#else
+typedef unsigned int      mp_digit;
+#define MP_DIGIT_MAX      UINT_MAX
+#define MP_DIGIT_FMT      "%08X"     /* printf() format for 1 digit */
+#define MP_HALF_DIGIT_MAX USHRT_MAX
+#undef  MP_USE_UINT_DIGIT
+#define MP_USE_UINT_DIGIT 1
+#undef  MP_USE_LONG_LONG_DIGIT
+#undef  MP_USE_LONG_DIGIT
+#endif
+
+#if !defined(MP_NO_MP_WORD)
+#if  defined(MP_USE_UINT_DIGIT) && \
+    (defined(MP_ULONG_LONG_MAX) || (ULONG_MAX > UINT_MAX))
+
+#if (ULONG_MAX > UINT_MAX)
+typedef unsigned long     mp_word;
+typedef          long     mp_sword;
+#define MP_WORD_MAX       ULONG_MAX
+
+#else
+typedef unsigned long long mp_word;
+typedef          long long mp_sword;
+#define MP_WORD_MAX       MP_ULONG_LONG_MAX
+#endif
+
+#else
+#define MP_NO_MP_WORD 1
+#endif
+#endif /* !defined(MP_NO_MP_WORD) */
+
+#if !defined(MP_WORD_MAX) && defined(MP_DEFINE_SMALL_WORD)
+typedef unsigned int      mp_word;
+typedef          int      mp_sword;
+#define MP_WORD_MAX       UINT_MAX
+#endif
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#define MP_DIGIT_BIT      (CHAR_BIT*sizeof(mp_digit))
+#define MP_WORD_BIT       (CHAR_BIT*sizeof(mp_word))
+#define MP_RADIX          (1+(mp_word)MP_DIGIT_MAX)
+
+#define MP_HALF_DIGIT_BIT (MP_DIGIT_BIT/2)
+#define MP_HALF_RADIX     (1+(mp_digit)MP_HALF_DIGIT_MAX)
+/* MP_HALF_RADIX really ought to be called MP_SQRT_RADIX, but it's named
+** MP_HALF_RADIX because it's the radix for MP_HALF_DIGITs, and it's
+** consistent with the other _HALF_ names.
+*/
+
+
+/* Macros for accessing the mp_int internals           */
+#define  MP_FLAG(MP)     ((MP)->flag)
+#define  MP_SIGN(MP)     ((MP)->sign)
+#define  MP_USED(MP)     ((MP)->used)
+#define  MP_ALLOC(MP)    ((MP)->alloc)
+#define  MP_DIGITS(MP)   ((MP)->dp)
+#define  MP_DIGIT(MP,N)  (MP)->dp[(N)]
+
+/* This defines the maximum I/O base (minimum is 2)   */
+#define MP_MAX_RADIX         64
+
+typedef struct {
+  mp_sign       flag;    /* KM_SLEEP/KM_NOSLEEP        */
+  mp_sign       sign;    /* sign of this quantity      */
+  mp_size       alloc;   /* how many digits allocated  */
+  mp_size       used;    /* how many digits used       */
+  mp_digit     *dp;      /* the digits themselves      */
+} mp_int;
+
+/* Default precision       */
+mp_size mp_get_prec(void);
+void    mp_set_prec(mp_size prec);
+
+/* Memory management       */
+mp_err mp_init(mp_int *mp, int kmflag);
+mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag);
+mp_err mp_init_copy(mp_int *mp, const mp_int *from);
+mp_err mp_copy(const mp_int *from, mp_int *to);
+void   mp_exch(mp_int *mp1, mp_int *mp2);
+void   mp_clear(mp_int *mp);
+void   mp_zero(mp_int *mp);
+void   mp_set(mp_int *mp, mp_digit d);
+mp_err mp_set_int(mp_int *mp, long z);
+#define mp_set_long(mp,z) mp_set_int(mp,z)
+mp_err mp_set_ulong(mp_int *mp, unsigned long z);
+
+/* Single digit arithmetic */
+mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_mul_2(const mp_int *a, mp_int *c);
+mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
+mp_err mp_div_2(const mp_int *a, mp_int *c);
+mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c);
+
+/* Sign manipulations      */
+mp_err mp_abs(const mp_int *a, mp_int *b);
+mp_err mp_neg(const mp_int *a, mp_int *b);
+
+/* Full arithmetic         */
+mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c);
+mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
+mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
+#if MP_SQUARE
+mp_err mp_sqr(const mp_int *a, mp_int *b);
+#else
+#define mp_sqr(a, b) mp_mul(a, a, b)
+#endif
+mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r);
+mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r);
+mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_2expt(mp_int *a, mp_digit k);
+mp_err mp_sqrt(const mp_int *a, mp_int *b);
+
+/* Modular arithmetic      */
+#if MP_MODARITH
+mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c);
+mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c);
+mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
+mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
+mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
+#if MP_SQUARE
+mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c);
+#else
+#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
+#endif
+mp_err mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
+mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
+#endif /* MP_MODARITH */
+
+/* Comparisons             */
+int    mp_cmp_z(const mp_int *a);
+int    mp_cmp_d(const mp_int *a, mp_digit d);
+int    mp_cmp(const mp_int *a, const mp_int *b);
+int    mp_cmp_mag(mp_int *a, mp_int *b);
+int    mp_cmp_int(const mp_int *a, long z, int kmflag);
+int    mp_isodd(const mp_int *a);
+int    mp_iseven(const mp_int *a);
+
+/* Number theoretic        */
+#if MP_NUMTH
+mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y);
+mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c);
+mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c);
+#endif /* end MP_NUMTH */
+
+/* Input and output        */
+#if MP_IOFUNC
+void   mp_print(mp_int *mp, FILE *ofp);
+#endif /* end MP_IOFUNC */
+
+/* Base conversion         */
+mp_err mp_read_raw(mp_int *mp, char *str, int len);
+int    mp_raw_size(mp_int *mp);
+mp_err mp_toraw(mp_int *mp, char *str);
+mp_err mp_read_radix(mp_int *mp, const char *str, int radix);
+mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix);
+int    mp_radix_size(mp_int *mp, int radix);
+mp_err mp_toradix(mp_int *mp, char *str, int radix);
+int    mp_tovalue(char ch, int r);
+
+#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
+
+/* Error strings           */
+const  char  *mp_strerror(mp_err ec);
+
+/* Octet string conversion functions */
+mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len);
+int    mp_unsigned_octet_size(const mp_int *mp);
+mp_err mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
+mp_err mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
+mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size len);
+
+/* Miscellaneous */
+mp_size mp_trailing_zeros(const mp_int *mp);
+
+#define MP_CHECKOK(x)  if (MP_OKAY > (res = (x))) goto CLEANUP
+#define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP
+
+#if defined(MP_API_COMPATIBLE)
+#define NEG             MP_NEG
+#define ZPOS            MP_ZPOS
+#define DIGIT_MAX       MP_DIGIT_MAX
+#define DIGIT_BIT       MP_DIGIT_BIT
+#define DIGIT_FMT       MP_DIGIT_FMT
+#define RADIX           MP_RADIX
+#define MAX_RADIX       MP_MAX_RADIX
+#define FLAG(MP)        MP_FLAG(MP)
+#define SIGN(MP)        MP_SIGN(MP)
+#define USED(MP)        MP_USED(MP)
+#define ALLOC(MP)       MP_ALLOC(MP)
+#define DIGITS(MP)      MP_DIGITS(MP)
+#define DIGIT(MP,N)     MP_DIGIT(MP,N)
+
+#if MP_ARGCHK == 1
+#define  ARGCHK(X,Y)  {if(!(X)){return (Y);}}
+#elif MP_ARGCHK == 2
+#ifdef _KERNEL
+#define  ARGCHK(X,Y)  ASSERT(X)
+#else
+#include <assert.h>
+#define  ARGCHK(X,Y)  assert(X)
+#endif
+#else
+#define  ARGCHK(X,Y)  /*  */
+#endif
+#endif /* defined MP_API_COMPATIBLE */
+
+#endif /* _MPI_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mplogic.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,242 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ *
+ *  Bitwise logical operations on MPI values
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael J. Fromberger.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
+
+#include "mpi-priv.h"
+#include "mplogic.h"
+
+/* {{{ Lookup table for population count */
+
+static unsigned char bitc[] = {
+   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+   4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
+
+/* }}} */
+
+/*
+  mpl_rsh(a, b, d)     - b = a >> d
+  mpl_lsh(a, b, d)     - b = a << d
+ */
+
+/* {{{ mpl_rsh(a, b, d) */
+
+mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  s_mp_div_2d(b, d);
+
+  return MP_OKAY;
+
+} /* end mpl_rsh() */
+
+/* }}} */
+
+/* {{{ mpl_lsh(a, b, d) */
+
+mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  return s_mp_mul_2d(b, d);
+
+} /* end mpl_lsh() */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/*
+  mpl_set_bit
+
+  Returns MP_OKAY or some error code.
+  Grows a if needed to set a bit to 1.
+ */
+mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
+{
+  mp_size      ix;
+  mp_err       rv;
+  mp_digit     mask;
+
+  ARGCHK(a != NULL, MP_BADARG);
+
+  ix = bitNum / MP_DIGIT_BIT;
+  if (ix + 1 > MP_USED(a)) {
+    rv = s_mp_pad(a, ix + 1);
+    if (rv != MP_OKAY)
+      return rv;
+  }
+
+  bitNum = bitNum % MP_DIGIT_BIT;
+  mask = (mp_digit)1 << bitNum;
+  if (value)
+    MP_DIGIT(a,ix) |= mask;
+  else
+    MP_DIGIT(a,ix) &= ~mask;
+  s_mp_clamp(a);
+  return MP_OKAY;
+}
+
+/*
+  mpl_get_bit
+
+  returns 0 or 1 or some (negative) error code.
+ */
+mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
+{
+  mp_size      bit, ix;
+  mp_err       rv;
+
+  ARGCHK(a != NULL, MP_BADARG);
+
+  ix = bitNum / MP_DIGIT_BIT;
+  ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
+
+  bit   = bitNum % MP_DIGIT_BIT;
+  rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1;
+  return rv;
+}
+
+/*
+  mpl_get_bits
+  - Extracts numBits bits from a, where the least significant extracted bit
+  is bit lsbNum.  Returns a negative value if error occurs.
+  - Because sign bit is used to indicate error, maximum number of bits to
+  be returned is the lesser of (a) the number of bits in an mp_digit, or
+  (b) one less than the number of bits in an mp_err.
+  - lsbNum + numbits can be greater than the number of significant bits in
+  integer a, as long as bit lsbNum is in the high order digit of a.
+ */
+mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
+{
+  mp_size    rshift = (lsbNum % MP_DIGIT_BIT);
+  mp_size    lsWndx = (lsbNum / MP_DIGIT_BIT);
+  mp_digit * digit  = MP_DIGITS(a) + lsWndx;
+  mp_digit   mask   = ((1 << numBits) - 1);
+
+  ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG);
+  ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE);
+
+  if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) ||
+      (lsWndx + 1 >= MP_USED(a))) {
+    mask &= (digit[0] >> rshift);
+  } else {
+    mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift)));
+  }
+  return (mp_err)mask;
+}
+
+/*
+  mpl_significant_bits
+  returns number of significnant bits in abs(a).
+  returns 1 if value is zero.
+ */
+mp_err mpl_significant_bits(const mp_int *a)
+{
+  mp_err bits   = 0;
+  int    ix;
+
+  ARGCHK(a != NULL, MP_BADARG);
+
+  ix = MP_USED(a);
+  for (ix = MP_USED(a); ix > 0; ) {
+    mp_digit d;
+    d = MP_DIGIT(a, --ix);
+    if (d) {
+      while (d) {
+        ++bits;
+        d >>= 1;
+      }
+      break;
+    }
+  }
+  bits += ix * MP_DIGIT_BIT;
+  if (!bits)
+    bits = 1;
+  return bits;
+}
+
+/*------------------------------------------------------------------------*/
+/* HERE THERE BE DRAGONS                                                  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mplogic.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,105 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ *
+ *  Bitwise logical operations on MPI values
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael J. Fromberger.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MPLOGIC_H
+#define _MPLOGIC_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* $Id: mplogic.h,v 1.7 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
+
+#include "mpi.h"
+
+/*
+  The logical operations treat an mp_int as if it were a bit vector,
+  without regard to its sign (an mp_int is represented in a signed
+  magnitude format).  Values are treated as if they had an infinite
+  string of zeros left of the most-significant bit.
+ */
+
+/* Parity results                    */
+
+#define MP_EVEN       MP_YES
+#define MP_ODD        MP_NO
+
+/* Bitwise functions                 */
+
+mp_err mpl_not(mp_int *a, mp_int *b);            /* one's complement  */
+mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c); /* bitwise AND       */
+mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c);  /* bitwise OR        */
+mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c); /* bitwise XOR       */
+
+/* Shift functions                   */
+
+mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d);   /* right shift    */
+mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d);   /* left shift     */
+
+/* Bit count and parity              */
+
+mp_err mpl_num_set(mp_int *a, int *num);         /* count set bits    */
+mp_err mpl_num_clear(mp_int *a, int *num);       /* count clear bits  */
+mp_err mpl_parity(mp_int *a);                    /* determine parity  */
+
+/* Get & Set the value of a bit */
+
+mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value);
+mp_err mpl_get_bit(const mp_int *a, mp_size bitNum);
+mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits);
+mp_err mpl_significant_bits(const mp_int *a);
+
+#endif /* _MPLOGIC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mpmontg.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,199 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sheueling Chang Shantz <sheueling.chang@sun.com>,
+ *   Stephen Fung <stephen.fung@sun.com>, and
+ *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/* $Id: mpmontg.c,v 1.20 2006/08/29 02:41:38 nelson%bolyard.com Exp $ */
+
+/* This file implements moduluar exponentiation using Montgomery's
+ * method for modular reduction.  This file implements the method
+ * described as "Improvement 1" in the paper "A Cryptogrpahic Library for
+ * the Motorola DSP56000" by Stephen R. Dusse' and Burton S. Kaliski Jr.
+ * published in "Advances in Cryptology: Proceedings of EUROCRYPT '90"
+ * "Lecture Notes in Computer Science" volume 473, 1991, pg 230-244,
+ * published by Springer Verlag.
+ */
+
+#define MP_USING_CACHE_SAFE_MOD_EXP 1
+#ifndef _KERNEL
+#include <string.h>
+#include <stddef.h> /* ptrdiff_t */
+#endif
+#include "mpi-priv.h"
+#include "mplogic.h"
+#include "mpprime.h"
+#ifdef MP_USING_MONT_MULF
+#include "montmulf.h"
+#endif
+
+/* if MP_CHAR_STORE_SLOW is defined, we  */
+/* need to know endianness of this platform. */
+#ifdef MP_CHAR_STORE_SLOW
+#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN)
+#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \
+       "  if you define MP_CHAR_STORE_SLOW."
+#endif
+#endif
+
+#ifndef STATIC
+#define STATIC
+#endif
+
+#define MAX_ODD_INTS    32   /* 2 ** (WINDOW_BITS - 1) */
+
+#ifndef _KERNEL
+#if defined(_WIN32_WCE)
+#define ABORT  res = MP_UNDEF; goto CLEANUP
+#else
+#define ABORT abort()
+#endif
+#else
+#define ABORT  res = MP_UNDEF; goto CLEANUP
+#endif /* _KERNEL */
+
+/* computes T = REDC(T), 2^b == R */
+mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm)
+{
+  mp_err res;
+  mp_size i;
+
+  i = MP_USED(T) + MP_USED(&mmm->N) + 2;
+  MP_CHECKOK( s_mp_pad(T, i) );
+  for (i = 0; i < MP_USED(&mmm->N); ++i ) {
+    mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime;
+    /* T += N * m_i * (MP_RADIX ** i); */
+    MP_CHECKOK( s_mp_mul_d_add_offset(&mmm->N, m_i, T, i) );
+  }
+  s_mp_clamp(T);
+
+  /* T /= R */
+  s_mp_div_2d(T, mmm->b);
+
+  if ((res = s_mp_cmp(T, &mmm->N)) >= 0) {
+    /* T = T - N */
+    MP_CHECKOK( s_mp_sub(T, &mmm->N) );
+#ifdef DEBUG
+    if ((res = mp_cmp(T, &mmm->N)) >= 0) {
+      res = MP_UNDEF;
+      goto CLEANUP;
+    }
+#endif
+  }
+  res = MP_OKAY;
+CLEANUP:
+  return res;
+}
+
+#if !defined(MP_ASSEMBLY_MUL_MONT) && !defined(MP_MONT_USE_MP_MUL)
+mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
+                   mp_mont_modulus *mmm)
+{
+  mp_digit *pb;
+  mp_digit m_i;
+  mp_err   res;
+  mp_size  ib;
+  mp_size  useda, usedb;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if (MP_USED(a) < MP_USED(b)) {
+    const mp_int *xch = b;      /* switch a and b, to do fewer outer loops */
+    b = a;
+    a = xch;
+  }
+
+  MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
+  ib = MP_USED(a) + MP_MAX(MP_USED(b), MP_USED(&mmm->N)) + 2;
+  if((res = s_mp_pad(c, ib)) != MP_OKAY)
+    goto CLEANUP;
+
+  useda = MP_USED(a);
+  pb = MP_DIGITS(b);
+  s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c));
+  s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1));
+  m_i = MP_DIGIT(c, 0) * mmm->n0prime;
+  s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0);
+
+  /* Outer loop:  Digits of b */
+  usedb = MP_USED(b);
+  for (ib = 1; ib < usedb; ib++) {
+    mp_digit b_i    = *pb++;
+
+    /* Inner product:  Digits of a */
+    if (b_i)
+      s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
+    m_i = MP_DIGIT(c, ib) * mmm->n0prime;
+    s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
+  }
+  if (usedb < MP_USED(&mmm->N)) {
+    for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib ) {
+      m_i = MP_DIGIT(c, ib) * mmm->n0prime;
+      s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
+    }
+  }
+  s_mp_clamp(c);
+  s_mp_div_2d(c, mmm->b);
+  if (s_mp_cmp(c, &mmm->N) >= 0) {
+    MP_CHECKOK( s_mp_sub(c, &mmm->N) );
+  }
+  res = MP_OKAY;
+
+CLEANUP:
+  return res;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/mpprime.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,89 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ *
+ *  Utilities for finding and working with prime and pseudo-prime
+ *  integers
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael J. Fromberger.
+ * Portions created by the Initial Developer are Copyright (C) 1997
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MP_PRIME_H
+#define _MP_PRIME_H
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include "mpi.h"
+
+extern const int prime_tab_size;   /* number of primes available */
+extern const mp_digit prime_tab[];
+
+/* Tests for divisibility    */
+mp_err  mpp_divis(mp_int *a, mp_int *b);
+mp_err  mpp_divis_d(mp_int *a, mp_digit d);
+
+/* Random selection          */
+mp_err  mpp_random(mp_int *a);
+mp_err  mpp_random_size(mp_int *a, mp_size prec);
+
+/* Pseudo-primality testing  */
+mp_err  mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which);
+mp_err  mpp_divis_primes(mp_int *a, mp_digit *np);
+mp_err  mpp_fermat(mp_int *a, mp_digit w);
+mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes);
+mp_err  mpp_pprime(mp_int *a, int nt);
+mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
+                 unsigned char *sieve, mp_size nSieve);
+mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
+                      unsigned long * nTries);
+
+#endif /* _MP_PRIME_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/oid.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,473 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+#include <sys/types.h>
+
+#ifndef _WIN32
+#ifndef __linux__
+#include <sys/systm.h>
+#endif /* __linux__ */
+#include <sys/param.h>
+#endif /* _WIN32 */
+
+#ifdef _KERNEL
+#include <sys/kmem.h>
+#else
+#include <string.h>
+#endif
+#include "ec.h"
+#include "ecl-curve.h"
+#include "ecc_impl.h"
+#include "secoidt.h"
+
+#define CERTICOM_OID            0x2b, 0x81, 0x04
+#define SECG_OID                CERTICOM_OID, 0x00
+
+#define ANSI_X962_OID           0x2a, 0x86, 0x48, 0xce, 0x3d
+#define ANSI_X962_CURVE_OID     ANSI_X962_OID, 0x03
+#define ANSI_X962_GF2m_OID      ANSI_X962_CURVE_OID, 0x00
+#define ANSI_X962_GFp_OID       ANSI_X962_CURVE_OID, 0x01
+
+#define CONST_OID static const unsigned char
+
+/* ANSI X9.62 prime curve OIDs */
+/* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the
+ * same as secp256r1
+ */
+CONST_OID ansiX962prime192v1[] = { ANSI_X962_GFp_OID, 0x01 };
+CONST_OID ansiX962prime192v2[] = { ANSI_X962_GFp_OID, 0x02 };
+CONST_OID ansiX962prime192v3[] = { ANSI_X962_GFp_OID, 0x03 };
+CONST_OID ansiX962prime239v1[] = { ANSI_X962_GFp_OID, 0x04 };
+CONST_OID ansiX962prime239v2[] = { ANSI_X962_GFp_OID, 0x05 };
+CONST_OID ansiX962prime239v3[] = { ANSI_X962_GFp_OID, 0x06 };
+CONST_OID ansiX962prime256v1[] = { ANSI_X962_GFp_OID, 0x07 };
+
+/* SECG prime curve OIDs */
+CONST_OID secgECsecp112r1[] = { SECG_OID, 0x06 };
+CONST_OID secgECsecp112r2[] = { SECG_OID, 0x07 };
+CONST_OID secgECsecp128r1[] = { SECG_OID, 0x1c };
+CONST_OID secgECsecp128r2[] = { SECG_OID, 0x1d };
+CONST_OID secgECsecp160k1[] = { SECG_OID, 0x09 };
+CONST_OID secgECsecp160r1[] = { SECG_OID, 0x08 };
+CONST_OID secgECsecp160r2[] = { SECG_OID, 0x1e };
+CONST_OID secgECsecp192k1[] = { SECG_OID, 0x1f };
+CONST_OID secgECsecp224k1[] = { SECG_OID, 0x20 };
+CONST_OID secgECsecp224r1[] = { SECG_OID, 0x21 };
+CONST_OID secgECsecp256k1[] = { SECG_OID, 0x0a };
+CONST_OID secgECsecp384r1[] = { SECG_OID, 0x22 };
+CONST_OID secgECsecp521r1[] = { SECG_OID, 0x23 };
+
+/* SECG characterisitic two curve OIDs */
+CONST_OID secgECsect113r1[] = {SECG_OID, 0x04 };
+CONST_OID secgECsect113r2[] = {SECG_OID, 0x05 };
+CONST_OID secgECsect131r1[] = {SECG_OID, 0x16 };
+CONST_OID secgECsect131r2[] = {SECG_OID, 0x17 };
+CONST_OID secgECsect163k1[] = {SECG_OID, 0x01 };
+CONST_OID secgECsect163r1[] = {SECG_OID, 0x02 };
+CONST_OID secgECsect163r2[] = {SECG_OID, 0x0f };
+CONST_OID secgECsect193r1[] = {SECG_OID, 0x18 };
+CONST_OID secgECsect193r2[] = {SECG_OID, 0x19 };
+CONST_OID secgECsect233k1[] = {SECG_OID, 0x1a };
+CONST_OID secgECsect233r1[] = {SECG_OID, 0x1b };
+CONST_OID secgECsect239k1[] = {SECG_OID, 0x03 };
+CONST_OID secgECsect283k1[] = {SECG_OID, 0x10 };
+CONST_OID secgECsect283r1[] = {SECG_OID, 0x11 };
+CONST_OID secgECsect409k1[] = {SECG_OID, 0x24 };
+CONST_OID secgECsect409r1[] = {SECG_OID, 0x25 };
+CONST_OID secgECsect571k1[] = {SECG_OID, 0x26 };
+CONST_OID secgECsect571r1[] = {SECG_OID, 0x27 };
+
+/* ANSI X9.62 characteristic two curve OIDs */
+CONST_OID ansiX962c2pnb163v1[] = { ANSI_X962_GF2m_OID, 0x01 };
+CONST_OID ansiX962c2pnb163v2[] = { ANSI_X962_GF2m_OID, 0x02 };
+CONST_OID ansiX962c2pnb163v3[] = { ANSI_X962_GF2m_OID, 0x03 };
+CONST_OID ansiX962c2pnb176v1[] = { ANSI_X962_GF2m_OID, 0x04 };
+CONST_OID ansiX962c2tnb191v1[] = { ANSI_X962_GF2m_OID, 0x05 };
+CONST_OID ansiX962c2tnb191v2[] = { ANSI_X962_GF2m_OID, 0x06 };
+CONST_OID ansiX962c2tnb191v3[] = { ANSI_X962_GF2m_OID, 0x07 };
+CONST_OID ansiX962c2onb191v4[] = { ANSI_X962_GF2m_OID, 0x08 };
+CONST_OID ansiX962c2onb191v5[] = { ANSI_X962_GF2m_OID, 0x09 };
+CONST_OID ansiX962c2pnb208w1[] = { ANSI_X962_GF2m_OID, 0x0a };
+CONST_OID ansiX962c2tnb239v1[] = { ANSI_X962_GF2m_OID, 0x0b };
+CONST_OID ansiX962c2tnb239v2[] = { ANSI_X962_GF2m_OID, 0x0c };
+CONST_OID ansiX962c2tnb239v3[] = { ANSI_X962_GF2m_OID, 0x0d };
+CONST_OID ansiX962c2onb239v4[] = { ANSI_X962_GF2m_OID, 0x0e };
+CONST_OID ansiX962c2onb239v5[] = { ANSI_X962_GF2m_OID, 0x0f };
+CONST_OID ansiX962c2pnb272w1[] = { ANSI_X962_GF2m_OID, 0x10 };
+CONST_OID ansiX962c2pnb304w1[] = { ANSI_X962_GF2m_OID, 0x11 };
+CONST_OID ansiX962c2tnb359v1[] = { ANSI_X962_GF2m_OID, 0x12 };
+CONST_OID ansiX962c2pnb368w1[] = { ANSI_X962_GF2m_OID, 0x13 };
+CONST_OID ansiX962c2tnb431r1[] = { ANSI_X962_GF2m_OID, 0x14 };
+
+#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
+#ifndef SECOID_NO_STRINGS
+#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, desc, mech, ext }
+#else
+#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, 0, mech, ext }
+#endif
+
+#define CKM_INVALID_MECHANISM 0xffffffffUL
+
+/* XXX this is incorrect */
+#define INVALID_CERT_EXTENSION 1
+
+#define CKM_ECDSA                      0x00001041
+#define CKM_ECDSA_SHA1                 0x00001042
+#define CKM_ECDH1_DERIVE               0x00001050
+
+static SECOidData ANSI_prime_oids[] = {
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+
+    OD( ansiX962prime192v1, ECCurve_NIST_P192,
+        "ANSI X9.62 elliptic curve prime192v1 (aka secp192r1, NIST P-192)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962prime192v2, ECCurve_X9_62_PRIME_192V2,
+        "ANSI X9.62 elliptic curve prime192v2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962prime192v3, ECCurve_X9_62_PRIME_192V3,
+        "ANSI X9.62 elliptic curve prime192v3",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962prime239v1, ECCurve_X9_62_PRIME_239V1,
+        "ANSI X9.62 elliptic curve prime239v1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962prime239v2, ECCurve_X9_62_PRIME_239V2,
+        "ANSI X9.62 elliptic curve prime239v2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962prime239v3, ECCurve_X9_62_PRIME_239V3,
+        "ANSI X9.62 elliptic curve prime239v3",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962prime256v1, ECCurve_NIST_P256,
+        "ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION )
+};
+
+static SECOidData SECG_oids[] = {
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+
+    OD( secgECsect163k1, ECCurve_NIST_K163,
+        "SECG elliptic curve sect163k1 (aka NIST K-163)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect163r1, ECCurve_SECG_CHAR2_163R1,
+        "SECG elliptic curve sect163r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect239k1, ECCurve_SECG_CHAR2_239K1,
+        "SECG elliptic curve sect239k1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect113r1, ECCurve_SECG_CHAR2_113R1,
+        "SECG elliptic curve sect113r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect113r2, ECCurve_SECG_CHAR2_113R2,
+        "SECG elliptic curve sect113r2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp112r1, ECCurve_SECG_PRIME_112R1,
+        "SECG elliptic curve secp112r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp112r2, ECCurve_SECG_PRIME_112R2,
+        "SECG elliptic curve secp112r2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp160r1, ECCurve_SECG_PRIME_160R1,
+        "SECG elliptic curve secp160r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp160k1, ECCurve_SECG_PRIME_160K1,
+        "SECG elliptic curve secp160k1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp256k1, ECCurve_SECG_PRIME_256K1,
+        "SECG elliptic curve secp256k1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    OD( secgECsect163r2, ECCurve_NIST_B163,
+        "SECG elliptic curve sect163r2 (aka NIST B-163)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect283k1, ECCurve_NIST_K283,
+        "SECG elliptic curve sect283k1 (aka NIST K-283)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect283r1, ECCurve_NIST_B283,
+        "SECG elliptic curve sect283r1 (aka NIST B-283)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    OD( secgECsect131r1, ECCurve_SECG_CHAR2_131R1,
+        "SECG elliptic curve sect131r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect131r2, ECCurve_SECG_CHAR2_131R2,
+        "SECG elliptic curve sect131r2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect193r1, ECCurve_SECG_CHAR2_193R1,
+        "SECG elliptic curve sect193r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect193r2, ECCurve_SECG_CHAR2_193R2,
+        "SECG elliptic curve sect193r2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect233k1, ECCurve_NIST_K233,
+        "SECG elliptic curve sect233k1 (aka NIST K-233)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect233r1, ECCurve_NIST_B233,
+        "SECG elliptic curve sect233r1 (aka NIST B-233)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp128r1, ECCurve_SECG_PRIME_128R1,
+        "SECG elliptic curve secp128r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp128r2, ECCurve_SECG_PRIME_128R2,
+        "SECG elliptic curve secp128r2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp160r2, ECCurve_SECG_PRIME_160R2,
+        "SECG elliptic curve secp160r2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp192k1, ECCurve_SECG_PRIME_192K1,
+        "SECG elliptic curve secp192k1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp224k1, ECCurve_SECG_PRIME_224K1,
+        "SECG elliptic curve secp224k1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp224r1, ECCurve_NIST_P224,
+        "SECG elliptic curve secp224r1 (aka NIST P-224)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp384r1, ECCurve_NIST_P384,
+        "SECG elliptic curve secp384r1 (aka NIST P-384)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsecp521r1, ECCurve_NIST_P521,
+        "SECG elliptic curve secp521r1 (aka NIST P-521)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect409k1, ECCurve_NIST_K409,
+        "SECG elliptic curve sect409k1 (aka NIST K-409)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect409r1, ECCurve_NIST_B409,
+        "SECG elliptic curve sect409r1 (aka NIST B-409)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect571k1, ECCurve_NIST_K571,
+        "SECG elliptic curve sect571k1 (aka NIST K-571)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( secgECsect571r1, ECCurve_NIST_B571,
+        "SECG elliptic curve sect571r1 (aka NIST B-571)",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION )
+};
+
+static SECOidData ANSI_oids[] = {
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+
+    /* ANSI X9.62 named elliptic curves (characteristic two field) */
+    OD( ansiX962c2pnb163v1, ECCurve_X9_62_CHAR2_PNB163V1,
+        "ANSI X9.62 elliptic curve c2pnb163v1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2pnb163v2, ECCurve_X9_62_CHAR2_PNB163V2,
+        "ANSI X9.62 elliptic curve c2pnb163v2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2pnb163v3, ECCurve_X9_62_CHAR2_PNB163V3,
+        "ANSI X9.62 elliptic curve c2pnb163v3",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2pnb176v1, ECCurve_X9_62_CHAR2_PNB176V1,
+        "ANSI X9.62 elliptic curve c2pnb176v1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb191v1, ECCurve_X9_62_CHAR2_TNB191V1,
+        "ANSI X9.62 elliptic curve c2tnb191v1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb191v2, ECCurve_X9_62_CHAR2_TNB191V2,
+        "ANSI X9.62 elliptic curve c2tnb191v2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb191v3, ECCurve_X9_62_CHAR2_TNB191V3,
+        "ANSI X9.62 elliptic curve c2tnb191v3",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    OD( ansiX962c2pnb208w1, ECCurve_X9_62_CHAR2_PNB208W1,
+        "ANSI X9.62 elliptic curve c2pnb208w1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb239v1, ECCurve_X9_62_CHAR2_TNB239V1,
+        "ANSI X9.62 elliptic curve c2tnb239v1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb239v2, ECCurve_X9_62_CHAR2_TNB239V2,
+        "ANSI X9.62 elliptic curve c2tnb239v2",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb239v3, ECCurve_X9_62_CHAR2_TNB239V3,
+        "ANSI X9.62 elliptic curve c2tnb239v3",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    { { siDEROID, NULL, 0 }, ECCurve_noName,
+        "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+    OD( ansiX962c2pnb272w1, ECCurve_X9_62_CHAR2_PNB272W1,
+        "ANSI X9.62 elliptic curve c2pnb272w1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2pnb304w1, ECCurve_X9_62_CHAR2_PNB304W1,
+        "ANSI X9.62 elliptic curve c2pnb304w1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb359v1, ECCurve_X9_62_CHAR2_TNB359V1,
+        "ANSI X9.62 elliptic curve c2tnb359v1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2pnb368w1, ECCurve_X9_62_CHAR2_PNB368W1,
+        "ANSI X9.62 elliptic curve c2pnb368w1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION ),
+    OD( ansiX962c2tnb431r1, ECCurve_X9_62_CHAR2_TNB431R1,
+        "ANSI X9.62 elliptic curve c2tnb431r1",
+        CKM_INVALID_MECHANISM,
+        INVALID_CERT_EXTENSION )
+};
+
+SECOidData *
+SECOID_FindOID(const SECItem *oid)
+{
+    SECOidData *po;
+    SECOidData *ret;
+    int i;
+
+    if (oid->len == 8) {
+        if (oid->data[6] == 0x00) {
+                /* XXX bounds check */
+                po = &ANSI_oids[oid->data[7]];
+                if (memcmp(oid->data, po->oid.data, 8) == 0)
+                        ret = po;
+        }
+        if (oid->data[6] == 0x01) {
+                /* XXX bounds check */
+                po = &ANSI_prime_oids[oid->data[7]];
+                if (memcmp(oid->data, po->oid.data, 8) == 0)
+                        ret = po;
+        }
+    } else if (oid->len == 5) {
+        /* XXX bounds check */
+        po = &SECG_oids[oid->data[4]];
+        if (memcmp(oid->data, po->oid.data, 5) == 0)
+                ret = po;
+    } else {
+        ret = NULL;
+    }
+    return(ret);
+}
+
+ECCurveName
+SECOID_FindOIDTag(const SECItem *oid)
+{
+    SECOidData *oiddata;
+
+    oiddata = SECOID_FindOID (oid);
+    if (oiddata == NULL)
+        return ECCurve_noName;
+
+    return oiddata->offset;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/secitem.c	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,199 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/*
+ * Support routines for SECItem data structure.
+ *
+ * $Id: secitem.c,v 1.14 2006/05/22 22:24:34 wtchang%redhat.com Exp $
+ */
+
+#include <sys/types.h>
+
+#ifndef _WIN32
+#ifndef __linux__
+#include <sys/systm.h>
+#endif /* __linux__ */
+#include <sys/param.h>
+#endif /* _WIN32 */
+
+#ifdef _KERNEL
+#include <sys/kmem.h>
+#else
+#include <string.h>
+
+#ifndef _WIN32
+#include <strings.h>
+#endif /* _WIN32 */
+
+#include <assert.h>
+#endif
+#include "ec.h"
+#include "ecl-curve.h"
+#include "ecc_impl.h"
+
+void SECITEM_FreeItem(SECItem *, PRBool);
+
+SECItem *
+SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len,
+    int kmflag)
+{
+    SECItem *result = NULL;
+    void *mark = NULL;
+
+    if (arena != NULL) {
+        mark = PORT_ArenaMark(arena);
+    }
+
+    if (item == NULL) {
+        if (arena != NULL) {
+            result = PORT_ArenaZAlloc(arena, sizeof(SECItem), kmflag);
+        } else {
+            result = PORT_ZAlloc(sizeof(SECItem), kmflag);
+        }
+        if (result == NULL) {
+            goto loser;
+        }
+    } else {
+        PORT_Assert(item->data == NULL);
+        result = item;
+    }
+
+    result->len = len;
+    if (len) {
+        if (arena != NULL) {
+            result->data = PORT_ArenaAlloc(arena, len, kmflag);
+        } else {
+            result->data = PORT_Alloc(len, kmflag);
+        }
+        if (result->data == NULL) {
+            goto loser;
+        }
+    } else {
+        result->data = NULL;
+    }
+
+    if (mark) {
+        PORT_ArenaUnmark(arena, mark);
+    }
+    return(result);
+
+loser:
+    if ( arena != NULL ) {
+        if (mark) {
+            PORT_ArenaRelease(arena, mark);
+        }
+        if (item != NULL) {
+            item->data = NULL;
+            item->len = 0;
+        }
+    } else {
+        if (result != NULL) {
+            SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE);
+        }
+        /*
+         * If item is not NULL, the above has set item->data and
+         * item->len to 0.
+         */
+    }
+    return(NULL);
+}
+
+SECStatus
+SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from,
+   int kmflag)
+{
+    to->type = from->type;
+    if (from->data && from->len) {
+        if ( arena ) {
+            to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len,
+                kmflag);
+        } else {
+            to->data = (unsigned char*) PORT_Alloc(from->len, kmflag);
+        }
+
+        if (!to->data) {
+            return SECFailure;
+        }
+        PORT_Memcpy(to->data, from->data, from->len);
+        to->len = from->len;
+    } else {
+        to->data = 0;
+        to->len = 0;
+    }
+    return SECSuccess;
+}
+
+void
+SECITEM_FreeItem(SECItem *zap, PRBool freeit)
+{
+    if (zap) {
+#ifdef _KERNEL
+        kmem_free(zap->data, zap->len);
+#else
+        free(zap->data);
+#endif
+        zap->data = 0;
+        zap->len = 0;
+        if (freeit) {
+#ifdef _KERNEL
+            kmem_free(zap, sizeof (SECItem));
+#else
+            free(zap);
+#endif
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/ec/impl/secoidt.h	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,103 @@
+/* *********************************************************************
+ *
+ * Sun elects to have this file available under and governed by the
+ * Mozilla Public License Version 1.1 ("MPL") (see
+ * http://www.mozilla.org/MPL/ for full license text). For the avoidance
+ * of doubt and subject to the following, Sun also elects to allow
+ * licensees to use this file under the MPL, the GNU General Public
+ * License version 2 only or the Lesser General Public License version
+ * 2.1 only. Any references to the "GNU General Public License version 2
+ * or later" or "GPL" in the following shall be construed to mean the
+ * GNU General Public License version 2 only. Any references to the "GNU
+ * Lesser General Public License version 2.1 or later" or "LGPL" in the
+ * following shall be construed to mean the GNU Lesser General Public
+ * License version 2.1 only. However, the following notice accompanied
+ * the original version of this file:
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ *********************************************************************** */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SECOIDT_H_
+#define _SECOIDT_H_
+
+#pragma ident   "%Z%%M% %I%     %E% SMI"
+
+/*
+ * secoidt.h - public data structures for ASN.1 OID functions
+ *
+ * $Id: secoidt.h,v 1.23 2007/05/05 22:45:16 nelson%bolyard.com Exp $
+ */
+
+typedef struct SECOidDataStr SECOidData;
+typedef struct SECAlgorithmIDStr SECAlgorithmID;
+
+/*
+** An X.500 algorithm identifier
+*/
+struct SECAlgorithmIDStr {
+    SECItem algorithm;
+    SECItem parameters;
+};
+
+#define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
+#define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
+#define SEC_OID_PKCS12_KEY_USAGE  SEC_OID_X509_KEY_USAGE
+
+/* fake OID for DSS sign/verify */
+#define SEC_OID_SHA SEC_OID_MISS_DSS
+
+typedef enum {
+    INVALID_CERT_EXTENSION = 0,
+    UNSUPPORTED_CERT_EXTENSION = 1,
+    SUPPORTED_CERT_EXTENSION = 2
+} SECSupportExtenTag;
+
+struct SECOidDataStr {
+    SECItem            oid;
+    ECCurveName        offset;
+    const char *       desc;
+    unsigned long      mechanism;
+    SECSupportExtenTag supportedExtension;
+                                /* only used for x.509 v3 extensions, so
+                                   that we can print the names of those
+                                   extensions that we don't even support */
+};
+
+#endif /* _SECOIDT_H_ */
--- a/jdk/src/solaris/bin/java_md.c	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/solaris/bin/java_md.c	Wed Jul 05 17:01:15 2017 +0200
@@ -1324,12 +1324,12 @@
 {
    if (findBootClass == NULL) {
        findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
-          "JVM_FindClassFromClassLoader");
+          "JVM_FindClassFromBootLoader");
        if (findBootClass == NULL) {
            JLI_ReportErrorMessage(DLL_ERROR4,
-               "JVM_FindClassFromClassLoader");
+               "JVM_FindClassFromBootLoader");
            return NULL;
        }
    }
-   return findBootClass(env, classname, JNI_FALSE, (jobject)NULL, JNI_FALSE);
+   return findBootClass(env, classname);
 }
--- a/jdk/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,18 +25,23 @@
 
 package sun.net.www.protocol.http;
 
-import java.util.Arrays;
-import java.util.StringTokenizer;
-import java.util.Random;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.PasswordAuthentication;
+import java.net.UnknownHostException;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
 
 import sun.net.www.HeaderParser;
 
-import java.io.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
-import java.security.*;
-import java.net.*;
-
 /**
  * NTLMAuthentication:
  *
@@ -66,8 +71,6 @@
 class NTLMAuthentication extends AuthenticationInfo {
     private static final long serialVersionUID = -2403849171106437142L;
 
-    static char NTLM_AUTH = 'N';
-
     private byte[] type1;
     private byte[] type3;
 
@@ -142,7 +145,10 @@
      * from a system property: "http.auth.ntlm.domain".
      */
     public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) {
-        super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH, url, "");
+        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+                AuthScheme.NTLM,
+                url,
+                "");
         init (pw);
     }
 
@@ -166,7 +172,11 @@
     */
     public NTLMAuthentication(boolean isProxy, String host, int port,
                                 PasswordAuthentication pw) {
-        super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH,host, port, "");
+        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+                AuthScheme.NTLM,
+                host,
+                port,
+                "");
         init (pw);
     }
 
--- a/jdk/src/windows/bin/java_md.c	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/windows/bin/java_md.c	Wed Jul 05 17:01:15 2017 +0200
@@ -1093,12 +1093,6 @@
  */
 static FindClassFromBootLoader_t *findBootClass = NULL;
 
-#ifdef _M_AMD64
-#define JVM_BCLOADER "JVM_FindClassFromClassLoader"
-#else
-#define JVM_BCLOADER "_JVM_FindClassFromClassLoader@20"
-#endif /* _M_AMD64 */
-
 jclass FindBootStrapClass(JNIEnv *env, const char *classname)
 {
    HMODULE hJvm;
@@ -1108,13 +1102,13 @@
        if (hJvm == NULL) return NULL;
        /* need to use the demangled entry point */
        findBootClass = (FindClassFromBootLoader_t *)GetProcAddress(hJvm,
-            JVM_BCLOADER);
+            "JVM_FindClassFromBootLoader");
        if (findBootClass == NULL) {
-          JLI_ReportErrorMessage(DLL_ERROR4, JVM_BCLOADER);
+          JLI_ReportErrorMessage(DLL_ERROR4, "JVM_FindClassFromBootLoader");
           return NULL;
        }
    }
-   return findBootClass(env, classname, JNI_FALSE, (jobject)NULL, JNI_FALSE);
+   return findBootClass(env, classname);
 }
 
 void
--- a/jdk/src/windows/classes/java/util/prefs/WindowsPreferences.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/windows/classes/java/util/prefs/WindowsPreferences.java	Wed Jul 05 17:01:15 2017 +0200
@@ -29,7 +29,7 @@
 import java.util.TreeMap;
 import java.util.StringTokenizer;
 import java.io.ByteArrayOutputStream;
-import java.util.logging.Logger;
+import sun.util.logging.PlatformLogger;
 
 /**
  * Windows registry based implementation of  <tt>Preferences</tt>.
@@ -48,7 +48,7 @@
     /**
      * Logger for error messages
      */
-    private static Logger logger;
+    private static PlatformLogger logger;
 
     /**
      * Windows registry path to <tt>Preferences</tt>'s root nodes.
@@ -1102,9 +1102,9 @@
         // assert false;
     }
 
-    private static synchronized Logger logger() {
+    private static synchronized PlatformLogger logger() {
         if (logger == null) {
-            logger = Logger.getLogger("java.util.prefs");
+            logger = PlatformLogger.getLogger("java.util.prefs");
         }
         return logger;
     }
--- a/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java	Wed Jul 05 17:01:15 2017 +0200
@@ -67,6 +67,9 @@
         if (d3dAvailable) {
             // we don't use pixel formats for the d3d pipeline
             pfDisabled = true;
+            sun.misc.PerfCounter.getD3DAvailable().set(1);
+        } else {
+            sun.misc.PerfCounter.getD3DAvailable().set(0);
         }
     }
 
--- a/jdk/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,18 +25,13 @@
 
 package sun.net.www.protocol.http;
 
-import java.util.Arrays;
-import java.util.StringTokenizer;
-import java.util.Random;
-
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.PasswordAuthentication;
+import java.net.UnknownHostException;
+import java.net.URL;
 import sun.net.www.HeaderParser;
 
-import java.io.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
-import java.security.*;
-import java.net.*;
-
 /**
  * NTLMAuthentication:
  *
@@ -47,7 +42,6 @@
 
     private static final long serialVersionUID = 100L;
 
-    static final char NTLM_AUTH = 'N';
     private String hostname;
     private static String defaultDomain; /* Domain to use if not specified by user */
 
@@ -88,7 +82,10 @@
      * from a system property: "http.auth.ntlm.domain".
      */
     public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) {
-        super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH, url, "");
+        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+              AuthScheme.NTLM,
+              url,
+              "");
         init (pw);
     }
 
@@ -119,7 +116,11 @@
     */
     public NTLMAuthentication(boolean isProxy, String host, int port,
                                 PasswordAuthentication pw) {
-        super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH,host, port, "");
+        super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
+              AuthScheme.NTLM,
+              host,
+              port,
+              "");
         init (pw);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/BreakpointWithFullGC.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#  @test
+#  @bug 6862295
+#  @summary Verify breakpoints still work after a full GC.
+#  @author dcubed (based on the test program posted to the following
+#  Eclipse thread https://bugs.eclipse.org/bugs/show_bug.cgi?id=279137)
+#
+#  @run shell BreakpointWithFullGC.sh
+
+compileOptions=-g
+# Hijacking the mode parameter to make sure we use a small amount
+# of memory and can see what GC is doing.
+mode="-Xmx32m -verbose:gc"
+# Force use of a GC framework collector to see the original failure.
+#mode="$mode -XX:+UseSerialGC"
+
+# Uncomment this to see the JDI trace
+#jdbOptions=-dbgtrace
+
+createJavaFile()
+{
+    cat <<EOF > $1.java.1
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class $1 {
+    public static List<Object> objList = new ArrayList<Object>();
+
+    private static void init(int numObjs) {
+        for (int i = 0; i < numObjs; i++) {
+            objList.add(new Object());
+        }
+    }
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 10; i++) {
+            System.out.println("top of loop");     // @1 breakpoint
+            init(1000000);
+            objList.clear();
+            System.out.println("bottom of loop");  // @1 breakpoint
+        }
+        System.out.println("end of test");         // @1 breakpoint
+    }
+}
+
+EOF
+}
+
+# This is called to feed cmds to jdb.
+dojdbCmds()
+{
+    setBkpts @1
+
+    # get to the first loop breakpoint
+    runToBkpt
+    # 19 "cont" commands gets us through all the loop breakpoints.
+    # Use for-loop instead of while-loop to avoid creating processes
+    # for '[' and 'expr'.
+    for ii in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19; do
+        contToBkpt
+    done
+    # get to the last breakpoint
+    contToBkpt
+}
+
+
+mysetup()
+{
+    if [ -z "$TESTSRC" ] ; then
+        TESTSRC=.
+    fi
+
+    for ii in . $TESTSRC $TESTSRC/.. ; do
+        if [ -r "$ii/ShellScaffold.sh" ] ; then
+            . $ii/ShellScaffold.sh
+            break
+        fi
+    done
+}
+
+# You could replace this next line with the contents
+# of ShellScaffold.sh and this script will run just the same.
+mysetup
+
+runit
+
+# make sure we hit the first breakpoint at least once
+jdbFailIfNotPresent 'System\..*top of loop'
+
+# make sure we hit the second breakpoint at least once
+jdbFailIfNotPresent 'System\..*bottom of loop'
+
+# make sure we hit the last breakpoint
+jdbFailIfNotPresent 'System\..*end of test'
+
+# make sure we had at least one full GC
+debuggeeFailIfNotPresent 'Full GC'
+
+# check for error message due to thread ID change
+debuggeeFailIfPresent \
+    'Exception in thread "event-handler" java.lang.NullPointerException'
+
+pass
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java	Wed Jul 05 17:01:15 2017 +0200
@@ -25,7 +25,7 @@
  * @test
  * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
  *      5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
- *      6464154 6523983 6206031 4960438 6631352 6631966
+ *      6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
  * @summary Basic tests for Process and Environment Variable code
  * @run main/othervm Basic
  * @author Martin Buchholz
@@ -302,6 +302,14 @@
                 printUTF8(val == null ? "null" : val);
             } else if (action.equals("System.getenv()")) {
                 printUTF8(getenvAsString(System.getenv()));
+            } else if (action.equals("ArrayOOME")) {
+                Object dummy;
+                switch(new Random().nextInt(3)) {
+                case 0: dummy = new Integer[Integer.MAX_VALUE]; break;
+                case 1: dummy = new double[Integer.MAX_VALUE];  break;
+                case 2: dummy = new byte[Integer.MAX_VALUE][];  break;
+                default: throw new InternalError();
+                }
             } else if (action.equals("pwd")) {
                 printUTF8(new File(System.getProperty("user.dir"))
                           .getCanonicalPath());
@@ -1473,6 +1481,22 @@
         } catch (Throwable t) { unexpected(t); }
 
         //----------------------------------------------------------------
+        // OOME in child allocating maximally sized array
+        // Test for hotspot/jvmti bug 6850957
+        //----------------------------------------------------------------
+        try {
+            List<String> list = new ArrayList<String>(javaChildArgs);
+            list.add(1, String.format("-XX:OnOutOfMemoryError=%s -version",
+                                      javaExe));
+            list.add("ArrayOOME");
+            ProcessResults r = run(new ProcessBuilder(list));
+            check(r.out().contains("java.lang.OutOfMemoryError:"));
+            check(r.out().contains(javaExe));
+            check(r.err().contains(System.getProperty("java.version")));
+            equal(r.exitValue(), 1);
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
         // Windows has tricky semi-case-insensitive semantics
         //----------------------------------------------------------------
         if (Windows.is())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/ProxySelector/B6737819.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6737819
+ * @summary sun.misc.net.DefaultProxySelector doesn't use proxy setting to localhost
+ */
+
+import java.net.ProxySelector;
+import java.net.Proxy;
+import java.net.URI;
+
+public class B6737819 {
+    private static String[] uris = {
+        "http://localhost/index.html",
+        "http://127.0.0.1/index.html",
+        "http://127.2/index.html",
+        "http://[::1]/index.html"
+    };
+    public static void main(String[] args) throws Exception {
+        System.setProperty("http.proxyHost", "myproxy");
+        System.setProperty("http.proxyPort", "8080");
+        ProxySelector sel = ProxySelector.getDefault();
+        java.util.List<Proxy> l;
+        // Default value for http.nonProxyHots should exclude all this uris
+        // from going through the HTTP proxy
+        for (String s : uris) {
+            l = sel.select(new URI(s));
+            if (l.size() == 1 && l.get(0).type() != Proxy.Type.DIRECT) {
+                throw new RuntimeException("ProxySelector returned the wrong proxy for " + s);
+            }
+        }
+        // Let's override the default nonProxyHosts and make sure we now get a
+        // HTTP proxy
+        System.setProperty("http.nonProxyHosts", "");
+        for (String s : uris) {
+            l = sel.select(new URI(s));
+            if (l.size() == 1 && l.get(0).type() != Proxy.Type.HTTP) {
+                throw new RuntimeException("ProxySelector returned the wrong proxy for " + s);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/WalkWithSecurity.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6876541
+ * @summary Test Files.walkFileTree in the presence of a security manager
+ * @build WalkWithSecurity
+ * @run main/othervm WalkWithSecurity grantAll.policy pass
+ * @run main/othervm WalkWithSecurity denyAll.policy fail
+ * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+public class WalkWithSecurity {
+
+    public static void main(String[] args) throws IOException {
+        String policyFile = args[0];
+        ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
+
+        String here = System.getProperty("user.dir");
+        String testSrc = System.getProperty("test.src");
+        if (testSrc == null)
+            throw new RuntimeException("This test must be run by jtreg");
+        Path dir = Paths.get(testSrc);
+
+        // Sanity check the environment
+        if (Paths.get(here).isSameFile(dir))
+            throw new RuntimeException("Working directory cannot be " + dir);
+        DirectoryStream<Path> stream = dir.newDirectoryStream();
+        try {
+            if (!stream.iterator().hasNext())
+                throw new RuntimeException(testSrc + " is empty");
+        } finally {
+            stream.close();
+        }
+
+        // Install security manager with the given policy file
+        System.setProperty("java.security.policy",
+            dir.resolve(policyFile).toString());
+        System.setSecurityManager(new SecurityManager());
+
+        // Walk the source tree
+        CountingVisitor visitor = new CountingVisitor();
+        SecurityException exception = null;
+        try {
+            Files.walkFileTree(dir, visitor);
+        } catch (SecurityException se) {
+            exception = se;
+        }
+
+        // Check result
+        switch (expectedResult) {
+            case PASS:
+                if (exception != null) {
+                    exception.printStackTrace();
+                    throw new RuntimeException("SecurityException not expected");
+                }
+                if (visitor.count() == 0)
+                    throw new RuntimeException("No files visited");
+                break;
+            case FAIL:
+                if (exception == null)
+                    throw new RuntimeException("SecurityException expected");
+                if (visitor.count() > 0)
+                    throw new RuntimeException("Files were visited");
+                break;
+            case TOP_ONLY:
+                if (exception != null) {
+                    exception.printStackTrace();
+                    throw new RuntimeException("SecurityException not expected");
+                }
+                if (visitor.count() == 0)
+                    throw new RuntimeException("Starting file not visited");
+                if (visitor.count() > 1)
+                    throw new RuntimeException("More than starting file visited");
+                break;
+            default:
+                throw new RuntimeException("Should not get here");
+        }
+    }
+
+    static enum ExpectedResult {
+        PASS,
+        FAIL,
+        TOP_ONLY;
+    }
+
+    static class CountingVisitor extends SimpleFileVisitor<Path> {
+        private int count;
+
+        int count() {
+            return count;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(Path dir) {
+            System.out.println(dir);
+            count++;
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+            System.out.println(file);
+            count++;
+            return FileVisitResult.CONTINUE;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/denyAll.policy	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,3 @@
+// policy file that does not grant any permissions
+grant {
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/grantAll.policy	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,5 @@
+// policy file that grants read access to source directory and all descendants
+grant {
+    permission java.io.FilePermission "${test.src}", "read";
+    permission java.io.FilePermission "${test.src}${file.separator}-", "read";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/grantTopOnly.policy	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,4 @@
+// policy file that grants read access to source directory
+grant {
+    permission java.io.FilePermission "${test.src}", "read";
+};
--- a/jdk/test/sun/security/ec/TestEC.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/test/sun/security/ec/TestEC.java	Wed Jul 05 17:01:15 2017 +0200
@@ -27,6 +27,8 @@
  * @summary  Provide out-of-the-box support for ECC algorithms
  * @library ../pkcs11
  * @library ../pkcs11/ec
+ * @library ../pkcs11/sslecc
+ * @compile -XDignore.symbol.file TestEC.java
  * @run main TestEC
  */
 
@@ -35,12 +37,15 @@
 /*
  * Leverage the collection of EC tests used by PKCS11
  *
- * NOTE: the following files were copied here from the PKCS11 EC Test area
+ * NOTE: the following 6 files were copied here from the PKCS11 EC Test area
  *       and must be kept in sync with the originals:
  *
  *           ../pkcs11/ec/p12passwords.txt
+ *           ../pkcs11/ec/certs/sunlabscerts.pem
  *           ../pkcs11/ec/pkcs12/secp256r1server-secp384r1ca.p12
  *           ../pkcs11/ec/pkcs12/sect193r1server-rsa1024ca.p12
+ *           ../pkcs11/sslecc/keystore
+ *           ../pkcs11/sslecc/truststore
  */
 
 public class TestEC {
@@ -49,18 +54,23 @@
         Provider p = new sun.security.ec.SunEC();
         System.out.println("Running tests with " + p.getName() +
             " provider...\n");
+        long start = System.currentTimeMillis();
 
-        long start = System.currentTimeMillis();
+        /*
+         * The entry point used for each test is its instance method
+         * called main (not its static method called main).
+         */
         new TestECDH().main(p);
         new TestECDSA().main(p);
         new TestCurves().main(p);
         new TestKeyFactory().main(p);
         new TestECGenSpec().main(p);
         new ReadPKCS12().main(p);
-        //new ReadCertificates().main(p);
-        long stop = System.currentTimeMillis();
+        new ReadCertificates().main(p);
+        new ClientJSSEServerJSSE().main(p);
 
+        long stop = System.currentTimeMillis();
         System.out.println("\nCompleted tests with " + p.getName() +
-            " provider (" + (stop - start) + " ms).");
+            " provider (" + ((stop - start) / 1000.0) + " seconds).");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ec/certs/sunlabscerts.pem	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,1317 @@
+-----BEGIN CERTIFICATE-----
+MIIDyDCCAzGgAwIBAgIJAJh6e4zfP9lXMA0GCSqGSIb3DQEBBQUAMIGfMQswCQYD
+VQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAk
+BgNVBAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMR8wHQYDVQQLDBZU
+ZXN0IFNlcnZlciAoUlNBIDEwMjQpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFs
+c3R1ZmYuY29tMB4XDTA1MTIwNjIxMjk1OFoXDTEwMDExNDIxMjk1OFowgZ8xCzAJ
+BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEm
+MCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHzAdBgNVBAsM
+FlRlc3QgU2VydmVyIChSU0EgMTAyNCkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50
+YWxzdHVmZi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJrKL3D9xOca
+b5C5m1yeIFXvwufm5m06RnQdLWaj5Epg9+6tM3uZNn9B0r4k7MKYPbzBqyQO9ZSm
+sulV9U3nWLhjChOrrNCIxzAUIR1//11QVKfjv3k8Ts7N5g5kIIiG8GUXh1WCNYhN
+SvPo0BpNJ3FFwMMCZu0VpAP0j9krqWjfAgMBAAGjggEIMIIBBDAdBgNVHQ4EFgQU
+FrXN7dxlrB1ccI0ZOi+NzYpz6UIwgdQGA1UdIwSBzDCByYAUFrXN7dxlrB1ccI0Z
+Oi+NzYpz6UKhgaWkgaIwgZ8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQG
+A1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBM
+YWJvcmF0b3JpZXMxHzAdBgNVBAsMFlRlc3QgU2VydmVyIChSU0EgMTAyNCkxIjAg
+BgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5jb22CCQCYenuM3z/ZVzAMBgNV
+HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAAEQHmeWmoe+s784Qi1oK04eNeI3
+m3Iw06IWjdKH5xatQqj9VjvngLWnmY26PYlF6PK3cAktuempXVA2rZ3Dv5pkgAdQ
+f3LXGHBKfAEsSjSSpxIsQA6Q+Yk7zqht5hSPOtUXHcWUx9EMvh7HnjmEEdR80fw/
+txvN4xm8V+flmK/T
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICxjCCAi8CCQCg3U8Mc7XCZzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwNTlaFw0xMDAxMTQyMTMwNTlaMIGuMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMS4wLAYDVQQLDCVUZXN0
+IFNlcnZlciAocnNhMTAyNHNlcnZlci1yc2ExMDI0Y2EpMSIwIAYDVQQDDBlkZXYu
+ZXhwZXJpbWVudGFsc3R1ZmYuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQCZCOorl//TxbVdj8X+fb9xhMlApe9sAU/jlHRtrv+7FflqCLMmhcR8s90LTCjq
+gcX0mGm7fIusBff4/hjaKlmrto0YLNg8c8Zvev5CD+0HQHtbGUfx3TGOHv7gvG31
+nt88ZOzyIlPe2khcDTmb613zxFZhgJBs3bCsQz0TK3bR/wIDAQABMA0GCSqGSIb3
+DQEBBQUAA4GBABHP8xO3ouLm6SgZefjJnmbURTpjosE7oR15T1Fpf6o0WARaTeYO
+07H/GdDFUgV3RTA/zNMimfq6XqJB5r5WBziVkLLuixzS7nNaAci6o5b2UaU7shUc
+z3k0O4Dclybb4J1dYeAIwXUGqLAzI1NCgjRoGirFWT+O+02tT1KCiSl3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDRzCCAi8CCQCg3U8Mc7XCaDANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMxMDBaFw0xMDAxMTQyMTMxMDBaMIGuMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMS4wLAYDVQQLDCVUZXN0
+IFNlcnZlciAocnNhMTAyNHNlcnZlci1yc2EyMDQ4Y2EpMSIwIAYDVQQDDBlkZXYu
+ZXhwZXJpbWVudGFsc3R1ZmYuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQC5EyeXl7YTi5NPgJiIZHNSrG9qlAVoM5BYKqAVtFwHCbLYB7ZWyN2BuEfUSf8p
+KSKkq28DkNTqnyz6Rg57kHzO3+kca0+iHlqFpbcP6uuN4ubOGZCuEDT0Ti7VXRtc
+a8hGNrOEzZKA6DCl9csfrN0jHB5VBfJ4qTJCEi8fXNQbzwIDAQABMA0GCSqGSIb3
+DQEBBQUAA4IBAQC05575dPOqJ6Qk2rs7wHu4tGE15OR2jnXSZXXDObRUHetykmfQ
+YbUq9/z9f3k4R53GAisgDwbVUb3EUsXofy7eMTUD89A7MiZ99SvebPilDQE3djqM
+D0uA9a96LG6fAarc1MdpbMPcFiFFiwwlqJVtx4TNlektFbFQRzrrbMSF/ISLzdWK
+fR3XD5qpwiCQbSug9Zm7cornUk8cK/Fs571wErOrdPo47aw1C8NjspLhux/JtHM9
+hNuAqona/4lX5lMVNpnSkWaT+B281+ysm1uEK8lvsDSUuLy+fZvokCrhQPFLoI+h
+l5HGNqXdyIu1POCl6yqd6+BKNnfA5Qy+Bp87
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICbDCCAioCCQCg3U8Mc7XCYTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA0OVoXDTEwMDExNDIxMzA0OVowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2ExMDI0c2VydmVyLXNlY3AxNjByMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyvWS
+/5LJKlEJNR+jEWB1VMQVC09227El9V80yZ8WYqL0RdvWvDHN/vN1HKlFni/X5pwK
+Def0vpXEDueeUgs9nQd+WDI/HOHTZ6BwUu2x2JParIBm9+dylWiBqhV+9LI/TyIr
+4KMKjcnTMlCKZvzrIplIvcf+Gu/OFG46q3PUIFcCAwEAATAJBgcqhkjOPQQBAzEA
+MC4CFQCslg/BEN7fygz0CIIWO+1n/yenNwIVAMivW2BhQhk1TEPw5Zs3QgXEw187
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIChDCCAioCCQCg3U8Mc7XCYjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA1MVoXDTEwMDExNDIxMzA1MVowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2ExMDI0c2VydmVyLXNlY3AyNTZyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5v3h
+NBYB07K2o8TMStAW5j5qDfy1XciU6Hx32qeoPwBdsvalmiAP+Scawfi7xPWGCMTK
+zBiRSRHVgFU+tsvpFhJ+7mnl0k7zQMdmuzJCH/IV8889TAobQbGsvSdMa5ry+FRo
+u+2QoEAaOQik4RFZcZmw+46wbMbeNhesirEkG20CAwEAATAJBgcqhkjOPQQBA0kA
+MEYCIQCMTGl7AImRhjsdQuEUaODQKFWGcZSFT0ZVe+ikWQCdcQIhANOPoSjaBDHa
+kJVhR6MrTMHvnfAGL+EZpAqHGPMM12JD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICpDCCAioCCQCg3U8Mc7XCYzAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA1MloXDTEwMDExNDIxMzA1MlowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2ExMDI0c2VydmVyLXNlY3AzODRyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArsTW
+yLsCTz6nEeBEHW1JvMFPFnFqvXWWJJsEHbJtPDU0FF3xurgfNX4T7BsPW5LNIneh
+MJbKqSCRgw0q97zgVLhB1WBE6y5jkfYCTDA5QAuNOlqgTGrBg0WIANgsXjHFZ5kQ
+46i98IzFOFHZFOdtj+i0T3GviZWKGCbjKShyWnMCAwEAATAJBgcqhkjOPQQBA2kA
+MGYCMQD4L6X8M2oCiwQE0/HqNNI4zCt6gp2o8Uk2HWa5If59QhwlfjXQSdbvVGfW
+T2XpnUACMQDJ6Ir8G4H9Mu9ktf64MhnYg6A22hV4nWZ5bpM3AiD+10q+30r+TWV4
+89YQz707Eok=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICyDCCAioCCQCg3U8Mc7XCZDAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA1NFoXDTEwMDExNDIxMzA1NFowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2ExMDI0c2VydmVyLXNlY3A1MjFyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1Nmx
+2TOGk8FQXJIzDM2+x4jVWocD2lRShsFQaMhltST4PWm+TbXBPSxpvS9oFW7eZE3J
+50OqxMiZkmH8un44Iet7E6fi0iRhw0bl4uqG2JHtyMzSYR6niSy0yqgHVJVwM24Q
+Z/39X17PD0NwCEiPBGFx9Xa5E2JP9KcnCbrj49sCAwEAATAJBgcqhkjOPQQBA4GM
+ADCBiAJCAZ4Apzk6L7BLjKoln+NEl5a/I1TmNIPVR0HtcLwbdZQ/y9b0+vhENkkS
+XIGTc/2Jx+OV/tc4JyNW7PNM/YPl5FDUAkIByKevbRtsBD0HuCVK6WOf+6uz+QFs
+fgxz0XoMyWMuoUIM2ytx+Eq9UY13QgqCQ5FxYWJ6RtDiNhEovr5GMjqjG0Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICbDCCAioCCQCg3U8Mc7XCZTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA1NVoXDTEwMDExNDIxMzA1NVowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2ExMDI0c2VydmVyLXNlY3QxNjNyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy4Vh
+Ju/NaZEhiu6wsh4fsKGvwdHwRKvmJwMk8wEk3/Vz92/9kPR5B/Co3XVGBmW4UJwD
+0BcdPcMyr1TDHYOL7kS65MJGq0eFcBblA5hr2G3unZwgVwpS9GzMA7n8s3BtDGYN
+UpUyt5u5C6mTqQoK39xVWWbke5tM90T3jr6MiN0CAwEAATAJBgcqhkjOPQQBAzEA
+MC4CFQOcO1rEZFieKqpNL8E8T1wwchv2FQIVAQ4DEcV2AkLqSXxgt+h03NyWPeEN
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICcjCCAioCCQCg3U8Mc7XCZjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA1N1oXDTEwMDExNDIxMzA1N1owgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2ExMDI0c2VydmVyLXNlY3QxOTNyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAws4d
+5PHRj1UOeuc60MnkGhmwJ/RD7Vmaq8NUJwliTHnAscTlZuv5Irv9cYHhAka2p8WJ
+mo8xZxlUQMIUxIx/9ocZEYAKrv/vjWo05iaDQowJOUHM77usJnTZbDrVfeuOBqFo
+6G2scl6RBGdCUOGUBVdRT6sEWQnYm/wIcTxj9OcCAwEAATAJBgcqhkjOPQQBAzcA
+MDQCGHDRiFsRMDB+Y4+Mnjs4jWHHKyjqoOYFlwIYemZsC0uC1/oI/ZFUuERW7TEe
+BPpqMQgX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICyzCCAjQCCQClVpDHKllBjTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEpMCcGA1UECwwgVGVzdCBT
+ZXJ2ZXIgKHJzYTEwMjRzZXJ2ZXItc2VsZikxIjAgBgNVBAMMGWRldi5leHBlcmlt
+ZW50YWxzdHVmZi5jb20wHhcNMDUxMjA2MjEzMTAxWhcNMTAwMTE0MjEzMTAxWjCB
+qTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MSYwJAYDVQQKDB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEpMCcG
+A1UECwwgVGVzdCBTZXJ2ZXIgKHJzYTEwMjRzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALx55L25d1DjV6X6z/rqebCJvhD0IfWqUU6ekiADnDgmOhFT8gutI4Xh
+2AlBhIyticLU5IMP/MYud0OPnavaH3dcNRsfkJkfmZRULqIDjWnVmtmBhV8th9TM
+KaH7V1TOqxqMfGuzFq9uwL8p5i2f8fLQjZ9sNNj7qeuW5XI05cv1AgMBAAEwDQYJ
+KoZIhvcNAQEFBQADgYEAG3UcMUmwpTKUwNA6P0i0073ptjmzhRIeDdpf1d69X99Y
+Wrnf2H6xA2boa8gBkVFjCaLBakIq6px5IuGFZNB2+0yJqd8QE22DKk1Ikr5hBsEC
+owhd0feRaNjO0u/kPFZU1XAVFyz2AGKdLUOw4OEV8tuSOXAmWoMZHwfoocy1JnQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEzTCCA7WgAwIBAgIJAMkNhmYP6nKsMA0GCSqGSIb3DQEBBQUAMIGfMQswCQYD
+VQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAk
+BgNVBAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMR8wHQYDVQQLDBZU
+ZXN0IFNlcnZlciAoUlNBIDIwNDgpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFs
+c3R1ZmYuY29tMB4XDTA1MTIwNjIxMzAwOVoXDTEwMDExNDIxMzAwOVowgZ8xCzAJ
+BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEm
+MCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHzAdBgNVBAsM
+FlRlc3QgU2VydmVyIChSU0EgMjA0OCkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50
+YWxzdHVmZi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO/6vZ
+zPZAmeKP/fMAwKTRzCmy30TnoEZJybsk8QDlL9xaYIcEiIhf6eOV0/IYPcSwPakv
+Ha5lT9aCTEEdcxACqAQlm2LOFZ79pUc0bGEmeFpHDZoO2w7+/RCYbGLkdWKTfj1D
+kKG9PoWX5MelBZqkQuvE3+6eAr70IlQRA8uMA+Aq+Hl7KZys+eTX3eVWcNYZu94U
+Z9wOKsRnRT4Yzf1G8aPJq4gIwxW4nBVAHqUc2N8bUzsHVqbTpcytU3KYT1YlcLGG
+Ir1LulgjWws3Lncx1rZQuAIT5cyjCmW8wZ/O+GewzmbgV95lFsf8HCd0ZD4j65sS
+/l0xB4zHnSBAegntAgMBAAGjggEIMIIBBDAdBgNVHQ4EFgQUS1aD1pb8BOGcjSyh
+9IhovqLk1TcwgdQGA1UdIwSBzDCByYAUS1aD1pb8BOGcjSyh9IhovqLk1TehgaWk
+gaIwgZ8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRh
+aW4gVmlldzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMx
+HzAdBgNVBAsMFlRlc3QgU2VydmVyIChSU0EgMjA0OCkxIjAgBgNVBAMMGWRldi5l
+eHBlcmltZW50YWxzdHVmZi5jb22CCQDJDYZmD+pyrDAMBgNVHRMEBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQBDl6f5HVzv0r0/DNAMy6vaKHrKXCJYVXLh7AZWLShP
+3BfvekDRncLFjldTEqE1vqD4wndxpHVVwyZWWBWHVcw76AAtYnZp36ex5ZP56pHw
+Mg308O+tYLgjdm5cDEzGzqNgavUIi/T/lMnWJrls1Zr/qnf7hzbvIAlMGJ4jcZGF
+U1Z8T4mpFyroafXSbHEE/awX9DbyZL0ryXXtlTggxgLfzPqmSx4ZXurqv4LFdjlu
+pZ/+/b6qU3JAlDMDMReb+iDBIllNGVZj88QTp3cC2CtwnYBYvLLWFtWoQpN2Ppz4
+X5xcdh4VuTICpk5kQSbzrij3GXZl0fDVuX4Z+5J1xodl
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDSjCCArMCCQCg3U8Mc7XCbzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMyMjlaFw0xMDAxMTQyMTMyMjlaMIGuMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMS4wLAYDVQQLDCVUZXN0
+IFNlcnZlciAocnNhMjA0OHNlcnZlci1yc2ExMDI0Y2EpMSIwIAYDVQQDDBlkZXYu
+ZXhwZXJpbWVudGFsc3R1ZmYuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA7I6hIU6+t1DQABGWtaqyhUjieQTzoaN3dZzmzTcUXY62F+IedLuVrxcQ
+3YJU8+jcM6rl+/eIa90rNcKpxjrdzx676CqFCHO3/aHF1iCMmQF368ezfs2lDPTF
+mobrn6KMNe71SM8bQ8MHFmRxY1wWk7GKIuz8OQnJOHD1nXQisjv1GBZ7HssaEPGd
+m8c1rKCvzqrC4Nj/U+cKV0VeWtJod5inIx5RT/5FYW4QdBwuhovoKumPxpImYz6Y
+SuFAce2hTMjxmvFXD0V1+VfWsYUe0/TilRgOv5l9iWo4haGBftYFWW8w0iqOB4+q
+cPqcKozI7Tjs9r3Rby0zTdjB6vZi9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAAUd
+cnt8YHDUvIroDiLQQsH+p2mDD+ra10K3C9H0Lsvt6cb3/2jn6PupFVJzwkEEankS
+Lo/pOe+bO5uSA4C2FQAymrYZX5Hh1guK/Has+Sf0K+HKPx28QPGg1EoS2KAbUf1t
+RBX2jtq8Suz3iS9u77PbpB7aMNAEBihr2jAyfSka
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDyzCCArMCCQCg3U8Mc7XCcDANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMyMzVaFw0xMDAxMTQyMTMyMzVaMIGuMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMS4wLAYDVQQLDCVUZXN0
+IFNlcnZlciAocnNhMjA0OHNlcnZlci1yc2EyMDQ4Y2EpMSIwIAYDVQQDDBlkZXYu
+ZXhwZXJpbWVudGFsc3R1ZmYuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAxHxrsAwLznaK+dmgQxUzmWTsNLhuKk+yBkpJZQDQDjkdxVrime1DxPAZ
+MDi4OL+9YCIDS3ZWG0uLH49Atq08/2TB+aYDm0YBjrq3BRphTBrNNpntezSgP/nz
+R2hOBvBgSvFqorTLzRF9THq18CrSJJB/OPFzvl6mYK8dtS4CnOfdUs0Pv8SwdxhJ
+X6qsO0NJclrfBYBodGW1PiY62NPX0h2mLcg4OmD3gThfjUvXnsdjLJYV6hZFT+YC
+vPJNTxTGebfnJr4sRGdqRUyBrjiqZtXwGpIBCSg/YpnUOfDSxJNA2Wd/WFJJv8Fq
+kBh2oDRqlFNC/Z+HjGqKj0gFowTq3QIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQBp
+iFO+5KbnHfRBStgxZdTBrr+HEezeFlxeE04bM7kSWII2SiQbAWSG5Rkb518m5x65
+q23KqUK+YJiy7k0zoKInvG/qLf1D5osFlwaAll7AKBadn/R8x822xSJCydHgD64V
+b3u89zBY5Jtl+EzTA+n+UWRsurlLL1K9ockWZrDiZn6gGO5/ucR8OkZ192sxqKRr
+iQbN12LWSmUCYPwba8nvDdm1ymAbnFOg1oQJ9HvxmFI3GaGjdmNo9rlaoNS/xQ35
+iTtJyi1MK2d+O2JPD5cS5otGfFnQiTWIngBiuEoOwzw7x8eWsOQaBPVnNSlMdU+z
+Zrc6M1OSOUh2+DqvAoBp
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC8DCCAq4CCQCg3U8Mc7XCaTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzExM1oXDTEwMDExNDIxMzExM1owgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2EyMDQ4c2VydmVyLXNlY3AxNjByMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AMPD0turqL6uNjGfquQy3MTv90+RvDCvCQXGnxdJa6QcOOHnv/4ua9g/TOO2cVuc
+UuF3EnMSDg+HIo8qJhdKcOa4nnp1IxAnPsQs1K9vq8eqtuSuFMZUoUKy969ThPqd
+UTYyZpOn87XMftm76nz92q2gDPLj7ZxD1QOv0MpMHjXJMSRHWEhsoCpYBdFT5Nl5
+28bK0AWTv4nw2RmQryn+UMblAqnJBNiIWzVHBUa1UNMBt2lnO12w6EpSGmkx9+Op
+rv8kcfJgXnUkH/l7krHUADplp4yxO1hIzdH5Xsd+Hxrnl85vGjNJyuNOlFJ1Eh0x
+AJTT6m1ypPKAs+zF1nWJaJECAwEAATAJBgcqhkjOPQQBAzEAMC4CFQCsQDzAbX4C
+uri94k3X0mUTxCrweAIVAON/UYsS+fYp74XS5ucP8I31tl8n
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDCDCCAq4CCQCg3U8Mc7XCajAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzEyOFoXDTEwMDExNDIxMzEyOFowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2EyMDQ4c2VydmVyLXNlY3AyNTZyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ALYeH/U234MovGN9iM3mr3kah93WJY64Dg8kGHg4zaUeKSmZVBgj/IlaCbfsRzXp
+0xtsBCXAHGlZosiIInQzfxVNS/XIUOI3B5h+n3wMl61BsC2R/pmHyEg8eFp6Jiwv
+1HMW9xKYF4qGgH396HczXPxOov3iJvtHHLElzYXDwCqy+x4D1PzXQLEkaGQzXsY4
+xhqskq1qg4pacNvow1eJair9zk5ebrV9t39icdTMkrtwgNBYAM/RU5DBxjdHDb/p
+Ef26uOmpEfgopcRpoZlDY7mpBozK49Ocsx+PCAx74A1kj8M2i7s+edlLMxIl66Co
++ELzqZW7YjwtyrOakPNb1m0CAwEAATAJBgcqhkjOPQQBA0kAMEYCIQCwL9kS1Dza
+3G7UiC3Hxo2f/kfp9621l8dLV5Uh+yhxagIhAIj28sZe3blr+MkrJHZjkYsAMY1e
+JijPcsnXEr0uGamb
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDJzCCAq4CCQCg3U8Mc7XCazAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzE0NloXDTEwMDExNDIxMzE0NlowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2EyMDQ4c2VydmVyLXNlY3AzODRyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AK0JI2U8gdr/OdkEIeWTRnwnmfXJYyIvTQjsMIK/v2o9jpCh5rRiEJfF/JuypP5O
+yHg6F1Qs6P/XafvxC/jsEe6VLbkwvT8THCKKMEvy6WyJuq58U5N5Zy2VEdMi+Q8C
+XI4QrL6igOEW2W4wgYHgh6qxUee0kUeqY7DJJwvgTVTTHVTWpub/yrY+5LOAiQis
+6eHxgp7xfUKKt64nk7pPdEdXeJ80PuCbau27/lQMhT8mBdE9YPkzX8dpS6ivYWFk
+6VCv/qTz0qxQZF9BHHLJeStRgcGIQOV3Udm/EsjRfcTipDwVdxhHxJxpAOQ/xO+m
+kJRKFitovc90AV9K2TtlG5UCAwEAATAJBgcqhkjOPQQBA2gAMGUCMHzhiyCuCuN6
+UxwoWA0q0nytE4H9t/2PnFGtAgmrzhnb4aWHw4xs5EJbTjGbqfVgBQIxAOIU5d2o
+nnpT/vmlvyijgAHFXAE8qHsKi2XTI7bPy9PDrv2FCS7lLAw8+mNF2mJCug==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDSzCCAq4CCQCg3U8Mc7XCbDAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzE1MloXDTEwMDExNDIxMzE1MlowgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2EyMDQ4c2VydmVyLXNlY3A1MjFyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AKB2axKYh2X1jRjtLpQIqhjLeIv55HiqlhF2dElrdTQP/qGN9TAYG9m0hAEzLKE/
+djgYMrsp0M9QfSxlNcLYjOtmYVLz57v1BQnDZI7/DS4jWOKfcnlvJSPbwE7LBoLQ
+KKfmXmDWvMwmTBtIEs4nxPph2UuROc5exd1samwS6doAcUm09wqP60aM3lK+9ml3
+/Ukd0coK9824cWa5m4OUcqPtbS8u3LcYJqFb7q7N8q0yYBwuU4kUVpGRlKz5baEv
+43qr5l+Fyib/pNEEAO1YhEW+7WjmvOAW4F/GSTI7SHce3Q4+3EoMoORM9nF9t482
+ojDsCe8emGFsGq0eS6MwYY0CAwEAATAJBgcqhkjOPQQBA4GLADCBhwJBdd9GUYv4
+BCF0NKQ583v33GreTlqD2Z0iXnni5du9A+8qJgG1wZlAGAosqXpZCi7i+3q2DVxI
+hCU67LcsUi59GJMCQgDTLuJI2gkKvqNufZXIR5vR7/RUd4EddkLw2whv4NMfwLJM
+532DeZIH+BtbyfjWYFujjoR/rhhcvtU0+lXsRT4xPQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC7zCCAq4CCQCg3U8Mc7XCbTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzE1N1oXDTEwMDExNDIxMzE1N1owgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2EyMDQ4c2VydmVyLXNlY3QxNjNyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AJ/8bNSkM/3fhVhEiFtu2r1fam1CVdbHE1tW1MjF2HOHBt2kz2LwLrJZq8ae9NkF
+82qSw7TB7b5EWWa+o7y6we8So8VenTXnk1oxRRh1tJi2AMFgqpx+LVh4EVqnhfAp
+r7UrtrnM+eAxOyGUVaTMgJKIkhDcfdIS3zHEL1i4tlbmLYRhWUE+wyogZ56FyWhR
+mIpfWv9yV8pMaF1VDEBEN/Yl/6w5f8DG4bQnvkOhL51GVb9GdUBKXI/0bybKTgr3
+Ku/T4q1ppHJSSFohM4Riju4EAgrJ2f3p0ebhX0dtTV7SuCH6vgTpOmSqTIGQ5cHh
+sGFV4/9Aoky/grDx9hp9D4sCAwEAATAJBgcqhkjOPQQBAzAAMC0CFA1Rg/uMcGW2
+lXuIUjKOiWxBhox7AhUDz3eNq7ir06Ukk5DxFpjGWA4kx2s=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC9zCCAq4CCQCg3U8Mc7XCbjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzIxM1oXDTEwMDExNDIxMzIxM1owgbAxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMDAuBgNVBAsMJ1Rlc3QgU2VydmVy
+IChyc2EyMDQ4c2VydmVyLXNlY3QxOTNyMWNhKTEiMCAGA1UEAwwZZGV2LmV4cGVy
+aW1lbnRhbHN0dWZmLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ALY3OYbAL3fEdoDHiak/3aj7141wmsobDVXPbNR1QFoHDrUqpgdQR3zHGY+BPjDD
+qvo0xzzIUE40Hg49R3ya6WyECH8ozl9WJ+JS+lH63RYlHDWOJfzjylF6ihiqixj7
+Twjk1j9ZBPjjiGUA/6RlikxsRhoQTDU/pDD6bSn+yosimpePbOao1BDPfntYFejw
+JWPlgC307o++ZKLcGjZH/9IfaKvgiBgl48rVDlQjFNLRkehufk1lviz5CdGph4uF
+D8qoO83mIH/wGJ9kWVjv0nvcEOGeGfaM1mDBwsuzVPXqtvUQHOnCfc18B8y8Fw8g
+bdoNde6lzDo6IMttKQEa+LMCAwEAATAJBgcqhkjOPQQBAzgAMDUCGQCV2p48seE6
+bqHpTgNOe3WdVuZe9dQYJgECGFG66yqtsjvMSg7snsWmMU/S2a8jvMywLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID0DCCArgCCQDHAy9pv/zMBzANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEpMCcGA1UECwwgVGVzdCBT
+ZXJ2ZXIgKHJzYTIwNDhzZXJ2ZXItc2VsZikxIjAgBgNVBAMMGWRldi5leHBlcmlt
+ZW50YWxzdHVmZi5jb20wHhcNMDUxMjA2MjEzMjM5WhcNMTAwMTE0MjEzMjM5WjCB
+qTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MSYwJAYDVQQKDB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEpMCcG
+A1UECwwgVGVzdCBTZXJ2ZXIgKHJzYTIwNDhzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDt8MTCSkfQyPw/EjB/lzT1yHMDVuniAFLkxe8GzJYOUEbZQTRt
+3gIZ56kX65DDW4R7VCcrFtDbF+PBVwwuBR3YT5adV0mbI0k2jBkteBe2N7CrQMAn
+3m5Mmb3pcxLZOHSSH2HJXJzDGY7YCY4UfdUjNCFro56NeSKylTF1TdVpPkDPzbEm
+BliscaJZ56WB9AKujbVx2apEaNcpaEXnJ5XbEmtccC463TPXX6Su8haccdXrfDFV
+mLe+kwe1w8B/nQbVGWw/v9lysIdx6i1FmWtsU8lJp+kwzg47RiCeb68cumJxvJHp
+/WoZGHFE15CYEp4N7lbF/UuiyWsn1VqHfkqnAgMBAAEwDQYJKoZIhvcNAQEFBQAD
+ggEBAF0+NeYI0T+ZiDhR4B9kOMZfeQGYov+m2d/Y3Ly3rV35NJ6PbuGpb/VbYSxP
+m0l6PhLB/c0V0pyg7MwgwtumhAxlnR5te0wNyYXzuO2oVBoO/8JmsQT8jnCFoANG
+9KNrI+A6ed0V7V1u4Uz3YFbD33FWIDWIR+nfDe07FNl7th/8jzpZAhqudtj372jy
+Andyzedx/kI4yePpjkHf8F0/MocI691C3rPW8uhSYloPfmaTftYoGl7+E1Xc85bW
+JMvnUqwPptOzIVrd2Ei4/4jQDxmI05gDKxZ8aMZddJFkLPKMIFAMwEzo75fCJCBr
+7Qo20ez/vMV+XAWGbHr1qLYhHzU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAzCCAsKgAwIBAgIJAIsK5NQHdHWbMAkGByqGSM49BAEwgZwxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UE
+CgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHDAaBgNVBAsME1Rlc3Qg
+Q0EgKHNlY3AxNjByMSkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5j
+b20wHhcNMDUxMjA2MjEyOTUzWhcNMTAwMTE0MjEyOTUzWjCBnDELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEcMBoGA1UECwwTVGVzdCBD
+QSAoc2VjcDE2MHIxKTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZmLmNv
+bTA+MBAGByqGSM49AgEGBSuBBAAIAyoABEomOz9/rS0q4OSF2hP23h8Cobi6nftl
+PlvgqVcjp+vnica6wXZ8TYOjggEFMIIBATAdBgNVHQ4EFgQUfdItvmVsDmZPpKZD
+nEvW2UkF1GEwgdEGA1UdIwSByTCBxoAUfdItvmVsDmZPpKZDnEvW2UkF1GGhgaKk
+gZ8wgZwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRh
+aW4gVmlldzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMx
+HDAaBgNVBAsME1Rlc3QgQ0EgKHNlY3AxNjByMSkxIjAgBgNVBAMMGWRldi5leHBl
+cmltZW50YWxzdHVmZi5jb22CCQCLCuTUB3R1mzAMBgNVHRMEBTADAQH/MAkGByqG
+SM49BAEDMAAwLQIUGxw8NFGW58flX5kQ+9sTr62kN/UCFQClrPQNlpt7uW9Q5qMB
+WRpd1SDyIQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICZjCCAc8CCQCg3U8Mc7XCNzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMTNaFw0xMDAxMTQyMTMwMTNaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDE2MHIxc2VydmVyLXJzYTEwMjRjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wPjAQBgcqhkjOPQIBBgUrgQQACAMqAAT9
+re7ILR102TfjTOu5h9XN7kIs42BEGeVyFHGqc9El4PEOy8Q4h5waMA0GCSqGSIb3
+DQEBBQUAA4GBAG0/n0eT7HK/1cgn4Qa6czMBpms0ca22r/V11Aj+h2mAqJNuz4aU
+7q1r+W94hblFrzAlGSZqRIHykFL/yr6/xzStCB3gd9OslvXIjgrGatzuhAttuO8A
+mA6VmPYG2aT5Ih9Bdg/HKuWdkSIeZTDJKMZli/CNWdtl/YcjsmyJDPUX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAc8CCQCg3U8Mc7XCODANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMTRaFw0xMDAxMTQyMTMwMTRaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDE2MHIxc2VydmVyLXJzYTIwNDhjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wPjAQBgcqhkjOPQIBBgUrgQQACAMqAAT+
+gt3/qI+svlfcqv3G+ldM/9cBveia+Z4S+UUurYsZR3joZVEUSm2JMA0GCSqGSIb3
+DQEBBQUAA4IBAQAGZFmNoRJUjpqoVkZWOP7ZDgjAgQqKFYI3Mm0QGNPvIEq1VCcj
+LQnx9PY2B1oMKZJQQ/1KsNqnEMm8jlFXq+O25/QuD1/jv37ME2sn8rZe6vsdKLr6
+4SB/GU4mHID4eNDttT4WepT8OfRBO2EY8MWv+97tkUIr9saxjVMYrp4nK0vJ2Yql
+LY0Jw3PgZ11y+WDKwkTWQkOx0SaZhKGRKZelbZZ2xcrV5XUtOFj2Ze27RMARRmmG
+SEnSPUg95eaKjpFbjMiPvTACcYJfnpRKN+ev/dQ0lJa1mZEnsXkaNqzb3q7F91Fm
+/NQ0Qi0OLeNZWeUUo1q3xhA3L2YvRyvz3425
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAcoCCQCg3U8Mc7XCMTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxMFoXDTEwMDExNDIxMzAxMFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMTYwcjFzZXJ2ZXItc2VjcDE2MHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMD4wEAYHKoZIzj0CAQYFK4EEAAgDKgAEeIPEikmn
+11U+4+r1Q1MikFns3u/81SlifvD9FK7i2eHXsm4pJbz66DAJBgcqhkjOPQQBAzEA
+MC4CFQD+m6pQXn1FPgD5NS62SFJwZxTe+QIVAOGRJ9XxBZ8CfPMEDDmNkzEyw5I+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICIzCCAcoCCQCg3U8Mc7XCMjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxMFoXDTEwMDExNDIxMzAxMFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMTYwcjFzZXJ2ZXItc2VjcDI1NnIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMD4wEAYHKoZIzj0CAQYFK4EEAAgDKgAEsNpgI810
+hR1H/L88VDCIsDJbvQVU/WBqSi+dTVX0E1lITw4S8oJwSDAJBgcqhkjOPQQBA0gA
+MEUCIQDTPITeYMLlsJT8jh2CyDHjEskSGLb62OaM4a0iq7wiPwIgbM9hJwczrPcw
+3uCNgCT990nAdET61HPVfWOBwDJi7tU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQjCCAcoCCQCg3U8Mc7XCMzAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxMVoXDTEwMDExNDIxMzAxMVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMTYwcjFzZXJ2ZXItc2VjcDM4NHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMD4wEAYHKoZIzj0CAQYFK4EEAAgDKgAE/E51tE6b
+bbeYQtaomWTWdwqTlW/8UbNDlC/LDHFXhYhNNJJzGdHoLzAJBgcqhkjOPQQBA2cA
+MGQCMHjfuIklGYjJgYQYBBDNraRptWiaPe7dsI58LZdeJIwJcQcesTpPjjLDszS9
+jfTUNgIwZiD6FVi1yVTckFvPIGqNwzz46KrpKEO1JWR05DkawDnYoUzOoZjEtDhI
+fktezP7a
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICZzCCAcoCCQCg3U8Mc7XCNDAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxMVoXDTEwMDExNDIxMzAxMVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMTYwcjFzZXJ2ZXItc2VjcDUyMXIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMD4wEAYHKoZIzj0CAQYFK4EEAAgDKgAExrjEN9Rb
+kS59txyKYNnlunaAY8PGDBeWy/t5JItcB8BdYNNaQ6Td1jAJBgcqhkjOPQQBA4GL
+ADCBhwJBDPCBtcw+W8IBo9x6F9ajBOlstHeR9lV6dE3sLyJhpV9sn697LHA6fQ6u
+s4x0aT8OJLod+62DFwDX40ATPoT3RoACQgHscuDNMVpOCx8mdka2mvD442Tcb76w
+Qc5DQSd+d0Rw0c9zAvPwObwSttNaaNmuT4v3DturgBVQGdb02bmQIuDNrA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICDDCCAcoCCQCg3U8Mc7XCNTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxMloXDTEwMDExNDIxMzAxMlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMTYwcjFzZXJ2ZXItc2VjdDE2M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMD4wEAYHKoZIzj0CAQYFK4EEAAgDKgAEuQ9FFr/a
+O6E1WAQ0LtG1wH8nczXWLqJc7f+sgDgzrub2NjvOvfcQ5DAJBgcqhkjOPQQBAzEA
+MC4CFQGBzvmRQ4HhuGwqOnKztHmUS9viEwIVAKZCrx0tZO03y9nSpGBRXeTB+bb2
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICEzCCAcoCCQCg3U8Mc7XCNjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxM1oXDTEwMDExNDIxMzAxM1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMTYwcjFzZXJ2ZXItc2VjdDE5M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMD4wEAYHKoZIzj0CAQYFK4EEAAgDKgAEp8qqFVSZ
+48NmZKnPWpaJXybje/F2E0wDq8rNOX+LC73zfK3ZC7xDvDAJBgcqhkjOPQQBAzgA
+MDUCGQCQP6SvfPS/AVHix6tG38uduEl53DG97JACGBWSckcbWsXYXDhKo3LrNy0h
+9uBgV9Gs5Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICEzCCAdICCQDt+YU/aZ6s4TAJBgcqhkjOPQQBMIGrMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMSswKQYDVQQLDCJUZXN0IFNlcnZl
+ciAoc2VjcDE2MHIxc2VydmVyLXNlbGYpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVu
+dGFsc3R1ZmYuY29tMB4XDTA1MTIwNjIxMzAxNFoXDTEwMDExNDIxMzAxNFowgasx
+CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmll
+dzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxKzApBgNV
+BAsMIlRlc3QgU2VydmVyIChzZWNwMTYwcjFzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wPjAQBgcqhkjOPQIBBgUrgQQACAMq
+AATr4Hx367/3ldBBiTV/6WfVuaRjVYUrFtcXLqsF04z3yL3dw4TcwSnQMAkGByqG
+SM49BAEDMAAwLQIVAICB0ciEiBjudkS5M+TgDRowS9wqAhQxdt3pJoNMch0sBGvy
+ZvpPEqW4lA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDNTCCAt2gAwIBAgIJAMWAX1EW46gEMAkGByqGSM49BAEwgZwxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UE
+CgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHDAaBgNVBAsME1Rlc3Qg
+Q0EgKHNlY3AyNTZyMSkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5j
+b20wHhcNMDUxMjA2MjEyOTUzWhcNMTAwMTE0MjEyOTUzWjCBnDELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEcMBoGA1UECwwTVGVzdCBD
+QSAoc2VjcDI1NnIxKTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZmLmNv
+bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNzAD4317T6bb1oio1J2awuyb2wS
+F7okuHwbFhfTuXgvLsQcAWh34Md5SJ711rN7an+sEr0RVyE6h6zgQkD8DUyjggEF
+MIIBATAdBgNVHQ4EFgQUSPfZCnqQodFg6YlBySBCsrjQ7hYwgdEGA1UdIwSByTCB
+xoAUSPfZCnqQodFg6YlBySBCsrjQ7hahgaKkgZ8wgZwxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHDAaBgNVBAsME1Rlc3QgQ0EgKHNl
+Y3AyNTZyMSkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5jb22CCQDF
+gF9RFuOoBDAMBgNVHRMEBTADAQH/MAkGByqGSM49BAEDRwAwRAIgeXLod9K7A3VG
+Rw/3wMXrnxNUA+K4yzfAf1OlCy8923kCIGqu3+9B5lZgHWvHiWBkjpkBqegBp5t1
+7YyV4K1ALxcH
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICgTCCAeoCCQCg3U8Mc7XCPzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMThaFw0xMDAxMTQyMTMwMThaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDI1NnIxc2VydmVyLXJzYTEwMjRjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
+AARnBDetfBY6JJYtJ6BTttMX/edfb+Lc/DCwTneZzjE5lUaM+LzNwNt02H/+XD27
+hhTDJWXP5r26qZzuBkwpi2UJMA0GCSqGSIb3DQEBBQUAA4GBAF1uQyY7WpxJkkht
+Ru87ib8WISy/liosB1ijy2bcPHjcpKRSW+LH2+A2+mQYiasfOkLck+9pS7efhFtT
+b1A/3BkI9tMGhvMgop8860Khkl6pRETNu/nlVIQ2xzdRdpvJCmFPa67YK25/cn0O
+XN6PHMPJF1JVyJhppvjmV/u6TS2N
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAeoCCQCg3U8Mc7XCQDANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMTlaFw0xMDAxMTQyMTMwMTlaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDI1NnIxc2VydmVyLXJzYTIwNDhjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
+AAQmlPt4PtwUBkFqDl1dc+5XqpiPYJ8t0oVklz86WljYLHXNWl20Wd+t+/4akyc+
+3L9Wr2OzkZyXWv4nA4UteyFiMA0GCSqGSIb3DQEBBQUAA4IBAQBWbbxxLkiwz7eo
+uN7Jfa+I9xMNFwPhCc7api63Z6Q6P1tcdTxtl6xQefdiFc550H+tOWb+sn3EmBFo
+r8XIPAb73dG+41Vp2bSajkY9povAT/UHFYt9rwr9bQfWtJktd939A/hQix4YImzV
+7cw8b+SAoEWuWifScDKDlFQvs4zxUAOxFeXbOrb3X1oGDjE93TEx7+x9DBNMDSu3
+hN11j9cyMotJCWB5OFYzCf3ibwwo0usiz768Wu1C3RvauET+xbcE3NkxM6rsQxI1
+lNXM1NNbm7/nOm+zK2lTH7g4Qui8owSgwR0uwEHhmrAHIug0uHC7GbrIn4yibkrq
+xkZaaUr3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICJTCCAeUCCQCg3U8Mc7XCOTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxNVoXDTEwMDExNDIxMzAxNVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMjU2cjFzZXJ2ZXItc2VjcDE2MHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErJOw
+EmmdQcay7oSZTNySdc2m4/iwftH3KfY3wDA5qVusJ85AJUYPbwEvqloKpOTdCZI7
+P4za7x7COTuZAzVFVzAJBgcqhkjOPQQBAy8AMCwCFG5V4voKrcE0UlK1osPuHXZD
+N2f5AhQR9TzLTT7D1Ee270xtQ+Bwcq9mBA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPjCCAeUCCQCg3U8Mc7XCOjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxNVoXDTEwMDExNDIxMzAxNVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMjU2cjFzZXJ2ZXItc2VjcDI1NnIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERwmM
+YUHXpp9LfbDmk33yWOjAf9flz43IHqFq2xa6bczvcht7ZDka7UmSOVQ8A8d2FdjG
+BlqAnEKvCHlxqw41SjAJBgcqhkjOPQQBA0gAMEUCIH++MmRaY7IhySci6HGfsACD
+otlDDt6kvpJOCTXQS0G8AiEAwNA+4/wVeEvtjendgLX7icNK33L53fK9CqiZovfi
+w7o=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICXjCCAeUCCQCg3U8Mc7XCOzAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxNloXDTEwMDExNDIxMzAxNlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMjU2cjFzZXJ2ZXItc2VjcDM4NHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXjcN
+bCMqCgsKw4WhdPm6ankP3pHHg/bKWiJXJ6BI4QQYGsNBXPb8YvwP6Q1tFPSyjSJo
+VRUVmWGn9X7FzQAGQzAJBgcqhkjOPQQBA2gAMGUCMG4SIhLBYKht8fGzVRte/4lJ
+Aj+hMTbCuNa36BMOoez16SskyhCtar46QkFIGnmoQgIxAKIxzKgH4dBAdRGu7fsU
+OawK3AvNYm9Xb8bn7js+KjB4pJdYBZw4Q3kHB2cBgX+hvg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICgjCCAeUCCQCg3U8Mc7XCPDAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxNloXDTEwMDExNDIxMzAxNlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMjU2cjFzZXJ2ZXItc2VjcDUyMXIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEH/cQ
+KncxMblNmy+gpvCcfxdnC96RTzVT5ZdbeTBlmsRLXxWlrORx4+URCmHGpFdFzpmb
+Hfc8rPAIQNGiQucuQDAJBgcqhkjOPQQBA4GLADCBhwJCANGrCUSZ/X2XMwFavryU
+JGEOQFLMAAsEWVMUYbJifwNyeQVuwNV7cJjE5UGEzFDLbazmdrPVmDeSt4nQYCYN
+zy/nAkEhOcJqFzXb2PW1E2MK7qGOswGNr1EifKIF5Tn//nCmpfDSH7G7VXH2IqPC
+X6P0wdhzr72Gy3YmjXoj/CTZ/fK6Vg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICJjCCAeUCCQCg3U8Mc7XCPTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxN1oXDTEwMDExNDIxMzAxN1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMjU2cjFzZXJ2ZXItc2VjdDE2M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHEs0
+EFQnApDDnOBH0DZtSu7mDqzv3BEwm43BWfjQbuvWtKZxTzCc6Pv3dxLgdblE3Fl5
+MK/8Gk3ugDZwe563KzAJBgcqhkjOPQQBAzAAMC0CFQD8O8WJ7okGjHRs/J6rWo+n
+FNrwCgIUcFcuAK3K1tfYuE3QGm4smu2n8iM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICLzCCAeUCCQCg3U8Mc7XCPjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAxOFoXDTEwMDExNDIxMzAxOFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMjU2cjFzZXJ2ZXItc2VjdDE5M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6I/f
+uxD+wYynPua+enF00uSb3hHLi105QljhMjfpXRyMt7jW7N0N44AeQLqvUuX/Ou0B
+zXDtE8R5tbU5n1p9vjAJBgcqhkjOPQQBAzkAMDYCGQCRU8ROxYXzP4UclxGtca7W
+b03WyYZAva8CGQCTE3650WcJy0ka07FL3RuScknp/D4SZh0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRTCCAe0CCQCwSXFmzpBH6zAJBgcqhkjOPQQBMIGrMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMSswKQYDVQQLDCJUZXN0IFNlcnZl
+ciAoc2VjcDI1NnIxc2VydmVyLXNlbGYpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVu
+dGFsc3R1ZmYuY29tMB4XDTA1MTIwNjIxMzAxOVoXDTEwMDExNDIxMzAxOVowgasx
+CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmll
+dzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxKzApBgNV
+BAsMIlRlc3QgU2VydmVyIChzZWNwMjU2cjFzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB
+BwNCAAQtDOsv5pQz7RzsMK68LUeAIDtdJddk55oLsrd2+93FHIr1CiqOwr/3sH3V
+USapRS4Xlb7VvtkFmCGLMna0TEdiMAkGByqGSM49BAEDRwAwRAIgGqI3kC9COsLQ
+nUnZmwVaNp6le9PQwro6m6b0r6MgaOgCIFH1x+AgAV+HvbGkPTjIW+Cp1oUcbMgd
+iDnA5kk037nh
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDczCCAvqgAwIBAgIJAMKpQMf1IUoCMAkGByqGSM49BAEwgZwxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UE
+CgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHDAaBgNVBAsME1Rlc3Qg
+Q0EgKHNlY3AzODRyMSkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5j
+b20wHhcNMDUxMjA2MjEyOTU0WhcNMTAwMTE0MjEyOTU0WjCBnDELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEcMBoGA1UECwwTVGVzdCBD
+QSAoc2VjcDM4NHIxKTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZmLmNv
+bTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMaXMYyVYpN6QWe+5TpTN8r9jbAPUEO/
+YuR23HOX5Kq1bP0GoF96uXx53X0V0EOncf/navTd9e7oF4BOgkCsHe0bD2p8b82I
+IbQ953K3DDT6eIW4TXF7YvS/xF9ByIx/iaOCAQUwggEBMB0GA1UdDgQWBBTqywJZ
+V6bCSeOnSQ3riDM0TDfIMTCB0QYDVR0jBIHJMIHGgBTqywJZV6bCSeOnSQ3riDM0
+TDfIMaGBoqSBnzCBnDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQH
+DA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQKDB1TdW4gTWljcm9zeXN0ZW1zIExhYm9y
+YXRvcmllczEcMBoGA1UECwwTVGVzdCBDQSAoc2VjcDM4NHIxKTEiMCAGA1UEAwwZ
+ZGV2LmV4cGVyaW1lbnRhbHN0dWZmLmNvbYIJAMKpQMf1IUoCMAwGA1UdEwQFMAMB
+Af8wCQYHKoZIzj0EAQNoADBlAjBb8D7U8OiqO8ZU9gUrkMo0Y23AN58o3TSapRge
+7qiAuUOVraWioNrrNVpC2z2YI2YCMQC53bKQvlqIQ+GbGMY6C5v+F/zESmVie06v
+ba7qe2vIl6OIBiPOP5c5gCj4Nj1g3uI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICnjCCAgcCCQCg3U8Mc7XCRzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMjVaFw0xMDAxMTQyMTMwMjVaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDM4NHIxc2VydmVyLXJzYTEwMjRjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR+
++z6+8do8BpOuYXtGlnKN6jwDj1MdbcUM9sqJBdvVnBJdHfOCL+nVGSvyTY5BUxJ7
+FT5XG+9H0+juJlC7iUu7guxwXdhkChnOQ28buUqsWYH0yHiKJe5F/Re2ESERPi8w
+DQYJKoZIhvcNAQEFBQADgYEAPPio0j09V6vXhN3GYwa3ARjboJIO53kTNa65UGgC
+qvdLNufcBRldt2vezR0NKj3CTY+/uD+lNwTp+HdnIGkz0hHA722nv0VZGX2MWdMs
+/2/D36kJA89IIPLKkQjzmmjIQ9wNDSAt31j9b/TiUfeodaEZZR/iST5UHDvkSIZE
+EHs=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDHzCCAgcCCQCg3U8Mc7XCSDANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMjVaFw0xMDAxMTQyMTMwMjVaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDM4NHIxc2VydmVyLXJzYTIwNDhjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASw
+i3q++pOW/2tqHTpGB6X85pKO+oCQa/1KSQhKCjVExJxwfQlClNkHgerFUnMr1Zvu
+e468EX7/r4gdnMQn+8FPWcYZ+2PYLHaNa4zmLPZq1YJRq5gjIU96uE9nJLoCJO8w
+DQYJKoZIhvcNAQEFBQADggEBAE5R94CP/nqChXrMPmHThRReMGXc65FOXtXrQvNb
+YKa26EKHy50fqh0sZkfIMqF8CVYhpMM96f7xJgHBJ1GY20Ayp4Om+nmC1U6in5yk
+G+LO1H5uDwn3be9tLXW9Jiif/FSDJvY7GhWMys9W9QpojHrNT1eVGPu5zmZxfvDn
+nPlrxOxx2yVSkc04zAfBibKd+iNBLI9x1hEWv9gVILow/nsF+HEceGqCKrKtw3CB
+vRek+mUZCUDD6gKsN0LeGnRbEFTjyYp3iqbA7/zaCsXi0C9RowKD/uhQmmsduxFT
++mRBNP2Ni4BGJoFGt6ynkhQMKMcZOgCfG9qu9xFpRa2wn+s=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRDCCAgICCQCg3U8Mc7XCQTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyMFoXDTEwMDExNDIxMzAyMFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMzg0cjFzZXJ2ZXItc2VjcDE2MHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEeU60tao/
+d69lrHxMAx6xC9aIXgbFzDxSl39sQORDuiv7YgqxSNxusAnCCER5YT7i0WfH2LEh
+kSO16D40edXpxFXXctF6uOT9KK84oCT2ciV1QbArI1ROExKum1U/qYd3MAkGByqG
+SM49BAEDMQAwLgIVAJNssWK3wbZ17bXdaVCc2oydMEqBAhUApNb51n/19FEejcXt
+msPefDlmlWA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICWzCCAgICCQCg3U8Mc7XCQjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyMVoXDTEwMDExNDIxMzAyMVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMzg0cjFzZXJ2ZXItc2VjcDI1NnIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEUKGBne87
+l7cssaiEtxw1EOATJFv/yHz1811mfKPqCJjpVi5NVLt5q2b7DfWvi4839ywNdD5l
+ne3mzh6WT20lH52LkS/sMj2shtx0NAIWQM+SJMi7BrBRtymaXtRZQQxdMAkGByqG
+SM49BAEDSAAwRQIgBmcyaM69Ryota/XMkDJzkW8a3zCZahsE5DlTrg+Y+VkCIQD1
+Sp6MuZy6JzwtASW/l/Z313mvQduVpzdtezQtvhXqMw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICfDCCAgICCQCg3U8Mc7XCQzAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyMloXDTEwMDExNDIxMzAyMlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMzg0cjFzZXJ2ZXItc2VjcDM4NHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAELraTwEbQ
+rTk40nU76I/MUWvDrX4HEhnNt2Wor50zzHpNtcWlDh64xyDIUO6IgwPumY93PMUR
+E2ObEw1zm2jLx+ld32CHZhVD3NFg1eyUzxUWXlnV5YyMQg4kM+Q4RfSoMAkGByqG
+SM49BAEDaQAwZgIxAJp22vZKPO/FetlqwLIcghqoy0rueCskFQC53fhU0zAybTiI
+zDLzM3AwwwIjHHIvOQIxALyleafaqz+Uh10WWnhenZ4wEcGtnvMq7NOLA26DttBq
+Hda4UJnBkRFBo5+N0m+l6Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICoDCCAgICCQCg3U8Mc7XCRDAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyMloXDTEwMDExNDIxMzAyMlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMzg0cjFzZXJ2ZXItc2VjcDUyMXIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEtyVcUCcJ
+RsoFtoxLIFg32suhU2Vsm3HjI5+uMg/04EdQWsSZ20b2aPZ0G9eOI//t4LT9ha7D
+Q8XjDRQl4+MMpcQZPz05CPeM3V+51ORa0TsU5H55mkaI6jzyqjBqU1zMMAkGByqG
+SM49BAEDgYwAMIGIAkIApq6d1qKZ5OzFIEJQ2eqFa4TRW2BH18BhK/5+LHv4hI5Q
+yIFU0wvnWufrlDpPd0sHZs4Rtyv7DXKLalafI0rt8wMCQgF3KIktGZN0ppn42anJ
+UgxeryI8lssrz6y7o1t8bgkCSpPUHFOJiaPcAMaCJIy9/pTkNqItAS6vD9OXvLCq
+qkTIUg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQzCCAgICCQCg3U8Mc7XCRTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyM1oXDTEwMDExNDIxMzAyM1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMzg0cjFzZXJ2ZXItc2VjdDE2M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEkRuBmaS+
+693na8/kbscQtkKYQyhZ1w+fRbK8vSoPey6GxxDsFU01DAZtxhAiFKDh5Eh1s8ur
+goSjJFGjIJWSzgzK2NN6zrvlpuNFYeIbM4ALvRsYDAMJ+3tl3Vq30BWhMAkGByqG
+SM49BAEDMAAwLQIUDc0O2pwXZTxjX/TO4dmxlMoBUUYCFQL051eCJ9zO3XAww5Rv
+n2Obyhhq6w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICTDCCAgICCQCg3U8Mc7XCRjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyNFoXDTEwMDExNDIxMzAyNFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwMzg0cjFzZXJ2ZXItc2VjdDE5M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAENttarKTc
+CJ4k1b8Fd14pSbGQprsbAFfxk7QhONku4iyam7bmVM5b9Q0SjfNzKIT8yW2swCdi
+cFFOcMlpYFGbGNk9kV3mkMhHi5qgbw4iv6/U3WiT7kxfbJjNzWAcGQOQMAkGByqG
+SM49BAEDOQAwNgIZAIDGXPjGWx96qYTgjUzg80VsiRV5TINzjQIZAIoa/jec5ioW
+ZAvx7piEzY3fRw/YpRMF1A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICgjCCAgoCCQCROG+IEgiARDAJBgcqhkjOPQQBMIGrMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMSswKQYDVQQLDCJUZXN0IFNlcnZl
+ciAoc2VjcDM4NHIxc2VydmVyLXNlbGYpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVu
+dGFsc3R1ZmYuY29tMB4XDTA1MTIwNjIxMzAyNloXDTEwMDExNDIxMzAyNlowgasx
+CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmll
+dzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxKzApBgNV
+BAsMIlRlc3QgU2VydmVyIChzZWNwMzg0cjFzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AASCHyVEN+D1kiuu8teqNLvuT/r0cNoE7RyKEt9wpkOMB9NdcFEzVClX9A0AmovZ
++OGwM4ltWN40BFkImyHmwzGRwZEJYdgmFtZOwRKJaMWadbqpto5PtuB+SpFhtQmO
+dDMwCQYHKoZIzj0EAQNnADBkAjBCpsIVKSYpyYXCWfeYVf5odGJ7ZAgnT7iYstM3
+HZBfdXA6t8zjXICA2ICOqrR1xUoCMDm7poy6GrsHEOMsBoVS5T9U0p3ouMyOhkIm
+0EykkGk1wK+9Z6QM/DLP8lLJB0IrDA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDvjCCAyCgAwIBAgIJANErVg+ok6iAMAkGByqGSM49BAEwgZwxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UE
+CgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHDAaBgNVBAsME1Rlc3Qg
+Q0EgKHNlY3A1MjFyMSkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5j
+b20wHhcNMDUxMjA2MjEyOTU1WhcNMTAwMTE0MjEyOTU1WjCBnDELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEcMBoGA1UECwwTVGVzdCBD
+QSAoc2VjcDUyMXIxKTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZmLmNv
+bTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEADNScfIghIZGN1TI9A6iM8F+LrAg
+xrInc7nmKIBtdYYfsFWwT4P6bQqNrOZixrSmTiZXSGWhzaj+gGAdF8vfr81YAVNe
+1hkuP3iC/4iaRk9vyMDHNvKDHQeUxFNIL2UTAfSTl0vYmL1C5KkpYU3+qBVFTLpa
+7uImk1s3wQIkTTHyFLLMo4IBBTCCAQEwHQYDVR0OBBYEFAwP2eZOjIq6F87PsSjp
+qniRzxZpMIHRBgNVHSMEgckwgcaAFAwP2eZOjIq6F87PsSjpqniRzxZpoYGipIGf
+MIGcMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWlu
+IFZpZXcxJjAkBgNVBAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRww
+GgYDVQQLDBNUZXN0IENBIChzZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJp
+bWVudGFsc3R1ZmYuY29tggkA0StWD6iTqIAwDAYDVR0TBAUwAwEB/zAJBgcqhkjO
+PQQBA4GMADCBiAJCAYD/Rk9FMPk0ZzNrXCHKRdXkjBqfsoB5VYRjFIQnIz8+xEAC
+KqHjdmYd4djR6l6NA4olKQn+LUwE2hmtom6res2GAkIBPDlBcwGzoDxU4CQQb/rP
+cFEMaA5I4fpGdSNYtIJDkXNluVHAPkv+uK9lrhsjuvpVbh76+mM3B9bg4Tq6+Pxb
+KN0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICxDCCAi0CCQCg3U8Mc7XCTzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMzRaFw0xMDAxMTQyMTMwMzRaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDUyMXIxc2VydmVyLXJzYTEwMjRjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYA
+BAB+Wp/To8yXNzzp1Iw12ACR2Zc2s8o19H3E8cgC26eDcDYzlAf67/ldZyQ0WDzI
+xUlxeJjmNcdiavR5usOo/2lE2AEK1tWu/xVhZZZHWiNQ0vZdZ43BHtBPcqdHRZKv
+RRZWrP1pd9ubq1UDzegZdFQ5JwwQjPXz4jpOfTYO5TrmftxZjzANBgkqhkiG9w0B
+AQUFAAOBgQAMYv77n1SJ+MDneFbJ2ssBd6aw+hbVqwBVopd0YC+i1Kt5bDe649d/
+vMAtnEmOF8G9/ugg5XVoB0M+6DINC/a5HYYZEYAW/g3Q44XaZCJWOvEVYhFAeUNb
+BigmNP4yGv3vP+1rqwEqhb9quxYF2n1e3BuBbi9HkIf2Gp0sMP3pcA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDRTCCAi0CCQCg3U8Mc7XCUDANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwMzVaFw0xMDAxMTQyMTMwMzVaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjcDUyMXIxc2VydmVyLXJzYTIwNDhjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYA
+BABjwtNCj8IRxv8e0qyePjKGqOvlcPDzx54bcokXDVHxWOL3OEljqi8qWxJm+Mzg
+Xhr888VBZdWjF8iXGgtGPEyNRwF635gdYvpcJoz+I1Jg5XzJYo+kLpf/xt5V44/P
+EizJQyx/aJ4thsf2gCfFg/zWpDQbcjrwjz10fzLW7rkt7otbAjANBgkqhkiG9w0B
+AQUFAAOCAQEAK88ka6Xlvl/Bg2W9TyAh6zPEtDHU3WPN10LxU4ghbStUGx/YupTr
+LSg7nLOQo9CI8LKb+tpTaMPmCSTH5Cfwh+f7Uw20wbvPBg06GiBdQjuK3Dvk64B6
+41s4Y75J0wpXJfgezARRlLe0VLAWwH9ZnZRiqtndF527dPBi8EF3qc8X1sGaQ8tn
+EVCd2ifptLgp+eI78QdKsgDFpjDOSJNbLDI1yQcm/0EafyJLKd+xH3EBkaaiw+OV
+ctYsD3ebQ6tldDnopgbisTmtwvHGqzVGTG8DDX1El2YhVe4bwZTtLBjcbtJxDg/V
+0FLkpRjQ/sDqMbDMb6CUoHRa8Urq13e0Cg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICaDCCAigCCQCg3U8Mc7XCSTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyN1oXDTEwMDExNDIxMzAyN1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwNTIxcjFzZXJ2ZXItc2VjcDE2MHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBQ/O2
+98Fp8ZlEDVNNUHEHYrdrhmofdEsOMsyaabFAWp4cexMjGYgOZaD4/sCYjc1N9sXp
+1LqIlBVeAfQ5BCSdqJYAaUQrvL/4evYANvIiymw/peV60y6Vchz/XuKH3M4RVCxa
+8d7eeobwzCbM2PjR1loiInAhdFrKJHF2z3M84MPgQJswCQYHKoZIzj0EAQMvADAs
+AhQ7SDvm2UNjV6SQf5HoMMrh+K1V4wIUBIIDOf2vtxEmVLXZvaoJGbOf9Vs=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICgTCCAigCCQCg3U8Mc7XCSjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyOFoXDTEwMDExNDIxMzAyOFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwNTIxcjFzZXJ2ZXItc2VjcDI1NnIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAqYn6
+hGbL5dTx1gnWnUBp40JXPKxlrAi4p6ofvM6Kd1HwtQLgeNpIqi1TtxXPc4HkHu9F
+gqV5pOJhEUAF9ABqeigBCGHqHtp7eqq8ZKVfIdQKDUTGsHZe1mkQA9JHqBwi35Mo
+TOkUlws3aEFtXyfZcjgUd7PYzOM5Ry/m56RiZGdMu+EwCQYHKoZIzj0EAQNIADBF
+AiEAzxdUODAqmgqDDM13NLrIREDlN8BlRgFUW4AFxOg87Y4CICW2qf+ioupQuvWE
+da8fLQVnCbVbLUKFZlJd02uIsud7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICojCCAigCCQCg3U8Mc7XCSzAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAyOVoXDTEwMDExNDIxMzAyOVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwNTIxcjFzZXJ2ZXItc2VjcDM4NHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAx9bl
+XZ1Voix3FACqRqpURu5ZjoPPMIY93jbYEL6wZdDU4FFbXOiTYt2At+aQPi8Rjy8a
+DI3CxXQ5PCPrCPip8gwABVTtjfQzwJwbqIlZuE/HZL6ZmRkz1iCOmWhk4qDqGUpw
+/k78Wgl4GYPBdsZOxzSa0g+XIQEW3MeLGzpEH86zKY8wCQYHKoZIzj0EAQNpADBm
+AjEAv1WKxcvLV9MQWHIu1rWic1soAGPIt30b/7Q8VZB7HnRTBtOQUteQevoHHxjo
+DZWaAjEA43j2Sh07TKD1c6lglFFONNNuR7orVCapEgoXNgcMceF8cwIuYyCqW75A
+EneclLfr
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICxjCCAigCCQCg3U8Mc7XCTDAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzMFoXDTEwMDExNDIxMzAzMFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwNTIxcjFzZXJ2ZXItc2VjcDUyMXIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAyY+l
+SUAwJE5hPEUCwuccerdfzoZMp3c9Hkw/fnvVjQpA0Vvb0piBJ39MRCGYi63RbaRs
+QexmUq3XGdbL8mwoV0YB5niOZ9cg6YeqXRAnkcS/GboHNjtYQWysta+D+dfX8S1g
+YBuXdNZrbGdAj9UP7+gz/9WrPOctz6gwyeiKLKsvosMwCQYHKoZIzj0EAQOBjAAw
+gYgCQgErxOvqzrTt5eHrdH4ZxUn4AM9dBAqX33jKXBKNuRgmyYIxoIO2c2tqkdxC
+rXmeudFZmFGEEBor5bg2RMI6pkcoWwJCAe6TIx0KcaF6D1wW9tlmRXZ+888SS6Fq
+BdVwn4a8/6TrTxQGmDD6qVTwGco76umjHnam50Kcvg6iBAjfSUmwj/56
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICajCCAigCCQCg3U8Mc7XCTTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzMloXDTEwMDExNDIxMzAzMlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwNTIxcjFzZXJ2ZXItc2VjdDE2M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB3xU0
+hOYQMnJ7L+TLdSkB7ruVnjWo6iwLe0N2GlpCc5jSmBfhGr0NyoKrNY1Zy+VcnGCu
+vYgT/aqN7nOnZ86qoQQAq8o2wpdlTbeyzzE26txGTVi+7IN3sVB7DFmqI/R6ngKK
+GdkmE6ZOBBcyipzOc/eXRpqoRaIRA+FP2LAPdBnsuNkwCQYHKoZIzj0EAQMxADAu
+AhUBOyoJaoo5E6UZ8ICdSZAsL7FpwcMCFQJ1wcD/KuK0g+2WMgpCAuElR+dZIg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICcDCCAigCCQCg3U8Mc7XCTjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzM1oXDTEwMDExNDIxMzAzM1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWNwNTIxcjFzZXJ2ZXItc2VjdDE5M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBvNN+
+2syVq0vx/Qj1W5IYpeUdyswTzyBNdz0LveNcNEV07jql3o25dPHNGZcVcCvPFw2H
+2zpaWV8t0YHjHETM3mEBxgyxwpbM3dkdCuM0VlKEA+rUY64QU8/f0WYU+1cFPBBi
+fMOuMKXfb1JNK93W9A9jzmFSVJJVauXYs6JURy60Z+8wCQYHKoZIzj0EAQM3ADA0
+AhgoBo+CqnLTn7UxFzNYtHabS0zMzBzBhN0CGAaNavBCHkk1eX0xmp+7BIxHnWOl
+bbeeYQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICzjCCAjACCQCYUruIqLYp5jAJBgcqhkjOPQQBMIGrMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMSswKQYDVQQLDCJUZXN0IFNlcnZl
+ciAoc2VjcDUyMXIxc2VydmVyLXNlbGYpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVu
+dGFsc3R1ZmYuY29tMB4XDTA1MTIwNjIxMzAzNloXDTEwMDExNDIxMzAzNlowgasx
+CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmll
+dzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxKzApBgNV
+BAsMIlRlc3QgU2VydmVyIChzZWNwNTIxcjFzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMD
+gYYABAH3WSHvJZH8mqyGfVxtoyF5pCUVJZTnebvRphld+jK1PFKlzglYN22J8yN9
+l7Ca2h2OjuuEVj3fZAwSAInZtZQzxAEHFMZEVAzoHUPjx9qEAJiNjXcVV79cvrvc
+Q8SbYBF3vGB0su2Qydig+VEjmkyklGhxFLQE8fo7fEZh+FfwGG3x6TAJBgcqhkjO
+PQQBA4GMADCBiAJCAYLsxXVifQfzuyZRMNqzldUcASTgs1L/MMtJcEvYtFpeaGXd
+Nn1jIynPkC3rgjbejtLe4OypPymrkVE0Bjn3rKU/AkIB1TtXqfmYkTdOO/AUriRl
+GSatOobx7QQ+CyOtziObl1UPe7hDYGX8quZPxWnx6MgtO4I4sSZWA7/0C6N61XSq
+NPs=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDBjCCAsSgAwIBAgIJAJUfXqNiGl4gMAkGByqGSM49BAEwgZwxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UE
+CgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHDAaBgNVBAsME1Rlc3Qg
+Q0EgKHNlY3QxNjNyMSkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5j
+b20wHhcNMDUxMjA2MjEyOTU2WhcNMTAwMTE0MjEyOTU2WjCBnDELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEcMBoGA1UECwwTVGVzdCBD
+QSAoc2VjdDE2M3IxKTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZmLmNv
+bTBAMBAGByqGSM49AgEGBSuBBAACAywABATc2/gR5Sk1spq3ktZK4UCWH8ILGQJy
+xhua4tLSekXuk3joLxw7GVD/K6OCAQUwggEBMB0GA1UdDgQWBBTRQhIcGNnfzY1r
+7mAO0j6l4jrt1jCB0QYDVR0jBIHJMIHGgBTRQhIcGNnfzY1r7mAO0j6l4jrt1qGB
+oqSBnzCBnDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3Vu
+dGFpbiBWaWV3MSYwJAYDVQQKDB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmll
+czEcMBoGA1UECwwTVGVzdCBDQSAoc2VjdDE2M3IxKTEiMCAGA1UEAwwZZGV2LmV4
+cGVyaW1lbnRhbHN0dWZmLmNvbYIJAJUfXqNiGl4gMAwGA1UdEwQFMAMBAf8wCQYH
+KoZIzj0EAQMxADAuAhUD5UVJP72K01PbvDeANWleHbjxd48CFQN6Qt34E0JeefbC
+NVkYG6pXLegBvQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICaDCCAdECCQCg3U8Mc7XCVzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwNDBaFw0xMDAxMTQyMTMwNDBaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjdDE2M3Ixc2VydmVyLXJzYTEwMjRjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wQDAQBgcqhkjOPQIBBgUrgQQAAgMsAAQE
+/r8twiEWpvxX4VUSmCw1JJNHF9IDvIxktMTtZqcK2/57GElqT5Hmi1swDQYJKoZI
+hvcNAQEFBQADgYEAHmeOaUdqT4x1o7UCpXTW8D2+XCTCFMpPENH0plL7ALUj5R2D
+av2TvKKSwpbyOJa26Rx5KEMNntGpSN1X4+a+wPHZ87J3wmtU7B6nEaHIkFM/iGRQ
+M2Ip+lBhebd1e+itwIRnpFcNt5dD276F30928E6kxwSge2uoQJySFV+Xuho=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC6TCCAdECCQCg3U8Mc7XCWDANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwNDFaFw0xMDAxMTQyMTMwNDFaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjdDE2M3Ixc2VydmVyLXJzYTIwNDhjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wQDAQBgcqhkjOPQIBBgUrgQQAAgMsAAQD
+jbQ3J7+yvmgc++WxXN52nfRQWnkFc1DUqspljUJyusmdPI1+8ki7FcMwDQYJKoZI
+hvcNAQEFBQADggEBAAF3SF1Wmlk6F/IeQs0hlLHF/ik0xWngsO/Qgqrax6MGLdPW
+jjJDE1UY6mjNXo8kuV9nIr4+27RN1q3hlSaVC47BX9kZNOs+nO/8h4mFXSV3osq4
+7RrJ5RJ/seXk6s7QItfmZslv7LR/FrzTF7pDv385WwwRXpfhCIY3X24bSt7dgK4j
+CkXf6GV9WTrICmNRBeV8/LJAbETU6XPhBXpIlYO0sasSfbCd/j4voIUhwZgPXdGx
+iNVWcwgntcOwx4wXJOoWoiiU/j+eS6YDrsxqgdV3j0+JYWQNUvFhrotI/HjbZ8RU
+rUiYpAcbghxkent0pcmkcHbJJcj/8/AzQcp+iYg=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICDTCCAcwCCQCg3U8Mc7XCUTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzN1oXDTEwMDExNDIxMzAzN1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTYzcjFzZXJ2ZXItc2VjcDE2MHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEAwEAYHKoZIzj0CAQYFK4EEAAIDLAAEBW5dGOJD
+CIYYqj8GEUDWGalB2d6wAQzBC6qR3h5seNsC212ApAdfYdTUMAkGByqGSM49BAED
+MAAwLQIVANtclGRvcbIOV+XiYhSBeiuj/XAZAhQjQSZ21bwoOnKjnybeDYMhqEIG
+1w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICJTCCAcwCCQCg3U8Mc7XCUjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzN1oXDTEwMDExNDIxMzAzN1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTYzcjFzZXJ2ZXItc2VjcDI1NnIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEAwEAYHKoZIzj0CAQYFK4EEAAIDLAAEAEvhHRk9
+YT/OvjnDdKuUpfv4RLbvA+ea8m5+4zH4agPsJFjEgC+Tl2AoMAkGByqGSM49BAED
+SAAwRQIgEE8zOqy0HkGCnAqdj0xUdpN43vyhBy08G6wx5tWFYekCIQDk0Rc/a8Mz
+id0zWgeo4cFUv75+S86WaSSxnkbgKD/PfA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRDCCAcwCCQCg3U8Mc7XCUzAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzOFoXDTEwMDExNDIxMzAzOFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTYzcjFzZXJ2ZXItc2VjcDM4NHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEAwEAYHKoZIzj0CAQYFK4EEAAIDLAAEBLc5EQ+F
+QABNsN7pyoOE60q/aokmAgE6Su1TfwZKvAGjxcAF4+l/I015MAkGByqGSM49BAED
+ZwAwZAIwD2i5VWRPgSSx/Q2JgJTN96q/T/rmDW+IzyqEU78KwzVIhf8zUIjQH5Pv
+az+KrObIAjBNUjCd2rUJorAOrDcf/s8d7KFBnxoiRjNCRKO6SiPvI8Cc4jaXfja5
+XZJjzk8P/nc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICajCCAcwCCQCg3U8Mc7XCVDAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwNTIxcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzOFoXDTEwMDExNDIxMzAzOFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTYzcjFzZXJ2ZXItc2VjcDUyMXIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEAwEAYHKoZIzj0CAQYFK4EEAAIDLAAEAcPPApQN
+hrXdgu0Rxv5SSy9Exry/Ag78xFNPzTR9mJxS1X8tN1wfiJOBMAkGByqGSM49BAED
+gYwAMIGIAkIA1Fm7h0vZAywp1Wf3xNI3wm29lK0BSWOVO6fQyWYmKghKi325Tkbw
+MbyO3D9YXC2K1G7zQrG5GXA1Jo82ndhpsKUCQgHK67lXzYtfCndSWDrPftXEqn0T
+epSGI3I5vxlJuvx2UW1fvZt098Ku4bR8ixKVgDHo8TuEEsJJg+johh0oZHQj7Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICDTCCAcwCCQCg3U8Mc7XCVTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzOVoXDTEwMDExNDIxMzAzOVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTYzcjFzZXJ2ZXItc2VjdDE2M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEAwEAYHKoZIzj0CAQYFK4EEAAIDLAAEBd4sp9FM
+F2RQWVjZqhqKPRhVhcOrB20Iqn3MfUIXpKnZWBugJZYgQVIvMAkGByqGSM49BAED
+MAAwLQIUAwzB/r2hCllysJwxwC4VKKF90igCFQCO0ik9fYlw5RInDzDH/f7xjOOS
+gw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICFTCCAcwCCQCg3U8Mc7XCVjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzAzOVoXDTEwMDExNDIxMzAzOVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTYzcjFzZXJ2ZXItc2VjdDE5M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEAwEAYHKoZIzj0CAQYFK4EEAAIDLAAEAgD1SibB
+UQJtSvkK42sdggot73fzBk2J+aj3WSvDHwMXsYslaPQG71lYMAkGByqGSM49BAED
+OAAwNQIZANBEfel7WcTKFV0q3UTeod1T3K7ClZQpQgIYZe6dll2Llj3A2S6eRB1G
+qjDJaejrFGxR
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICFjCCAdQCCQCKZ9MLoj/3JDAJBgcqhkjOPQQBMIGrMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMSswKQYDVQQLDCJUZXN0IFNlcnZl
+ciAoc2VjdDE2M3Ixc2VydmVyLXNlbGYpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVu
+dGFsc3R1ZmYuY29tMB4XDTA1MTIwNjIxMzA0MVoXDTEwMDExNDIxMzA0MVowgasx
+CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmll
+dzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxKzApBgNV
+BAsMIlRlc3QgU2VydmVyIChzZWN0MTYzcjFzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wQDAQBgcqhkjOPQIBBgUrgQQAAgMs
+AAQAbsGEXvpTlsxcf5b1S0Uv+CW6aDIAD1SB5MwpErkmq6eCFPVF2c3iIZ4wCQYH
+KoZIzj0EAQMxADAuAhUAhh4DeqrebKZ7IoIO+gYcs1tT4IsCFQD51UVBnZrYhqHT
+tKfswmapHLXMzA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDFTCCAsygAwIBAgIJAI4aIMim8fazMAkGByqGSM49BAEwgZwxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UE
+CgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxHDAaBgNVBAsME1Rlc3Qg
+Q0EgKHNlY3QxOTNyMSkxIjAgBgNVBAMMGWRldi5leHBlcmltZW50YWxzdHVmZi5j
+b20wHhcNMDUxMjA2MjEyOTU2WhcNMTAwMTE0MjEyOTU2WjCBnDELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEcMBoGA1UECwwTVGVzdCBD
+QSAoc2VjdDE5M3IxKTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZmLmNv
+bTBIMBAGByqGSM49AgEGBSuBBAAYAzQABADC/YtwwrsyHusPx05mHRMV3Rjw5dcw
+LLUAIh3jrWVGFFLWZl0QCs2xBnGF6KfjKnOdo4IBBTCCAQEwHQYDVR0OBBYEFHVx
+jVCVss3ZetdFkR0auNgmLXljMIHRBgNVHSMEgckwgcaAFHVxjVCVss3ZetdFkR0a
+uNgmLXljoYGipIGfMIGcMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNV
+BAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1biBNaWNyb3N5c3RlbXMgTGFi
+b3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChzZWN0MTkzcjEpMSIwIAYDVQQD
+DBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tggkAjhogyKbx9rMwDAYDVR0TBAUw
+AwEB/zAJBgcqhkjOPQQBAzgAMDUCGFVX2d9M0NbxeusbaUjMcWwviXPQpNEHvwIZ
+AOPKXDtDGAwkb42kO7ms7rzN7R4LN788MA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICcDCCAdkCCQCg3U8Mc7XCXzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAxMDI0KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwNDVaFw0xMDAxMTQyMTMwNDVaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjdDE5M3Ixc2VydmVyLXJzYTEwMjRjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wSDAQBgcqhkjOPQIBBgUrgQQAGAM0AAQA
+vZA91W5lNk3Ru3pALBexkJpZ9K0WjZrLASMO9wZGvbukocKAPYTfDYdcSwdwqHuU
+RzANBgkqhkiG9w0BAQUFAAOBgQB/Gcwd09VVyOWJq9cIA5tga/ZBYwgXv+T3eAUU
+Ert7tGQgD/eysWYvTB+Vu9zUvGyWWtUfzoFMP1R2MeuxnDMiXyhhQ+7UKl3P7AQy
+P060oo1DP7RWK8D8oz8IFeP6ttaiRgetE3hnHUwbxnO30bdiN61EdWBT0Dp+0LuP
+Yg6Ndw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC8TCCAdkCCQCg3U8Mc7XCYDANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MSYwJAYDVQQK
+DB1TdW4gTWljcm9zeXN0ZW1zIExhYm9yYXRvcmllczEfMB0GA1UECwwWVGVzdCBT
+ZXJ2ZXIgKFJTQSAyMDQ4KTEiMCAGA1UEAwwZZGV2LmV4cGVyaW1lbnRhbHN0dWZm
+LmNvbTAeFw0wNTEyMDYyMTMwNDZaFw0xMDAxMTQyMTMwNDZaMIGwMQswCQYDVQQG
+EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNV
+BAoMHVN1biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMTAwLgYDVQQLDCdUZXN0
+IFNlcnZlciAoc2VjdDE5M3Ixc2VydmVyLXJzYTIwNDhjYSkxIjAgBgNVBAMMGWRl
+di5leHBlcmltZW50YWxzdHVmZi5jb20wSDAQBgcqhkjOPQIBBgUrgQQAGAM0AAQA
+qMKb0SJmrWoWnZxXZh5jhRZnF9vRyljvARAR7/z2+gU/qkOTcxuE9RYxgqHtDVRE
+fjANBgkqhkiG9w0BAQUFAAOCAQEAScWVdynbg9B9VCtF4Ct8sXMRRYuwCLUt5Yp/
+rtLXmhUuZR0qCvuCMoDo2+HdQNcwEZr7teH2jZ9gYcfq1GWouwA36rafR8e4GQ4P
+egySyKLYkZ7sKhrKacN4k1XItlxHsWWtVRs79smAVgpVIu5IA2Pm5BZEuIUPCIAF
+3gSHM6Y0UHWGazxaToUEiPh7jVh5eUA8wAdhKFhiLtrIlZo9u2BCXmPiwBj71fSY
+iyEArag7u/n5pfoBYzwiiAFLddQiuwaxe8jPt0+RJI5Dhs0IzX6L/Xzu06qkKPjF
+9AX5PkBWj5GAjPCU/8t3O2wrMBvCw7G7epMXNXjTqJf6no5sig==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICFTCCAdQCCQCg3U8Mc7XCWTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMTYwcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA0MloXDTEwMDExNDIxMzA0MlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTkzcjFzZXJ2ZXItc2VjcDE2MHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEgwEAYHKoZIzj0CAQYFK4EEABgDNAAEANui7TQR
+XIBnrqvvP9zgztIKdqeIwISmzQBKKwC3FMR/Ma/MJCuBuXANUV3Xbi/rwwswCQYH
+KoZIzj0EAQMwADAtAhUAhNmGbEAG/eht1YE9KUUf7v/k9ywCFDO9YqZLm7mvDe2Q
+Vp2EWIS8AFw0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICLjCCAdQCCQCg3U8Mc7XCWjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMjU2cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA0MloXDTEwMDExNDIxMzA0MlowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTkzcjFzZXJ2ZXItc2VjcDI1NnIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEgwEAYHKoZIzj0CAQYFK4EEABgDNAAEAE/bjnPS
+yBqy8ageF1ZpfzHTAoEzcV5UywAlrF6AsP5UDVbbxWzEYENodBbIAyu5gmswCQYH
+KoZIzj0EAQNJADBGAiEAyOvzEV5o/+YRAkIQY/+Le1n3wzUvr9QMwVlOg/yZMvsC
+IQCFFD9AOt0tQTxWsDgGzCoVbz9MnnWzptIsGx4HXUm4YA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICTTCCAdQCCQCg3U8Mc7XCWzAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWNwMzg0cjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA0M1oXDTEwMDExNDIxMzA0M1owgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTkzcjFzZXJ2ZXItc2VjcDM4NHIxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEgwEAYHKoZIzj0CAQYFK4EEABgDNAAEASNBKWzJ
++B+4G2UTsTqBM0cjsdS6C5cmHwC1oYKyagdGeWkSzI3wsNJri29OBB3wg1YwCQYH
+KoZIzj0EAQNoADBlAjEAvCF43f3XJZHJ43dChTwVcMxrvrkEg33BCdkpab3ZzQGc
+4z8YLxgXwNgQtoWakxepAjAT9zi78gOcvIOLt+cONUWX1Q3dwsqz7ELfB51+H9EC
+njcMe07enAwPTGZhifhBqfQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICFjCCAdQCCQCg3U8Mc7XCXTAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTYzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA0NFoXDTEwMDExNDIxMzA0NFowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTkzcjFzZXJ2ZXItc2VjdDE2M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEgwEAYHKoZIzj0CAQYFK4EEABgDNAAEAInznYj4
+XfwSdi2XrqLF6uQ1/sJoFEveBQCqz+XoSsXKgRmMCO2iMHVGctNbcz8RptMwCQYH
+KoZIzj0EAQMxADAuAhUBfBAH/3ROR9VsZKAhW0fR6i/ud9gCFQCdjuAk1NhSTtAD
+AcZ+gSnBmESa1g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICHDCCAdQCCQCg3U8Mc7XCXjAJBgcqhkjOPQQBMIGcMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMRwwGgYDVQQLDBNUZXN0IENBIChz
+ZWN0MTkzcjEpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVudGFsc3R1ZmYuY29tMB4X
+DTA1MTIwNjIxMzA0NVoXDTEwMDExNDIxMzA0NVowgbIxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEmMCQGA1UECgwdU3Vu
+IE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxMjAwBgNVBAsMKVRlc3QgU2VydmVy
+IChzZWN0MTkzcjFzZXJ2ZXItc2VjdDE5M3IxY2EpMSIwIAYDVQQDDBlkZXYuZXhw
+ZXJpbWVudGFsc3R1ZmYuY29tMEgwEAYHKoZIzj0CAQYFK4EEABgDNAAEAGJbRZVS
+qbKx8P+C60EaCmnuolgSDf7fqwE0oMSo8dtSmq1vSmqXjbQHWaze3zev50swCQYH
+KoZIzj0EAQM3ADA0AhhsmuN8sbGYzItLtNqk/kXRvBSk+gOeKaECGBAT5pnVqKan
+q4wuATzeJEv5LeT9H3GU1A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICJDCCAdwCCQCzW7zGCDpEhzAJBgcqhkjOPQQBMIGrMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxJjAkBgNVBAoMHVN1
+biBNaWNyb3N5c3RlbXMgTGFib3JhdG9yaWVzMSswKQYDVQQLDCJUZXN0IFNlcnZl
+ciAoc2VjdDE5M3Ixc2VydmVyLXNlbGYpMSIwIAYDVQQDDBlkZXYuZXhwZXJpbWVu
+dGFsc3R1ZmYuY29tMB4XDTA1MTIwNjIxMzA0N1oXDTEwMDExNDIxMzA0N1owgasx
+CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmll
+dzEmMCQGA1UECgwdU3VuIE1pY3Jvc3lzdGVtcyBMYWJvcmF0b3JpZXMxKzApBgNV
+BAsMIlRlc3QgU2VydmVyIChzZWN0MTkzcjFzZXJ2ZXItc2VsZikxIjAgBgNVBAMM
+GWRldi5leHBlcmltZW50YWxzdHVmZi5jb20wSDAQBgcqhkjOPQIBBgUrgQQAGAM0
+AAQAjhf42KmZLPPrcBCdsOJpU9uDCZDh7CD7Af3pMkj8friWXyIZBoKwChbkPOnT
+wq4XMTAJBgcqhkjOPQQBAzcAMDQCGD0nycV04j9b/1/l1cnRJWtuaHUK2LPmdAIY
+fDH6KdS9OQSXMHdiCLnK5mWYTDG0g0em
+-----END CERTIFICATE-----
Binary file jdk/test/sun/security/ec/keystore has changed
Binary file jdk/test/sun/security/ec/truststore has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/IPv6.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6877357
+ * @summary IPv6 address does not work
+ */
+
+import com.sun.security.auth.module.Krb5LoginModule;
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.security.auth.Subject;
+
+public class IPv6 {
+
+    public static void main(String[] args) throws Exception {
+
+        String[][] kdcs = {
+                {"simple.host", null},  // These are legal settings
+                {"simple.host", ""},
+                {"simple.host", "8080"},
+                {"0.0.0.1", null},
+                {"0.0.0.1", ""},
+                {"0.0.0.1", "8080"},
+                {"1::1", null},
+                {"[1::1]", null},
+                {"[1::1]", ""},
+                {"[1::1]", "8080"},
+                {"[1::1", null},        // Two illegal settings
+                {"[1::1]abc", null},
+        };
+        // Prepares a krb5.conf with every kind of KDC settings
+        PrintStream out = new PrintStream(new FileOutputStream("ipv6.conf"));
+        out.println("[libdefaults]");
+        out.println("default_realm = V6");
+        out.println("[realms]");
+        out.println("V6 = {");
+        for (String[] hp: kdcs) {
+            if (hp[1] != null) out.println("    kdc = "+hp[0]+":"+hp[1]);
+            else out.println("    kdc = " + hp[0]);
+        }
+        out.println("}");
+        out.close();
+
+        System.setProperty("sun.security.krb5.debug", "true");
+        System.setProperty("java.security.krb5.conf", "ipv6.conf");
+
+        ByteArrayOutputStream bo = new ByteArrayOutputStream();
+        PrintStream po = new PrintStream(bo);
+        PrintStream oldout = System.out;
+        System.setOut(po);
+
+        try {
+            Subject subject = new Subject();
+            Krb5LoginModule krb5 = new Krb5LoginModule();
+            Map<String, String> map = new HashMap<String, String>();
+            Map<String, Object> shared = new HashMap<String, Object>();
+
+            map.put("debug", "true");
+            map.put("doNotPrompt", "true");
+            map.put("useTicketCache", "false");
+            map.put("useFirstPass", "true");
+            shared.put("javax.security.auth.login.name", "any");
+            shared.put("javax.security.auth.login.password", "any".toCharArray());
+            krb5.initialize(subject, null, shared, map);
+            krb5.login();
+        } catch (Exception e) {
+            // Ignore
+        }
+
+        po.flush();
+
+        System.setOut(oldout);
+        String[] lines = new String(bo.toByteArray()).split("\n");
+        int cc = 0;
+        Pattern r = Pattern.compile(".*KrbKdcReq send: kdc=(.*) UDP:(\\d+),.*");
+        for (String line: lines) {
+            Matcher m = r.matcher(line.subSequence(0, line.length()));
+            if (m.matches()) {
+                System.out.println("------------------");
+                System.out.println(line);
+                String h = m.group(1), p = m.group(2);
+                String eh = kdcs[cc][0], ep = kdcs[cc][1];
+                if (eh.charAt(0) == '[') {
+                    eh = eh.substring(1, eh.length()-1);
+                }
+                System.out.println("Expected: " + eh + " : " + ep);
+                System.out.println("Actual: " + h + " : " + p);
+                if (!eh.equals(h) ||
+                        (ep == null || ep.length() == 0) && !p.equals("88") ||
+                        (ep != null && ep.length() > 0) && !p.equals(ep)) {
+                    throw new Exception("Mismatch");
+                }
+                cc++;
+            }
+        }
+        if (cc != kdcs.length - 2) {    // 2 illegal settings at the end
+            throw new Exception("Not traversed");
+        }
+    }
+}
+
+
--- a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java	Wed Jul 05 17:01:15 2017 +0200
@@ -100,7 +100,15 @@
             X509Certificate issuer = certs.get(cert.getIssuerX500Principal());
             System.out.println("Verifying " + cert.getSubjectX500Principal() + "...");
             PublicKey key = issuer.getPublicKey();
-            cert.verify(key, p.getName());
+            // First try the provider under test (if it does not support the
+            // necessary algorithm then try any registered provider).
+            try {
+                cert.verify(key, p.getName());
+            } catch (NoSuchAlgorithmException e) {
+                System.out.println("Warning: " + e.getMessage() +
+                ". Trying another provider...");
+                cert.verify(key);
+            }
         }
 
         // try some random invalid signatures to make sure we get the correct
--- a/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java	Wed Jul 05 17:01:15 2017 +0200
@@ -298,7 +298,7 @@
             throws Exception {
         long time = System.currentTimeMillis();
         String relPath;
-        if ((args.length > 0) && args[0].equals("sh")) {
+        if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
             relPath = pathToStoresSH;
         } else {
             relPath = pathToStores;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6882376
+ * @summary Test if java.util.logging.Logger is created before and after
+ *          logging is enabled.  Also validate some basic PlatformLogger
+ *          operations.
+ *
+ * @build PlatformLoggerTest
+ * @run main PlatformLoggerTest
+ */
+
+import java.util.logging.*;
+import sun.util.logging.PlatformLogger;
+
+public class PlatformLoggerTest {
+    private static final int defaultEffectiveLevel = 0;
+    public static void main(String[] args) throws Exception {
+        final String FOO_PLATFORM_LOGGER = "test.platformlogger.foo";
+        final String BAR_PLATFORM_LOGGER = "test.platformlogger.bar";
+        final String GOO_PLATFORM_LOGGER = "test.platformlogger.goo";
+        final String BAR_LOGGER = "test.logger.bar";
+        PlatformLogger goo = PlatformLogger.getLogger(GOO_PLATFORM_LOGGER);
+
+        // Create a platform logger using the default
+        PlatformLogger foo = PlatformLogger.getLogger(FOO_PLATFORM_LOGGER);
+        checkPlatformLogger(foo, FOO_PLATFORM_LOGGER);
+
+        // create a java.util.logging.Logger
+        // now java.util.logging.Logger should be created for each platform logger
+        Logger logger = Logger.getLogger(BAR_LOGGER);
+        logger.setLevel(Level.WARNING);
+
+        PlatformLogger bar = PlatformLogger.getLogger(BAR_PLATFORM_LOGGER);
+        checkPlatformLogger(bar, BAR_PLATFORM_LOGGER);
+
+        checkLogger(FOO_PLATFORM_LOGGER, Level.FINER);
+        checkLogger(BAR_PLATFORM_LOGGER, Level.FINER);
+
+        checkLogger(GOO_PLATFORM_LOGGER, null);
+        checkLogger(BAR_LOGGER, Level.WARNING);
+
+        foo.setLevel(PlatformLogger.SEVERE);
+        checkLogger(FOO_PLATFORM_LOGGER, Level.SEVERE);
+    }
+
+    private static void checkPlatformLogger(PlatformLogger logger, String name) {
+        if (!logger.getName().equals(name)) {
+            throw new RuntimeException("Invalid logger's name " +
+                logger.getName() + " but expected " + name);
+        }
+
+        if (logger.getLevel() != defaultEffectiveLevel) {
+            throw new RuntimeException("Invalid default level for logger " +
+                logger.getName());
+        }
+
+        if (logger.isLoggable(PlatformLogger.FINE) != false) {
+            throw new RuntimeException("isLoggerable(FINE) returns true for logger " +
+                logger.getName() + " but expected false");
+        }
+
+        logger.setLevel(PlatformLogger.FINER);
+        if (logger.getLevel() != Level.FINER.intValue()) {
+            throw new RuntimeException("Invalid level for logger " +
+                logger.getName() + " " + logger.getLevel());
+        }
+
+        if (logger.isLoggable(PlatformLogger.FINE) != true) {
+            throw new RuntimeException("isLoggerable(FINE) returns false for logger " +
+                logger.getName() + " but expected true");
+        }
+
+        logger.info("OK: Testing log message");
+    }
+
+    private static void checkLogger(String name, Level level) {
+        Logger logger = LogManager.getLogManager().getLogger(name);
+        if (logger == null) {
+            throw new RuntimeException("Logger " + name +
+                " does not exist");
+        }
+
+        if (logger.getLevel() != level) {
+            throw new RuntimeException("Invalid level for logger " +
+                logger.getName() + " " + logger.getLevel());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/6842838/CreateBadJar.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * Borrowing significantly from Martin Buchholz's CorruptedZipFiles.java
+ *
+ * Needed a way of testing the checks for corrupt zip/jar entry in
+ * inflate_file from file j2se/src/share/bin/parse_manifest.c
+ * and running them with the 64-bit launcher. e.g.
+ * sparcv9/bin/java -jar badjar.jar
+ *
+ * Run from a script driver Test6842838.sh as we want to specifically run
+ * bin/sparcv9/java, the 64-bit launcher.
+ *
+ * So this program will create a zip file and damage it in the way
+ * required to tickle this bug.
+ *
+ * It will cause a buffer overrun: but that will not always crash.
+ * Use libumem preloaded by the script driver in order to
+ * abort quickly when the overrun happens.  That makes the test
+ * Solaris-specific.
+ */
+
+import java.util.*;
+import java.util.zip.*;
+import java.io.*;
+import static java.lang.System.*;
+import static java.util.zip.ZipFile.*;
+
+public class CreateBadJar {
+
+public static void main(String [] arguments) {
+
+        if (arguments.length != 2) {
+            throw new RuntimeException("Arguments: jarfilename entryname");
+        }
+        String outFile = arguments[0];
+        String entryName = arguments[1];
+
+        try {
+        // If the named file doesn't exist, create it.
+        // If it does, we are expecting it to contain the named entry, for
+        // alteration.
+        if (!new File(outFile).exists()) {
+          System.out.println("Creating file " + outFile);
+
+          // Create the requested zip/jar file.
+          ZipOutputStream zos = null;
+          zos = new ZipOutputStream(
+            new FileOutputStream(outFile));
+
+          ZipEntry e = new ZipEntry(entryName);
+          zos.putNextEntry(e);
+          for (int j=0; j<50000; j++) {
+            zos.write((int)'a');
+          }
+          zos.closeEntry();
+          zos.close();
+          zos = null;
+        }
+
+        // Read it.
+        int len = (int)(new File(outFile).length());
+        byte[] good = new byte[len];
+        FileInputStream fis = new FileInputStream(outFile);
+        fis.read(good);
+        fis.close();
+        fis = null;
+
+        int endpos = len - ENDHDR;
+        int cenpos = u16(good, endpos+ENDOFF);
+        if (u32(good, cenpos) != CENSIG) throw new RuntimeException("Where's CENSIG?");
+
+        byte[] bad;
+        bad = good.clone();
+
+        // Corrupt it...
+        int pos = findInCEN(bad, cenpos, entryName);
+
+        // What bad stuff are we doing to it?
+        // Store a 32-bit -1 in uncomp size.
+        bad[pos+0x18]=(byte)0xff;
+        bad[pos+0x19]=(byte)0xff;
+        bad[pos+0x1a]=(byte)0xff;
+        bad[pos+0x1b]=(byte)0xff;
+
+        // Bad work complete, delete the original.
+        new File(outFile).delete();
+
+        // Write it.
+        FileOutputStream fos = new FileOutputStream(outFile);
+        fos.write(bad);
+        fos.close();
+        fos = null;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+}
+
+        /*
+         * Scan Central Directory File Headers looking for the named entry.
+         */
+
+    static int findInCEN(byte[] bytes, int cenpos, String entryName) {
+        int pos = cenpos;
+        int nextPos = 0;
+        String filename = null;
+        do {
+            if (nextPos != 0) {
+                pos = nextPos;
+            }
+            System.out.println("entry at pos = " + pos);
+            if (u32(bytes, pos) != CENSIG) throw new RuntimeException ("entry not found in CEN or premature end...");
+
+            int csize = u32(bytes, pos+0x14);          // +0x14 1 dword csize
+            int uncompsize = u32(bytes, pos+0x18);     // +0x18 1 dword uncomp size
+            int filenameLength = u16(bytes, pos+0x1c); // +0x1c 1 word length of filename
+            int extraLength = u16(bytes, pos+0x1e);    // +0x1e 1 world length of extra field
+            int commentLength = u16(bytes, pos+0x20);  // +0x20 1 world length of file comment
+            filename = new String(bytes, pos+0x2e, filenameLength); // +0x2e chars of filename
+            int offset = u32(bytes, pos+0x2a);         // +0x2a chars of filename
+
+            System.out.println("filename = " + filename + "\ncsize = " + csize +
+                               " uncomp.size = " + uncompsize +" file offset = " + offset);
+            nextPos =  pos + 0x2e + filenameLength + extraLength + commentLength;
+
+        } while (!filename.equals(entryName));
+
+        System.out.println("entry found at pos = " + pos);
+        return pos;
+    }
+
+    static int u8(byte[] data, int offset) {
+        return data[offset]&0xff;
+    }
+
+    static int u16(byte[] data, int offset) {
+        return u8(data,offset) + (u8(data,offset+1)<<8);
+    }
+
+    static int u32(byte[] data, int offset) {
+        return u16(data,offset) + (u16(data,offset+2)<<16);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/6842838/Test6842838.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,76 @@
+#
+# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+
+# @test Test6842838.sh
+# @bug 6842838
+# @summary Test 6842838 64-bit launcher failure due to corrupt jar
+# @compile CreateBadJar.java
+# @run shell Test6842838.sh
+
+set -x
+
+if [ "${TESTJAVA}" = "" ]; then
+  PARENT=`dirname \`which java\``
+  TESTJAVA=`dirname ${PARENT}`
+  printf "TESTJAVA not set.  Test cannot execute.  Failed.\n"
+fi
+
+if [ "${TESTCLASSES}" = "" ]; then
+  printf "TESTCLASSES not set.  Test cannot execute.  Failed.\n"
+  exit 1
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS )
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    JAVA_EXE=${TESTJAVA}${FS}bin${FS}sparcv9${FS}java
+    ;;
+  * )
+    printf "Only testing on sparcv9 (use libumem to reliably catch buffer overrun)\n"
+    exit 0;
+    ;;
+esac
+
+if [ ! -x ${JAVA_EXE} ]; then
+    printf "Warning: sparcv9 components not installed - skipping test.\n"
+    exit 0
+fi
+
+LIBUMEM=/lib/64/libumem.so
+if [ ! -x ${LIBUMEM} ]; then
+    printf "Warning: libumem not installed - skipping test.\n"
+    exit 0
+fi
+
+BADFILE=newbadjar.jar
+${JAVA_EXE} -version
+${JAVA_EXE} -cp ${TESTCLASSES} CreateBadJar ${BADFILE} "META-INF/MANIFEST.MF"
+LD_PRELOAD=${LIBUMEM} ${JAVA_EXE} -jar ${BADFILE} > test.out 2>&1
+
+grep "Invalid or corrupt jarfile" test.out
+exit $?
--- a/langtools/.hgtags	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/.hgtags	Wed Jul 05 17:01:15 2017 +0200
@@ -46,3 +46,4 @@
 ce9bcdcb7859bb7ef10afd078ad59ba7847f208d jdk7-b69
 97d06f3e87873e310aa2f3fbca58fc8872d86b9f jdk7-b70
 33c8c38e1757006c17d80499fb3347102501fae5 jdk7-b71
+261c54b2312ed26d6ec45c675831375460250519 jdk7-b72
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1435,7 +1435,17 @@
                 // documented, this must be an inherited link.  Redirect it.
                 // The current class either overrides the referenced member or
                 // inherits it automatically.
-                containing = ((ClassWriterImpl) this).getClassDoc();
+                if (this instanceof ClassWriterImpl) {
+                    containing = ((ClassWriterImpl) this).getClassDoc();
+                } else if (!containing.isPublic()){
+                    configuration.getDocletSpecificMsg().warning(
+                        see.position(), "doclet.see.class_or_package_not_accessible",
+                        tagName, containing.qualifiedName());
+                } else {
+                    configuration.getDocletSpecificMsg().warning(
+                        see.position(), "doclet.see.class_or_package_not_found",
+                        tagName, seetext);
+                }
             }
             if (configuration.currentcd != containing) {
                 refMemName = containing.name() + "." + refMemName;
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -69,6 +69,7 @@
 doclet.No_Package_Comment_File=For Package {0} Package.Comment file not found
 doclet.No_Source_For_Class=Source information for class {0} not available.
 doclet.see.class_or_package_not_found=Tag {0}: reference not found: {1}
+doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1}
 doclet.see.malformed_tag=Tag {0}: Malformed: {1}
 doclet.Inherited_API_Summary=Inherited API Summary
 doclet.Deprecated_API=Deprecated API
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Wed Jul 05 17:01:15 2017 +0200
@@ -159,6 +159,12 @@
     public boolean allowTypeAnnotations() {
         return compareTo(JDK1_7) >= 0;
     }
+    public boolean allowBinaryLiterals() {
+        return compareTo(JDK1_7) >= 0;
+    }
+    public boolean allowUnderscoresInLiterals() {
+        return compareTo(JDK1_7) >= 0;
+    }
     public static SourceVersion toSourceVersion(Source source) {
         switch(source) {
         case JDK1_2:
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java	Wed Jul 05 17:01:15 2017 +0200
@@ -69,8 +69,10 @@
                 if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) {
                     Field jarField = l.getClass().getDeclaredField("jar");
                     JarFile jar = (JarFile) getField(l, jarField);
-                    //System.err.println("CloseableURLClassLoader: closing " + jar);
-                    jar.close();
+                    if (jar != null) {
+                        //System.err.println("CloseableURLClassLoader: closing " + jar);
+                        jar.close();
+                    }
                 }
             }
         } catch (Throwable t) {
--- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jul 05 17:01:15 2017 +0200
@@ -593,7 +593,7 @@
 //where
         boolean isZero(String s) {
             char[] cs = s.toCharArray();
-            int base = ((Character.toLowerCase(s.charAt(1)) == 'x') ? 16 : 10);
+            int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10);
             int i = ((base==16) ? 2 : 0);
             while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
             return !(i < cs.length && (Character.digit(cs[i], base) > 0));
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Wed Jul 05 17:01:15 2017 +0200
@@ -100,6 +100,18 @@
      */
     private boolean allowHexFloats;
 
+    /** Allow binary literals.
+     */
+    private boolean allowBinaryLiterals;
+
+    /** Allow underscores in literals.
+     */
+    private boolean allowUnderscoresInLiterals;
+
+    /** The source language setting.
+     */
+    private Source source;
+
     /** The token's position, 0-based offset from beginning of text.
      */
     private int pos;
@@ -162,10 +174,13 @@
 
     /** Common code for constructors. */
     private Scanner(Factory fac) {
-        this.log = fac.log;
-        this.names = fac.names;
-        this.keywords = fac.keywords;
-        this.allowHexFloats = fac.source.allowHexFloats();
+        log = fac.log;
+        names = fac.names;
+        keywords = fac.keywords;
+        source = fac.source;
+        allowBinaryLiterals = source.allowBinaryLiterals();
+        allowHexFloats = source.allowHexFloats();
+        allowUnderscoresInLiterals = source.allowBinaryLiterals();
     }
 
     private static final boolean hexFloatsWork = hexFloatsWork();
@@ -396,23 +411,42 @@
         scanLitChar(true);
     }
 
+    private void scanDigits(int digitRadix) {
+        char saveCh;
+        int savePos;
+        do {
+            if (ch != '_') {
+                putChar(ch);
+            } else {
+                if (!allowUnderscoresInLiterals) {
+                    lexError("unsupported.underscore", source.name);
+                    allowUnderscoresInLiterals = true;
+                }
+            }
+            saveCh = ch;
+            savePos = bp;
+            scanChar();
+        } while (digit(digitRadix) >= 0 || ch == '_');
+        if (saveCh == '_')
+            lexError(savePos, "illegal.underscore");
+    }
+
     /** Read fractional part of hexadecimal floating point number.
      */
     private void scanHexExponentAndSuffix() {
         if (ch == 'p' || ch == 'P') {
             putChar(ch);
             scanChar();
+            skipIllegalUnderscores();
             if (ch == '+' || ch == '-') {
                 putChar(ch);
                 scanChar();
             }
+            skipIllegalUnderscores();
             if ('0' <= ch && ch <= '9') {
-                do {
-                    putChar(ch);
-                    scanChar();
-                } while ('0' <= ch && ch <= '9');
+                scanDigits(10);
                 if (!allowHexFloats) {
-                    lexError("unsupported.fp.lit");
+                    lexError("unsupported.fp.lit", source.name);
                     allowHexFloats = true;
                 }
                 else if (!hexFloatsWork)
@@ -438,23 +472,22 @@
     /** Read fractional part of floating point number.
      */
     private void scanFraction() {
-        while (digit(10) >= 0) {
-            putChar(ch);
-            scanChar();
+        skipIllegalUnderscores();
+        if ('0' <= ch && ch <= '9') {
+            scanDigits(10);
         }
         int sp1 = sp;
         if (ch == 'e' || ch == 'E') {
             putChar(ch);
             scanChar();
+            skipIllegalUnderscores();
             if (ch == '+' || ch == '-') {
                 putChar(ch);
                 scanChar();
             }
+            skipIllegalUnderscores();
             if ('0' <= ch && ch <= '9') {
-                do {
-                    putChar(ch);
-                    scanChar();
-                } while ('0' <= ch && ch <= '9');
+                scanDigits(10);
                 return;
             }
             lexError("malformed.fp.lit");
@@ -487,10 +520,10 @@
         assert ch == '.';
         putChar(ch);
         scanChar();
-        while (digit(16) >= 0) {
+        skipIllegalUnderscores();
+        if (digit(16) >= 0) {
             seendigit = true;
-            putChar(ch);
-            scanChar();
+            scanDigits(16);
         }
         if (!seendigit)
             lexError("invalid.hex.number");
@@ -498,28 +531,35 @@
             scanHexExponentAndSuffix();
     }
 
+    private void skipIllegalUnderscores() {
+        if (ch == '_') {
+            lexError(bp, "illegal.underscore");
+            while (ch == '_')
+                scanChar();
+        }
+    }
+
     /** Read a number.
-     *  @param radix  The radix of the number; one of 8, 10, 16.
+     *  @param radix  The radix of the number; one of 2, j8, 10, 16.
      */
     private void scanNumber(int radix) {
         this.radix = radix;
         // for octal, allow base-10 digit in case it's a float literal
-        int digitRadix = (radix <= 10) ? 10 : 16;
+        int digitRadix = (radix == 8 ? 10 : radix);
         boolean seendigit = false;
-        while (digit(digitRadix) >= 0) {
+        if (digit(digitRadix) >= 0) {
             seendigit = true;
-            putChar(ch);
-            scanChar();
+            scanDigits(digitRadix);
         }
         if (radix == 16 && ch == '.') {
             scanHexFractionAndSuffix(seendigit);
         } else if (seendigit && radix == 16 && (ch == 'p' || ch == 'P')) {
             scanHexExponentAndSuffix();
-        } else if (radix <= 10 && ch == '.') {
+        } else if (digitRadix == 10 && ch == '.') {
             putChar(ch);
             scanChar();
             scanFractionAndSuffix();
-        } else if (radix <= 10 &&
+        } else if (digitRadix == 10 &&
                    (ch == 'e' || ch == 'E' ||
                     ch == 'f' || ch == 'F' ||
                     ch == 'd' || ch == 'D')) {
@@ -821,6 +861,7 @@
                     scanChar();
                     if (ch == 'x' || ch == 'X') {
                         scanChar();
+                        skipIllegalUnderscores();
                         if (ch == '.') {
                             scanHexFractionAndSuffix(false);
                         } else if (digit(16) < 0) {
@@ -828,8 +869,25 @@
                         } else {
                             scanNumber(16);
                         }
+                    } else if (ch == 'b' || ch == 'B') {
+                        if (!allowBinaryLiterals) {
+                            lexError("unsupported.binary.lit", source.name);
+                            allowBinaryLiterals = true;
+                        }
+                        scanChar();
+                        skipIllegalUnderscores();
+                        scanNumber(2);
                     } else {
                         putChar('0');
+                        if (ch == '_') {
+                            int savePos = bp;
+                            do {
+                                scanChar();
+                            } while (ch == '_');
+                            if (digit(10) < 0) {
+                                lexError(savePos, "illegal.underscore");
+                            }
+                        }
                         scanNumber(8);
                     }
                     return;
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jul 05 17:01:15 2017 +0200
@@ -216,6 +216,8 @@
     illegal line end in character literal
 compiler.err.illegal.nonascii.digit=\
     illegal non-ASCII digit
+compiler.err.illegal.underscore=\
+    illegal underscore
 compiler.err.illegal.qual.not.icls=\
     illegal qualifier; {0} is not an inner class
 compiler.err.illegal.start.of.expr=\
@@ -1163,7 +1165,16 @@
 # Diagnostics for language feature changes
 ########################################
 compiler.err.unsupported.fp.lit=\
-    hexadecimal floating-point literals are not supported before -source 5
+    hexadecimal floating point literals are not supported in -source {0}\n\
+(use -source 5 or higher to enable hexadecimal floating point literals)
+
+compiler.err.unsupported.binary.lit=\
+    binary literals are not supported in -source {0}\n\
+(use -source 7 or higher to enable binary literals)
+
+compiler.err.unsupported.underscore.lit=\
+    underscores in literals are not supported in -source {0}\n\
+(use -source 7 or higher to enable underscores in literals)
 
 compiler.warn.enum.as.identifier=\
     as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java	Wed Jul 05 17:01:15 2017 +0200
@@ -60,7 +60,12 @@
      */
     public AnnotationTypeDoc annotationType() {
         ClassSymbol atsym = (ClassSymbol)annotation.type.tsym;
-        return (AnnotationTypeDoc)env.getClassDoc(atsym);
+        if (annotation.type.isErroneous()) {
+            env.warning(null, "javadoc.class_not_found", annotation.type.toString());
+            return new AnnotationTypeDocImpl(env, atsym);
+        } else {
+            return (AnnotationTypeDoc)env.getClassDoc(atsym);
+        }
     }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/javax/lang/model/element/TypeElement.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/src/share/classes/javax/lang/model/element/TypeElement.java	Wed Jul 05 17:01:15 2017 +0200
@@ -60,6 +60,22 @@
  * @since 1.6
  */
 public interface TypeElement extends Element, Parameterizable, QualifiedNameable {
+    /**
+     * {@inheritDoc}
+     *
+     * <p> Note that as a particular instance of the {@linkplain
+     * javax.lang.model.element general accuracy requirements} and the
+     * ordering behavior required of this interface, the list of
+     * enclosed elements will be returned in the natural order for the
+     * originating source of information about the type.  For example,
+     * if the information about the type is originating from a source
+     * file, the elements will be returned in source code order.
+     * (However, in that case the the ordering of synthesized
+     * elements, such as a default constructor, is not specified.)
+     *
+     * @return the enclosed elements in proper order, or an empty list if none
+     */
+    List<? extends Element> getEnclosedElements();
 
     /**
      * Returns the <i>nesting kind</i> of this type element.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/5093723/DocumentedClass.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009 Google, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/** A documented class. */
+public class DocumentedClass extends UndocumentedClass {
+  /** {@link #method} */
+  public void m1() {}
+  /** {@link #publicMethod} */
+  public void m2() {}
+  /** {@link #protectedMethod} */
+  public void m3() {}
+  /** {@link #privateMethod} */
+  public void m4() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2009 Google, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug      5093723
+ * @summary  REGRESSION: ClassCastException in SingleIndexWriter
+ * @library  ../lib/
+ * @build    JavadocTester
+ * @build    T5093723
+ * @run main T5093723
+ */
+
+public class T5093723 extends JavadocTester {
+
+    private static final String BUG_ID = "5093723";
+
+    private static final String[] ARGS = new String[] {
+        "-d", BUG_ID + ".out", "-source", "5",
+        SRC_DIR + "/DocumentedClass.java",
+        SRC_DIR + "/UndocumentedClass.java"
+    };
+
+    public static void main(String... args) {
+        T5093723 tester = new T5093723();
+        if (tester.runJavadoc(ARGS) != 0)
+          throw new AssertionError("non-zero return code from javadoc");
+    }
+
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/5093723/UndocumentedClass.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2009 Google, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+class UndocumentedClass {
+    void method() {}
+    public void publicMethod() {}
+    protected void protectedMethod() {}
+    private void privateMethod() {}
+}
--- a/langtools/test/com/sun/javadoc/lib/JavadocTester.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/com/sun/javadoc/lib/JavadocTester.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/com/sun/javadoc/testCRLineSeparator/pkg/MyClass.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testCRLineSeparator/pkg/MyClass.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/com/sun/javadoc/testTaglets/TestTaglets.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testTaglets/TestTaglets.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/apt/Basics/apt.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/apt/Basics/apt.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2004-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/apt/Basics/print.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/apt/Basics/print.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2004-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2004-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/apt/Compile/compile.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/apt/Compile/compile.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2004-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2004-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/4846262/Test.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/4846262/Test.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh -f
 
 #
-# Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/6302184/T6302184.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/6302184/T6302184.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #! /bin/sh -f
 
 #
-# Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/6627362/T6627362.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/6627362/T6627362.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/ClassPathTest/ClassPathTest.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/ClassPathTest/ClassPathTest.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 1999-2003 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/ExtDirs/ExtDirs.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/ExtDirs/ExtDirs.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/MissingInclude.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/MissingInclude.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 1998-2003 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/T5090006/compiler.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/T5090006/compiler.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2004-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6882235.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6882235
+ * @summary invalid exponent causes silent javac crash
+ *
+ * @compile/fail T6882235.java
+ * @compile/fail/ref=T6882235.out -XDrawDiagnostics T6882235.java
+ */
+
+class T6882235 {
+    int i = ;           // invalid expression
+    float f = 0e*;      // invalid exponent, should not crash compiler
+    int j = ;           // invalid expression
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6882235.out	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,5 @@
+T6882235.java:11:13: compiler.err.illegal.start.of.expr
+T6882235.java:12:15: compiler.err.malformed.fp.lit
+T6882235.java:12:18: compiler.err.illegal.start.of.expr
+T6882235.java:13:13: compiler.err.illegal.start.of.expr
+4 errors
--- a/langtools/test/tools/javac/api/6440333/T6440333.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/api/6440333/T6440333.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2006-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/api/Sibling.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/api/Sibling.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2006-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/code/ArrayClone.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/code/ArrayClone.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/constDebug/ConstDebug.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/constDebug/ConstDebug.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2002-2003 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/enum/6384542/T6384542.out	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/enum/6384542/T6384542.out	Wed Jul 05 17:01:15 2017 +0200
@@ -1,6 +1,6 @@
 T6384542.java:10:8: compiler.err.static.import.not.supported.in.source: 1.4
 T6384542.java:12:8: compiler.err.enums.not.supported.in.source: 1.4
-T6384542.java:14:13: compiler.err.unsupported.fp.lit
+T6384542.java:14:13: compiler.err.unsupported.fp.lit: 1.4
 T6384542.java:15:9: compiler.err.generics.not.supported.in.source: 1.4
 T6384542.java:16:35: compiler.err.varargs.not.supported.in.source: 1.4
 T6384542.java:17:25: compiler.err.foreach.not.supported.in.source: 1.4
--- a/langtools/test/tools/javac/fatalErrors/NoJavaLang.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/fatalErrors/NoJavaLang.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/generics/inference/6302954/T6476073.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6302954/T6476073.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2006-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/innerClassFile/Driver.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/innerClassFile/Driver.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/javazip/Test.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/javazip/Test.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #! /bin/sh -f
 
 #
-# Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/BadBinaryLiterals.6.out	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,8 @@
+BadBinaryLiterals.java:10:17: compiler.err.unsupported.binary.lit: 1.6
+BadBinaryLiterals.java:11:24: compiler.err.expected: ';'
+BadBinaryLiterals.java:13:21: compiler.err.int.number.too.large: 111111111111111111111111111111111
+BadBinaryLiterals.java:15:21: compiler.err.int.number.too.large: 11111111111111111111111111111111111111111111111111111111111111111
+BadBinaryLiterals.java:16:27: compiler.err.expected: ';'
+BadBinaryLiterals.java:17:27: compiler.err.expected: ';'
+BadBinaryLiterals.java:17:30: compiler.err.expected: token.identifier
+7 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/BadBinaryLiterals.7.out	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,7 @@
+BadBinaryLiterals.java:11:24: compiler.err.expected: ';'
+BadBinaryLiterals.java:13:21: compiler.err.int.number.too.large: 111111111111111111111111111111111
+BadBinaryLiterals.java:15:21: compiler.err.int.number.too.large: 11111111111111111111111111111111111111111111111111111111111111111
+BadBinaryLiterals.java:16:27: compiler.err.expected: ';'
+BadBinaryLiterals.java:17:27: compiler.err.expected: ';'
+BadBinaryLiterals.java:17:30: compiler.err.expected: token.identifier
+6 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/BadBinaryLiterals.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6860965
+ * @summary Project Coin: binary literals
+ * @compile/fail/ref=BadBinaryLiterals.6.out -XDrawDiagnostics -source 6 BadBinaryLiterals.java
+ * @compile/fail/ref=BadBinaryLiterals.7.out -XDrawDiagnostics BadBinaryLiterals.java
+ */
+
+public class BadBinaryLiterals {
+    int valid = 0b0;            // valid literal, illegal in source 6
+    int baddigit = 0b012;       // bad digit
+                    //aaaabbbbccccddddeeeeffffgggghhhh
+    int overflow1 = 0b111111111111111111111111111111111; // too long for int
+                    //aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnoooopppp
+    int overflow2 = 0b11111111111111111111111111111111111111111111111111111111111111111L; // too long for long
+    float badfloat1 = 0b01.01;  // no binary floats
+    float badfloat2 = 0b01e01;  // no binary floats
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/BadUnderscoreLiterals.6.out	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,21 @@
+BadUnderscoreLiterals.java:14:17: compiler.err.unsupported.underscore: 1.6
+BadUnderscoreLiterals.java:18:15: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:22:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:25:14: compiler.err.unsupported.binary.lit: 1.6
+BadUnderscoreLiterals.java:25:16: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:26:17: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:29:16: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:30:17: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:33:17: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:34:18: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:35:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:36:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:37:18: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:38:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:41:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:42:20: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:43:21: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:44:22: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:45:21: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:46:22: compiler.err.illegal.underscore
+20 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/BadUnderscoreLiterals.7.out	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,19 @@
+BadUnderscoreLiterals.java:18:15: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:22:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:25:16: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:26:17: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:29:16: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:30:17: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:33:17: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:34:18: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:35:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:36:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:37:18: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:38:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:41:19: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:42:20: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:43:21: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:44:22: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:45:21: compiler.err.illegal.underscore
+BadUnderscoreLiterals.java:46:22: compiler.err.illegal.underscore
+18 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/BadUnderscoreLiterals.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6860973
+ * @summary Project Coin: underscores in literals
+ *
+ * @compile/fail BadUnderscoreLiterals.java
+ * @compile/fail/ref=BadUnderscoreLiterals.7.out -XDrawDiagnostics BadUnderscoreLiterals.java
+ *
+ * @compile/fail -source 6 BadUnderscoreLiterals.java
+ * @compile/fail/ref=BadUnderscoreLiterals.6.out -XDrawDiagnostics -source 6 BadUnderscoreLiterals.java
+ */
+
+public class BadUnderscoreLiterals {
+    int valid = 1_1;            // valid literal; illegal in -source 6
+
+    // test zero
+    int z1 = _0;                // valid (but undefined) variable
+    int z2 = 0_;                // trailing underscore
+
+    // test simple (decimal) integers
+    int i1 = _1_2_3;            // valid (but undefined) variable
+    int i2 = 1_2_3_;            // trailing underscore
+
+    // test binary integers
+    int b1 = 0b_0;              // leading underscore after radix
+    int b2 = 0b0_;              // trailing underscore
+
+    // test hexadecimal integers
+    int x1 = 0x_0;              // leading underscore after radix
+    int x2 = 0x0_;              // trailing underscore
+
+    // test floating point numbers
+    float f1 = 0_.1;            // trailing underscore before decimal point
+    float f2 = 0._1;            // leading underscore after decimal point
+    float f3 = 0.1_;            // trailing underscore
+    float f4 = 0.1_e0;          // trailing underscore before exponent
+    float f5 = 0e_1;            // leading underscore in exponent
+    float f6 = 0e1_;            // trailing underscore in exponent
+
+    // hexadecimal floating point
+    float xf1 = 0x_0.1p0;       // leading underscore after radix
+    float xf2 = 0x0_.1p0;       // trailing underscore before decimal point
+    float xf3 = 0x0._1p0;       // leading underscore after decimal point
+    float xf4 = 0x0.1_p0;       // trailing underscore before exponent
+    float xf5 = 0x0p_1;         // leading underscore after exponent
+    float xf6 = 0x0p1_;         // trailing underscore
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/BinaryLiterals.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6860965
+ * @summary Project Coin: binary literals
+ */
+
+public class BinaryLiterals {
+    public static void main(String... args) throws Exception {
+        new BinaryLiterals().run();
+    }
+
+    public void run() throws Exception {
+        test(0,  0B0);
+        test(1,  0B1);
+        test(2, 0B10);
+        test(3, 0B11);
+
+        test(0,  0b0);
+        test(1,  0b1);
+        test(2, 0b10);
+        test(3, 0b11);
+
+        test(-0,  -0b0);
+        test(-1,  -0b1);
+        test(-2, -0b10);
+        test(-3, -0b11);
+
+        test(-1,  0b11111111111111111111111111111111);
+        test(-2,  0b11111111111111111111111111111110);
+        test(-3,  0b11111111111111111111111111111101);
+
+        test( 1, -0b11111111111111111111111111111111);
+        test( 2, -0b11111111111111111111111111111110);
+        test( 3, -0b11111111111111111111111111111101);
+
+        test(0,     0b00);
+        test(1,    0b001);
+        test(2,  0b00010);
+        test(3, 0b000011);
+
+        //                 aaaabbbbccccddddeeeeffffgggghhhh
+        test(      0x10,                            0b10000);
+        test(     0x100,                        0b100000000);
+        test(   0x10000,                0b10000000000000000);
+        test(0x80000000, 0b10000000000000000000000000000000);
+        test(0xffffffff, 0b11111111111111111111111111111111);
+
+        test(0L,  0b0L);
+        test(1L,  0b1L);
+        test(2L, 0b10L);
+        test(3L, 0b11L);
+
+        test(0,     0b00L);
+        test(1,    0b001L);
+        test(2,  0b00010L);
+        test(3, 0b000011L);
+
+        //                          aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnoooopppp
+        test(              0x10L,                                                            0b10000L);
+        test(             0x100L,                                                        0b100000000L);
+        test(           0x10000L,                                                0b10000000000000000L);
+        test(        0x80000000L,                                 0b10000000000000000000000000000000L);
+        test(        0xffffffffL,                                 0b11111111111111111111111111111111L);
+        test(0x8000000000000000L, 0b1000000000000000000000000000000000000000000000000000000000000000L);
+        test(0xffffffffffffffffL, 0b1111111111111111111111111111111111111111111111111111111111111111L);
+
+        test(0l,  0b0l);
+        test(1l,  0b1l);
+        test(2l, 0b10l);
+        test(3l, 0b11l);
+
+        test(0,     0b00l);
+        test(1,    0b001l);
+        test(2,  0b00010l);
+        test(3, 0b000011l);
+
+        //                          aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnoooopppp
+        test(              0x10l,                                                            0b10000l);
+        test(             0x100l,                                                        0b100000000l);
+        test(           0x10000l,                                                0b10000000000000000l);
+        test(        0x80000000l,                                 0b10000000000000000000000000000000l);
+        test(        0xffffffffl,                                 0b11111111111111111111111111111111l);
+        test(0x8000000000000000l, 0b1000000000000000000000000000000000000000000000000000000000000000l);
+        test(0xffffffffffffffffl, 0b1111111111111111111111111111111111111111111111111111111111111111l);
+
+        if (errors > 0)
+             throw new Exception(errors + " errors found");
+    }
+
+    void test(int expect, int found) {
+        count++;
+        if (found != expect)
+            error("test " + count + "\nexpected: 0x" + Integer.toHexString(expect) + "\n   found: 0x" + Integer.toHexString(found));
+    }
+
+    void test(long expect, long found) {
+        count++;
+        if (found != expect)
+            error("test " + count + "\nexpected: 0x" + Long.toHexString(expect) + "\n   found: 0x" + Long.toHexString(found));
+    }
+
+    void error(String message) {
+        System.out.println(message);
+        errors++;
+    }
+
+    int count;
+    int errors;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/literals/UnderscoreLiterals.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6860973
+ * @summary Project Coin: Underscores in literals
+ */
+
+
+public class UnderscoreLiterals {
+    public static void main(String... args) throws Exception {
+        new UnderscoreLiterals().run();
+    }
+
+    public void run() throws Exception {
+        // decimal
+        test(1, 1);
+        test(10, 10);
+        test(1_0, 10);
+        test(1__0, 10);
+        test(1_0_0, 100);
+        test(1__0__0, 100);
+        test(123_456_789, 123456789);
+
+        // long
+        test(1l, 1l);
+        test(10l, 10l);
+        test(1_0l, 10l);
+        test(1__0l, 10l);
+        test(1_0_0l, 100l);
+        test(1__0__0l, 100l);
+        test(123_456_789l, 123456789l);
+
+        // float
+        test(.1f, .1f);
+        test(.10f, .10f);
+        test(.1_0f, .10f);
+        test(.1__0f, .10f);
+        test(.1_0_0f, .100f);
+        test(.1__0__0f, .100f);
+        test(1e1, 1e1);
+        test(1e10, 1e10);
+        test(1e1_0, 1e10);
+        test(1e1__0, 1e10);
+        test(1e1_0_0, 1e100);
+        test(1e1__0__0, 1e100);
+        test(.123_456_789f, .123456789f);
+        test(0.1f, 0.1f);
+        test(0.10f, 0.10f);
+        test(0.1_0f, 0.10f);
+        test(0.1__0f, 0.10f);
+        test(0.1_0_0f, 0.100f);
+        test(0.1__0__0f, 0.100f);
+        test(0.123_456_789f, 0.123456789f);
+        test(1_1.1f, 1_1.1f);
+        test(1_1.10f, 1_1.10f);
+        test(1_1.1_0f, 1_1.10f);
+        test(1_1.1__0f, 1_1.10f);
+        test(1_1.1_0_0f, 1_1.100f);
+        test(1_1.1__0__0f, 1_1.100f);
+        test(1_1.123_456_789f, 1_1.123456789f);
+
+        // double
+        test(.1d, .1d);
+        test(.10d, .10d);
+        test(.1_0d, .10d);
+        test(.1__0d, .10d);
+        test(.1_0_0d, .100d);
+        test(.1__0__0d, .100d);
+        test(1e1, 1e1);
+        test(1e10, 1e10);
+        test(1e1_0, 1e10);
+        test(1e1__0, 1e10);
+        test(1e1_0_0, 1e100);
+        test(1e1__0__0, 1e100);
+        test(.123_456_789d, .123456789d);
+        test(0.1d, 0.1d);
+        test(0.10d, 0.10d);
+        test(0.1_0d, 0.10d);
+        test(0.1__0d, 0.10d);
+        test(0.1_0_0d, 0.100d);
+        test(0.1__0__0d, 0.100d);
+        test(0.123_456_789d, 0.123456789d);
+        test(1_1.1d, 1_1.1d);
+        test(1_1.10d, 1_1.10d);
+        test(1_1.1_0d, 1_1.10d);
+        test(1_1.1__0d, 1_1.10d);
+        test(1_1.1_0_0d, 1_1.100d);
+        test(1_1.1__0__0d, 1_1.100d);
+        test(1_1.123_456_789d, 1_1.123456789d);
+
+        // binary
+        test(0b1, 1);
+        test(0b10, 2);
+        test(0b1_0, 2);
+        test(0b1__0, 2);
+        test(0b1_0_0, 4);
+        test(0b1__0__0, 4);
+        test(0b0001_0010_0011, 0x123);
+
+        // octal
+        test(01, 1);
+        test(010, 8);
+        test(01_0, 8);
+        test(01__0, 8);
+        test(01_0_0, 64);
+        test(01__0__0, 64);
+        test(0_1, 1);
+        test(0_10, 8);
+        test(0_1_0, 8);
+        test(0_1__0, 8);
+        test(0_1_0_0, 64);
+        test(0_1__0__0, 64);
+        test(0_001_002_003, 01002003);
+
+        // hexadecimal
+        test(0x1, 1);
+        test(0x10, 16);
+        test(0x1_0, 16);
+        test(0x1__0, 16);
+        test(0x1_0_0, 256);
+        test(0x1__0__0, 256);
+        test(0x01_02_03_04, 0x1020304);
+
+        // misc
+        long creditCardNumber = 1234_5678_9012_3456L;
+        test(creditCardNumber, 1234567890123456L);
+        long socialSecurityNumbers = 999_99_9999L;
+        test(socialSecurityNumbers, 999999999L);
+        double monetaryAmount = 12_345_132.12d;
+        test(monetaryAmount, 12345132.12d);
+        long hexBytes = 0xFF_EC_DE_5E;
+        test(hexBytes, 0xffecde5e);
+        long hexWords = 0xFFEC_DE5E;
+        test(hexWords, 0xffecde5e);
+        long maxLong = 0x7fff_ffff_ffff_ffffL;
+        test(maxLong, 0x7fffffffffffffffL);
+        long maxLongDecimal = 9223372036854775807L;
+        long alsoMaxLong = 9_223_372_036_854_775_807L;
+        test(alsoMaxLong, maxLongDecimal);
+        double whyWouldYouEverDoThis = 0x1.ffff_ffff_ffff_fp10_23;
+        double whyWouldYouEverDoEvenThis = 0x1.fffffffffffffp1023;
+        test(whyWouldYouEverDoThis, whyWouldYouEverDoEvenThis);
+
+        if (errors > 0)
+             throw new Exception(errors + " errors found");
+    }
+
+    void test(int value, int expect) {
+        count++;
+        if (value != expect)
+            error("test " + count + "\nexpected: 0x" + Integer.toHexString(expect) + "\n   found: 0x" + Integer.toHexString(value));
+    }
+
+    void test(double value, double expect) {
+        count++;
+        if (value != expect)
+            error("test " + count + "\nexpected: 0x" + expect + "\n   found: 0x" + value);
+    }
+
+    void test(long value, long expect) {
+        count++;
+        if (value != expect)
+            error("test " + count + "\nexpected: 0x" + Long.toHexString(expect) + "\n   found: 0x" + Long.toHexString(value));
+    }
+
+    void error(String message) {
+        System.out.println(message);
+        errors++;
+    }
+
+    int count;
+    int errors;
+}
--- a/langtools/test/tools/javac/meth/MakeNegTests.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/meth/MakeNegTests.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/newlines/Newlines.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/newlines/Newlines.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/quid/MakeNegTests.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/quid/MakeNegTests.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/quid/QuotedIdent.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/quid/QuotedIdent.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/quid/QuotedIdent2.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/quid/QuotedIdent2.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/stackmap/T4955930.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/stackmap/T4955930.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/unicode/SupplementaryJavaID6.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javac/unicode/SupplementaryJavaID6.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2004-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/annotations/missing/Main.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2009 Google, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6709246
+ * @summary Class-cast exception when annotation type is missing.
+ * @library ../../lib
+ */
+
+import java.io.IOException;
+import com.sun.javadoc.RootDoc;
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.AnnotationDesc;
+
+public class Main extends Tester.Doclet {
+
+    private static final Tester tester = new Tester("Main", "somepackage");
+
+    public static void main(String... args) throws Exception {
+        tester.run();
+    }
+
+    public static boolean start(RootDoc root) {
+        for (ClassDoc d : root.classes()) {
+            for (AnnotationDesc a : d.annotations()) {
+                System.out.println(a.annotationType());
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/annotations/missing/somepackage/MissingAnnotationClass.java	Wed Jul 05 17:01:15 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2009 Google, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package somepackage;
+
+/**
+ * This class has an annotation which is not available.
+ */
+@NoSuchAnnotation
+public class MissingAnnotationClass {
+}
--- a/langtools/test/tools/javah/6257087/foo.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javah/6257087/foo.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #! /bin/sh -f
 
 #
-# Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2006-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javah/ConstMacroTest.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javah/ConstMacroTest.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javah/MissingParamClassTest.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javah/MissingParamClassTest.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javah/ReadOldClass.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javah/ReadOldClass.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javap/T4975569.java	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javap/T4975569.java	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javap/pathsep.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javap/pathsep.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javap/stackmap/T6271292.sh	Wed Jul 05 17:00:34 2017 +0200
+++ b/langtools/test/tools/javap/stackmap/T6271292.sh	Wed Jul 05 17:01:15 2017 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/make/Defs-internal.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/Defs-internal.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -28,6 +28,23 @@
 # not contain rules.
 #
 
+# Indicate that we are visiting a separate repo or component 
+define MakeStart
+$(PRINTF) "\n\n%s\n%s\n##### %-60.60s #####\n%s\n" \
+"########################################################################" \
+"########################################################################" \
+"Entering $1 for target $2" \
+"########################################################################"
+endef
+
+define MakeFinish
+$(PRINTF) "%s\n##### %-60.60s #####\n%s\n%s\n\n" \
+"########################################################################" \
+"Leaving $1 for target $2" \
+"########################################################################" \
+"########################################################################"
+endef
+
 ifdef OPENJDK
   ifneq ($(OPENJDK),true)
     x:=$(error "OPENJDK (if defined) can only be set to true")
--- a/make/corba-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/corba-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -40,13 +40,17 @@
 corba: corba-build
 corba-build:
 	$(MKDIR) -p $(CORBA_OUTPUTDIR)
+	@$(call MakeStart, corba, all)
 	($(CD) $(CORBA_TOPDIR)/make && \
 	 $(MAKE) $(CORBA_BUILD_ARGUMENTS) all)
+	@$(call MakeFinish, corba, all)
 
 corba-clobber::
 	$(MKDIR) -p $(CORBA_OUTPUTDIR)
+	@$(call MakeStart, corba, clobber)
 	($(CD) $(CORBA_TOPDIR)/make &&  \
 	 $(MAKE) $(CORBA_BUILD_ARGUMENTS) clobber)
+	@$(call MakeFinish, corba, clobber)
 
 .PHONY: corba corba-build corba-clobber 
 
--- a/make/deploy-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/deploy-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -121,14 +121,18 @@
 
 deploy-build:
 ifeq ($(BUILD_DEPLOY), true)
+	@$(call MakeStart, deploy, $(DEPLOY_BUILD_TARGETS))
 	($(CD) $(DEPLOY_TOPDIR)/make && \
-	$(MAKE) $(DEPLOY_BUILD_TARGETS) $(DEPLOY_BUILD_ARGUMENTS))
+	  $(MAKE) $(DEPLOY_BUILD_TARGETS) $(DEPLOY_BUILD_ARGUMENTS))
+	@$(call MakeFinish, deploy, $(DEPLOY_BUILD_TARGETS))
 endif
 
 deploy-clobber::
 ifeq ($(BUILD_DEPLOY), true)
+	@$(call MakeStart, deploy, clobber)
 	($(CD) $(DEPLOY_TOPDIR)/make && \
-	$(MAKE) clobber $(DEPLOY_BUILD_ARGUMENTS))
+	  $(MAKE) clobber $(DEPLOY_BUILD_ARGUMENTS))
+	@$(call MakeFinish, deploy, clobber)
 endif 
 
 deploy-sanity::
--- a/make/hotspot-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/hotspot-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -88,8 +88,10 @@
 hotspot-build::
 	$(MKDIR) -p $(HOTSPOT_OUTPUTDIR)
 	$(MKDIR) -p $(HOTSPOT_EXPORT_PATH)
+	@$(call MakeStart, hotspot, $(HOTSPOT_TARGET))
 	$(CD) $(HOTSPOT_TOPDIR)/make && \
 	    $(MAKE) $(HOTSPOT_BUILD_ARGUMENTS) $(HOTSPOT_TARGET)
+	@$(call MakeFinish, hotspot, $(HOTSPOT_TARGET))
 
 #####################
 # .PHONY
--- a/make/install-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/install-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -57,38 +57,48 @@
 
 install-build:
 ifeq ($(BUILD_INSTALL), true)
+	@$(call MakeStart, install, $(INSTALL_BUILD_TARGETS))
 	($(CD) $(INSTALL_TOPDIR)/make && \
 	  $(MAKE) $(INSTALL_BUILD_TARGETS) $(INSTALL_BUILD_ARGUMENTS))
+	@$(call MakeFinish, install, $(INSTALL_BUILD_TARGETS))
 endif
 
 update-patcher:
 ifeq ($(BUILD_INSTALL), true)
 	if [ -r $(INSTALL_TOPDIR)/make/update/Makefile ]; then \
+	  $(call MakeStart, install update, all); \
 	  ( $(CD) $(INSTALL_TOPDIR)/make/update && \
 	    $(MAKE) all $(INSTALL_BUILD_ARGUMENTS) ); \
+	  $(call MakeFinish, install, all); \
 	fi
 endif
 
 update-patchgen:
 ifeq ($(BUILD_INSTALL), true)
 	if [ -r $(INSTALL_TOPDIR)/make/update/Makefile ]; then \
+	  $(call MakeStart, install update, patchgen); \
 	  ( $(CD) $(INSTALL_TOPDIR)/make/update && \
 	    $(MAKE) patchgen $(INSTALL_BUILD_ARGUMENTS) ); \
+	  $(call MakeFinish, install, patchgen); \
 	fi
 endif
 
 installer:
 ifeq ($(BUILD_INSTALL), true)
 	if [ -r $(INSTALL_TOPDIR)/make/installer/Makefile ]; then \
+	  $(call MakeStart, install installer, all); \
 	  ( $(CD) $(INSTALL_TOPDIR)/make/installer && \
 	    $(MAKE) all $(INSTALL_BUILD_ARGUMENTS) ); \
+	  $(call MakeFinish, install, all); \
 	fi
 endif
 
 install-clobber:
 ifeq ($(BUILD_INSTALL), true)
+	@$(call MakeStart, install, clobber)
 	($(CD) $(INSTALL_TOPDIR)/make && \
 	  $(MAKE) clobber $(INSTALL_BUILD_ARGUMENTS))
+	@$(call MakeFinish, install, clobber)
 endif
 
 install-sanity:: 
--- a/make/jaxp-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/jaxp-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -40,13 +40,17 @@
 jaxp: jaxp-build
 jaxp-build:
 	$(MKDIR) -p $(JAXP_OUTPUTDIR)
+	@$(call MakeStart, jaxp, all)
 	($(CD) $(JAXP_TOPDIR)/make && \
 	 $(MAKE) $(JAXP_BUILD_ARGUMENTS) all)
+	@$(call MakeFinish, jaxp, all)
 
 jaxp-clobber::
 	$(MKDIR) -p $(JAXP_OUTPUTDIR)
+	@$(call MakeStart, jaxp, clobber)
 	($(CD) $(JAXP_TOPDIR)/make &&  \
 	 $(MAKE) $(JAXP_BUILD_ARGUMENTS) clobber)
+	@$(call MakeFinish, jaxp, clobber)
 
 .PHONY: jaxp jaxp-build jaxp-clobber
 
--- a/make/jaxws-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/jaxws-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -40,13 +40,17 @@
 jaxws: jaxws-build
 jaxws-build:
 	$(MKDIR) -p $(JAXWS_OUTPUTDIR)
+	@$(call MakeStart, jaxws, all)
 	($(CD) $(JAXWS_TOPDIR)/make && \
 	 $(MAKE) $(JAXWS_BUILD_ARGUMENTS) all)
+	@$(call MakeFinish, jaxws, all)
 
 jaxws-clobber::
 	$(MKDIR) -p $(JAXWS_OUTPUTDIR)
+	@$(call MakeStart, jaxws, clobber)
 	($(CD) $(JAXWS_TOPDIR)/make &&  \
 	 $(MAKE) $(JAXWS_BUILD_ARGUMENTS) clobber)
+	@$(call MakeFinish, jaxws, clobber)
 
 .PHONY: jaxws jaxws-build jaxws-clobber
 
--- a/make/jdk-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/jdk-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -98,12 +98,16 @@
 
 jdk: jdk-build
 jdk-build:
+	@$(call MakeStart, jdk, $(JDK_BUILD_TARGETS))
 	( $(CD) $(JDK_TOPDIR)/make && \
 	  $(MAKE) $(JDK_BUILD_TARGETS) $(JDK_BUILD_ARGUMENTS) ; )
+	@$(call MakeFinish, jdk, $(JDK_BUILD_TARGETS))
 
 jdk-clobber::
+	@$(call MakeStart, jdk, $(JDK_CLOBBER_TARGETS))
 	( $(CD) $(JDK_TOPDIR)/make && \
 	  $(MAKE) $(JDK_CLOBBER_TARGETS) $(JDK_BUILD_ARGUMENTS) ; )
+	@$(call MakeFinish, jdk, $(JDK_CLOBBER_TARGETS))
 
 jdk-sanity::
 	( $(CD) $(JDK_TOPDIR)/make && \
@@ -111,13 +115,17 @@
 
 compare-images: compare-image
 compare-image:
+	@$(call MakeStart, jdk, compare-image)
 	( $(CD) $(JDK_TOPDIR)/make && \
 	  $(MAKE) ALT_OUTPUTDIR=$(ABS_OUTPUTDIR) compare-image )
+	@$(call MakeFinish, jdk, compare-image)
 
 compare-images-clobber: compare-image-clobber
 compare-image-clobber:
+	@$(call MakeStart, jdk, compare-image-clobber)
 	( $(CD) $(JDK_TOPDIR)/make && \
 	  $(MAKE) ALT_OUTPUTDIR=$(ABS_OUTPUTDIR) compare-image-clobber )
+	@$(call MakeFinish, jdk, compare-image-clobber)
 
 .PHONY: jdk jdk-build jdk-clobber jdk-sanity 
 
--- a/make/langtools-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/langtools-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -35,13 +35,17 @@
 langtools: langtools-build
 langtools-build:
 	$(MKDIR) -p $(LANGTOOLS_OUTPUTDIR)
+	@$(call MakeStart, langtools, all)
 	($(CD) $(LANGTOOLS_TOPDIR)/make && \
-	 $(MAKE) $(LANGTOOLS_BUILD_ARGUMENTS) all)
+	  $(MAKE) $(LANGTOOLS_BUILD_ARGUMENTS) all)
+	@$(call MakeFinish, langtools, all)
 
 langtools-clobber::
 	$(MKDIR) -p $(LANGTOOLS_OUTPUTDIR)
+	@$(call MakeStart, langtools, clobber)
 	($(CD) $(LANGTOOLS_TOPDIR)/make &&  \
-	 $(MAKE) $(LANGTOOLS_BUILD_ARGUMENTS) clobber)
+	  $(MAKE) $(LANGTOOLS_BUILD_ARGUMENTS) clobber)
+	@$(call MakeFinish, langtools, clobber)
 
 .PHONY: langtools langtools-build langtools-clobber
 
--- a/make/sponsors-rules.gmk	Wed Jul 05 17:00:34 2017 +0200
+++ b/make/sponsors-rules.gmk	Wed Jul 05 17:01:15 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2006-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -59,8 +59,10 @@
 sponsors-build:
 ifeq ($(ARCH_DATA_MODEL), 32)
   ifeq ($(BUILD_SPONSORS), true)
+	@$(call MakeStart, sponsors, $(SPONSORS_BUILD_TARGETS))
 	($(CD) $(SPONSORS_TOPDIR)/make && \
-	 $(MAKE) $(SPONSORS_BUILD_TARGETS) $(SPONSORS_BUILD_ARGUMENTS))
+	  $(MAKE) $(SPONSORS_BUILD_TARGETS) $(SPONSORS_BUILD_ARGUMENTS))
+	@$(call MakeFinish, sponsors, $(SPONSORS_BUILD_TARGETS))
   endif
 endif