def gen_xi_leech_to_short(x1): """Convert Leech lattice to short vector encoding. Both, Leech lattice and short vector encoding of a short vector in Q_x are decribed in the header of this module. The function returns the short vector encoding of element x1 given in Leech lattice encoding. The function returns 0 if the vector x1 is not short. """ sign = (x1 >> 24) & 1 x1 ^= Mat24.ploop_theta(x1 >> 12) gcodev = Mat24.gcode_to_vect(x1 >> 12) cocodev = Mat24.cocode_syndrome(x1, min(23, Mat24.lsbit24(gcodev)) ) w = Mat24.gcode_weight(x1 >> 12) if x1 & 0x800: if (Mat24.bw24(cocodev) > 1 or Mat24.scalar_prod(x1 >> 12, x1) != (w & 1)): return 0 y = Mat24.lsbit24(cocodev) code = (x1 & 0x7ff000) >> 7 | y box = 4 + (code >> 15) code &= 0x7fff else: if w == 3: return 0 elif w in [2,4]: if w == 4: gcodev ^= 0xffffff x1 ^= 0x800000 w_bad = (Mat24.bw24(cocodev) ^ 2 ^ w) & 3 if w_bad or (cocodev & gcodev) != cocodev: return 0 c = Mat24.extract_b24(cocodev, gcodev) if (c & 0x80): c ^= 0xff y1 = Mat24.gcode_to_octad(x1 >> 12) code = (y1 << 6) | (c >> 1) if code >= 24000: # this is (15 + 360) * 64 code -= 24000 box = 3 elif code >= 960: # this is 15 * 64 code -= 960 box = 2 else: code += 1536 box = 1 else: y1 = Mat24.lsbit24(cocodev) cocodev ^= 1 << y1 y2 = Mat24.lsbit24(cocodev) if cocodev != (1 << y2) or y1 >= 24: return 0 code = 384 * (w & 2) + 32 * y2 + y1 box = 1 return (box << 16) | (sign << 15) | code
def gen_xi_short_to_leech(x1): """Convert short vector to Leech lattice encoding. Both, Leech lattice and short vector encoding of a short vector in Q_x are decribed in the header of this module. The function returns the Leech lattice encoding of element x1 given in short vector encoding. The function returns 0 for an illegal input x1. """ box, sign, code = x1 >> 16, (x1 >> 15) & 1, x1 & 0x7fff octad = 0xffff if box == 1: if code < 1536: # this is 2 * 24 * 32 gcode = code >= 768 if gcode: code -= 768 gcode <<= 11 i, j = code >> 5, code & 31 cocode = Mat24.vect_to_cocode((1 << i) ^ (1 << j)) if cocode == 0 or cocode & 0x800: return 0 elif code < 2496: # this is 2 * 24 * 32 + 15 * 64 octad = code - 1536 else: return 0 elif box == 2: if code >= 23040: # this is 360 * 64 return 0 octad = code + 960 # this is 15 * 64 elif box == 3: if code >= 24576: # this is 384 * 64 return 0 octad = code + 24000 # this is (15 + 360) * 64 elif box < 6: code += (box - 4) << 15 cocode = Mat24.vect_to_cocode(1 << (x1 & 31)) if cocode == 0: return 0 gcode = (code >> 5) & 0x7ff w = Mat24.gcode_weight(gcode) ^ Mat24.scalar_prod(gcode, cocode) gcode ^= (w & 1) << 11 else: return 0 if octad < 48756: # this is 759 * 64 cc = octad & 0x3f w = Mat24.bw24(cc) cc = (cc << 1) ^ (w & 1) w += w & 1 gcode = Mat24.octad_to_gcode(octad >> 6) gcodev = Mat24.gcode_to_vect(gcode) cocode = Mat24.vect_to_cocode(Mat24.spread_b24(cc, gcodev)) gcode ^= ((w >> 1) & 1) << 11 cocode ^= Mat24.ploop_theta(gcode) return (sign << 24) | (gcode << 12) | cocode