1 package org.bouncycastle.pqc.crypto.util; 2 3 import java.io.IOException; 4 5 import org.bouncycastle.asn1.ASN1Set; 6 import org.bouncycastle.asn1.DEROctetString; 7 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 8 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 9 import org.bouncycastle.crypto.params.AsymmetricKeyParameter; 10 import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; 11 import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; 12 import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; 13 import org.bouncycastle.pqc.crypto.qtesla.QTESLAPrivateKeyParameters; 14 import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPrivateKeyParameters; 15 import org.bouncycastle.util.Pack; 16 17 /** 18 * Factory to create ASN.1 private key info objects from lightweight private keys. 19 */ 20 public class PrivateKeyInfoFactory 21 { PrivateKeyInfoFactory()22 private PrivateKeyInfoFactory() 23 { 24 25 } 26 27 /** 28 * Create a PrivateKeyInfo representation of a private key. 29 * 30 * @param privateKey the key to be encoded into the info object. 31 * @return the appropriate PrivateKeyInfo 32 * @throws java.io.IOException on an error encoding the key 33 */ createPrivateKeyInfo(AsymmetricKeyParameter privateKey)34 public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey) throws IOException 35 { 36 return createPrivateKeyInfo(privateKey, null); 37 } 38 39 /** 40 * Create a PrivateKeyInfo representation of a private key with attributes. 41 * 42 * @param privateKey the key to be encoded into the info object. 43 * @param attributes the set of attributes to be included. 44 * @return the appropriate PrivateKeyInfo 45 * @throws java.io.IOException on an error encoding the key 46 */ createPrivateKeyInfo(AsymmetricKeyParameter privateKey, ASN1Set attributes)47 public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey, ASN1Set attributes) throws IOException 48 { 49 if (privateKey instanceof QTESLAPrivateKeyParameters) 50 { 51 QTESLAPrivateKeyParameters keyParams = (QTESLAPrivateKeyParameters)privateKey; 52 53 AlgorithmIdentifier algorithmIdentifier = Utils.qTeslaLookupAlgID(keyParams.getSecurityCategory()); 54 55 return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(keyParams.getSecret()), attributes); 56 } 57 else if (privateKey instanceof SPHINCSPrivateKeyParameters) 58 { 59 SPHINCSPrivateKeyParameters params = (SPHINCSPrivateKeyParameters)privateKey; 60 AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.sphincs256, 61 new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); 62 63 return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getKeyData())); 64 } 65 else if (privateKey instanceof NHPrivateKeyParameters) 66 { 67 NHPrivateKeyParameters params = (NHPrivateKeyParameters)privateKey; 68 69 AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.newHope); 70 71 short[] privateKeyData = params.getSecData(); 72 73 byte[] octets = new byte[privateKeyData.length * 2]; 74 for (int i = 0; i != privateKeyData.length; i++) 75 { 76 Pack.shortToLittleEndian(privateKeyData[i], octets, i * 2); 77 } 78 79 return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(octets)); 80 } 81 else 82 { 83 throw new IOException("key parameters not recognized"); 84 } 85 } 86 } 87