1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8171277 27 * @summary XEC curve operations iterative test vectors 28 * @build Convert 29 * @modules jdk.crypto.ec/sun.security.ec 30 * @run main XECIterative 0 10000 31 * @run main XECIterative 10000 20000 32 * @run main XECIterative 20000 30000 33 * @run main XECIterative 30000 40000 34 * @run main XECIterative 40000 50000 35 * @run main XECIterative 50000 60000 36 * @run main XECIterative 60000 70000 37 * @run main XECIterative 70000 80000 38 * @run main XECIterative 80000 90000 39 * @run main XECIterative 90000 100000 40 */ 41 42 import sun.security.ec.*; 43 44 import java.io.*; 45 import java.util.*; 46 47 /* 48 * This test is derived from the iterative test in RFC 7748. To produce the 49 * test vectors, the implementation ran for 1,000,000 iterations and saved 50 * values of k and u at periodic checkpoints. The RFC includes the correct 51 * value of k after 1,000,000 iterations, and this value was used to ensure 52 * that the test vectors are correct. This test has multiple @run tags so that 53 * no single run taks too long. 54 */ 55 56 public class XECIterative { 57 58 private static class KU { 59 60 public byte[] k; 61 public byte[] u; 62 63 } 64 65 public static void main(String[] args) throws IOException { 66 67 long start = Long.parseLong(args[0]); 68 long end = Long.parseLong(args[1]); 69 70 XECIterative m = new XECIterative(); 71 72 m.runIterativeTest("X25519", start, end); 73 m.runIterativeTest("X448", start, end); 74 75 } 76 77 private void runIterativeTest(String opName, long start, long end) 78 throws IOException { 79 80 XECParameters settings = XECParameters.getByName(opName).get(); 81 XECOperations ops = new XECOperations(settings); 82 83 File vectorFile = new File(System.getProperty("test.src", "."), 84 opName + ".iter"); 85 86 Map<Long, KU> testIters = new HashMap<Long, KU>(); 87 BufferedReader in = new BufferedReader(new FileReader(vectorFile)); 88 String line; 89 while ((line = in.readLine()) != null) { 90 StringTokenizer tok = new StringTokenizer(line, ","); 91 long iter = Long.parseLong(tok.nextToken()); 92 String kOrU = tok.nextToken(); 93 byte[] value = Convert.hexStringToByteArray(tok.nextToken()); 94 KU entry = testIters.get(iter); 95 if (entry == null) { 96 entry = new KU(); 97 testIters.put(iter, entry); 98 } 99 if (kOrU.equals("k")) { 100 entry.k = value; 101 } else { 102 entry.u = value; 103 } 104 } 105 106 KU startEntry = testIters.get(start); 107 byte[] k = startEntry.k.clone(); 108 byte[] u = startEntry.u.clone(); 109 110 for (long i = start; i <= end; i++) { 111 KU curEntry; 112 if (i % 1000 == 0 && (curEntry = testIters.get(i)) != null) { 113 if (!Arrays.equals(k, curEntry.k)) { 114 throw new RuntimeException("At iter " + i + ": expected k: " 115 + Convert.byteArrayToHexString(curEntry.k) 116 + ", computed k: " + Convert.byteArrayToHexString(k)); 117 } 118 if (!Arrays.equals(u, curEntry.u)) { 119 throw new RuntimeException("At iter " + i + ": expected u: " 120 + Convert.byteArrayToHexString(curEntry.u) 121 + ", computed u: " + Convert.byteArrayToHexString(u)); 122 } 123 System.out.println(opName + " checkpoint passed at " + i); 124 } 125 126 byte[] k_copy = Arrays.copyOf(k, k.length); 127 byte[] u_out = ops.encodedPointMultiply(k, u); 128 u = k_copy; 129 k = u_out; 130 } 131 } 132 133 } 134 135