Ejemplo n.º 1
0
    def client(self, index: int) -> str:
        """

        Args:
            index: int, which index the client want to get from server's input list.

        Returns: str, message

        """
        param_s = self.var_chan.recv(tag='ot_param_s')

        x = self.secrets_generator.randint(1, P-1)
        param_r = add(multiply(param_s, int(index)), multiply(G, x))
        self.var_chan.send(param_r, tag='ot_param_r')

        key_pub = multiply(param_s, x)
        key = hashlib.sha256(str(int("04" + "%064x" % key_pub[0] + "%064x" % key_pub[1], 16)).encode('utf-8')).digest()

        recv_msg_list = self.var_chan.recv(tag='ot_encrypted_messages')

        if not (0 <= index <= self.n - 1):
            raise ValueError(f"Index {index} is supposed to be a number between 1 and n.")

        recv_msg = base64.b64decode(recv_msg_list[index])
        iv = recv_msg[:AES.block_size]
        cipher = recv_msg[AES.block_size:]
        aes = AES.new(key, AES.MODE_CBC, iv)
        decrypted_message = self._unpad(aes.decrypt(cipher)).decode('utf-8')
        return decrypted_message
Ejemplo n.º 2
0
    def server(self, msg_list: List[str]) -> None:
        """

        Args:
            msg_list: list, list consist of string.

        Returns: None

        """
        y = self.secrets_generator.randint(1, P-1)
        param_s = multiply(G, y)

        self.var_chan.send(param_s, tag='ot_param_s')
        param_r = self.var_chan.recv(tag='ot_param_r')

        encrypted_msg_list = []
        iv = Random.new().read(AES.block_size)

        for i, msg in enumerate(msg_list):
            key_pub = multiply(add(param_r, multiply(param_s, (-1) * i)), y)
            key = hashlib.sha256(
                str(int("04" + "%064x" % key_pub[0] + "%064x" % key_pub[1], 16)).encode('utf-8')).digest()
            aes = AES.new(key, AES.MODE_CBC, iv)
            cipher = aes.encrypt(self._pad(msg).encode())
            encrypted_msg_list.append(base64.b64encode(iv + cipher))

        self.var_chan.send(encrypted_msg_list, tag='ot_encrypted_messages')
        return
Ejemplo n.º 3
0
def encrypt(message: bytes, enckey: (int, int)) -> bytes:
    # This is an implementation of ECIES
    # https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme
    util.validate_curve_point(enckey)
    r = util.random_private_value()
    R = secp256k1.multiply(secp256k1.G, r)
    S = secp256k1.multiply(enckey, r)
    kEkM = sha3.keccak_256(S[0].to_bytes(32, byteorder='big')).digest()
    kE, kM = kEkM[0:16], kEkM[16:32]

    # Use CTR mode to do encryption 256 bits at a time
    # https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CTR
    num_trunc_bytes = (32 - len(message)) % 32
    iv = util.random.randrange(2**256).to_bytes(32, byteorder='big')
    num_chunks = len(message) // 32 + (1 if num_trunc_bytes > 0 else 0)
    c = b''.join(
        (int.from_bytes(message[32 * i:32 * (i + 1)].ljust(32, b'\0'), 'big')
         ^ int.from_bytes(
             sha3.keccak_256(kE + iv + i.to_bytes(32, 'big')).digest(), 'big')
         ).to_bytes(32, byteorder='big') for i in range(num_chunks))

    # Quote from http://keccak.noekeon.org/:
    # Unlike SHA-1 and SHA-2, Keccak does not have the length-extension weakness,
    # hence does not need the HMAC nested construction. Instead, MAC computation
    # can be performed by simply prepending the message with the key.
    d = sha3.keccak_256(kM + c).digest()
    return (util.curve_point_to_bytes(R) +  # 64 byte ephemeral key
            bytes((num_trunc_bytes, )) +  # 1 byte truncation descriptor
            iv +  # 32 byte initialization vector
            c +  # arbitrary length 32 byte aligned enciphered message
            d)  # 32 byte message authentication code (MAC)
Ejemplo n.º 4
0
    def generateZKP(self, preSecrets, shares):
        vArr = []
        wArr = []
        n = len(preSecrets)

        toBeHashed = bytes('')
        for i in range(n):
            sh = shares[i]
            v = ec.multiply(self.generatorSecondary, preSecrets[i])
            vArr.append(v)
            w = self.sample(self.order)
            wArr.append(w)
            (a1, a2) = (ec.multiply(self.publicKeys[i],
                                    w), ec.multiply(self.generatorSecondary,
                                                    w))

            arr = [sh[0], sh[1], v[0], v[1], a1[0], a1[1], a2[0], a2[1]]
            for ele in arr:
                toBeHashed += encode_int32(ele)
        e = sha3(toBeHashed)
        e = mpz(codecs.encode(str(e), 'hex'), 16)
        zArr = [
            long(gmpy2.f_mod(wArr[i] - preSecrets[i] * e, self.order))
            for i in range(n)
        ]
        e = long(e)
        return [vArr, e, zArr]
Ejemplo n.º 5
0
    def process_encryption_key_vector(self,
                                      sender_address: int,
                                      encryption_key_vector: tuple,
                                      signature: 'rsv triplet'):
        own_address = self.node.address
        participant = self.get_participant_by_address(sender_address)

        msg_bytes = (
            b'ENCRYPTIONKEYPART' +
            self.decryption_condition.encode() +
            util.curve_point_tuple_to_bytes(encryption_key_vector)
        )

        recovered_address = util.address_from_message_and_signature(msg_bytes, signature)

        if sender_address != recovered_address:
            raise ValueError(
                'sender address {:040x} does not match recovered address {:040x}'
                .format(sender_address, recovered_address)
            )

        if participant.encryption_key_vector is None:
            lhs = secp256k1.multiply(secp256k1.G, participant.secret_share1)
            rhs = functools.reduce(
                secp256k1.add,
                (secp256k1.multiply(ps, pow(own_address, k, secp256k1.N))
                    for k, ps in enumerate(encryption_key_vector)))
            if lhs != rhs:
                participant.get_or_create_complaint_by_complainer_address(own_address)
                raise ValueError(
                    '{:040x} sent enc key vector which does not match previously sent secret share'
                    .format(sender_address)
                )

            participant.encryption_key_vector = encryption_key_vector
            participant.encryption_key_vector_signature = signature

            if all(p.encryption_key_vector is not None for p in self.participants):
                self.encryption_key = functools.reduce(
                    secp256k1.add,
                    (p.encryption_key_vector[0] for p in self.participants),
                    self.encryption_key_vector[0]
                )

            db.Session.commit()
        elif participant.encryption_key_vector != encryption_key_vector:
            participant.get_or_create_complaint_by_complainer_address(own_address)
            raise ValueError(
                '{:040x} sent encryption key part for {} which do not match: {} != {}'
                .format(
                    sender_address,
                    self.decryption_condition,
                    participant.encryption_key_vector,
                    encryption_key_vector,
                )
            )
Ejemplo n.º 6
0
def encrypt(pubkey, plaintext_bytes):
    padded = pad(plaintext_bytes, AES.block_size)
    r = random.SystemRandom().randrange(1, secp256k1.N)
    R = secp256k1.multiply(secp256k1.G, r)
    R_bytes = encode_point(R)
    S = secp256k1.multiply(decode_point(pubkey), r)[0]
    key_enc = ethereum.utils.sha3(ethereum.utils.int_to_bytes(S + 1))
    prefix_bytes = random.getrandbits(64).to_bytes(8, byteorder='big')
    ctr = Counter.new(64, prefix=prefix_bytes)
    cipher = AES.new(key=key_enc, mode=AES.MODE_CTR, counter=ctr)
    ciphertext = cipher.encrypt(padded)
    return rlp.encode([R_bytes, prefix_bytes, ciphertext])
Ejemplo n.º 7
0
def decrypt(ciphertext: bytes, deckey: int, foo=False) -> bytes:
    util.validate_private_value(deckey)
    R = util.bytes_to_curve_point(ciphertext[:64])
    S = secp256k1.multiply(R, deckey)
    num_trunc_bytes = ord(ciphertext[64:65])
    iv = ciphertext[65:97]
    c = ciphertext[97:-32]

    if len(c) % 32 != 0:
        raise ValueError('enciphered message not properly aligned')

    kEkM = sha3.keccak_256(S[0].to_bytes(32, byteorder='big')).digest()
    kE, kM = kEkM[0:16], kEkM[16:32]

    num_chunks = len(c) // 32
    message = b''.join(
        (int.from_bytes(c[32 * i:32 * (i + 1)], 'big') ^ int.from_bytes(
            sha3.keccak_256(kE + iv + i.to_bytes(32, 'big')).digest(), 'big')
         ).to_bytes(32, byteorder='big') for i in range(num_chunks))

    if num_trunc_bytes > 0:
        message, padding = message[:-num_trunc_bytes], message[
            -num_trunc_bytes:]

        if padding != b'\0' * num_trunc_bytes:
            raise ValueError('invalid padding')

    d = ciphertext[-32:]
    if d != sha3.keccak_256(kM + c).digest():
        raise ValueError('message authentication code does not match')

    if foo:
        return int.from_bytes(sha3.keccak_256(message).digest(), 'big')

    return message
Ejemplo n.º 8
0
def decrypt(privkey, encrypted_bytes):
    R_bytes, prefix_bytes, ciphertext = rlp.decode(encrypted_bytes)
    S = secp256k1.multiply(decode_point(R_bytes), privkey)[0]
    key_enc = ethereum.utils.sha3(ethereum.utils.int_to_bytes(S + 1))
    ctr = Counter.new(64, prefix=prefix_bytes)
    cipher = AES.new(key=key_enc, mode=AES.MODE_CTR, counter=ctr)
    plaintext = cipher.decrypt(ciphertext)
    return unpad(plaintext, AES.block_size)
Ejemplo n.º 9
0
    def generate1ZKP(self, ex, gen1, gen2):
        sh = ec.multiply(gen1, ex)
        v = ec.multiply(gen2, ex)
        w = self.sample(self.order)

        (a1, a2) = (ec.multiply(gen1, w), ec.multiply(gen2, w))
        print 'As : '
        print[a1[0], a1[1], a2[0], a2[1]]

        arr = [sh[0], sh[1], v[0], v[1], a1[0], a1[1], a2[0], a2[1]]
        toBeHashed = bytes('')
        for ele in arr:
            toBeHashed += encode_int32(ele)
        e = sha3(toBeHashed)
        e = mpz(codecs.encode(str(e), 'hex'), 16)
        z = long(gmpy2.f_mod(w - ex * e, self.order))
        e = long(e)
        return [v, sh, e, z]
Ejemplo n.º 10
0
    def process_secret_share_verification(self, address: int):
        own_address = self.node.address
        participant = self.get_participant_by_address(address)

        share1 = participant.secret_share1
        share2 = participant.secret_share2

        vlhs = secp256k1.add(secp256k1.multiply(secp256k1.G, share1),
                             secp256k1.multiply(G2, share2))
        vrhs = functools.reduce(
            secp256k1.add,
            (secp256k1.multiply(ps, pow(own_address, k, secp256k1.N))
                for k, ps in enumerate(participant.verification_points)))

        if vlhs == vrhs:
            return

        participant.get_or_create_complaint_by_complainer_address(own_address)
Ejemplo n.º 11
0
    def verify1ZKP(self, proof, gen1, gen2, verbal):
        #print proof
        v, sh, e, z = proof
        if verbal: print "Verifying ZKP..."
        if verbal: print "e = " + str(e) + "\nIntermediates"

        a1 = ec.add(ec.multiply(gen1, z), ec.multiply(sh, e))
        a2 = ec.add(ec.multiply(gen2, z), ec.multiply(v, e))
        if verbal:
            print conc([str(ele) for ele in [a1[0], a1[1], a2[0], a2[1]]])
        arr = [sh[0], sh[1], v[0], v[1], a1[0], a1[1], a2[0], a2[1]]
        toBeHashed = bytes('')
        for ele in arr:
            toBeHashed += encode_int32(ele)
        eVerify = sha3(toBeHashed)
        e = encode_int32(e)
        if verbal:
            print "Recovered e : " + mpz(codecs.encode(eVerify, 'hex'),
                                         16).digits()
        return eVerify == e
Ejemplo n.º 12
0
def CreateStealthTx(pub_scan_key, pub_spend_key):
    from random import SystemRandom
    rnd = SystemRandom()
    r = rnd.getrandbits(256)
    R = CompressPoint(curve.multiply(curve.G, r))

    ss = GetSharedSecret(pub_scan_key, r)
    addr = GetAddrFromSharedSecret(ss, pub_spend_key)

    R = hex(int.from_bytes(R, 'big'))
    addr = hex(int.from_bytes(addr, 'big'))
    return R, addr
Ejemplo n.º 13
0
    def init(self):
        for addr in networking.channels.keys():
            self.get_or_create_participant_by_address(addr)

        # everyone should on agree on participants
        self.threshold = math.ceil(THRESHOLD_FACTOR * (len(self.participants)+1))

        spoly1 = random_polynomial(self.threshold)
        spoly2 = random_polynomial(self.threshold)

        self.secret_poly1 = spoly1
        self.secret_poly2 = spoly2

        self.encryption_key_vector = tuple(secp256k1.multiply(secp256k1.G, coeff) for coeff in self.secret_poly1)

        self.verification_points = tuple(
            secp256k1.add(secp256k1.multiply(secp256k1.G, a), secp256k1.multiply(G2, b))
            for a, b in zip(spoly1, spoly2)
        )

        self.phase = ECDKGPhase.key_distribution
Ejemplo n.º 14
0
def GetSharedSecret(R, scan_key):
    from hashlib import sha256

    if type(scan_key) == bytes:
        scan_key = int.from_bytes(scan_key, 'big')
        
    SS = curve.multiply(R, scan_key)

    hasher = sha256()
    hasher.update(int.to_bytes(SS[0], 32, 'big') + int.to_bytes(SS[1], 32, 'big'))
    ss = hasher.digest()

    return ss
Ejemplo n.º 15
0
    def PVSSDistribute(self, s):
        publicKeys = self.publicKeys
        s = long(s)
        n = self.n
        t = self.t
        secret = ec.multiply(self.generatorPrimary, s)
        print "Secret : " + tostr(secret)
        poly = [self.sample(self.order) for i in range(t - 1)]
        poly.append(s)
        preSecrets = []
        shares = []

        for i in range(1, n + 1):
            temp = long(self.evaluatePoly(poly, i, self.order))
            preSecrets.append(temp)
            temp = ec.multiply(publicKeys[i - 1], temp)
            shares.append(temp)
        proof = self.generateZKP(preSecrets, shares)

        print "Polynomial Coefficients : " + tostr(poly)
        print "Evaluations: " + tostr(preSecrets)
        print "...Shares: " + conc([tostr(s) for s in shares])
        return shares, proof
Ejemplo n.º 16
0
 def verifyZKP(self, shares, vArr, e, zArr, verbal):
     if verbal: print "\nVerification..."
     self.verifyByCode(vArr, verbal)
     n = len(shares)
     if verbal: print "\ne = " + str(e) + "\nIntermediates"
     toBeHashed = bytes('')
     for i in range(n):
         sh = shares[i]
         v = vArr[i]
         (a1,a2) = (ec.add(ec.multiply(self.publicKeys[i],zArr[i]),ec.multiply(shares[i],e)),\
          ec.add(ec.multiply(self.generatorSecondary,zArr[i]),ec.multiply(vArr[i],e)))
         if verbal:
             print conc([str(ele) for ele in [a1[0], a1[1], a2[0], a2[1]]])
         arr = [sh[0], sh[1], v[0], v[1], a1[0], a1[1], a2[0], a2[1]]
         for ele in arr:
             toBeHashed += encode_int32(ele)
     eVerify = sha3(toBeHashed)
     e = encode_int32(e)
     if verbal:
         print "Recovered e : " + mpz(codecs.encode(eVerify, 'hex'),
                                      16).digits()
     #if verbal : print codecs.encode(str(e),'hex')
     return eVerify == e
Ejemplo n.º 17
0
    def process_decryption_key_part(self,
                                    sender_address: int,
                                    decryption_key_part: int,
                                    signature: 'rsv triplet'):
        participant = self.get_participant_by_address(sender_address)

        msg_bytes = (
            b'DECRYPTIONKEYPART' +
            self.decryption_condition.encode() +
            util.private_value_to_bytes(decryption_key_part)
        )

        recovered_address = util.address_from_message_and_signature(msg_bytes, signature)

        if sender_address != recovered_address:
            raise ValueError(
                'sender address {:040x} does not match recovered address {:040x}'
                .format(sender_address, recovered_address)
            )

        if participant.decryption_key_part is None:
            if secp256k1.multiply(secp256k1.G, decryption_key_part) != participant.encryption_key_vector[0]:
                participant.get_or_create_complaint_by_complainer_address(own_address)
                raise ValueError(
                    '{:040x} sent dec key part which does not match previously sent enc key vector'
                    .format(sender_address)
                )

            participant.decryption_key_part = decryption_key_part
            participant.decryption_key_part_signature = signature

            if all(p.decryption_key_part is not None for p in self.participants):
                self.decryption_key = (
                    sum(p.decryption_key_part for p in self.participants) +
                    self.secret_poly1[0]
                ) % secp256k1.N

            db.Session.commit()
        elif participant.decryption_key_part != decryption_key_part:
            participant.get_or_create_complaint_by_complainer_address(own_address)
            raise ValueError(
                '{:040x} sent decryption key part for {} which do not match: {} != {}'
                .format(
                    sender_address,
                    self.decryption_condition,
                    participant.decryption_key_part,
                    decryption_key_part,
                )
            )
Ejemplo n.º 18
0
    def PVSSReconstruct(self, xl, dSecrets):
        t = self.t
        result = (0, 0)
        for x, d in zip(xl, dSecrets):
            lambnum = 1
            lambden = 1
            for otherx in xl:
                if not otherx == x:
                    lambnum *= otherx
                    lambden *= otherx - x

            lamb = lambnum * gmpy2.invert(lambden, self.order)
            lamb = gmpy2.f_mod(lamb, self.order)
            print "Lambda (" + str(x) + ") : " + str(lamb)
            temp = ec.multiply(d, long(lamb))
            result = ec.add(result, temp)
        return result
Ejemplo n.º 19
0
def test_can_decrypt_encrypted_random_messages(chain):
    # TODO: Fix populus compat
    ies, _ = chain.provider.get_or_deploy_contract(
        'IntegratedEncryptionScheme')
    num_runs = 10
    average_gas_cost = 0
    for _ in range(num_runs):
        message = os.urandom(util.random.randrange(1, 100))
        deckey = util.random_private_value()
        enckey = secp256k1.multiply(secp256k1.G, deckey)
        ciphertext = crypto.encrypt(message, enckey)
        assert message == crypto.decrypt(ciphertext, deckey)
        assert crypto.decrypt(ciphertext, deckey,
                              foo=True) == ies.call().decrypt(
                                  ciphertext, deckey)
        average_gas_cost += ies.estimateGas().decrypt(ciphertext, deckey)

    average_gas_cost /= num_runs
Ejemplo n.º 20
0
    def verifyByCode(self, vArr, verbal):
        randomVec = [
            int(gmpy2.mpz_random(self.rs, self.order))
            for i in range(self.n - self.t)
        ]
        codewordInDual = self.code.getCodewordInDual(randomVec)
        codewordInDual = [
            gmpy2.f_mod(mpz(int(ele)), self.order) for ele in codewordInDual
        ]
        if verbal: print "Random codeword from dual : " + tostr(codewordInDual)
        if verbal: print "Intermediates"

        product = (0L, 0L)
        for vi, ci in zip(vArr, codewordInDual):
            temp = ec.multiply(vi, ci)
            if verbal: print str(ci) + " x " + tostr(vi) + " = " + tostr(temp)
            product = ec.add(product, temp)
        if verbal: print "Product : " + tostr(product)
        if product == (0L, 0L):
            if verbal: print "...Codeword valid : v"
Ejemplo n.º 21
0
def test_nodes_match_enckey_and_deckeys(nodes, request_timeout):
    wait_for_all_nodes_connected(nodes, request_timeout)

    deccond = 'past {}'.format(datetime.utcnow().isoformat())
    enckeys = [
        requests.post('http://localhost:{}'.format(n.port),
                      verify=False,
                      timeout=request_timeout,
                      data=json.dumps({
                          'id': 'honk',
                          'method': 'get_encryption_key',
                          'params': [deccond],
                      })).json()['result'] for n in nodes
    ]

    enckeys = [tuple(int(ek[i:i + 64], 16) for i in (0, 64)) for ek in enckeys]

    for ek in enckeys:
        util.validate_curve_point(ek)

    assert (all(ek == enckeys[0] for ek in enckeys[1:]))

    deckeys = [
        requests.post('http://localhost:{}'.format(n.port),
                      verify=False,
                      timeout=request_timeout,
                      data=json.dumps({
                          'id': 'honk',
                          'method': 'get_decryption_key',
                          'params': [deccond],
                      })).json()['result'] for n in nodes
    ]

    deckeys = [int(dk, 16) for dk in deckeys]

    for dk in deckeys:
        util.validate_private_value(dk)

    assert (all(dk == deckeys[0] for dk in deckeys[1:]))

    assert (secp256k1.multiply(secp256k1.G, deckeys[0]) == enckeys[0])
Ejemplo n.º 22
0
def private_value_to_eth_address(private_value: int) -> int:
    return curve_point_to_eth_address(secp256k1.multiply(secp256k1.G, private_value))
Ejemplo n.º 23
0
def generate_public_shares(poly1, poly2):
    if len(poly1) != len(poly2):
        raise ValueError('polynomial lengths must match ({} != {})'.format(len(poly1), len(poly2)))

    return (secp256k1.add(secp256k1.multiply(secp256k1.G, a), secp256k1.multiply(G2, b)) for a, b in zip(poly1, poly2))
Ejemplo n.º 24
0
import sys
from random import randint
from py_ecc.secp256k1.secp256k1 import add, multiply, inv, N, P, G
from .utils import hashs

#assert False == "Do not use, use altbn128"

safe_ord = ord if sys.version_info.major == 2 else lambda x: x if isinstance(
    x, int) else ord(x)
bytes_to_int = lambda x: reduce(lambda o, b:
                                (o << 8) + safe_ord(b), [0] + list(x))
hashsn = lambda *x: hashs(*x) % N
hashpn = lambda *x: hashsn(*[item for sublist in x for item in sublist])
randsn = lambda: randint(1, N - 1)
sbmul = lambda s: multiply(G, s)
invmulp = lambda x, y: (x * pow(y, P - 2, P))
invmodn = lambda x: inv(x, N)
addmodn = lambda x, y: (x + y) % N
mulmodn = lambda x, y: (x * y) % N
submodn = lambda x, y: (x - y) % N
negp = lambda x: (x[0], -x[1])
Ejemplo n.º 25
0
 def public_key(self):
     return secp256k1.multiply(secp256k1.G, self.private_key)
Ejemplo n.º 26
0
 def generateKeyPair(self):
     secretKey = self.sample(self.order - 1) + 1
     publicKey = ec.multiply(self.generatorPrimary, secretKey)
     return [secretKey, publicKey]
Ejemplo n.º 27
0
def GetAddrFromSharedSecret(ss, pub_spend_key):
    P = curve.multiply(curve.G, int.from_bytes(ss, 'big'))
    P = curve.add(P, pub_spend_key)
    addr = GetAddrFromPubKey(P)
    return addr
Ejemplo n.º 28
0
 def decryptShare(self, share, secretKey):
     secretKey = mpz(secretKey)
     inv = long(gmpy2.invert(secretKey, self.order))
     result = ec.multiply(share, inv)
     return result