Open in with one click!
class NTRUPrime(object): def __init__(self, p = 739, q = 9829 ): # The Ring R. Zx.<x> = ZZ[ ] self.Zx = Zx # The Field R/q. Fq = GF( q ) # Galois Field of GF(q). Fqx.<xp> = Fq[ ] Rq.<xqp> = Fqx.quotient( x ^ p - x - 1 ) self.Rq = Rq def decapsulate( self, ciphertext, key_private ): Zx = self.Zx # The Ring R. Rq = self.Rq # The Field R/q. # # NOTE: I have excluded the derivation of the following int list, but can re-add it if helpful # int_representation_of_key_private = [1, 0, 1, 2, 1, 0, 2, 2, 0, 0, 0, 2, 2, 1, 1, 1, 2, 0, 0, 1, 2, 0, 1, 2, 1, -1, 1, 2, 2, 0, 1, 1, 2, 2, 1, 1, 2, -1, -1, 0, -1, 2, 0, 2, 2, 1, 2, 0, 0, 1, -1, 1, 1, -1, 2, 2, 2, -1, -1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 2, -1, 2, -1, 2, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 0, 2, 2, -1, -1, -1, 2, 0, 1, 1, 2, -1, 1, 2, 1, 2, -1, 1, 0, 2, -1, 1, 0, 0, -1, 1, -1, 0, 0, 1, -1, 1, -1, 1, -1, 1, 0, 2, -1, -1, 1, 0, 0, 0, 2, 0, 2, 1, 0, 1, -1, 2, -1, 1, -1, 2, 2, 1, 0, 2, -1, -1, 2, 1, -1, 2, 1, 2, -1, -1, 0, 0, 0, -1, 2, 1, -1, 0, -1, 1, -1, -1, 1, 0, 0, 1, -1, 0, 1, 1, 1, 0, -1, -1, 1, 2, 1, 1, 0, 1, 0, -1, 0, 0, 0, 1, 0, 0, 1, -1, 1, 2, 0, 0, 1, 2, 2, 2, -1, 2, 0, 0, 1, 1, 1, 2, -1, 1, 0, 2, 0, 0, 1, -1, 2, 1, 1, 2, 1, 1, 0, 2, 1, 1, 1, -1, -1, 2, -1, -1, 1, 2, -1, 1, 0, 0, 1, 0, 1, 1, 2, 0, 2, 1, 1, 0, 1, 0, -1, -1, 2, 2, 2, 0, 0, 0, 2, 0, 2, -1, 0, 1, -1, 2, 1, -1, -1, 0, 2, 0, 1, 0, 2, 1, -1, 2, 1, 1, 0, 0, 2, -1, 1, 2, 2, 2, 2, -1, 1, 0, 0, 1, 1, -1, -1, 0, -1, -1, 2, -1, 1, 0, 2, 2, -1, 1, 2, -1, 0, 0, 2, 0, -1, 1, -1, 0, 0, 0, 2, 2, 1, 1, -1, -1, 1, 2, 2, 1, 0, 2, 0, 1, 0, 1, 1, -1, 0, 1, 2, 0, 0, -1, 0, 1, -1, 1, 2, 1, 2, -1, -1, 1, 2, -1, -1, 2, 0, -1, -1, 2, -1, 2, 1, 0, 0, 1, 2, 2, 2, -1, 2, 0, 0, 0, 2, -1, 2, -1, -1, 1, 2, 2, 1, 1, 1, 0, 0, -1, -1, 2, 0, -1, 2, 2, 1, 1, -1, 1, 1, 1, -1, 2, -1, 1, -1, 2, 1, 1, 1, 1, 2, -1, -1, -1, -1, 1, -1, 1, 1, 0, 2, 2, 0, 2, 2, 0, 2, 1, -1, 0, 1, 1, 2, 1, 0, -1, 1, 0, -1, -1, -1, -1, -1, -1, 2, 2, 0, -1, 2, 2, -1, 1, 1, -1, 0, 1, -1, 0, 2, 0, 1, 2, 0, 1, 2, -1, 0, 2, 1, 0, 1, 1, 1, -1, -1, 1, 0, 1, -1, 2, 1, 0, -1, 1, 1, 2, -1, -1, 2, 1, 1, -1, 1, 0, 2, 0, -1, -1, -1, 0, -1, 0, -1, 1, 2, 2, 1, 0, 0, 1, 0, 0, 0, 2, 1, 0, -1, 1, 2, -1, 2, 1, 0, 0, -1, 1, 0, 2, -1, 0, 2, 1, 0, -1, 2, 0, -1, 0, -1, 1, 1, 1, -1, 0, -1, 1, -1, 0, 0, -1, -1, 2, 0, 0, 2, -1, 2, 0, 2, 1, 1, 0, 0, 1, 0, 0, 2, 0, 2, 1, -1, 0, 2, 1, 2, 1, 1, 1, 1, -1, 1, 0, 0, 0, -1, 0, 1, 1, 0, -1, 1, 2, 2, -1, 2, 0, 0, 2, 0, 2, 0, 0, 1, 0, 1, 2, 2, 0, -1, 1, 0, -1, -1, 1, 2, -1, -1, 2, 1, 0, 0, 2, 1, 0, 2, 2, -1, 0, 1, 1, 2, 0, 2, -1, -1, 1, 0, 1, 2, 1, 0, 0, 1, -1, 1, -1, 1, 2, 0, -1, 1, 1, 0, -1, 2, 0, 2, 0, 0, -1, 1, -1, -1, 1, 1, -1, -1, 2, 1, 1, -1, 0, -1, 1, 1, -1, 0, 1, 0, 2, 1, 0, 2, 1, 2, -1, 2, 0, 2, 1, 1, 0, -1, 0, -1, -1, -1, 0, 0, 1, -1, 1, -1, 0, -1, 2, 2, -1, 2, 2, 1, 2, 2, 1, 1, 2, 2, -1, 2, 2, 1, 0, 1, 1, 1, -1, 0, 0, 2, 0, 1, -1, 1, 1] h = Zx( int_representation_of_key_private ) # (Old comment that may or may not be helpful:) Decode our ciphertext, obtaining c as an element of Ring R. # # NOTE: I have _also_ excluded the derivation of the following int list, but can re-add it if helpful # int_list_derived_from_ciphertext = [0, 1, -1, 1, -1, -1, -1, 0, 0, 1, 0, 0, 0, -1, 0, -1, 1, 0, -1, 1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 1, 1, 1, -1, -1, 0, 1, 1, 0, 0, 0, 0, 0, -1, 1, 0, 1, -1, 1, 0, 0, 1, -1, 0, -1, 0, 0, -1, 1, 0, 1, 0, 1, 1, 1, -1, 0, 0, 0, 0, -1, 0, 0, 1, 0, -1, -1, 0, 0, -1, 0, 1, 0, 1, -1, -1, 0, -1, 0, 0, 0, -1, 0, -1, -1, 0, 0, -1, 1, -1, 1, -1, 0, 1, 0, -1, -1, 0, 0, -1, 0, 0, 1, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, -1, 0, -1, 1, 0, 0, -1, 0, 1, 0, 1, 0, -1, -1, 1, -1, 0, -1, -1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, -1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 1, -1, 1, -1, 1, 0, 1, -1, -1, -1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 1, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 1, 1, 0, -1, -1, -1, 1, 0, 0, 1, -1, -1, -1, 0, 1, -1, 0, 1, 0, 0, 1, 0, 1, -1, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, -1, 1, 0, 0, -1, 1, -1, 0, 0, 1, 0, 1, 1, -1, 1, 0, 0, -1, -1, -1, 0, 1, 0, -1, 0, -1, 0, -1, 0, 0, 0, -1, 1, -1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, -1, -1, 0, 0, 0, 0, -1, 1, 1, 1, 0, 1, 0, 0, 0, 0, -1, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, -1, -1, 1, 0, -1, 0, 0, -1, 1, -1, 0, 1, 1, 0, 1, -1, -1, -1, 0, 1, -1, 1, -1, -1, 0, 1, -1, -1, -1, 0, 0, 1, 0, 0, 0, 1, 1, -1, -1, 1, -1, 0, 1, -1, -1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, -1, 1, 0, 1, 1, 1, 1, 1, -1, 0, -1, 1, 0, 1, 0, 0, 0, -1, -1, 1, 1, -1, -1, 0, -1, -1, -1, 0, 0, -1, 0, 1, 0, -1, 1, -1, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, -1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, -1, 1, -1, 1, 0, 1, 0, -1, 0, 1, 0, -1, 0, -1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, -1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, -1, -1, 0, 0, 1, 1, -1, 1, 1, 1, 1, 0, 1, 0, 0, -1, 0, -1, -1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, -1, -1, 1, 0, 0, 0, -1, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 0, 0, 1, -1, 1, 1, -1, 1, 0, -1, 0, 1, 1, 0, 0, 1, -1, -1, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, -1, 1, 0, 0, 1, -1, -1, 0, 1, 1, 0, 1, 0, -1, 0, 1, -1, 1, 0, -1, -1, -1, 0, 0, 1, -1, -1, 0, 1, 0, -1, -1, 0, 1, 1, 1, -1, -1, 1, 0, 1, 1, 1, 0, 1, -1, 0, 0, 1, 1, 0, 0, 1, 1, -1, 0, 0, -1, 0, 1, 1, 0, 0, -1, -1, -1, 1, -1, 1, -1, 1, 0, -1, -1, 0, -1, 0, 1, 1, 0, 1, 1, 0, -1, -1, 0, 0, 1, 0, 0, -1, -1, -1, 1, 0, 0, 0, 1, 0, 0, 0, -1, 1, 1, 0, 0, 1, 0, 0, 0, -1, 1, -1, 1, 1, 1, -1, -1, 0, 1, -1, 0, -1, 0, 1, -1, 1, 0, -1, 0, -1, 1, 0] r = Zx( int_list_derived_from_ciphertext ) # (Old comment that may or may not be helpful:) Compute c', C', and K' from r' as in encapsulation. # # NOTE: This is the line that throws the "unsupported operand parent(s) for '*'" exception # # FIX will be Rq(h) * Rq(r) #hr = h * Rq( r ) hr = Rq(h) * Rq( r) def test( self ): ciphertext = '\xe4u\x88\xfb\xf5\x19\xefE\xf1\x7f\xad\x1fCc\xbb\xff\xc7J\xa4\xab\xf0\xcb2\xcc\x82\xe2%\xfc\xe1\x9a\xe5\xd4"\xbaT=\xd0=\xab"\x8c\x0e;\x98\x07I:,\x01s5\x9b\x96\x85\xf5\\\xa2\x17\x97~\x18`\xe3C;\xea)\xc3_IR\xbeJw\xf0BV\xb8%4\xeeS>\x94d_G\xdb6\xec#\x07F\xeb_\xd14\x8b}F\x1d\xd3YKe\xf0\xb4n\[email protected]\r&\x85Q\xba#\t\x88C\xb3M\xb3F(\xdca\x99e\xc3J8\x17\xd6\xab(~\xb44\xcb)<\xac\xe2\x83\xe3k\x8c\xba\xd0FQS+\x16l\xc8\xa2\x9b\x9c>\x91\x1b\xef\xe6\xa3\xee\x9a3$\x94#e\xe4\xbf\xea\xa5i\x18\x92\x07\xa2F\x1aF\xd3\x90t\xc0\x91N\x0b\x93{\[email protected]\xb1n|\xbbse\xc0UXj\xb3\xd3d\xc1\xe2!\x0f\xf4\x19\\\x8a\x10\xec\xe1\x05\xb5\x83\x0c\x1cU\xb4\xc5\x06/\x84P^tr\xa1o\x9a\xa5\xfaZ\x90U9;\xbe\xbc\x85UU}\xbc&9\x80\xf3\xc3\xab![{G\xc7\x12\xc5E\x7f\xe7\xa5\xf8\x8ba\x98[\xc5\xfdBR\xf5\xd8Z\x0c\xf9\xbc\xf9\xfb\x8e\r\xd0C7P6]\t\x9e\xe3\xa8M\r\x10,\x1e\x06\xa6\x13\x97<e\x01>\xc8b)z\xf4\x13\xc0i\x92Y\xf4\x1fs\x17\xaa\xc1\xd4DD\x85<`\xc6\xc9\xf4\x07\x92\xbeu^i|\xbc\xbd\xfc\x1e\xb6fP\xc3\x032J\xc1w\xca\xc3\xa5sj3\x05\xe9`X)#\x06\xe5\xab\x8a\xf4\x93\xfe\xa4g\xd9\x19\x0e\xcb\x94\x8d\x90\x05`z\x0c\x11\xe8\x87\xcb\xe2\xbbe,\xa6)\xa9\xd9m$\xd5\xba\x11i\xb4\'|[[h\x184"8\x9a\'>\xa6l7"\x01\[email protected]\xa6\'2\xa9T8\xc1?\x11,\xa4\xab\x18B\x12t\xd6\x86\x87J\xe8\x13^3b\x8c\xfba[\xcc\xa8~q+$%n,Fh\xc2;"E8\x86\\\x86.\xe4180\x89Q\xac\xe7\x1f\xaf"3=\xf2p+\xb7{\xf2A\'x\x18T\xee\xeb\xc9,&?-\xa4\xba\x8ce\x9d\x9d\x07\x11(j\xc3\x99\xc3GL\x818\x9f \x03=\xc7\t\x95\x839\x07\xfaP\xa5\x19hC\xc6\xb6k\x93\x90c\xcb\x95]\x1a=Y\xc9\x1264\x11s\xfc\xbb.\x14R\x9fK]\xc0dfi\xa0\x13\x15\xc5%\x88F\x11\xeb\xb3\x19\xd4\x97"\xdbq}`Q\nE\x16x)\xcbznz8v[\xb5\x87\xea[\x1a\xfa\xc5\x14\xb7\xb00\x04\x1b\x81\xb0\xbf\x17\xe7\x85\x0c\xdb\x82\x8fV\xa2\xc8B\x8a\x968\xbc\x0e\x85*\xfa\xd9vo\x12\xc3!\xfbc\xd6\xd3\x16\x8e\xe6`\x00HV9\x19q?*@~\x94n\x1e\x01\xcc\xbc\xe4\x9e\xcf\xaap\xc6\x00!\x82\x00X!s\xb8\x9e\xe0\xbfIP\x08\xd7J\x84\x10\xc1RS\xe7\xa9p\xd5\x02\xee2\x85\xc9{\x82vy\xb8s\xb1\x83\x8d|\xa8\x0b\xf6*\x14I\x19\xd2tP\xba\x88\x11E v2yP\x8eF\x94#\x04HmZ|\xe4\xd66\n\xc8c\xa3\xf1|\xbd\xc5\xc5\xf0\x8b7\xcb\x99\x96\x98\x98\xcaj(\xbc\x8b<\x08\x8f\xda\x86\xd5\xe4I;\x06\x96Iy`\x03C\xba\xd3\xfa\xaaK\xcai\x18\xb8J\xeasR\x11*2\xe7\xf4V;\xf9\x19\x9c\xc6\x01\x8b"\x84\xe9I\x88\xca\xa4\xa5\xaf\x06I\xb6"\xa7\x04\xfb\x88\xf2\x96\t\x14\x1aY\x9d\xd2)\x9a\xc8pvS\xbe\xc9\xd5]1\x99I\xa7dW\x0b\x9au\xab\[email protected]\xb8.\xc01\x97\xb6\xb5O\xf4\x9bG\x0eBLy|\x9c\x00X\x81\xcc\xf2\xc3\x8bV\xc8\x85\xa7r\x91\x93[wR_\xc4\xf1-\x94\xd3\x86\xc2`\xa9\x17JC\x83\x8b\xb4/\xb1<\x11\x99\x9e\x81\xf8\x95\x99\x0b\xcb\xaf\x0bg\t\x02\xacVp\[email protected]\x9f\xde\xba\xc8\xb6\xc3VQ%H2CN\xec9J\x05\xf9\xac\x1e\xa2\x9c0\x901\xf5\xc6\x8f\xbb\xb0\xc6H\x10i2Z\x8e!s\x88\x82\[email protected]\xe6J\xa0:\x92u\xd2\xb2\xca\xb9"\xac\x8b\x84\x16xMXY^\xb8bJ<\x08\x97pRs7\xe8\x18rE\x05_b\x12\x93\xe8\xb6\x88\xbc\xbe\xbfxo\xdfg\x9cN\xc6CM\xbaGK\xd1\[email protected]\x05\x82\xc6\')\xa67\x1f\xc7<\'\xa8\x8b\x8b\xfcD\xb1\xf5t\xf4(\xb8\xcd\xd6\x14\xd1\x92\xab\xcb\xb2\xc8|\xf0\xc6y\xa4\xca\xf3\xd9\xa0:wO\xcf3i\x05\x13:\x9bY\xb5\\KS\x8b\xf1\x18\'\xd9S\x04K1\xc1\xf9z\xce\xfa\x9d\xc6P9\x8a\xcaW\xcc\xab\xaa<\xc3\xb6\x02\x94\x03\x8a\xd3T]\x96\x90\x96Ue\xa8\x91}\xae\t' key_private = '\xe6\xf6\xd5\xab\x97\xe7\xe2\xa7\xafC\xdc{\x89\xf2\x83\xbfU\xcd\\i\xa9\xf7\xc0\xe9\xb8cc!%"6X\xdd&#o\xc3\xb2C\xc5\x12\x82%\xa9\x81kFe\x89\x97?\x97:v\xc9\xba\xb6\n\x83c\x99\xde\x9a\xc1_\xdd$\x0b\x9d-k\x8d\xffX\n\xc1\xd8\xe3\xd4!\xd5+\xf8v\xa6\xe4E\xe2\x0e\x0e\x07\xb3\xe5\xcf\xd5\x0c\xbeZp\xbc\xa22\xb2\xea\x00\xa2}\xdf\x92n\x18\x00|<J\xd2yN\x9b\n&\x1b:\xac\xd8\x01\x11\xbee\xb5\xe1la\xd3\xc6\x11*!\x05\xd7\xdcZ\xd6-\xed\xaaX\x91\x86\xcfu\x97\xf9a\xe0\xb0\xb5=\xe9\r\xe6\x96\x88\x87\xc6]\x08\n+\xa1d\xdb\xce\xad\x11P"\xf1\xbc\xaf\xcf\x9bJ\x9d\xe8\x03+\x13\xa04\x0c\xe0#\xf0P\xfbR\xfbb\xb7\xc3\xe3\x92R\x05\xa08\xb9\xb5\xd9\xea\x0cz\'v\x1f\xf4\xf5\x0fj\xf0\n\x1e\xdf\xde\xf7S\xbaD\x980\x00i\xdf\xebEm\tU\x93\xc8\xe2\xbe\xfcx\xed\xb1\xd7\xef\xae\x8b{c\x93\xdfo\xab\x08\x0b6\xe7\xdb\xbbV\x175A\xd5\x0c\xe1\x11J\x07\x13\xab\xba\xd5\xb0\x80Vx\xe4Q\xf7k\xfcH\xd7\x05\xbf\xf5,\xff\tUq\x88Ndxi\x9dz<\xdc-L\x01\xd4\x7f\xc6~+v\xbc\xda\x9b3\xf8^\xf5i?\xd5\x0e\xc3%9\xb2\xa6T\x01\xb6\xf5d\xb1\xcbs\xa6i|\xbb\x18\x1bB\xb5r\x04\xa4\xbe2\x19\xd7\nF>\xaf!e\x880\xc7\xaf\x86\x8f\xd0\xf3\xa8\x98q\xce\xc8\x01#\t8)z\x8b\xb0\x96\xf7c\x94"\x16$`|<\xc6\x80\xf9\xf2\xd1\xca\xe7\xa1\xb7B\x0e?\n\xd6s\x9d\x04\xa2\x0f7\\\xceMCf&\xa7\xf3_\xd4\xe6\x8b\xd4C\xa2\x08\x99\xc2\xe9\xc6\x8c\xf05B`d\n^\xb6\xb3(\xc3\t7\x9f\x0b\xf4.\xb2h-Q\xb6ax*%\\!\xe3\x0e4\x0c\xd0\xa3\xa8\xa1\'\x16_\xb8\x10\'r8\xbd\xf0=\xef\xe2P\xd6\x8c\xdf\'p\x10\x113\x7f<b\x0f\x00\xcb\x0ex\x99%F\xdb\xd8s\x05\x1e\xae\xcc\x97QYv\x84\xfe\x88\xa8\xb0?\xed\xd1\x0c\x07\xb5\xee\xa1\xd5\x13\x14\xd3\xa4\xb5\xce\xe9\x86j\xc8q\xb2\xdc\xae\xcdk(\x05J\xa3,i\xc7\xcda\x82\xba\'\x98b\xea\x92-\xd7-OX\xe1y\xc6\xa5\x163\xc5y\xf6\xa7\x15\x9cJ\x17G\x9f\x8d\x86\xa89\x0e\xfeF\xda\xd1r\xd1\x8ca\x1a\xd0\x84\xa77\xb3\xc1\x1f\xdfF\x8c\x80\xe2S\x92\xc0\xb8\x82/8\x0fZK\x06\xa4\x95\xb8\xc1\ns\xbeo\x85q\x1b\xa2\x87\xb0\xbd\xee\xb8\x99\xa5oB\xa6\xd2\xb1\\\xf4?\xb8k\x11\xb9\t\xaa\xde\xe2\xe7\x83\xa5br\xb0g=QUiD}\x8b\xd7R\x02\xb0\xe4\xb1h\xda\x82n3\x9c\xec2E\xa3\x82}\xf0\xc7`\x7f\x95\xf6`Z\xff\x1e\x85b\x92\xc1\xcfs\xa0\x99\xbbl\xefT`\xbfe\x9b\xb89\x11.?`\x19\x12f\xac\xfcB\x95a\xc3\xf2\xd3\rz-\x1b\x8fF(\x88\xa2\x03JXW4\xdf\x00~\xfb\xcbg\xad0\x10\xb6\xa3\x97\xd7mY\xc8M\xdbU\x8db\xeb\xc8m\xbcu(\x82\xef\x81\x9c0\xf4\xf6]\xaeU\xd1#\x0e\x953\xe3\xd7\x8e|,\xc9\x95b\xa8\xa4Z\xbfj\x14fZ\xf0\xc5,I}b\x020.\x95_\xb2\x14mX(\x1a\xe7c\xca1\x05\xac1\x87\x16[\x8a\xc4\xb6L\xb7\xcd\xff\xeb\xf6\xa0(\x9d&\xb6$\xd7~\xd8p\x1d8D\xab\xd2.\xa7Q\xa8\xea[\x86\x8a\x98CvI\x11B\x92\xd1AX~\xc4\xf0A`A\x9fZP\x1b\x8d\xceP\xd4I\xfb\xac\x8f\x9a\x08E\xb0\xa3\x87s\x8a\xab.};\xc0\xee\x90dU\xa5\xaa\xd3G\xed\x82\x94:s`\xec\x93\x10\x17g\xed\x8d6\x1e\xb0\x89x\x01_\x93\xd9\x82\xa3B\xc7\xfb\xa4\x82\x9a\[email protected]\xe4\xb5\xd9\xed\x08sX\xb7M\xbbv;\xe7\x07\xf6`\xa6D\xa3\xc3\xbf\[email protected]\x1c}\x01j3c\xd6\x0b\x1b\x8f\xbd\x15\x1b\x98\xcd\xd1h9A\x081b\x9f\x8aFAGT\xfa\x93\xcbD\x19REFEw\xb0\xc3~-\xeb\xbf\xa6\xfa\xad\x1c\xd6\x8d\xb7\xfd8\xc1\xa6G\xf2\xa0\xc915\xb0\xdf\x921\xa9q\xed\xc6d\x00\x83\x00\xb9\x0c\xfd+\xcaK[\x06\x06n\xb5Ge\xecW\x1aY\x1f\xd2\x01\xd2\xca\xfd\xcb~}3\xb1\x1d\xe2G \xc3\xd9\xb3\x97\xe61dz$\xdf\xdf\x1c\xbd\xa9u\x17[W\x81^\xe6J\xb9j\xc8\xfe>\xdfj\xaf3a\x9e\xf4\xd4\xf2\x0e\x96\xc7\x94\xfa*\xa5\xf0U\xec\xe6D\xc8YQ\x9d\xde\x1a\xb5C}\x9e/&\xa2\xff\xbe\x00`x.\xad\xeeD`\xbeb\xa3\xdfq\xed\xa2\xf9\xe7\[email protected]\xda\x1fPk\xa0O2\xed\xf8\x05\xa7\[email protected]\xce>\x1bo)\x01\xbbR\xf4\xb54\xce\x83\xa3X\x9b\x05\x99{\x90t\xd3\xc7\xae\xaa\xf7\x1b\xd0\xfb\x10\xbe\xe0^\x95D\xbc\x12\xec\x07\xe6\xcf\x9f\x08zX\t_Awf\x10KS\xbfJyd\x90\xcbd\x0b\x12;c\xda|\x10' plaintext = self.decapsulate( ciphertext, key_private ) ntru_prime = NTRUPrime() ntru_prime.test( )
# Minimal example: p = 739; q = 9829 # The Ring R. Zx.<x> = ZZ[ ] # The Field R/q. Fq = GF( q ) # Galois Field of GF(q). Fqx.<xp> = Fq[ ] Rq.<xqp> = Fqx.quotient( x ^ p - x - 1 ) f = x^2 + x - 2 f * xqp # does not work
Error in lines 7-7 Traceback (most recent call last): File "/projects/sage/sage-7.3/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 976, in execute exec compile(block+'\n', '', 'single') in namespace, locals File "", line 1, in <module> File "sage/structure/element.pyx", line 1730, in sage.structure.element.RingElement.__mul__ (/projects/sage/sage-7.3/src/build/cythonized/sage/structure/element.c:15495) return coercion_model.bin_op(left, right, mul) File "sage/structure/coerce.pyx", line 1091, in sage.structure.coerce.CoercionModel_cache_maps.bin_op (/projects/sage/sage-7.3/src/build/cythonized/sage/structure/coerce.c:9974) raise TypeError(arith_error_message(x,y,op)) TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Quotient Polynomial Ring in xqp over Finite Field of size 9829 with modulus xp^739 + 9828*xp + 9828'
# The fix is to explicitly convert from R to Rq: Rq(f) * xqp
xqp^3 + xqp^2 + 9827*xqp