use of com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial in project LinLong-Java by zhenwei1108.
the class NTRUEncryptionKeyPairGenerator method generateKeyPair.
/**
* Generates a new encryption key pair.
*
* @return a key pair
*/
public AsymmetricCipherKeyPair generateKeyPair() {
int N = params.N;
int q = params.q;
int df = params.df;
int df1 = params.df1;
int df2 = params.df2;
int df3 = params.df3;
int dg = params.dg;
boolean fastFp = params.fastFp;
boolean sparse = params.sparse;
Polynomial t;
IntegerPolynomial fq;
IntegerPolynomial fp = null;
// choose a random f that is invertible mod 3 and q
while (true) {
IntegerPolynomial f;
// choose random t, calculate f and fp
if (fastFp) {
// if fastFp=true, f is always invertible mod 3
t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3, params.getRandom());
f = t.toIntegerPolynomial();
f.mult(3);
f.coeffs[0] += 1;
} else {
t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df - 1, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3 - 1, params.getRandom());
f = t.toIntegerPolynomial();
fp = f.invertF3();
if (fp == null) {
continue;
}
}
fq = f.invertFq(q);
if (fq == null) {
continue;
}
break;
}
// if fastFp=true, fp=1
if (fastFp) {
fp = new IntegerPolynomial(N);
fp.coeffs[0] = 1;
}
// choose a random g that is invertible mod q
DenseTernaryPolynomial g;
while (true) {
g = DenseTernaryPolynomial.generateRandom(N, dg, dg - 1, params.getRandom());
if (g.invertFq(q) != null) {
break;
}
}
IntegerPolynomial h = g.mult(fq, q);
h.mult3(q);
h.ensurePositive(q);
g.clear();
fq.clear();
NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(h, t, fp, params.getEncryptionParameters());
NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(h, params.getEncryptionParameters());
return new AsymmetricCipherKeyPair(pub, priv);
}
use of com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial in project LinLong-Java by zhenwei1108.
the class NTRUEncryptionPrivateKeyParameters method init.
/**
* Initializes <code>fp</code> from t.
*/
private void init() {
if (params.fastFp) {
fp = new IntegerPolynomial(params.N);
fp.coeffs[0] = 1;
} else {
fp = t.toIntegerPolynomial().invertF3();
}
}
use of com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial in project LinLong-Java by zhenwei1108.
the class NTRUEngine method decrypt.
/**
* @param e
* @param priv_t a polynomial such that if <code>fastFp=true</code>, <code>f=1+3*priv_t</code>;
* otherwise, <code>f=priv_t</code>
* @param priv_fp
* @return an IntegerPolynomial representing the output.
*/
protected IntegerPolynomial decrypt(IntegerPolynomial e, Polynomial priv_t, IntegerPolynomial priv_fp) {
IntegerPolynomial a;
if (params.fastFp) {
a = priv_t.mult(e, params.q);
a.mult(3);
a.add(e);
} else {
a = priv_t.mult(e, params.q);
}
a.center0(params.q);
a.mod3();
IntegerPolynomial c = params.fastFp ? a : new DenseTernaryPolynomial(a).mult(priv_fp, 3);
c.center0(3);
return c;
}
use of com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial in project LinLong-Java by zhenwei1108.
the class NTRUEngine method MGF.
/**
* An implementation of MGF-TP-1 from P1363.1 section 8.4.1.1.
*
* @param seed
* @param N
* @param minCallsR
* @param hashSeed whether to hash the seed
*/
private IntegerPolynomial MGF(byte[] seed, int N, int minCallsR, boolean hashSeed) {
Digest hashAlg = params.hashAlg;
int hashLen = hashAlg.getDigestSize();
byte[] buf = new byte[minCallsR * hashLen];
byte[] Z = hashSeed ? calcHash(hashAlg, seed) : seed;
int counter = 0;
while (counter < minCallsR) {
hashAlg.update(Z, 0, Z.length);
putInt(hashAlg, counter);
byte[] hash = calcHash(hashAlg);
System.arraycopy(hash, 0, buf, counter * hashLen, hashLen);
counter++;
}
IntegerPolynomial i = new IntegerPolynomial(N);
while (true) {
int cur = 0;
for (int index = 0; index != buf.length; index++) {
int O = (int) buf[index] & 0xFF;
if (// 243 = 3^5
O >= 243) {
continue;
}
for (int terIdx = 0; terIdx < 4; terIdx++) {
int rem3 = O % 3;
i.coeffs[cur] = rem3 - 1;
cur++;
if (cur == N) {
return i;
}
O = (O - rem3) / 3;
}
i.coeffs[cur] = O - 1;
cur++;
if (cur == N) {
return i;
}
}
if (cur >= N) {
return i;
}
hashAlg.update(Z, 0, Z.length);
putInt(hashAlg, counter);
byte[] hash = calcHash(hashAlg);
buf = hash;
counter++;
}
}
use of com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial in project LinLong-Java by zhenwei1108.
the class NTRUSigner method signHash.
private byte[] signHash(byte[] msgHash, NTRUSigningPrivateKeyParameters kp) {
int r = 0;
IntegerPolynomial s;
IntegerPolynomial i;
NTRUSigningPublicKeyParameters kPub = kp.getPublicKey();
do {
r++;
if (r > params.signFailTolerance) {
throw new IllegalStateException("Signing failed: too many retries (max=" + params.signFailTolerance + ")");
}
i = createMsgRep(msgHash, r);
s = sign(i, kp);
} while (!verify(i, s, kPub.h));
byte[] rawSig = s.toBinary(params.q);
ByteBuffer sbuf = ByteBuffer.allocate(rawSig.length + 4);
sbuf.put(rawSig);
sbuf.putInt(r);
return sbuf.array();
}
Aggregations