A Python port of the Invisible Internet Project (I2P)
at main 139 lines 6.1 kB view raw
1"""Tests for Garlic encryption types.""" 2 3import os 4import struct 5 6import pytest 7 8 9class TestDeliveryInstructions: 10 def test_enum_values(self): 11 from i2p_data.garlic import DeliveryType 12 assert DeliveryType.LOCAL == 0 13 assert DeliveryType.DESTINATION == 1 14 assert DeliveryType.ROUTER == 2 15 assert DeliveryType.TUNNEL == 3 16 17 def test_local_roundtrip(self): 18 from i2p_data.garlic import DeliveryInstructions, DeliveryType 19 di = DeliveryInstructions(DeliveryType.LOCAL) 20 data = di.to_bytes() 21 di2, consumed = DeliveryInstructions.from_bytes(data) 22 assert di2.delivery_type == DeliveryType.LOCAL 23 assert di2.destination is None 24 assert di2.router is None 25 assert di2.tunnel_id is None 26 27 def test_destination_roundtrip(self): 28 from i2p_data.garlic import DeliveryInstructions, DeliveryType 29 dest = os.urandom(32) 30 di = DeliveryInstructions(DeliveryType.DESTINATION, destination=dest) 31 data = di.to_bytes() 32 di2, consumed = DeliveryInstructions.from_bytes(data) 33 assert di2.delivery_type == DeliveryType.DESTINATION 34 assert di2.destination == dest 35 36 def test_router_roundtrip(self): 37 from i2p_data.garlic import DeliveryInstructions, DeliveryType 38 router = os.urandom(32) 39 di = DeliveryInstructions(DeliveryType.ROUTER, router=router) 40 data = di.to_bytes() 41 di2, consumed = DeliveryInstructions.from_bytes(data) 42 assert di2.delivery_type == DeliveryType.ROUTER 43 assert di2.router == router 44 45 def test_tunnel_roundtrip(self): 46 from i2p_data.garlic import DeliveryInstructions, DeliveryType 47 router = os.urandom(32) 48 di = DeliveryInstructions(DeliveryType.TUNNEL, router=router, tunnel_id=42) 49 data = di.to_bytes() 50 di2, consumed = DeliveryInstructions.from_bytes(data) 51 assert di2.delivery_type == DeliveryType.TUNNEL 52 assert di2.router == router 53 assert di2.tunnel_id == 42 54 55 56class TestGarlicClove: 57 def test_construct(self): 58 from i2p_data.garlic import GarlicClove, DeliveryInstructions, DeliveryType 59 di = DeliveryInstructions(DeliveryType.LOCAL) 60 msg_data = os.urandom(64) 61 clove = GarlicClove(di, msg_data, clove_id=123, expiration=1710000000000) 62 assert clove.delivery_instructions.delivery_type == DeliveryType.LOCAL 63 assert clove.message_data == msg_data 64 assert clove.clove_id == 123 65 assert clove.expiration == 1710000000000 66 67 def test_roundtrip_local(self): 68 from i2p_data.garlic import GarlicClove, DeliveryInstructions, DeliveryType 69 di = DeliveryInstructions(DeliveryType.LOCAL) 70 msg = os.urandom(32) 71 clove = GarlicClove(di, msg, clove_id=999, expiration=5000) 72 data = clove.to_bytes() 73 clove2 = GarlicClove.from_bytes(data) 74 assert clove2.clove_id == 999 75 assert clove2.expiration == 5000 76 assert clove2.message_data == msg 77 assert clove2.delivery_instructions.delivery_type == DeliveryType.LOCAL 78 79 def test_roundtrip_tunnel(self): 80 from i2p_data.garlic import GarlicClove, DeliveryInstructions, DeliveryType 81 router = os.urandom(32) 82 di = DeliveryInstructions(DeliveryType.TUNNEL, router=router, tunnel_id=777) 83 msg = os.urandom(100) 84 clove = GarlicClove(di, msg, clove_id=42, expiration=9999) 85 data = clove.to_bytes() 86 clove2 = GarlicClove.from_bytes(data) 87 assert clove2.delivery_instructions.delivery_type == DeliveryType.TUNNEL 88 assert clove2.delivery_instructions.router == router 89 assert clove2.delivery_instructions.tunnel_id == 777 90 assert clove2.message_data == msg 91 92 93class TestGarlicMessage: 94 def test_construct(self): 95 from i2p_data.garlic import GarlicMessage, GarlicClove, DeliveryInstructions, DeliveryType 96 di = DeliveryInstructions(DeliveryType.LOCAL) 97 clove = GarlicClove(di, b"msg1", clove_id=1, expiration=1000) 98 gm = GarlicMessage([clove]) 99 assert gm.clove_count() == 1 100 101 def test_multiple_cloves_roundtrip(self): 102 from i2p_data.garlic import GarlicMessage, GarlicClove, DeliveryInstructions, DeliveryType 103 cloves = [] 104 for i in range(3): 105 di = DeliveryInstructions(DeliveryType.LOCAL) 106 cloves.append(GarlicClove(di, os.urandom(16), clove_id=i, expiration=1000 + i)) 107 gm = GarlicMessage(cloves) 108 data = gm.to_bytes() 109 gm2 = GarlicMessage.from_bytes(data) 110 assert gm2.clove_count() == 3 111 for i in range(3): 112 assert gm2.cloves[i].clove_id == i 113 assert gm2.cloves[i].expiration == 1000 + i 114 115 def test_empty_cloves(self): 116 from i2p_data.garlic import GarlicMessage 117 gm = GarlicMessage([]) 118 assert gm.clove_count() == 0 119 data = gm.to_bytes() 120 gm2 = GarlicMessage.from_bytes(data) 121 assert gm2.clove_count() == 0 122 123 def test_mixed_delivery_types(self): 124 from i2p_data.garlic import GarlicMessage, GarlicClove, DeliveryInstructions, DeliveryType 125 cloves = [ 126 GarlicClove(DeliveryInstructions(DeliveryType.LOCAL), 127 b"local", clove_id=1, expiration=100), 128 GarlicClove(DeliveryInstructions(DeliveryType.ROUTER, router=os.urandom(32)), 129 b"router", clove_id=2, expiration=200), 130 GarlicClove(DeliveryInstructions(DeliveryType.TUNNEL, router=os.urandom(32), tunnel_id=55), 131 b"tunnel", clove_id=3, expiration=300), 132 ] 133 gm = GarlicMessage(cloves) 134 data = gm.to_bytes() 135 gm2 = GarlicMessage.from_bytes(data) 136 assert gm2.cloves[0].delivery_instructions.delivery_type == DeliveryType.LOCAL 137 assert gm2.cloves[1].delivery_instructions.delivery_type == DeliveryType.ROUTER 138 assert gm2.cloves[2].delivery_instructions.delivery_type == DeliveryType.TUNNEL 139 assert gm2.cloves[2].delivery_instructions.tunnel_id == 55