def test_rsk(self): N = 5 n = ed25519.scalar_random() k = ed25519.scalar_random() r = [ed25519.scalar_random() for i in range(N)] target = ed25519.Point.random() triples = [ elgamal.encrypt(ed25519.Point.random(), target) for i in range(N) ] pseudonyms = [pep3_pb2.Pseudonymizable() for i in range(N)] for i in range(N): pseudonyms[i].data = triples[i].pack() self.pu.rsk(pseudonyms, k, n, r) for i in range(N): triples[i] = triples[i].rsk(k, n, r[i]) self.assertEqual( [triples[i] for i in range(N)], [elgamal.Triple.unpack(pseudonyms[i].data) for i in range(N)])
def test_to_protobuf(self): msg = pep3_pb2.CertifiedComponent() k = ed25519.scalar_random() e = ed25519.scalar_random() cc = schnorr.CertifiedComponent.create(k, e) cc.to_protobuf(msg) self.assertEqual(cc, schnorr.CertifiedComponent.from_protobuf(msg))
def test_create(self): M = ed25519.Point.random() a = ed25519.scalar_random() ct = schnorr.DHTProof.create(a, M) A = ed25519.Point.B_times(a) N = M * a self.assertTrue(ct.is_valid_proof_for(A, M, N)) self.assertFalse(ct.is_valid_proof_for(ed25519.Point.random(), M, N)) self.assertFalse(ct.is_valid_proof_for(A, ed25519.Point.random(), N)) self.assertFalse(ct.is_valid_proof_for(A, M, ed25519.Point.random())) ct_ = copy.deepcopy(ct) ct_._R_M = ed25519.Point.random() self.assertFalse(ct_.is_valid_proof_for(A, M, N)) ct_ = copy.deepcopy(ct) ct_._R_B = ed25519.Point.random() self.assertFalse(ct_.is_valid_proof_for(A, M, N)) ct_ = copy.deepcopy(ct) ct_._s = ed25519.scalar_random() self.assertFalse(ct_.is_valid_proof_for(A, M, N))
def test_dht_proof_create(self): cbuf = ristretto.ffi.new("unsigned char[]", 96) buf = ristretto.ffi.buffer(cbuf) for i in range(10): a = ed25519.scalar_random() m = ed25519.scalar_random() A = ed25519.Point.B_times(a) M = ed25519.Point.B_times(m) N = M*a if i%2==0: cm = scalar_to_c(m) cM = ristretto.ffi.NULL else: cm = ristretto.ffi.NULL cM = point_to_c(M) ristretto.lib.dht_proof_create( cbuf, scalar_to_c(a), ed25519.scalar_pack(a), A.pack(), cm, cM, M.pack(), point_to_c(N), N.pack()) self.assertEqual(schnorr.DHTProof.create(a,M).pack(), buf[:])
def benchmark_certified_component(self, args): for i in range(1): k = ed25519.scalar_random() e = ed25519.scalar_random() cc = schnorr.CertifiedComponent.create(k,e) assert(cc.is_valid_proof_for(e, [ed25519.Point.B_times(pow(k,2**i,ed25519.l)) for i in range(253) ] ))
def test_pack(self): M = ed25519.Point.random() y = ed25519.Point.random() r = ed25519.scalar_random() n = ed25519.scalar_random() triple_in = elgamal.encrypt(M, y) rsp, triple_out = schnorr.RSProof.create(triple_in, n, r) self.assertEqual(rsp, schnorr.RSProof.unpack(rsp.pack()))
def test_rekey(self): m = ed25519.Point.random() y = ed25519.Point.random() r = ed25519.scalar_random() k = ed25519.scalar_random() self.assertEqual( elgamal.encrypt(m,y,r).rekey(k), elgamal.encrypt(m,y*k,ed25519.scalar_inv(k)*r) )
def test_reshuffle(self): m = ed25519.Point.random() y = ed25519.Point.random() r = ed25519.scalar_random() n = ed25519.scalar_random() self.assertEqual( elgamal.encrypt(m,y,r).reshuffle(n), elgamal.encrypt(m*n,y,r*n) )
def test_rerandomization(self): m = ed25519.Point.random() y = ed25519.Point.random() r = ed25519.scalar_random() s = ed25519.scalar_random() self.assertEqual( elgamal.encrypt(m,y,r).rerandomize(s), elgamal.encrypt(m,y,r+s) )
def test_certified_component_create(self): k = ed25519.scalar_random() e = ed25519.scalar_random() ones = schnorr.ones_of(e) N = len(list(ones)) ccc = ristretto.ffi.new("certified_component*") cpp = ccc.product_proof # prepare cpp cpp.number_of_factors = N cpartial_products = ristretto.ffi.new("unsigned char[]", 32*max(N-2,0)) cpp.partial_products = cpartial_products cdht_proofs = ristretto.ffi.new("unsigned char[]", 96*max(N-1,0)) cpp.dht_proofs = cdht_proofs # prepare cbase_powers_packed cbase_powers_packed = ristretto.ffi.new("unsigned char[]", 32*253) cbase_powers = ristretto.ffi.new("group_ge[]", 253) ristretto.lib.component_public_part(cbase_powers, scalar_to_c(k)) ristretto.lib.group_ges_pack(cbase_powers_packed, cbase_powers, 253) ristretto.lib.certified_component_create(ccc, cbase_powers_packed, scalar_to_c(k), scalar_to_c(e)) cc = schnorr.CertifiedComponent.create(k, e) pp = cc._product_proof self.assertEqual(cc._component.pack(), ristretto.ffi.buffer(ccc.component)[:]) dht_proofs_buf = ristretto.ffi.buffer(cpp.dht_proofs, 96*max(N-1,0)) partial_products_buf = ristretto.ffi.buffer( cpp.partial_products, 32*max(N-2,0)) for i in range(max(N-1,0)): self.assertEqual(pp._dht_proofs[i].pack(), dht_proofs_buf[96*i:96*(i+1)]) if i<N-2: self.assertEqual(pp._partial_products[i].pack(), partial_products_buf[32*i:32*(i+1)]) self.assertTrue(ristretto.lib.certified_component_is_valid_for( ccc, cbase_powers_packed, scalar_to_c(e))) # wrong exponent self.assertFalse(ristretto.lib.certified_component_is_valid_for( ccc, cbase_powers_packed, scalar_to_c(ed25519.scalar_random())))
def test_create(self): M = ed25519.Point.random() y = ed25519.Point.random() r = ed25519.scalar_random() n = ed25519.scalar_random() triple_in = elgamal.encrypt(M, y) rsp, triple_out = schnorr.RSProof.create(triple_in, n, r) self.assertEqual(triple_out, triple_in.rerandomize(r).reshuffle(n)) self.assertTrue( rsp.is_valid_proof_for(triple_in, ed25519.Point.B_times(n), triple_out))
def test_rsk(self): m = ed25519.Point.random() y = ed25519.Point.random() r = ed25519.scalar_random() n = ed25519.scalar_random() k = ed25519.scalar_random() r2 = ed25519.scalar_random() triple = elgamal.encrypt(m,y,r) self.assertEqual( triple.rsk(k,n,r2), triple.rekey(k).reshuffle(n).rerandomize(r2) )
def test_component_public_part(self): scalar = ed25519.scalar_random() y = self.pu.component_public_part(scalar) self.assertEqual(y, [ ed25519.Point.B_times(pow(scalar, 2**i, ed25519.l)).pack() for i in range(253) ])
def test_triples_pack_and_unpack(self): n = 5 triples = [ elgamal.encrypt( ed25519.Point.random(), ed25519.Point.random(), ed25519.scalar_random()) for i in range(n) ] cbuf1 = ristretto.ffi.new("unsigned char[]", n*96) for i in range(n): ristretto.ffi.memmove(cbuf1 + 96*i, triples[i].pack(), 96) ctriples = ristretto.ffi.new("elgamal_triple[]", n) cerror_codes = ristretto.ffi.new("int[]", n) ristretto.lib.elgamal_triples_unpack(ctriples, cbuf1, cerror_codes, n) for i in range(n): self.assertEqual(cerror_codes[i], 0) cbuf2 = ristretto.ffi.new("unsigned char[]", n*96) ristretto.lib.elgamal_triples_pack(cbuf2, ctriples, n) self.assertEqual( [ cbuf1[i] for i in range(96*n) ], [ cbuf2[i] for i in range(96*n) ])
def encrypt(self, names, key=None): if key==None: key = self.public_keys['pseudonym'] for name in names: assert(name.state==pep3_pb2.Pseudonymizable.UNENCRYPTED_PSEUDONYM) name.state = pep3_pb2.Pseudonymizable.ENCRYPTED_PSEUDONYM self._cryptopu.encrypt(names, key, [ed25519.scalar_random() for i in range(len(names))])
def test_component_public_part(self): x = ed25519.scalar_random() cy = ristretto.ffi.new('group_ge[]',253) ristretto.lib.component_public_part(cy, scalar_to_c(x)) y = points_from_c(cy, 253) for i in range(253): self.assertEqual(y[i], ed25519.Point.B_times(pow(x,2**i,ed25519.l)))
def pseudonymize(self, names): for name in names: assert(name.state==pep3_pb2.Pseudonymizable.UNENCRYPTED_NAME) name.state = pep3_pb2.Pseudonymizable.ENCRYPTED_PSEUDONYM name.data = ed25519.lizard_without_elligator(name.data) self._cryptopu.elligator(names) self._cryptopu.encrypt(names, self.public_keys['pseudonym'], [ed25519.scalar_random() for i in range(len(names))])
def test_certified_component_create(self): k = ed25519.scalar_random() e = ed25519.scalar_random() cc_protobuf = pep3_pb2.CertifiedComponent() self.pu.certified_component_create(cc_protobuf, self.pu.component_public_part(k), k, e) cc = schnorr.CertifiedComponent.create(k, e) cc_protobuf2 = pep3_pb2.CertifiedComponent() cc.to_protobuf(cc_protobuf2) self.assertEqual(cc_protobuf2, cc_protobuf) self.assertTrue( self.pu.certified_component_is_valid_for( cc_protobuf, self.pu.component_public_part(k), e))
def test_group_scalar_tstbit(self): s = ed25519.scalar_random() ones = set(schnorr.ones_of(s)) cs = scalar_to_c(s) for i in range(253): result, = ristretto.lib.scalar_tstbit(cs, i), if i in ones: self.assertEqual(result, 1) else: self.assertEqual(result, 0)
def test_create(self): # N = 0 dht_proof, factors, product = schnorr.ProductProof.create(()) self.assertEqual(len(factors), 0) self.assertEqual(product, ed25519.Point.B_times(1)) self.assertTrue(dht_proof.is_valid_proof_for(product, factors)) # N = 1 a = ed25519.scalar_random() dht_proof, factors, product = schnorr.ProductProof.create((a, )) self.assertEqual(len(factors), 1) self.assertEqual(factors[0], product) self.assertEqual(product, ed25519.Point.B_times(a)) self.assertTrue(dht_proof.is_valid_proof_for(product, factors)) self.assertFalse(dht_proof.is_valid_proof_for(product, ())) factors[0] = ed25519.Point.random() self.assertFalse(dht_proof.is_valid_proof_for(product, factors)) N = 10 ## factors_scalars = [ed25519.scalar_random() for i in range(N)] dht_proof, factors, product = \ schnorr.ProductProof.create(factors_scalars) self.assertTrue(dht_proof.is_valid_proof_for(product, factors)) product_scalar = 1 for factor in factors_scalars: product_scalar *= factor self.assertEqual(product, ed25519.Point.B_times(product_scalar)) self.assertFalse( dht_proof.is_valid_proof_for(ed25519.Point.random(), factors)) i = random.choice(range(N)) self.assertFalse( dht_proof.is_valid_proof_for(product, factors[:i] + factors[i + 1:])) self.assertFalse( dht_proof.is_valid_proof_for( product, factors[:i] + [ed25519.Point.random()] + factors[i:]))
def test_triple_rsk(self): m = ed25519.Point.random() y = ed25519.Point.random() r = ed25519.scalar_random() s = ed25519.scalar_random() k = ed25519.scalar_random() r2 = ed25519.scalar_random() triple = elgamal.encrypt(m,y,r2) ctriple = ristretto.ffi.new("elgamal_triple*") ck = ristretto.ffi.new("group_scalar*") cs = ristretto.ffi.new("group_scalar*") cr = ristretto.ffi.new("group_scalar*") ristretto.lib.elgamal_triple_unpack(ctriple, triple.blinding.pack() + triple.core.pack() + triple.target.pack()) ristretto.lib.group_scalar_unpack(ck, ed25519.scalar_pack(k)) ristretto.lib.group_scalar_unpack(cs, ed25519.scalar_pack(s)) ristretto.lib.group_scalar_unpack(cr, ed25519.scalar_pack(r)) ristretto.lib.elgamal_triple_rsk(ctriple, ctriple, ck, cs, cr) cbuf = ristretto.ffi.new("unsigned char []", 96) ristretto.lib.elgamal_triple_pack(cbuf, ctriple) buf = ristretto.ffi.buffer(cbuf) triple2 = elgamal.Triple( ed25519.Point.unpack(buf[0:32]), ed25519.Point.unpack(buf[32:64]), ed25519.Point.unpack(buf[64:96])) triple = triple.rsk(k,s,r) self.assertEqual(triple.blinding, triple2.blinding) self.assertEqual(triple.core, triple2.core) self.assertEqual(triple.target, triple2.target)
def test_create(self): k = ed25519.scalar_random() k_powers = [ ed25519.Point.B_times(pow(k, 2**i, ed25519.l)) for i in range(253) ] e = 0 cc = schnorr.CertifiedComponent.create(k, e) self.assertTrue(cc.is_valid_proof_for(e, k_powers)) i = random.choice(range(253)) e = 2**i cc = schnorr.CertifiedComponent.create(k, e) self.assertTrue(cc.is_valid_proof_for(e, k_powers)) e = ed25519.scalar_random() cc = schnorr.CertifiedComponent.create(k, e) self.assertTrue(cc.is_valid_proof_for(e, k_powers)) cc_ = copy.deepcopy(cc) cc_._component = ed25519.Point.random() self.assertFalse(cc_.is_valid_proof_for(e, k_powers))
def test_triple_decrypt(self): key = ed25519.scalar_random() t = elgamal.encrypt( ed25519.Point.random(), ed25519.Point.B_times(key)) ckey = scalar_to_c(key) ct = triple_to_c(t) cresult = point_to_c(ed25519.Point.Zero()) ristretto.lib.elgamal_triple_decrypt(cresult, ct, ckey) result = point_from_c(cresult) self.assertEqual(result, t.decrypt(key))
def rsk(self, rekey_scalar, reshuffle_scalar, rerandomization_scalar=None): if rerandomization_scalar == None: rerandomization_scalar = ed25519.scalar_random() return Triple( blinding = self.blinding \ * (ed25519.scalar_inv(rekey_scalar) * reshuffle_scalar) + ed25519.Point.B_times(rerandomization_scalar), core = self.core * reshuffle_scalar + self.target * (rekey_scalar * rerandomization_scalar), target = self.target * rekey_scalar )
def test_triple_encrypt(self): a = ed25519.Point.random() t = ed25519.Point.random() r = ed25519.scalar_random() ca = point_to_c(a) ct = point_to_c(t) cr = scalar_to_c(r) ctriple = ristretto.ffi.new("elgamal_triple*") ristretto.lib.elgamal_triple_encrypt(ctriple, ca, ct, cr) triple = triple_from_c(ctriple) self.assertEqual(triple, elgamal.encrypt(a,t,r))
def test_dht_proof_is_valid(self): M = ed25519.Point.random() a = ed25519.scalar_random() ct = schnorr.DHTProof.create(a, M) A = ed25519.Point.B_times(a) N = M*a cA = point_to_c(A) cM = point_to_c(M) cN = point_to_c(N) A_packed = A.pack() M_packed = M.pack() N_packed = N.pack() ct_packed = ct.pack() self.assertTrue(ristretto.lib.dht_proof_is_valid_for( ct_packed, cA, cM, cN, A_packed, M_packed, N_packed)) R = ed25519.Point.random() cR = point_to_c(R) R_packed = R.pack() self.assertFalse(ristretto.lib.dht_proof_is_valid_for( ct_packed, cR, cM, cN, R_packed, M_packed, N_packed)) self.assertFalse(ristretto.lib.dht_proof_is_valid_for( ct_packed, cA, cR, cN, A_packed, R_packed, N_packed)) self.assertFalse(ristretto.lib.dht_proof_is_valid_for( ct_packed, cA, cM, cR, A_packed, M_packed, R_packed)) self.assertFalse(ristretto.lib.dht_proof_is_valid_for( os.urandom(32)+ct_packed[32:], cA, cM, cN, A_packed, M_packed, N_packed)) self.assertFalse(ristretto.lib.dht_proof_is_valid_for( ct_packed[:32] + os.urandom(32) + ct_packed[64:], cA, cM, cN, A_packed, M_packed, N_packed)) self.assertFalse(ristretto.lib.dht_proof_is_valid_for( ct_packed[:64] + os.urandom(32), cA, cM, cN, A_packed, M_packed, N_packed))
def test_invalid_decryption(self): m = ed25519.Point.random() x = ed25519.scalar_random() y = ed25519.Point.B() * x with self.assertRaises(elgamal.WrongPrivateKey): elgamal.encrypt(m,y).decrypt(x+1)
def test_encryption(self): m = ed25519.Point.random() x = ed25519.scalar_random() y = ed25519.Point.B() * x self.assertEqual(m, elgamal.encrypt(m, y).decrypt(x))
def Depseudonymize(self, request, context): common_name = common.authenticate(context) e = ed25519.scalar_unpack(common.sha256(common_name)) self._dispatch_message( pep3_pb2.Message(text="Depseudonymizing", code=pep3_pb2.Message.OK)) # catch trivial errors if len(request.warrant.signature) == 0: context.abort(grpc.StatusCode.PERMISSION_DENIED, "warrant has empty signature") if len(request.which_shards) == 0: context.abort(grpc.StatusCode.INVALID_ARGUMENT, "request.which_shards is empty") # verify warrant if common_name != request.warrant.act.actor: context.abort( grpc.StatusCode.PERMISSION_DENIED, f"you, {common_name}, presented a warrant that " f"was issued to {request.warrant.act.actor}") try: crypto.verify( crypto.load_certificate( crypto.FILETYPE_PEM, self.pep.global_config.root_certificates.warrants), request.warrant.signature, request.warrant.act.SerializeToString(), 'sha256') except crypto.Error as e: context.abort(grpc.StatusCode.PERMISSION_DENIED, "the warrant's signature appears to be invalid") # verify reminders for i, reminder in enumerate(request.reminders): if not common.verify_protobuf_signature( reminder, self.pep.secrets.reminders_hmac_secret): context.abort(grpc.StatusCode.PERMISSION_DENIED, f"could not verify reminder #{i}.") # verify chain name = request.warrant.act.name name_unpacked = elgamal.Triple.unpack(name.data) for i, link in enumerate(request.chain): if link.peer not in self.pep.global_config.peers: context.abort(grpc.StatusCode.INVALID_ARGUMENT, f"unknown peer '{link.peer}' in link #{i}") for shard in link.which_shards: if shard not in self.pep.global_config\ .peers[link.peer].shards: context.abort( grpc.StatusCode.PERMISSION_DENIED, f"the peer {link.peer} of link #{i} " f"doesn't hold the shard {shard}!") rs_p = schnorr.RSProof.unpack(link.peer_response.rs_proof) sB_p = schnorr.DHTProof.unpack(link.peer_response.sB_proof) sB = ed25519.Point.unpack(link.peer_response.sB) kB = ed25519.Point.B_times(1) s_inv_B = ed25519.Point.unpack(link.peer_response.s_inv_B) link_name_unpacked = elgamal.Triple.unpack( link.peer_response.name.data) # check that s_inv_B is the inverse of sB if not sB_p.is_valid_proof_for(sB, s_inv_B, ed25519.Point.B_times(1)): context.abort(grpc.StatusCode.PERMISSION_DENIED, f"could not verify the sB proof of link #{i}.") # check the rs-operation was performed correctly if not rs_p.is_valid_proof_for(name_unpacked, sB, link_name_unpacked): context.abort(grpc.StatusCode.PERMISSION_DENIED, f"could not verify the rs proof of link #{i}.") # check that s_inv_B is indeed the product of their factors s_inv_B_factors = [ ed25519.Point.unpack(pp) for pp in link.peer_response.s_inv_B_factors ] s_inv_B_p = schnorr.ProductProof.from_protobuf( link.peer_response.s_inv_B_proof) if not s_inv_B_p.is_valid_proof_for(s_inv_B, s_inv_B_factors): context.abort( grpc.StatusCode.PERMISSION_DENIED, "could not verify the s_inv_B product proof " f"for link #{i}.") # make a lookup dictionary for the reminders reminders = {} for reminder in request.reminders: component = reminder.component if component in reminders: context.abort(grpc.StatusCode.INVALID_ARGUMENT, "double reminder") reminders[component] = reminder # check that the provided factors are valid for j, shard in enumerate(link.which_shards): # check s_inv_B factor s_inv_B_factor_packed = link.peer_response.s_inv_B_factors[j] if shard in self.pep.config.shards: # we can check s_inv_B by computing it ourselves s_ = ed25519.scalar_unpack(self.pep.secrets\ .by_shard[shard].pseudonym_component_secret) s_B = ed25519.Point.B_times(pow(s_, e, ed25519.l)) if s_B.pack() != s_inv_B_factor_packed: context.abort( grpc.StatusCode.PERMISSION_DENIED, f"s_inv_B factor #{j} (for shard {shard}, " f"and common name {common_name}, e={e})" f" of link #{i} is not correct: it should be " f"{s_B.pack()}, but {s_inv_B_factor_packed} " "was given.") else: # we need a reminder that s_inv_B is correct if s_inv_B_factor_packed not in reminders: context.abort( grpc.StatusCode.PERMISSION_DENIED, f"missing reminder that s_inv_B factor #{j} " f"of link #{i} is correct.") rem = reminders[s_inv_B_factor_packed] assert (rem.component == s_inv_B_factor_packed) error_message = None if not rem.HasField("pseudonym"): error_message = "reminder is for a key component"\ f" instead of a pseudonym component" elif rem.shard != shard: error_message = "reminder is for "\ f"the shard {rem.shard}"\ f" instead of the shard {shard}" if error_message != None: context.abort( grpc.StatusCode.PERMISSION_DENIED, f"s_inv_B factor #{j} of link #{i} " "is not correct: " + error_message) name = link.peer_response.name name_unpacked = link_name_unpacked # the provided request seems to be in order; # let us prepare our response. response = pep3_pb2.DepseudonymizationResponse() # compute rekey and reshuffle components k = s_inv = 1 s_inv_factors = [] for shard in request.which_shards: s_inv_factor = pow(ed25519.scalar_unpack(self.pep.secrets\ .by_shard[shard].pseudonym_component_secret), e, ed25519.l) s_inv_factors.append(s_inv_factor) s_inv *= s_inv_factor s_inv %= ed25519.l s = ed25519.scalar_inv(s_inv) r = ed25519.scalar_random() rs_proof, name_out = schnorr.RSProof.create(name_unpacked, s, r) response.rs_proof = rs_proof.pack() response.name.data = name_out.pack() response.name.state \ = pep3_pb2.Pseudonymizable.ENCRYPTED_PSEUDONYM # compute proofs for the reshuffle components s_inv_B_proof, s_inv_B_factors, s_inv_B \ = schnorr.ProductProof.create(s_inv_factors) s_inv_B_proof.to_protobuf(response.s_inv_B_proof) for s_inv_B_factor in s_inv_B_factors: response.s_inv_B_factors.append(s_inv_B_factor.pack()) response.s_inv_B = s_inv_B.pack() sB = ed25519.Point.B_times(s) sB_proof = schnorr.DHTProof.create(s, s_inv_B, A=sB, N=ed25519.Point.B_times(1)) response.sB = sB.pack() response.sB_proof = sB_proof.pack() return response
def Relocalize(self, request, context): common_name = common.authenticate(context) self._dispatch_message( pep3_pb2.Message(text="Relocalizing", code=pep3_pb2.Message.OK)) # catch trivial errors if len(request.warrant.signature) == 0: context.abort(grpc.StatusCode.PERMISSION_DENIED, "warrant has empty signature") if len(request.which_shards) == 0: context.abort(grpc.StatusCode.INVALID_ARGUMENT, "request.which_shards is empty") if len(request.names) == 0: context.abort(grpc.StatusCode.INVALID_ARGUMENT, "request.names is empty") # verify warrant if common_name != request.warrant.act.actor: context.abort( grpc.StatusCode.PERMISSION_DENIED, f"you, {common_name}, presented a warrant that " f"was issued to {request.warrant.act.actor}") try: crypto.verify( crypto.load_certificate( crypto.FILETYPE_PEM, self.pep.global_config.root_certificates.warrants), request.warrant.signature, request.warrant.act.SerializeToString(), 'sha256') except crypto.Error as e: context.abort(grpc.StatusCode.PERMISSION_DENIED, "the warrant's signature appears to be invalid") response = pep3_pb2.RelocalizationResponse() act = request.warrant.act k = s = 1 for shard in request.which_shards: s *= pow(ed25519.scalar_unpack(self.pep.secrets.by_shard[shard]\ .pseudonym_component_secret), ed25519.scalar_unpack(common.sha256(act.target)), ed25519.l) s %= ed25519.l if act.encrypt_for != b"": for shard in request.which_shards: k *= pow(ed25519.scalar_unpack(self.pep.secrets.by_shard[shard]\ .by_domain["pseudonym"].key_component_secret), ed25519.scalar_unpack(common.sha256(act.encrypt_for)), ed25519.l) k %= ed25519.l k_inv_comp = 1 encrypt_from = act.source if encrypt_from == b"plaintext": encrypt_from = act.actor for shard in request.which_shards: k_inv_comp *= \ pow(ed25519.scalar_unpack(self.pep.secrets.by_shard[shard]\ .by_domain["pseudonym"].key_component_secret), ed25519.scalar_unpack(common.sha256(encrypt_from)), ed25519.l) k_inv_comp %= ed25519.l k = (k * ed25519.scalar_inv(k_inv_comp)) % ed25519.l if act.source != b"plaintext": for shard in request.which_shards: s *= ed25519.scalar_inv(pow(ed25519.scalar_unpack( self.pep.secrets.by_shard[shard]\ .pseudonym_component_secret), ed25519.scalar_unpack(common.sha256(act.source)), ed25519.l)) s %= ed25519.l names = request.names # reshuffle, rekey, and rerandomize try: self.pep._cryptopu.rsk( names, k, s, [ed25519.scalar_random() for i in range(len(names))]) except cryptopu.InvalidArgument as e: context.abort(grpc.StatusCode.INVALID_ARGUMENT, str(e)) # change the state of the names if we rekeyed if act.encrypt_for != b"": for i in range(len(names)): names[i].state \ = pep3_pb2.Pseudonymizable.ENCRYPTED_PSEUDONYM response.names.extend(names) return response