Path: blob/master/test/jdk/sun/security/ec/ed/EdDSAKeySize.java
41152 views
/*1* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22import static javax.crypto.Cipher.PRIVATE_KEY;23import static javax.crypto.Cipher.PUBLIC_KEY;24import java.security.InvalidKeyException;25import java.security.Key;26import java.security.KeyFactory;27import java.security.KeyPair;28import java.security.KeyPairGenerator;29import java.security.NoSuchAlgorithmException;30import java.security.NoSuchProviderException;31import java.security.SecureRandom;32import java.security.interfaces.EdECPrivateKey;33import java.security.interfaces.EdECPublicKey;34import java.security.spec.PKCS8EncodedKeySpec;35import java.security.spec.X509EncodedKeySpec;36import java.security.spec.EdECPrivateKeySpec;37import java.security.spec.EdECPublicKeySpec;38import java.security.spec.InvalidKeySpecException;39import java.security.spec.NamedParameterSpec;40import java.util.Arrays;41import java.util.HexFormat;4243import jdk.test.lib.Convert;4445/*46* @test47* @bug 820963248* @summary Verify KeyLength for EDDSA, ED25519, ED448.49* @library /test/lib50* @build jdk.test.lib.Convert51* @run main EdDSAKeySize52*/53public class EdDSAKeySize {5455private static final String EDDSA = "EDDSA";56private static final String ED25519 = "ED25519";57private static final String ED448 = "ED448";58private static final String OIDN25519 = "1.3.101.112";59private static final String OID25519 = "OID.1.3.101.112";60private static final String OIDN448 = "1.3.101.113";61private static final String OID448 = "OID.1.3.101.113";62private static final String PROVIDER = "SunEC";63private static final SecureRandom RND = new SecureRandom(new byte[]{0x1});6465public static void main(String[] args) throws Exception {6667for (boolean initWithRandom : new boolean[]{true, false}) {6869// As per rfc8032 the generated keysize for ED25519 is70// 32 octets(256 bits) and ED448 is 57 octets(456 bits).71// Case with default parameter72testKeyAttributes(PROVIDER, EDDSA, initWithRandom, null, 256);73testKeyAttributes(PROVIDER, ED25519, initWithRandom, null, 256);74testKeyAttributes(PROVIDER, ED448, initWithRandom, null, 456);7576// With named parameter77testKeyAttributes(PROVIDER, EDDSA, initWithRandom, ED25519, 256);78testKeyAttributes(PROVIDER, ED25519, initWithRandom, ED25519, 256);79testKeyAttributes(PROVIDER, OIDN25519, initWithRandom, ED25519, 256);80testKeyAttributes(PROVIDER, OID25519, initWithRandom, ED25519, 256);81testKeyAttributes(PROVIDER, ED448, initWithRandom, ED448, 456);82testKeyAttributes(PROVIDER, OIDN448, initWithRandom, ED448, 456);83testKeyAttributes(PROVIDER, OID448, initWithRandom, ED448, 456);8485// With size parameter86testKeyAttributes(PROVIDER, EDDSA, initWithRandom, 255, 256);87testKeyAttributes(PROVIDER, ED25519, initWithRandom, 255, 256);88testKeyAttributes(PROVIDER, OIDN25519, initWithRandom, 255, 256);89testKeyAttributes(PROVIDER, OID25519, initWithRandom, 255, 256);90testKeyAttributes(PROVIDER, ED448, initWithRandom, 448, 456);91testKeyAttributes(PROVIDER, OIDN448, initWithRandom, 448, 456);92testKeyAttributes(PROVIDER, OID448, initWithRandom, 448, 456);93}94}9596/**97* Test standard Key attributes.98*/99private static void testKeyAttributes(String provider, String name,100boolean initWithRandom, Object param, int keySize) throws Exception {101102System.out.printf("Case name: %s, param: %s, Expected keysize: %s, "103+ "Initiate with random: %s%n", name, param, keySize,104initWithRandom);105KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider);106if (initWithRandom) {107if (param instanceof Integer) {108kpg.initialize((Integer) param, RND);109} else if (param instanceof String) {110kpg.initialize(new NamedParameterSpec((String) param), RND);111}112} else {113if (param instanceof Integer) {114kpg.initialize((Integer) param);115} else if (param instanceof String) {116kpg.initialize(new NamedParameterSpec((String) param));117}118}119KeyPair kp = kpg.generateKeyPair();120NamedParameterSpec namedSpec = getNamedParamSpec(name);121122// Verify original PrivateKey with it's different representation123Key[] privs = manipulateKey(provider, name, PRIVATE_KEY,124kp.getPrivate(), namedSpec);125Arrays.stream(privs).forEach(126priv -> testPrivateKey((EdECPrivateKey) kp.getPrivate(),127(EdECPrivateKey) priv, keySize));128129// Verify original PublicKey with it's different representation130Key[] pubs = manipulateKey(provider, name, PUBLIC_KEY,131kp.getPublic(), namedSpec);132Arrays.stream(pubs).forEach(133pub -> testPublicKey((EdECPublicKey) kp.getPublic(),134(EdECPublicKey) pub));135System.out.println("Passed.");136}137138private static NamedParameterSpec getNamedParamSpec(String algo) {139NamedParameterSpec namedSpec = switch (algo) {140case EDDSA141, OIDN25519, OID25519 -> new NamedParameterSpec(ED25519);142case OIDN448143, OID448 -> new NamedParameterSpec(ED448);144default->145new NamedParameterSpec(algo);146};147return namedSpec;148}149150private static Key[] manipulateKey(String provider, String algo, int type,151Key key, NamedParameterSpec namedSpec)152throws NoSuchAlgorithmException, InvalidKeySpecException,153NoSuchProviderException, InvalidKeyException {154155KeyFactory kf = KeyFactory.getInstance(algo, provider);156switch (type) {157case PUBLIC_KEY:158return new Key[]{159kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),160kf.generatePublic(kf.getKeySpec(161key, EdECPublicKeySpec.class)),162kf.generatePublic(new EdECPublicKeySpec(namedSpec,163((EdECPublicKey) key).getPoint())),164kf.translateKey(key)165};166case PRIVATE_KEY:167return new Key[]{168kf.generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())),169kf.generatePrivate(170kf.getKeySpec(key, EdECPrivateKeySpec.class)),171kf.generatePrivate(new EdECPrivateKeySpec(namedSpec,172((EdECPrivateKey) key).getBytes().get())),173kf.translateKey(key)174};175}176throw new RuntimeException("We shouldn't reach here");177}178179/**180* Basic PrivateKey Test cases181*/182private static void testPrivateKey(EdECPrivateKey orig,183EdECPrivateKey generated, int size) {184185equals(orig.getBytes().get().length * 8, size);186equals(generated.getBytes().get().length * 8, size);187equals(orig.getBytes().get(), generated.getBytes().get());188equals(orig.getFormat(), generated.getFormat());189equals(orig.getEncoded(), generated.getEncoded());190equals(((NamedParameterSpec) orig.getParams()).getName(),191((NamedParameterSpec) generated.getParams()).getName());192}193194/**195* Basic PublicKey Test cases196*/197private static void testPublicKey(EdECPublicKey orig,198EdECPublicKey generated) {199200equals(orig.getPoint().getY(), generated.getPoint().getY());201equals(orig.getPoint().isXOdd(), generated.getPoint().isXOdd());202equals(orig.getFormat(), generated.getFormat());203equals(orig.getEncoded(), generated.getEncoded());204equals(((NamedParameterSpec) orig.getParams()).getName(),205((NamedParameterSpec) generated.getParams()).getName());206}207208private static void equals(Object actual, Object expected) {209if (!actual.equals(expected)) {210throw new RuntimeException(String.format("Actual: %s, Expected: %s",211actual, expected));212}213}214215private static void equals(byte[] actual, byte[] expected) {216if (!Arrays.equals(actual, expected)) {217throw new RuntimeException(String.format("Actual array: %s, "218+ "Expected array:%s", HexFormat.of().withUpperCase().formatHex(actual),219HexFormat.of().withUpperCase().formatHex(expected)));220}221}222}223224225