-rw-r--r-- 3413 mceliece-sage-20221023/encap.sage raw
import encode
import fixedweight
import parameters
def encap_abstract(T,randombits,params):
r'''
Return the output of the abstract Classic McEliece Encap function
on input T
using the specified source of random bits
for the specified parameters.
"Abstract" means that this function does not include encodings
of the inputs and outputs as byte strings.
See encap() for the full function including encodings.
INPUT:
"T" - a matrix with mt rows and k columns
"randombits" - a function that, on input r, returns a list of r bits
"params" - a Classic McEliece parameter set
'''
assert isinstance(params,parameters.parameters)
m = params.m
n = params.n
t = params.t
k = params.k
H = params.H
assert T.nrows() == m*t
assert T.ncols() == k
# "Use FixedWeight to generate a vector e in F_2^n of weight t."
e = fixedweight.fixedweight(randombits,params)
assert len(e) == n
assert sum(1 if ej else 0 for ej in e) == t
if parameters.supportpc:
# for testing against previous versions
if params.pc:
C0 = encode.encode(e,T,params)
C1 = H((2,e))
C = C0,C1
K = H((1,e,C))
return C,K
# "Compute C = Encode(e,T)."
C = encode.encode(e,T,params)
# "Compute K = H(1,e,C)"
K = H((1,e,C))
# "Output ciphertext C and session key K."
return C,K
import byterepr
def encap(T,randombytes,params):
r'''
Return the output of the Classic McEliece Encap function
on input T
using the specified source of random bytes
for the specified parameters.
This is the full function, including encodings
of the inputs and outputs as byte strings.
INPUT:
"T" - a string of bytes representing a public key
"randombytes" - a function that, on input r, returns an r-byte string
"params" - a Classic McEliece parameter set
'''
assert isinstance(params,parameters.parameters)
try:
T = byterepr.to_publickey(T,params)
except ValueError:
# "Narrowly Decoded Classic McEliece rejects inputs
# (ciphertexts and public keys) where padding bits are nonzero;
# rejection means returning False."
return False
randombits = byterepr.randombits_from_randombytes(randombytes)
C,K = encap_abstract(T,randombits,params)
return byterepr.from_ciphertext(C,params),byterepr.from_sessionkey(K,params)
# ----- miscellaneous tests
def test1():
import os
import keygen
def randombits(r):
return [randrange(2) for j in range(r)]
def randombytes(r):
return os.urandom(r)
for system in parameters.alltests:
P = parameters.parameters(system,allowtestparams=True)
n = P.n
m = P.m
t = P.t
l = P.l
print('encap_abstract %s' % system)
sys.stdout.flush()
T,privatekey = keygen.keygen_abstract(randombits,P)
C,K = encap_abstract(T,randombits,P)
if parameters.supportpc and P.pc:
# for testing against previous versions
C0,C1 = C
assert len(C0) == m*t
assert len(C1) == l
else:
assert len(C) == m*t
assert len(K) == l
print('encap %s' % system)
sys.stdout.flush()
T,privatekey = keygen.keygen(randombytes,P)
C,K = encap(T,randombytes,P)
if parameters.supportpc and P.pc:
# for testing against previous versions
assert len(C) == ceil(m*t/8)+ceil(l/8)
else:
assert len(C) == ceil(m*t/8)
assert len(K) == ceil(l/8)
if __name__ == '__main__':
test1()