Skip to content

Commit

Permalink
added JCE implementation of NTRULPRime
Browse files Browse the repository at this point in the history
  • Loading branch information
dghgit committed Aug 16, 2022
1 parent 5ac46c0 commit 83135b0
Show file tree
Hide file tree
Showing 26 changed files with 1,478 additions and 168 deletions.
280 changes: 146 additions & 134 deletions core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ public byte[] extractSecret(byte[] encapsulation)
* hc = SHA-512(2 | encR | cache[0:32])
*/

byte[] hcInput = new byte[encR.length + (privateKey.getHash().length / 2)];
byte[] hcInput = new byte[encR.length + (privateKey.getHash().length)];
System.arraycopy(encR, 0, hcInput, 0, encR.length);
System.arraycopy(privateKey.getHash(), 0, hcInput, encR.length, privateKey.getHash().length / 2);
System.arraycopy(privateKey.getHash(), 0, hcInput, encR.length, privateKey.getHash().length);

byte[] hcPrefix = {2};
byte[] hc = Utils.getHashWithPrefix(hcPrefix, hcInput);
Expand Down Expand Up @@ -167,6 +167,11 @@ public byte[] extractSecret(byte[] encapsulation)
byte[] ssPrefix = {1};
byte[] ssHash = Utils.getHashWithPrefix(ssPrefix, ssInput);

return Arrays.copyOfRange(ssHash, 0, ssHash.length / 2);
return Arrays.copyOfRange(ssHash, 0, params.getSessionKeySize() / 8);
}

public int getInputSize()
{
return privateKey.getParameters().getRoundedPolynomialBytes() + 128 + 32;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recip

byte[] ssPrefix = {1};
byte[] ssHash = Utils.getHashWithPrefix(ssPrefix, ssInput);
byte[] ss = Arrays.copyOfRange(ssHash, 0, ssHash.length / 2);
byte[] ss = Arrays.copyOfRange(ssHash, 0, params.getSessionKeySize() / 8);

return new SecretWithEncapsulationImpl(ss, ct);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.util.Arrays;

public class NTRULPRimeKeyPairGenerator
implements AsymmetricCipherKeyPairGenerator
Expand Down Expand Up @@ -78,7 +79,7 @@ public AsymmetricCipherKeyPair generateKeyPair()
byte[] hash = Utils.getHashWithPrefix(prefix, publicKey.getEncoded());

NTRULPRimePrivateKeyParameters privateKey = new NTRULPRimePrivateKeyParameters(params.getNtrulprParams(), enca, publicKey.getEncoded(),
rho, "SHA-512", hash);
rho, Arrays.copyOfRange(hash, 0, hash.length / 2));

return new AsymmetricCipherKeyPair(publicKey, privateKey);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ public class NTRULPRimeParameters
{
public static final NTRULPRimeParameters ntrulpr653 = new NTRULPRimeParameters("ntrulpr653", 653, 4621, 252, 289,
2175, 113, 2031, 290,
865, 897, 1125);
865, 897, 1125, 16);
public static final NTRULPRimeParameters ntrulpr761 = new NTRULPRimeParameters("ntrulpr761", 761, 4591, 250, 292,
2156, 114, 2007, 287,
1007, 1039, 1294);
1007, 1039, 1294, 16);
public static final NTRULPRimeParameters ntrulpr857 = new NTRULPRimeParameters("ntrulpr857", 857, 5167, 281, 329,
2433, 101, 2265, 324,
1152, 1184, 1463);
1152, 1184, 1463, 16);
public static final NTRULPRimeParameters ntrulpr953 = new NTRULPRimeParameters("ntrulpr953", 953, 6343, 345, 404,
2997, 82, 2798, 400,
1317, 1349, 1652);
1317, 1349, 1652, 24);
public static final NTRULPRimeParameters ntrulpr1013 = new NTRULPRimeParameters("ntrulpr1013", 1013, 7177, 392, 450,
3367, 73, 3143, 449,
1423, 1455, 1773);
1423, 1455, 1773, 24);
public static final NTRULPRimeParameters ntrulpr1277 = new NTRULPRimeParameters("ntrulpr1277", 1277, 7879, 429, 502,
3724, 66, 3469, 496,
1815, 1847, 2231);
1815, 1847, 2231, 32);

private final String name;
private final int p;
Expand All @@ -39,6 +39,7 @@ public class NTRULPRimeParameters
private final int roundedPolynomialBytes;
private final int publicKeyBytes;
private final int privateKeyBytes;
private final int sharedKeyBytes;

/**
* Construct Parameter set and initialize engine
Expand All @@ -56,7 +57,7 @@ public class NTRULPRimeParameters
* @param publicKeyBytes Public Key byte length
* @param privateKeyBytes Private Key byte length
*/
private NTRULPRimeParameters(String name, int p, int q, int w, int delta, int tau0, int tau1, int tau2, int tau3, int roundedPolynomialBytes, int publicKeyBytes, int privateKeyBytes)
private NTRULPRimeParameters(String name, int p, int q, int w, int delta, int tau0, int tau1, int tau2, int tau3, int roundedPolynomialBytes, int publicKeyBytes, int privateKeyBytes, int sharedKeyBytes)
{
this.name = name;
this.p = p;
Expand All @@ -70,6 +71,7 @@ private NTRULPRimeParameters(String name, int p, int q, int w, int delta, int ta
this.roundedPolynomialBytes = roundedPolynomialBytes;
this.publicKeyBytes = publicKeyBytes;
this.privateKeyBytes = privateKeyBytes;
this.sharedKeyBytes = sharedKeyBytes;
}

public String getName()
Expand Down Expand Up @@ -131,4 +133,10 @@ public int getRoundedPolynomialBytes()
{
return roundedPolynomialBytes;
}

public int getSessionKeySize()
{
return sharedKeyBytes * 8;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,35 @@ public class NTRULPRimePrivateKeyParameters
private final byte[] enca;
private final byte[] pk;
private final byte[] rho;
private final String hashAlgorithm;
private final byte[] hash;

public NTRULPRimePrivateKeyParameters(NTRULPRimeParameters params, byte[] enca, byte[] pk, byte[] rho, String hashAlgorithm, byte[] hash)
public NTRULPRimePrivateKeyParameters(NTRULPRimeParameters params, byte[] enca, byte[] pk, byte[] rho, byte[] hash)
{
super(true, params);
this.enca = Arrays.clone(enca);
this.pk = Arrays.clone(pk);
this.rho = Arrays.clone(rho);
this.hashAlgorithm = hashAlgorithm;
this.hash = Arrays.clone(hash);
}

byte[] getEnca()
public byte[] getEnca()
{
return enca;
return Arrays.clone(enca);
}

byte[] getPk()
public byte[] getPk()
{
return pk;
return Arrays.clone(pk);
}

byte[] getRho()
public byte[] getRho()
{
return rho;
return Arrays.clone(rho);
}

String getHashAlgorithm()
public byte[] getHash()
{
return hashAlgorithm;
}

byte[] getHash()
{
return hash;
return Arrays.clone(hash);
}

public byte[] getEncoded()
Expand All @@ -52,7 +45,7 @@ public byte[] getEncoded()
System.arraycopy(enca, 0, key, 0, enca.length);
System.arraycopy(pk, 0, key, enca.length, pk.length);
System.arraycopy(rho, 0, key, enca.length + pk.length, rho.length);
System.arraycopy(hash, 0, key, enca.length + pk.length + rho.length, hash.length / 2);
System.arraycopy(hash, 0, key, enca.length + pk.length + rho.length, hash.length);
return key;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ public class NTRULPRimePublicKeyParameters
private final byte[] seed;
private final byte[] roundEncA;

public NTRULPRimePublicKeyParameters(NTRULPRimeParameters params, byte[] seed, byte[] roundEncA)
public NTRULPRimePublicKeyParameters(NTRULPRimeParameters params, byte[] encoding)
{
super(false, params);
this.seed = Arrays.copyOfRange(encoding, 0, 32);
this.roundEncA = Arrays.copyOfRange(encoding, seed.length, encoding.length);
}

NTRULPRimePublicKeyParameters(NTRULPRimeParameters params, byte[] seed, byte[] roundEncA)
{
super(false, params);
this.seed = Arrays.clone(seed);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.ntru.NTRUParameters;
import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters;
import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters;
import org.bouncycastle.pqc.crypto.picnic.PicnicParameters;
import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.saber.SABERParameters;
Expand Down Expand Up @@ -198,6 +200,18 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_kyber))

return new KyberPrivateKeyParameters(spParams, keyEnc);
}
else if (algOID.on(BCObjectIdentifiers.pqc_kem_ntruprime))
{
ASN1Sequence keyEnc = ASN1Sequence.getInstance(keyInfo.parsePrivateKey());

NTRULPRimeParameters spParams = Utils.ntrulprimeParamsLookup(keyInfo.getPrivateKeyAlgorithm().getAlgorithm());

return new NTRULPRimePrivateKeyParameters(spParams,
ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(),
ASN1OctetString.getInstance(keyEnc.getObjectAt(1)).getOctets(),
ASN1OctetString.getInstance(keyEnc.getObjectAt(2)).getOctets(),
ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets());
}
else if (algOID.equals(BCObjectIdentifiers.dilithium2)
|| algOID.equals(BCObjectIdentifiers.dilithium3) || algOID.equals(BCObjectIdentifiers.dilithium5))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.bouncycastle.pqc.crypto.lms.LMSPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters;
import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.sike.SIKEPrivateKeyParameters;
Expand Down Expand Up @@ -248,6 +249,21 @@ else if (privateKey instanceof KyberPrivateKeyParameters)

return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes);
}
else if (privateKey instanceof NTRULPRimePrivateKeyParameters)
{
NTRULPRimePrivateKeyParameters params = (NTRULPRimePrivateKeyParameters)privateKey;

ASN1EncodableVector v = new ASN1EncodableVector();

v.add(new DEROctetString(params.getEnca()));
v.add(new DEROctetString(params.getPk()));
v.add(new DEROctetString(params.getRho()));
v.add(new DEROctetString(params.getHash()));

AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntrulprimeOidLookup(params.getParameters()));

return new PrivateKeyInfo(algorithmIdentifier, new DERSequence(v), attributes);
}
else if (privateKey instanceof DilithiumPrivateKeyParameters)
{
DilithiumPrivateKeyParameters params = (DilithiumPrivateKeyParameters)privateKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters;
import org.bouncycastle.pqc.crypto.ntru.NTRUParameters;
import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters;
import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters;
import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters;
import org.bouncycastle.pqc.crypto.picnic.PicnicParameters;
import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters;
import org.bouncycastle.pqc.crypto.saber.SABERParameters;
Expand Down Expand Up @@ -135,6 +137,12 @@ public class PublicKeyFactory
converters.put(BCObjectIdentifiers.kyber512, new KyberConverter());
converters.put(BCObjectIdentifiers.kyber768, new KyberConverter());
converters.put(BCObjectIdentifiers.kyber1024, new KyberConverter());
converters.put(BCObjectIdentifiers.ntrulpr653, new NTRULPrimeConverter());
converters.put(BCObjectIdentifiers.ntrulpr761, new NTRULPrimeConverter());
converters.put(BCObjectIdentifiers.ntrulpr857, new NTRULPrimeConverter());
converters.put(BCObjectIdentifiers.ntrulpr953, new NTRULPrimeConverter());
converters.put(BCObjectIdentifiers.ntrulpr1013, new NTRULPrimeConverter());
converters.put(BCObjectIdentifiers.ntrulpr1277, new NTRULPrimeConverter());
converters.put(BCObjectIdentifiers.dilithium2, new DilithiumConverter());
converters.put(BCObjectIdentifiers.dilithium3, new DilithiumConverter());
converters.put(BCObjectIdentifiers.dilithium5, new DilithiumConverter());
Expand Down Expand Up @@ -462,6 +470,20 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
}
}

private static class NTRULPrimeConverter
extends SubjectPublicKeyInfoConverter
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets();

NTRULPRimeParameters ntruLPRimeParams = Utils.ntrulprimeParamsLookup(keyInfo.getAlgorithm().getAlgorithm());

return new NTRULPRimePublicKeyParameters(ntruLPRimeParams, keyEnc);
}
}

private static class DilithiumConverter
extends SubjectPublicKeyInfoConverter
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.bouncycastle.pqc.crypto.lms.LMSPublicKeyParameters;
import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters;
import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters;
import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters;
import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters;
import org.bouncycastle.pqc.crypto.saber.SABERPublicKeyParameters;
import org.bouncycastle.pqc.crypto.sike.SIKEPublicKeyParameters;
Expand Down Expand Up @@ -231,6 +232,15 @@ else if (publicKey instanceof KyberPublicKeyParameters)

return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding));
}
else if (publicKey instanceof NTRULPRimePublicKeyParameters)
{
NTRULPRimePublicKeyParameters params = (NTRULPRimePublicKeyParameters)publicKey;

byte[] encoding = params.getEncoded();
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntrulprimeOidLookup(params.getParameters()));

return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding));
}
else if (publicKey instanceof DilithiumPublicKeyParameters)
{
DilithiumPublicKeyParameters params = (DilithiumPublicKeyParameters)publicKey;
Expand Down
28 changes: 28 additions & 0 deletions core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.bouncycastle.pqc.crypto.falcon.FalconParameters;
import org.bouncycastle.pqc.crypto.frodo.FrodoParameters;
import org.bouncycastle.pqc.crypto.ntru.NTRUParameters;
import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters;
import org.bouncycastle.pqc.crypto.picnic.PicnicParameters;
import org.bouncycastle.pqc.crypto.saber.SABERParameters;
import org.bouncycastle.pqc.crypto.sike.SIKEParameters;
Expand Down Expand Up @@ -72,6 +73,9 @@ class Utils
static final Map kyberOids = new HashMap();
static final Map kyberParams = new HashMap();

static final Map ntruprimeOids = new HashMap();
static final Map ntruprimeParams = new HashMap();

static final Map dilithiumOids = new HashMap();
static final Map dilithiumParams = new HashMap();

Expand Down Expand Up @@ -207,6 +211,20 @@ class Utils
kyberParams.put(BCObjectIdentifiers.kyber768, KyberParameters.kyber768);
kyberParams.put(BCObjectIdentifiers.kyber1024, KyberParameters.kyber1024);

ntruprimeOids.put(NTRULPRimeParameters.ntrulpr653, BCObjectIdentifiers.ntrulpr653);
ntruprimeOids.put(NTRULPRimeParameters.ntrulpr761, BCObjectIdentifiers.ntrulpr761);
ntruprimeOids.put(NTRULPRimeParameters.ntrulpr857, BCObjectIdentifiers.ntrulpr857);
ntruprimeOids.put(NTRULPRimeParameters.ntrulpr953, BCObjectIdentifiers.ntrulpr953);
ntruprimeOids.put(NTRULPRimeParameters.ntrulpr1013, BCObjectIdentifiers.ntrulpr1013);
ntruprimeOids.put(NTRULPRimeParameters.ntrulpr1277, BCObjectIdentifiers.ntrulpr1277);

ntruprimeParams.put(BCObjectIdentifiers.ntrulpr653, NTRULPRimeParameters.ntrulpr653);
ntruprimeParams.put(BCObjectIdentifiers.ntrulpr761, NTRULPRimeParameters.ntrulpr761);
ntruprimeParams.put(BCObjectIdentifiers.ntrulpr857, NTRULPRimeParameters.ntrulpr857);
ntruprimeParams.put(BCObjectIdentifiers.ntrulpr953, NTRULPRimeParameters.ntrulpr953);
ntruprimeParams.put(BCObjectIdentifiers.ntrulpr1013, NTRULPRimeParameters.ntrulpr1013);
ntruprimeParams.put(BCObjectIdentifiers.ntrulpr1277, NTRULPRimeParameters.ntrulpr1277);

dilithiumOids.put(DilithiumParameters.dilithium2, BCObjectIdentifiers.dilithium2);
dilithiumOids.put(DilithiumParameters.dilithium3, BCObjectIdentifiers.dilithium3);
dilithiumOids.put(DilithiumParameters.dilithium5, BCObjectIdentifiers.dilithium5);
Expand Down Expand Up @@ -463,6 +481,16 @@ static KyberParameters kyberParamsLookup(ASN1ObjectIdentifier oid)
return (KyberParameters)kyberParams.get(oid);
}

static ASN1ObjectIdentifier ntrulprimeOidLookup(NTRULPRimeParameters params)
{
return (ASN1ObjectIdentifier)ntruprimeOids.get(params);
}

static NTRULPRimeParameters ntrulprimeParamsLookup(ASN1ObjectIdentifier oid)
{
return (NTRULPRimeParameters)ntruprimeParams.get(oid);
}

static ASN1ObjectIdentifier dilithiumOidLookup(DilithiumParameters params)
{
return (ASN1ObjectIdentifier)dilithiumOids.get(params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public int sharedKeyBytes()
return sharedKeyBytes;
}


/**
* @return {@code sample_iid_bits/8}
*/
Expand Down
Loading

0 comments on commit 83135b0

Please sign in to comment.