use of com.github.zhenwei.core.pqc.math.linearalgebra.GF2Vector in project LinLong-Java by zhenwei1108.
the class Conversions method encode.
/**
* Encode a number between 0 and (n|t) (binomial coefficient) into a binary vector of length n
* with weight t. The number is given as a byte array. Only the first s bits are used, where s =
* floor[log(n|t)].
*
* @param n integer
* @param t integer
* @param m the message as a byte array
* @return the encoded message as {@link GF2Vector}
*/
public static GF2Vector encode(final int n, final int t, final byte[] m) {
if (n < t) {
throw new IllegalArgumentException("n < t");
}
// compute the binomial c = (n|t)
BigInteger c = IntegerFunctions.binomial(n, t);
// get the number encoded in m
BigInteger i = new BigInteger(1, m);
// compare
if (i.compareTo(c) >= 0) {
throw new IllegalArgumentException("Encoded number too large.");
}
GF2Vector result = new GF2Vector(n);
int nn = n;
int tt = t;
for (int j = 0; j < n; j++) {
c = c.multiply(BigInteger.valueOf(nn - tt)).divide(BigInteger.valueOf(nn));
nn--;
if (c.compareTo(i) <= 0) {
result.setBit(j);
i = i.subtract(c);
tt--;
if (nn == tt) {
c = ONE;
} else {
c = (c.multiply(BigInteger.valueOf(tt + 1))).divide(BigInteger.valueOf(nn - tt));
}
}
}
return result;
}
use of com.github.zhenwei.core.pqc.math.linearalgebra.GF2Vector in project LinLong-Java by zhenwei1108.
the class McElieceCCA2Primitives method encryptionPrimitive.
/**
* The McEliece encryption primitive.
*
* @param pubKey the public key
* @param m the message vector
* @param z the error vector
* @return <tt>m*G + z</tt>
*/
public static GF2Vector encryptionPrimitive(BCMcElieceCCA2PublicKey pubKey, GF2Vector m, GF2Vector z) {
GF2Matrix matrixG = pubKey.getG();
Vector mG = matrixG.leftMultiplyLeftCompactForm(m);
return (GF2Vector) mG.add(z);
}
use of com.github.zhenwei.core.pqc.math.linearalgebra.GF2Vector in project LinLong-Java by zhenwei1108.
the class McElieceCCA2Primitives method encryptionPrimitive.
public static GF2Vector encryptionPrimitive(McElieceCCA2PublicKeyParameters pubKey, GF2Vector m, GF2Vector z) {
GF2Matrix matrixG = pubKey.getG();
Vector mG = matrixG.leftMultiplyLeftCompactForm(m);
return (GF2Vector) mG.add(z);
}
use of com.github.zhenwei.core.pqc.math.linearalgebra.GF2Vector in project LinLong-Java by zhenwei1108.
the class McElieceCCA2Primitives method decryptionPrimitive.
/**
* The McEliece decryption primitive.
*
* @param privKey the private key
* @param c the ciphertext vector <tt>c = m*G + z</tt>
* @return the message vector <tt>m</tt> and the error vector <tt>z</tt>
*/
public static GF2Vector[] decryptionPrimitive(BCMcElieceCCA2PrivateKey privKey, GF2Vector c) {
// obtain values from private key
int k = privKey.getK();
Permutation p = privKey.getP();
GF2mField field = privKey.getField();
PolynomialGF2mSmallM gp = privKey.getGoppaPoly();
GF2Matrix h = privKey.getH();
PolynomialGF2mSmallM[] q = privKey.getQInv();
// compute inverse permutation P^-1
Permutation pInv = p.computeInverse();
// multiply c with permutation P^-1
GF2Vector cPInv = (GF2Vector) c.multiply(pInv);
// compute syndrome of cP^-1
GF2Vector syndVec = (GF2Vector) h.rightMultiply(cPInv);
// decode syndrome
GF2Vector errors = GoppaCode.syndromeDecode(syndVec, field, gp, q);
GF2Vector mG = (GF2Vector) cPInv.add(errors);
// multiply codeword and error vector with P
mG = (GF2Vector) mG.multiply(p);
errors = (GF2Vector) errors.multiply(p);
// extract plaintext vector (last k columns of mG)
GF2Vector m = mG.extractRightVector(k);
// return vectors
return new GF2Vector[] { m, errors };
}
use of com.github.zhenwei.core.pqc.math.linearalgebra.GF2Vector in project LinLong-Java by zhenwei1108.
the class McEliecePointchevalCipher method messageEncrypt.
public byte[] messageEncrypt(byte[] input) {
if (!forEncryption) {
throw new IllegalStateException("cipher initialised for decryption");
}
int kDiv8 = k >> 3;
// generate random r of length k div 8 bytes
byte[] r = new byte[kDiv8];
sr.nextBytes(r);
// generate random vector r' of length k bits
GF2Vector rPrime = new GF2Vector(k, sr);
// convert r' to byte array
byte[] rPrimeBytes = rPrime.getEncoded();
// compute (input||r)
byte[] mr = ByteUtils.concatenate(input, r);
// compute H(input||r)
messDigest.update(mr, 0, mr.length);
byte[] hmr = new byte[messDigest.getDigestSize()];
messDigest.doFinal(hmr, 0);
// convert H(input||r) to error vector z
GF2Vector z = Conversions.encode(n, t, hmr);
// compute c1 = E(rPrime, z)
byte[] c1 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters) key, rPrime, z).getEncoded();
// get PRNG object
DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest());
// seed PRNG with r'
sr0.addSeedMaterial(rPrimeBytes);
// generate random c2
byte[] c2 = new byte[input.length + kDiv8];
sr0.nextBytes(c2);
// XOR with input
for (int i = 0; i < input.length; i++) {
c2[i] ^= input[i];
}
// XOR with r
for (int i = 0; i < kDiv8; i++) {
c2[input.length + i] ^= r[i];
}
// return (c1||c2)
return ByteUtils.concatenate(c1, c2);
}
Aggregations