-rw-r--r-- 3096 mceliece-sage-20221023/decap.sage raw
import decode
import parameters
def decap_abstract(C,priv,params):
r'''
Return the output of the abstract Classic McEliece Decap function
on input (C,priv)
for the specified parameters.
"Abstract" means that this function does not include encodings
of the inputs and outputs as byte strings.
See decap() for the full function including encodings.
INPUT:
"C" - a ciphertext
"priv" - a private key returned by keygen.keygen()
"params" - a Classic McEliece parameter set
'''
assert isinstance(params,parameters.parameters)
m = params.m
n = params.n
t = params.t
H = params.H
# "Extract s in F_2^n and Gammaprime = (G,alpha'_0,alpha'_1,...,alpha'_{n-1}) from the private key."
delta,c,g,alpha,s = priv
alphaprime = alpha[:n]
Gammaprime = tuple([g]+alphaprime)
if parameters.supportpc:
# for testing against previous versions
if params.pc:
C0,C1 = C
C0 = list(C0)
C1 = list(C1)
e = decode.decode(C0,Gammaprime,params)
if e == False: return H((0,s,C))
C1prime = H((2,e))
if C1prime != C1: return H((0,s,C))
return H((1,e,C))
# "takes as input a ciphertext C"
C = list(C)
assert len(C) == m*t
# "Set b <- 1."
b = 1
# "Compute e <- Decode(C,Gammaprime)."
e = decode.decode(C,Gammaprime,params)
# "If e = False, set e <- s and b <- 0."
if e == False:
e = s
b = 0
# "Compute K = H(b,e,C)"
K = H((b,e,C))
# "Output session key K."
return K
import byterepr
def decap(C,priv,params):
r'''
Return the output of the Classic McEliece Decap function
on input (C,priv)
for the specified parameters.
This is the full function, including encodings
of the inputs and outputs as byte strings.
INPUT:
"C" - a byte string that represents a ciphertext
"priv" - a byte string that represents a private key
"params" - a Classic McEliece parameter set
'''
assert isinstance(params,parameters.parameters)
try:
C = byterepr.to_ciphertext(C,params)
except ValueError:
# "Narrowly Decoded Classic McEliece rejects inputs
# (ciphertexts and public keys) where padding bits are nonzero;
# rejection means returning False."
return False
priv = byterepr.to_privatekey(priv,params)
K = decap_abstract(C,priv,params)
return byterepr.from_sessionkey(K,params)
# ----- miscellaneous tests
def test1():
import keygen
import encap
import os
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)
print('decap_abstract %s' % system)
sys.stdout.flush()
T,priv = keygen.keygen_abstract(randombits,P)
C,K = encap.encap_abstract(T,randombits,P)
assert decap_abstract(C,priv,P) == K
print('decap %s' % system)
sys.stdout.flush()
T,priv = keygen.keygen(randombytes,P)
C,K = encap.encap(T,randombytes,P)
assert decap(C,priv,P) == K
# not tested here: decap on invalid ciphertexts
if __name__ == '__main__':
test1()