Exemplo n.º 1
0
def verifiy_ASNL(P1, P2, L1, s2, s):
    """

    :param P1: public key 1, from_string format (32bytes)
    :param P2: public key 2, from_string format (32bytes)
    :param L1: vector of public key (to_string format, 32bytes)
    :param s2: vector of 32 bytes number
    :param s: 32 bytes number, aggregate of s1
    :return:
    """
    n = len(P1)
    LHS = to_32_bytes_number(0)
    RHS = g.from_string(s, curve=crv).verifying_key.pubkey.point
    for j in range(0, n):
        c2 = hashlib.sha256(L1[j]).digest()
        L2Point = g.from_string(s2[j], curve=crv).verifying_key.pubkey.point + (
            VerifyingKey.from_string(P2[j], curve=crv).pubkey.point
            * to_int_from_bytes(c2)
        )
        L2 = VerifyingKey.from_public_point(L2Point, curve=crv).to_string()
        if j == 0:
            LHS = VerifyingKey.from_string(L1[j], curve=crv).pubkey.point
        else:
            LHS = LHS + VerifyingKey.from_string(L1[j], curve=crv).pubkey.point
        c1 = hashlib.sha256(L2).digest()
        RHS = RHS + (
            VerifyingKey.from_string(P1[j], curve=crv).pubkey.point
            * to_int_from_bytes(c1)
        )
    assert (
        VerifyingKey.from_public_point(LHS, curve=crv).to_string()
        == VerifyingKey.from_public_point(RHS, curve=crv).to_string()
    ), "generate_ASNL failed to generate a valid signature.\nAborting..."
Exemplo n.º 2
0
def ecdh_encode(mask, amount, receiver_public_key):
    """
    This function encode the a number (the amount) so that it can only be decoded with the receiver private key.
    Amount is however only masked, calculation can still be applied on it.

    :param mask: the mask to hide (32 bytes number)
    :param amount: the amount to hide (32 bytes number)
    :param receiver_public_key: the receiver public key (sec format)
    :return: a triplet of new_mask: hidden mask (32 bytes number)
                          new_amount: hidden amount (32 bytes number)
                          sender_public_key: the public key generated by the sender to encode this amount (sec format)

    """
    secret = to_32_bytes_number(random.randrange(crv.order))
    sender_secret_key = g.from_string(secret, curve=crv)
    sender_public_key = sender_secret_key.verifying_key
    recv_public_key = VerifyingKey.from_string(receiver_public_key, curve=crv)
    to_hash = VerifyingKey.from_public_point(
        recv_public_key.pubkey.point * to_int_from_bytes(secret), curve=crv
    ).to_string()
    shared_secret_int = to_int_from_bytes(hashlib.sha256(to_hash).digest())
    new_mask = (to_int_from_bytes(mask) + shared_secret_int) % crv.order
    new_amount = (to_int_from_bytes(amount) + shared_secret_int) % crv.order
    return (
        to_32_bytes_number(new_mask),
        to_32_bytes_number(new_amount),
        sender_public_key.tpo_string(),
    )
Exemplo n.º 3
0
def verify_schnorr_non_linkable(P1, P2, L1, s1, s2):
    # P1: Pubkey in from_string format (32 bytes)
    # P2: Pubkey in from_string format (32 bytes)
    # L1: output of GenSchnorr, pubkey in from_string format (32 bytes)
    # s1: output of GenSchnorr, number (32 bytes)
    # s2: output of GenSchnorr, number (32 bytes)
    L1Point = VerifyingKey.from_string(L1, curve=crv).pubkey.point
    c2 = hashlib.sha256(
        to_32_bytes_number(L1Point.x()) + to_32_bytes_number(L1Point.y())
    ).digest()
    L2PointA = g.from_string(s2, curve=crv).verifying_key.pubkey.point
    L2Point = g.from_string(s2, curve=crv).verifying_key.pubkey.point + (
        VerifyingKey.from_string(P2, curve=crv).pubkey.point * to_int_from_bytes(c2)
    )
    c1 = hashlib.sha256(
        to_32_bytes_number(L2Point.x()) + to_32_bytes_number(L2Point.y())
    ).digest()
    L1p = VerifyingKey.from_public_point(
        g.from_string(s1, curve=crv).verifying_key.pubkey.point
        + (
            VerifyingKey.from_string(P1, curve=crv).pubkey.point * to_int_from_bytes(c1)
        ),
        curve=crv,
    ).to_string()
    assert (
        L1 == L1p
    ), "generate_schnorr_non_linkable failed to generate a valid signature.\nAborting..."
Exemplo n.º 4
0
 def from_point(cls, point, network=BitcoinMainNet, **kwargs):
     """Create a PublicKey from a point on the SECP256k1 curve.
     :param point: A point on the SECP256k1 curve.
     :type point: SECP256k1.point
     """
     verifying_key = VerifyingKey.from_public_point(point, curve=SECP256k1)
     return cls.from_verifying_key(verifying_key, network=network, **kwargs)
Exemplo n.º 5
0
    def verify(self,
               to_be_signed: bytes,
               signature: bytes,
               alg: Optional[CoseAlgorithms] = None,
               curve: Optional[EllipticCurveType] = None) -> bool:
        """
        Verifies the digital signature over 'to_be_signed'. The parameter 'alg' and 'curve' parameters are optional in
        case they are already provided by one of the COSE key objects.

        :param to_be_signed: data that was signed
        :param signature: signature to verify
        :param alg: an optional algorithm parameter (specifies the exact algorithm used for the signature).
        :param curve: an optional curve
        """

        self._check_key_conf(algorithm=alg,
                             key_operation=KeyOps.VERIFY,
                             curve=curve)

        try:
            alg_cfg = config(CoseAlgorithms(self.alg))
        except KeyError as err:
            raise CoseInvalidAlgorithm(err)

        p = Point(curve=alg_cfg.curve.curve,
                  x=int(hexlify(self.x), 16),
                  y=int(hexlify(self.y), 16))
        vk = VerifyingKey.from_public_point(p,
                                            alg_cfg.curve,
                                            alg_cfg.hash,
                                            validate_point=True)

        return vk.verify(signature, to_be_signed)
Exemplo n.º 6
0
def from_sec(string,
             curve=curves.SECP256k1,
             hashfunc=sha1,
             validate_point=True):
    """Convert a public key in SEC binary format to a verifying key."""
    # based on code from https://github.com/richardkiss/pycoin
    if string.startswith(b('\x04')):
        # uncompressed
        return VerifyingKey.from_string(string[1:], curve, hashfunc,
                                        validate_point)
    elif string.startswith(b('\x02')) or string.startswith(b('\x03')):
        # compressed
        is_even = string.startswith(b('\x02'))
        x = string_to_number(string[1:])
        order = curve.order
        p = curve.curve.p()
        alpha = (pow(x, 3, p) + (curve.curve.a() * x) + curve.curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        if is_even == bool(beta & 1):
            y = p - beta
        else:
            y = beta
        if validate_point:
            assert ecdsa.point_is_valid(curve.generator, x, y)
        point = ellipticcurve.Point(curve.curve, x, y, order)
        return VerifyingKey.from_public_point(point, curve, hashfunc)
Exemplo n.º 7
0
    def get_ecdsa_verifying_key(pub):
        #some shenanigans required to validate a transaction sig; see
        #python.ecdsa PR #54. This will be a lot simpler when that's merged.
        #https://github.com/warner/python-ecdsa/pull/54/files
        if not pub[0] in ["\x02", "\x03"]:
            log.debug("Invalid pubkey")
            return None
        is_even = pub.startswith('\x02')
        x = string_to_number(pub[1:])
        order = SECP256k1.order
        p = SECP256k1.curve.p()
        alpha = (pow(x, 3, p) +
                 (SECP256k1.curve.a() * x) + SECP256k1.curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        if is_even == bool(beta & 1):
            y = p - beta
        else:
            y = beta
        if not point_is_valid(SECP256k1.generator, x, y):
            return None

        point = Point(SECP256k1.curve, x, y, order)
        return VerifyingKey.from_public_point(point,
                                              SECP256k1,
                                              hashfunc=hashlib.sha256)
Exemplo n.º 8
0
    def from_parent(parent_key, i):
        if i & HARDENED_INDEX:
            raise ValueError(
                "Can't generate a hardened child key from a parent public key."
            )

        child = hmac.new(
            parent_key.chain_code,
            parent_key.compressed_key + i.to_bytes(length=4, byteorder='big'),
            hashlib.sha512).digest()
        child_left, child_right = child[:32], child[32:]
        if int.from_bytes(child_left, 'big') >= ecdsa.generator_256.order():
            return None

        temp_pri_key = SigningKey.from_string(string=child_left,
                                              curve=curves.NIST256p)

        ki = temp_pri_key.verifying_key.pubkey.point + parent_key.key.pubkey.point
        if ki == ellipticcurve.INFINITY:
            return None

        return HDPublicKey(public_key=VerifyingKey.from_public_point(
            point=ki, curve=curves.NIST256p),
                           chain_code=child_right,
                           index=i,
                           depth=parent_key.depth + 1,
                           parent_fingerprint=parent_key.fingerprint)
Exemplo n.º 9
0
 def derive(self, path="m"):
     tokens = path.split('/')
     if tokens[0] == "m":
         k = self.m
         c = self.c
         for r in tokens[1:]:
             if not rformat.match(r):
                 raise self.path_error
             if r[-1] == "'":
                 i = iH(int(r[:-1]))
             else:
                 i = int(r)
             k, c = ckd_prv(k, c, i)
         return SigningKey.from_string(k.to_bytes(32, byteorder='big'),
                                       curve=SECP256k1)
     elif tokens[0] == "M":
         K = self.M
         c = self.c
         for r in tokens[1:]:
             if not rformat.match(r):
                 raise self.path_error
             if r[-1] == "'":
                 i = iH(int(r[:-1]))
             else:
                 i = int(r)
             K, c = ckd_pub(K, c, i)
         return VerifyingKey.from_public_point(K, curve=SECP256k1)
     else:
         raise self.path_error
Exemplo n.º 10
0
Arquivo: ec.py Projeto: hdknr/jose
 def create_material(self, bits, d=None, x=None, y=None):
     curve = self.curve_for_bits(bits)
     if d:
         return SigningKey.from_secret_exponent(d, curve)
     if x and y:
         point = ec.Point(curve.curve, x, y, curve.order)
         return VerifyingKey.from_public_point(point, curve)
Exemplo n.º 11
0
    def from_point(cls, point, network=BitcoinMainNet, **kwargs):
        """Create a PublicKey from a point on the SECP256k1 curve.

        :param point: A point on the SECP256k1 curve.
        :type point: SECP256k1.point
        """
        verifying_key = VerifyingKey.from_public_point(point, curve=SECP256k1)
        return cls.from_verifying_key(verifying_key, network=network, **kwargs)
Exemplo n.º 12
0
Arquivo: util.py Projeto: IO42630/ace
def vk_from_point(x: bytes, y: bytes):
    curve = ecdsa_curves.NIST256p
    x = int(x.hex(), 16)
    y = int(y.hex(), 16)

    p = ellipticcurve.Point(curve.curve, x, y)
    key = VerifyingKey.from_public_point(p, curve)

    return key
Exemplo n.º 13
0
def _CKD_pub(cK, c, s):
    order = generator_secp256k1.order()
    I = hmac.new(c, cK + s, hashlib.sha512).digest()
    curve = SECP256k1
    pubkey_point = string_to_number(
        I[0:32]) * curve.generator + ser_to_point(cK)
    public_key = VerifyingKey.from_public_point(pubkey_point, curve=SECP256k1)
    c_n = I[32:]
    cK_n = GetPubKey(public_key.pubkey, True)
    return cK_n, c_n
Exemplo n.º 14
0
def _pubkey_point_to_bytes(public_key_point, compressed=True):
    """
    Converts public key point to bytes (compressed format).

    :param public_key_point:
    :return: public key in compressed format
    """
    arg_compr = 'compressed' if compressed else 'uncompressed'
    pki = VerifyingKey.from_public_point(public_key_point, curve=CURVE)
    pub_key = pki.to_string(encoding=arg_compr)
    return pub_key
Exemplo n.º 15
0
Arquivo: util.py Projeto: IO42630/ace
def ecdsa_cose_to_key(encoded: bytes) -> VerifyingKey:
    decoded = loads(encoded)

    kty = decoded[CoseKey.KTY]
    curve = _ecdsa_curves[decoded[CoseKey.CRV]]
    x = int(decoded[CoseKey.X].hex(), 16)
    y = int(decoded[CoseKey.Y].hex(), 16)

    p = ellipticcurve.Point(curve.curve, x, y)
    key = VerifyingKey.from_public_point(p, curve)

    return key
Exemplo n.º 16
0
 def readkeys(self, path):
     """
     read private keys from a directory, which must containser private.key, address and public.key
     """
     self.address = open(path + "/address").read()
     self.private_key_js = open(path + "/private.key").read()
     self.public_key_js = open(path + "/public.key").read()
     sk_obj = json.loads(self.private_key_js)
     X = int(sk_obj['X'])
     Y = int(sk_obj['Y'])
     D = int(sk_obj['D'])
     self.public_key = VerifyingKey.from_public_point(ellipticcurve.Point(NIST256p.curve, X, Y), NIST256p, double_sha256)
     self.private_key = SigningKey.from_secret_exponent(D, NIST256p, double_sha256)
Exemplo n.º 17
0
def verify_range_proofs(rg):
    HPow2 = hash_to_point(to_32_bytes_number(1)).pubkey.point
    H2 = []
    for i in range(0, ATOMS):
        H2.append(VerifyingKey.from_public_point(HPow2, curve=crv).to_string())
        HPow2 = HPow2 * 2
    CiH = []
    Ci = rg[0]
    [L1, s2, s] = rg[1]
    for i in range(0, ATOMS):
        negate_h2 = Point(
            crv.curve,
            VerifyingKey.from_string(H2[i], curve=crv).pubkey.point.x(),
            (-VerifyingKey.from_string(H2[i], curve=crv).pubkey.point.y()),
            crv.order,
        )
        CiH.append(
            VerifyingKey.from_public_point(
                VerifyingKey.from_string(Ci[i], curve=crv).pubkey.point + negate_h2,
                curve=crv,
            ).to_string()
        )
    verifiy_ASNL(Ci, CiH, L1, s2, s)
Exemplo n.º 18
0
 def mk_public_keyobj(self):
     if self.public_key is None:
         return
     if self.type == KeyType.ECDSA_SECP256k1_XY:
         self.key_len = int(len(self.public_key) / 2)
         x = self.to_bigint(self.public_key[0:self.key_len])
         y = self.to_bigint(self.public_key[self.key_len:self.key_len * 2])
         point = ecdsa.ellipticcurve.Point(ECDSA_CURVE.curve, x, y)
         if not ecdsa.ecdsa.point_is_valid(ECDSA_CURVE.generator, x, y):
             return
         self.public_key_object = VerifyingKey.from_public_point(
             point, curve=ECDSA_CURVE)
     elif self.type == KeyType.ECDSA_SECP256k1_X:
         self.key_len = len(self.public_key)
         x = self.to_bigint(self.public_key)
         # TODO: calc Y and make point object(X,Y)
         pass
Exemplo n.º 19
0
def verify_message(address, signature, message):
    curve = curve_secp256k1
    G = generator_secp256k1
    order = G.order()
    # extract r,s from signature
    sig = base64.b64decode(signature)
    if len(sig) != 65: raise BaseException("Wrong encoding")
    r, s = util.sigdecode_string(sig[1:], order)
    nV = ord(sig[0])
    if nV < 27 or nV >= 35:
        return False
    if nV >= 31:
        compressed = True
        nV -= 4
    else:
        compressed = False
    recid = nV - 27
    # 1.1
    x = r + (recid / 2) * order
    # 1.3
    alpha = (x * x * x + curve.a() * x + curve.b()) % curve.p()
    beta = modular_sqrt(alpha, curve.p())
    y = beta if (beta - recid) % 2 == 0 else curve.p() - beta
    # 1.4 the constructor checks that nR is at infinity
    R = Point(curve, x, y, order)
    # 1.5 compute e from message:
    h = double_sha256(message)
    e = int(h.encode('hex'), 16)
    minus_e = -e % order
    # 1.6 compute Q = r^-1 (sR - eG)
    inv_r = numbertheory.inverse_mod(r, order)
    Q = inv_r * (s * R + minus_e * G)
    public_key = VerifyingKey.from_public_point(Q, curve=secp256k1)
    # check that Q is the public key
    public_key.verify_digest(sig[1:], h, sigdecode=util.sigdecode_string)
    # check that we get the original signing address
    addr = public_key_to_bc_address(encode_point(public_key, compressed))
    if address == addr:
        return True
    else:
        # print addr
        return False
def validate_keys(sk: int, vk: Point) -> bool:
    std_sk = SigningKey.from_secret_exponent(sk, SECP256k1, sha256)
    std_vk = std_sk.get_verifying_key()
    std_point = ellipticcurve.Point(SECP256k1.curve, vk[0].value, vk[1].value)
    std_vk_from_point = VerifyingKey.from_public_point(std_point, SECP256k1,
                                                       sha256)
    public_keys_match = std_vk_from_point.to_string() == std_vk.to_string()

    print(
        f"Your private key is {sk} and the respective public key is {represent_point(vk)}."
    )
    if public_keys_match:
        print(
            f"This private key generates the same public key using py-ecdsa.")
    else:
        print(
            f"The public key generated using py-ecdsa is {str(std_vk.pubkey.point)}"
        )

    return public_keys_match
Exemplo n.º 21
0
def ecdh_decode(mask, amount, sender_public_key, receiver_secret_key):
    """
    Function doing the decoding of ecdhEncode. Take the mask, the masked amount and appropriate public keys and return
    the decoded amount.
    :param mask: the hidden mask (32 bytes number)
    :param amount: the hidden amount (32 bytes number)
    :param sender_public_key: the public key generated by the sender to encode this amount (sec format)
    :param receiver_secret_key: the receiver sk (32 bytes number)
    :return: tuple consisting of new_mask: unhidden mask (32 bytes number)
                                 new_amount: unhidden amount (32 bytes number)
    """

    send_public_key = VerifyingKey.from_string(sender_public_key, curve=crv)
    to_hash = VerifyingKey.from_public_point(
        send_public_key.pubkey.point * to_int_from_bytes(receiver_secret_key), curve=crv
    ).to_string()
    shared_secret_int = to_int_from_bytes(hashlib.sha256(to_hash).digest())
    new_mask = (to_int_from_bytes(mask) - shared_secret_int) % crv.order
    new_amount = (to_int_from_bytes(amount) - shared_secret_int) % crv.order
    return to_32_bytes_number(new_mask), to_32_bytes_number(new_amount)
Exemplo n.º 22
0
def from_sec(string, curve=curves.SECP256k1, hashfunc=sha1, validate_point=True):
    """Convert a public key in SEC binary format to a verifying key."""
    # based on code from https://github.com/richardkiss/pycoin
    if string.startswith(b("\x04")):
        # uncompressed
        return VerifyingKey.from_string(string[1:], curve, hashfunc, validate_point)
    elif string.startswith(b("\x02")) or string.startswith(b("\x03")):
        # compressed
        is_even = string.startswith(b("\x02"))
        x = string_to_number(string[1:])
        order = curve.order
        p = curve.curve.p()
        alpha = (pow(x, 3, p) + (curve.curve.a() * x) + curve.curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        if is_even == bool(beta & 1):
            y = p - beta
        else:
            y = beta
        if validate_point:
            assert ecdsa.point_is_valid(curve.generator, x, y)
        point = ellipticcurve.Point(curve.curve, x, y, order)
        return VerifyingKey.from_public_point(point, curve, hashfunc)
Exemplo n.º 23
0
 def get_ecdsa_verifying_key(pub):
     #some shenanigans required to validate a transaction sig; see
     #python.ecdsa PR #54. This will be a lot simpler when that's merged.
     #https://github.com/warner/python-ecdsa/pull/54/files
     if not pub[0] in ["\x02", "\x03"]:
         log.debug("Invalid pubkey")
         return None    
     is_even = pub.startswith('\x02')
     x = string_to_number(pub[1:])
     order = SECP256k1.order
     p = SECP256k1.curve.p()
     alpha = (pow(x, 3, p) + (SECP256k1.curve.a() * x) + SECP256k1.curve.b()) % p
     beta = square_root_mod_prime(alpha, p)
     if is_even == bool(beta & 1):
         y = p - beta
     else:
         y = beta
     if not point_is_valid(SECP256k1.generator, x, y):
         return None
     
     point = Point(SECP256k1.curve, x, y, order)
     return VerifyingKey.from_public_point(point, SECP256k1,
                                                hashfunc=hashlib.sha256)
Exemplo n.º 24
0
def ecdsa_pub(x, y):
    """Create a public key from a public point"""
    point = ellipticcurve.Point(SECP256k1, x, y)
    return VerifyingKey.from_public_point(point, curve=SECP256k1)
Exemplo n.º 25
0
def create_transaction(
    message, in_public_key, in_secret_key, in_amounts, destinations, out_amounts, mixin
):
    """

    :param message:
    :param in_public_key: vector of public keys corresponding to the owner inputs(sec format)
    :param in_secret_key: vector of private keys corresponding to the public keys (format 32bytes number)
    :param in_amounts: vector of number corresponding to the amount coming from corresponding public key
    :param destinations: vector of public keys (sec format)
    :param out_amounts: vector of the different amounts going to the respective destinations public keys (int)
    :param mixin: the number of pk to get involved in the rings (int)
    :return: a list composed of destinations: a vector of destinations public keys as received (sec format)
                                destinations_commitment: a vector of commitment assigned to each
                                                        destinations public keys (32 bytes numbers)
                                I: part of MLSAG, a vector of pk in sec format corresponding the the sha256 hash of the
                                   sender public key
                                c_0: part of MLSAG, first sha3_256 (keccack) of the consecutive series of the MLSAG
                                ss: part of MLSAG, a matrix of "random" 32 bytes number
                                info: an array of ecdhEncode result containing the amount paid to the
                                       corresponding output pk
                                range_signatures: vector of range_signatures (format TODO)
    """

    print("------  Let's create a the transaction  ------")
    assert 0 < mixin < MAX_MIXIN, (
        "The number of ring participant should be between 0 and "
        + str(MAX_MIXIN)
        + "\n Aborting..."
    )
    assert len(in_secret_key) == len(in_public_key) and len(in_amounts) == len(
        in_public_key
    ), "The number of private key doesn't match the number of public key or the number of input amounts.\nAborting..."
    assert len(destinations) == len(
        out_amounts
    ), "The number of outputs addresses should match the number of outputs amounts.\nAborting..."
    m = len(in_secret_key)
    for i in range(0, m):
        assert 0 < in_amounts[i] < MAX_AMOUNT, (
            "The ingoing amount #"
            + str(i)
            + " should be between 0 and "
            + str(MAX_AMOUNT)
            + "\nAborting..."
        )
    out_num = len(destinations)
    for i in range(0, out_num):
        assert 0 < out_amounts[i] < MAX_AMOUNT, (
            "The outgoing amount #"
            + str(i)
            + " should be between 0 and "
            + str(MAX_AMOUNT)
            + "\nAborting..."
        )

    for i in range(0, m):
        assert (
            g.from_string(in_secret_key[i], curve=crv).verifying_key.to_string()
            == in_public_key[i]
        ), "One secret key doesn't match the corresponding public key.\nAborting..."

    print("------  All arguments are good, next !  ------")

    in_sk_masks = []
    in_pk_masks = []
    for i in range(0, m):
        sk_mask = to_32_bytes_number(random.randrange(crv.order))
        in_sk_masks.append(sk_mask)
        pk_mask = g.from_string(sk_mask, curve=crv).verifying_key
        a_h = hash_to_point(to_32_bytes_number(1)).pubkey.point * in_amounts[i]
        pk_mask_point = pk_mask.pubkey.point + a_h
        in_pk_masks.append(
            VerifyingKey.from_public_point(pk_mask_point, curve=crv).to_string()
        )

    destinations_commitment = []
    info = []
    range_signatures = []
    out_sk_masks = []
    for i in range(0, out_num):
        print("------ Creating rangeproof for amount#" + str(i + 1) + " ------")
        out_commit, out_sk_mask, rg = prove_range_signatures(out_amounts[i])
        destinations_commitment.append(out_commit)
        out_sk_masks.append(out_sk_mask)
        range_signatures.append(rg)
        hidden_mask, hidden_amount, sender_pk = ecdh_encode(
            out_sk_mask, to_32_bytes_number(out_amounts[i]), destinations[i]
        )
        info.append([hidden_mask, hidden_amount, sender_pk])

    print("------   Rangeproofs are valid. Next    ------")

    pk_matrix, pk_masks_matrix, index = populate_from_blockchain(
        in_public_key, in_pk_masks, mixin
    )

    print("------ Matrix populated, going further! ------")

    if debug:
        (newMatrix, (I, c_0, ss)) = prepareMG(
            message,
            pk_matrix,
            pk_masks_matrix,
            in_secret_key,
            in_sk_masks,
            destinations_commitment,
            out_sk_masks,
            index,
        )
        print("------ Transaction created with succes! ------")
        return (
            newMatrix,
            destinations,
            destinations_commitment,
            I,
            c_0,
            ss,
            info,
            range_signatures,
        )
    else:
        (newMatrix, (I, c_0, ss)) = prepareMG(
            message,
            pk_matrix,
            pk_masks_matrix,
            in_secret_key,
            in_sk_masks,
            destinations_commitment,
            out_sk_masks,
            index,
        )
        print("------ Transaction created with succes! ------")
        return (
            newMatrix,
            destinations,
            destinations_commitment,
            I,
            c_0,
            ss,
            info,
            range_signatures,
        )
Exemplo n.º 26
0
 def from_pair(cls, pair):
     x, y = pair
     point = Point(curve=SECP256k1.curve, x=x, y=y, order=SECP256k1.order)
     key = VerifyingKey.from_public_point(point, curve=SECP256k1)
     return cls(key)
Exemplo n.º 27
0
    def verify_message(self, address, signature, message):
        """Creates a public key from a message signature and verifies message

        Bitcoin uses a compact format for message signatures (for tx sigs it
        uses normal DER format). The format has the normal r and s parameters
        that ECDSA signatures have but also includes a prefix which encodes
        extra information. Using the prefix the public key can be
        reconstructed from the signature.

        |  Prefix values:
        |      27 - 0x1B = first key with even y
        |      28 - 0x1C = first key with odd y
        |      29 - 0x1D = second key with even y
        |      30 - 0x1E = second key with odd y

        If key is compressed add 4 (31 - 0x1F, 32 - 0x20, 33 - 0x21, 34 - 0x22 respectively)

        Raises
        ------
        ValueError
            If signature is invalid
        """

        sig = b64decode(signature.encode('utf-8'))
        if len(sig) != 65:
            raise ValueError('Invalid signature size')

        # get signature prefix, compressed and recid (which key is odd/even)
        prefix = sig[0]
        if prefix < 27 or prefix > 35:
            return False
        if prefix >= 31:
            compressed = True
            recid = prefix - 31
        else:
            compressed = False
            recid = prefix - 27

        # create message digest -- note double hashing
        message_magic = add_magic_prefix(message)
        message_digest = hashlib.sha256(
            hashlib.sha256(message_magic).digest()).digest()

        #
        # use recid, r and s to get the point in the curve
        #

        # get signature's r and s
        r, s = sigdecode_string(sig[1:], _order)

        # ger R's x coordinate
        x = r + (recid // 2) * _order

        # get R's y coordinate (y**2 = x**3 + 7)
        y_values = sqrt_mod((x**3 + 7) % _p, _p, True)
        if (y_values[0] - recid) % 2 == 0:
            y = y_values[0]
        else:
            y = y_values[1]

        # get R (recovered ephemeral key) from x,y
        R = ellipticcurve.Point(_curve, x, y, _order)

        # get e (hash of message encoded as big integer)
        e = int(hexlify(message_digest), 16)

        # compute public key Q = r^-1 (sR - eG)
        # because Point substraction is not defined we will instead use:
        # Q = r^-1 (sR + (-eG) )
        minus_e = -e % _order
        inv_r = numbertheory.inverse_mod(r, _order)
        Q = inv_r * (s * R + minus_e * _G)

        # instantiate the public key and verify message
        public_key = VerifyingKey.from_public_point(Q, curve=SECP256k1)
        key_hex = hexlify(public_key.to_string()).decode('utf-8')
        pubkey = PublicKey.from_hex('04' + key_hex)
        if not pubkey.verify(signature, message):
            return False

        # confirm that the address provided corresponds to that public key
        if pubkey.get_address(compressed=compressed).to_string() != address:
            return False

        return True
Exemplo n.º 28
0
 def from_pair(cls, pair):
     x, y = pair
     point = Point(curve=SECP256k1.curve, x=x, y=y, order=SECP256k1.order)
     key = VerifyingKey.from_public_point(point, curve=SECP256k1)
     return cls(key)
Exemplo n.º 29
0
def prepareMG(
    message,
    public_keys,
    public_key_commitments,
    in_sk,
    in_sk_mask,
    out_commitment,
    out_sk_masks,
    index,
):
    """

    :param message:
    :param public_keys: matrix of public key (size: qxm, sec format)
    :param public_key_commitments: matrix of commitment for pk (size: qxm, 32bytes)
    :param in_sk: vector of private key (size: m, bytes32 format)
    :param in_sk_mask: vector of mask for the corresponding sk (size: m, 32bytes)
    :param out_commitment: vector of commitment for pk (hidden amount) (size: outPKsize, 32bytes)
    :param out_sk_masks: vector mask for out public keys (bytes32)
    :param index: index of where in the public_keys matrix our pks are located
    :return: same as gen_MG
    """

    print("------  Preparing the matrix for the MG ------")

    rows_q = len(public_keys)
    if debug:
        assert (
            len(public_keys) == len(public_key_commitments) and len(public_keys) > 0
        ), "\
            Mismatch in the number of public commitment and keys.\nAborting..."
    cols_m = len(public_keys[0])
    if debug:
        assert (
            len(in_sk) == len(in_sk_mask) and len(in_sk) == cols_m
        ), "Mismatch in the number of private keys or private key masks.\nAborting..."
        for i in range(0, rows_q):
            assert (
                len(public_keys[i]) == len(public_key_commitments[i])
                and len(public_keys[i]) == cols_m
            ), "Mismatch in the number of public commitment and keys.\nAborting..."
        assert 0 <= index < rows_q, (
            "index: "
            + str(index)
            + " should be between 0 and "
            + str(rows_q)
            + " (the number of public key).\nAborting..."
        )
        assert (
            len(out_commitment) == len(out_sk_masks) and len(out_commitment) > 0
        ), "Mismatch in the number of private commitment and keys.\nAborting..."

    matrix = [[None] * (cols_m + 1) for y in range(rows_q)]
    sk = [None] * (cols_m + 1)
    for i in range(cols_m):
        sk[i] = in_sk[i]
        if i == 0:
            sk[cols_m] = in_sk_mask[i]
        else:
            sk[cols_m] = add_2_32b(sk[cols_m], in_sk_mask[i])
        for j in range(rows_q):
            matrix[j][i] = public_keys[j][i]
            if i == 0:
                matrix[j][cols_m] = VerifyingKey.from_string(
                    public_key_commitments[j][i], curve=crv
                ).pubkey.point
            else:
                matrix[j][cols_m] = (
                    matrix[j][cols_m]
                    + VerifyingKey.from_string(
                        public_key_commitments[j][i], curve=crv
                    ).pubkey.point
                )

    for i in range(len(out_commitment)):
        sk[cols_m] = sub_2_32b(sk[cols_m], out_sk_masks[i])
    for i in range(rows_q):
        for j in range(len(out_commitment)):
            point = VerifyingKey.from_string(out_commitment[j], curve=crv).pubkey.point
            matrix[i][cols_m] = (
                matrix[i][cols_m]
                + VerifyingKey.from_public_point(
                    Point(
                        crv.curve, point.x(), (-point.y()) % crv.curve.p(), crv.order
                    ),
                    curve=crv,
                ).pubkey.point
            )

    for j in range(rows_q):
        matrix[j][cols_m] = VerifyingKey.from_public_point(
            matrix[j][cols_m], curve=crv
        ).to_string()

    print("------  Done with the matrix for the MG ------")

    # TODO message
    return matrix, genMG(message, matrix, sk, index)
Exemplo n.º 30
0
def genMG(message, matrix, sk, index):

    n = len(matrix)
    if debug:
        assert n > 0, "No public key received.\nAborting..."
    m = len(matrix[0])
    if debug:
        assert m == len(
            sk
        ), "The number of secret key doesn't match the number of public key.\nAborting..."
        for i in range(0, n):
            assert (
                len(matrix[i]) == m
            ), "Public key array is not rectangular.\nAborting..."
        assert m > 0, "No public key in the array.\nAborting..."
        assert 0 <= index < m, "Not a valid index.\nAborting..."
        for i in range(0, m):
            assert (
                g.from_string(sk[i], curve=crv).verifying_key.to_string()
                == matrix[index][i]
            ), (
                "One secret key doesn't match the public key. Index: "
                + str(i)
                + "\n\
                Aborting..."
            )

    message_bytes = bytes(message, "UTF-8")

    alpha = [None] * m
    I = [None] * m
    ss = [[None] * m] * n

    L = [[[None, None]] * m] * n
    R = [[[None, None]] * m] * n

    for j in range(0, m):
        sk_j_hash_pub_point = hash_to_point(
            matrix[index][j]
        ).pubkey.point * to_int_from_bytes(sk[j])
        I[j] = VerifyingKey.from_public_point(
            sk_j_hash_pub_point, curve=crv
        ).to_string()

        alpha[j] = to_32_bytes_number(random.randrange(crv.order))
        LPoint = g.from_string(alpha[j], curve=crv).verifying_key.pubkey.point
        L[index][j] = [LPoint.x(), LPoint.y()]

        alpha_hash_pub_point = hash_to_point_special(
            matrix[index][j]
        ).pubkey.point * to_int_from_bytes(alpha[j])
        R[index][j] = [alpha_hash_pub_point.x(), alpha_hash_pub_point.y()]

    c_idx_1 = sha3.keccak_256(
        message_bytes + list_to_bytes(L[index]) + list_to_bytes(R[index])
    ).digest()

    c = c_idx_1
    c_0 = None
    for i in range(1, n):
        idx = (index + i) % n
        for j in range(0, m):
            # assert ss[idx][j] == None, "Hmm sounds bad"
            ss[idx][j] = to_32_bytes_number(random.randrange(crv.order))

            c_PubK = VerifyingKey.from_string(
                matrix[idx][j], curve=crv
            ).pubkey.point * to_int_from_bytes(c)
            sj_G = g.from_string(ss[idx][j], curve=crv)
            L_point = c_PubK + sj_G.verifying_key.pubkey.point
            L[idx][j] = [L_point.x(), L_point.y()]

            c_I = VerifyingKey.from_string(
                I[j], curve=crv
            ).pubkey.point * to_int_from_bytes(c)
            R_point = (
                hash_to_point_special(matrix[idx][j]).pubkey.point
                * to_int_from_bytes(ss[idx][j])
                + c_I
            )
            R[idx][j] = [R_point.x(), R_point.y()]

        c = sha3.keccak_256(
            message_bytes + list_to_bytes(L[idx]) + list_to_bytes(R[idx])
        ).digest()
        if idx == n - 1:
            c_0 = c

    print("------  Done with generating the MLSAG  ------")

    if debug:
        # sanity check:
        L_tmp = [[None, None]] * m
        R_tmp = [[None, None]] * m

        for j in range(0, m):
            ss[index][j] = to_32_bytes_number(
                (
                    to_int_from_bytes(alpha[j])
                    - to_int_from_bytes(c) * to_int_from_bytes(sk[j])
                )
                % crv.order
            )

            c_PubK = VerifyingKey.from_string(
                matrix[index][j], curve=crv
            ).pubkey.point * to_int_from_bytes(c)
            sj_G = g.from_string(ss[index][j], curve=crv)
            L_point = c_PubK + sj_G.verifying_key.pubkey.point
            L_tmp[j] = [L_point.x(), L_point.y()]

            c_I = VerifyingKey.from_string(
                I[j], curve=crv
            ).pubkey.point * to_int_from_bytes(c)
            R_point = (
                hash_to_point_special(matrix[index][j]).pubkey.point
                * to_int_from_bytes(ss[index][j])
                + c_I
            )
            R_tmp[j] = [R_point.x(), R_point.y()]

        c_tmp = sha3.keccak_256(
            message_bytes + list_to_bytes(L_tmp) + list_to_bytes(R_tmp)
        ).digest()
        assert (
            L_tmp == L[index] and R_tmp == R[index]
        ), "Sanity check for computing ss[index] failed.\nAborting..."

    if debug:
        assert verifyMG(
            message, matrix, I, c_0, ss
        ), "Ring verification failed.\nAborting..."
        print("------  Done with verifying the MLSAG   ------")
        return I, c_0, ss
    else:
        return I, c_0, ss
Exemplo n.º 31
0
 def __init__(self, pub_point: ecdsa.ellipticcurve.Point):
     self.verifying_key = VerifyingKey.from_public_point(
         pub_point, ecdsa.SECP256k1)
Exemplo n.º 32
0
def generate_schnorr_non_linkable(x, P1, P2, index):
    """

    :param x: 32 bytes number
    :param P1: public key (format string of bytes32 representation)
    :param P2: public key (format string of bytes32 representation)
    :param index: random value
    :return:
    """
    # x: bytes32 number
    # P1: pubkey in to string format bytes32
    # P2: pubkey in to string format bytes32

    if not index:
        a = to_32_bytes_number(random.randrange(crv.order))
        L1Point = g.from_string(a, curve=crv).verifying_key.pubkey.point
        s2 = to_32_bytes_number(random.randrange(crv.order))
        c2 = hashlib.sha256(
            to_32_bytes_number(L1Point.x()) + to_32_bytes_number(L1Point.y())
        ).digest()
        L2Point = g.from_string(s2, curve=crv).verifying_key.pubkey.point + (
            VerifyingKey.from_string(P2, curve=crv).pubkey.point * to_int_from_bytes(c2)
        )
        c1 = hashlib.sha256(
            to_32_bytes_number(L2Point.x()) + to_32_bytes_number(L2Point.y())
        ).digest()
        s1 = to_32_bytes_number(
            (to_int_from_bytes(a) - to_int_from_bytes(x) * to_int_from_bytes(c1))
            % crv.order
        )

        # sanity check
        if debug:
            L1p = g.from_string(s1, curve=crv).verifying_key.pubkey.point + (
                VerifyingKey.from_string(P1, curve=crv).pubkey.point
                * to_int_from_bytes(c1)
            )
            assert (
                VerifyingKey.from_public_point(L1p, curve=crv).to_string()
                == VerifyingKey.from_public_point(L1Point, curve=crv).to_string()
            ), "Sanity check failed in GenSchnorr 1\nAborting..."

    if index:
        a = to_32_bytes_number(random.randrange(crv.order))
        L2Point = g.from_string(a, curve=crv).verifying_key.pubkey.point
        s1 = to_32_bytes_number(random.randrange(crv.order))
        c1 = hashlib.sha256(
            to_32_bytes_number(L2Point.x()) + to_32_bytes_number(L2Point.y())
        ).digest()
        L1Point = g.from_string(s1, curve=crv).verifying_key.pubkey.point + (
            VerifyingKey.from_string(P1, curve=crv).pubkey.point * to_int_from_bytes(c1)
        )
        c2 = hashlib.sha256(
            to_32_bytes_number(L1Point.x()) + to_32_bytes_number(L1Point.y())
        ).digest()
        s2 = to_32_bytes_number(
            (to_int_from_bytes(a) - (to_int_from_bytes(x) * to_int_from_bytes(c2)))
            % crv.order
        )
        # sanity check
        if debug:
            L2p = g.from_string(s2, curve=crv).verifying_key.pubkey.point + (
                VerifyingKey.from_string(P2, curve=crv).pubkey.point
                * to_int_from_bytes(c2)
            )
            assert (
                VerifyingKey.from_public_point(L2p, curve=crv).to_string()
                == VerifyingKey.from_public_point(L2Point, curve=crv).to_string()
            ), "Sanity check failed in GenSchnorr 2\nAborting..."
    L1 = VerifyingKey.from_public_point(L1Point, curve=crv).to_string()
    return L1, s1, s2
Exemplo n.º 33
0
def prove_range_signatures(amount):
    """

    :param amount: the amount that should be proved (int)
    :return: a list made of C_pk: output commitment serving as a public key (to_string 32bytes format)
                            mask: part of the private key for C_pk. mask * G + amount * H == C_pk, 32 bytes number
                                  format
                            rg: vector of range proofs, each entry contain a vector of public key Ci and a
                                aggregate signature.
                            The aggregate signature itself contains L1: vector of public key (to_string format, 32bytes)
                                                                    s2: vector of 32 bytes number
                                                                    s: 32 bytes number, aggregate of s1
    For more info on asig, see generate_ASNL(...)
    """

    HPow2 = hash_to_point(to_32_bytes_number(1)).pubkey.point
    H2 = []
    for i in range(0, ATOMS):
        H2.append(VerifyingKey.from_public_point(HPow2, curve=crv).to_string())
        HPow2 = HPow2 * 2

    def d2b(n, digits):
        b = [0] * digits
        i = 0
        while n:
            b[i] = n & 1
            i = i + 1
            n >>= 1
        return b

    bb = d2b(amount, ATOMS)  # gives binary form of bb in "digits" binary digits
    mask = to_32_bytes_number(0)

    ai = []
    Ci = []
    CiH = []

    print("------   Preparing different elements   ------")
    for i in range(0, ATOMS):
        ai.append(to_32_bytes_number(random.randrange(crv.order)))
        mask = add_2_32b(
            mask, ai[i]
        )  # creating the total mask since you have to pass this to receiver...
        if bb[i] == 0:
            Ci.append(g.from_string(ai[i], curve=crv).verifying_key.to_string())
        if bb[i] == 1:
            Ci.append(
                VerifyingKey.from_public_point(
                    g.from_string(ai[i], curve=crv).verifying_key.pubkey.point
                    + VerifyingKey.from_string(H2[i], curve=crv).pubkey.point,
                    curve=crv,
                ).to_string()
            )

        negateH2 = Point(
            crv.curve,
            VerifyingKey.from_string(H2[i], curve=crv).pubkey.point.x(),
            (-VerifyingKey.from_string(H2[i], curve=crv).pubkey.point.y()),
            crv.order,
        )
        CiH.append(
            VerifyingKey.from_public_point(
                VerifyingKey.from_string(Ci[i], curve=crv).pubkey.point + negateH2,
                curve=crv,
            ).to_string()
        )

        if debug and bb[i] == 1:
            # Sanity check A + h2 - h2 == A
            assert (
                g.from_string(ai[i], curve=crv).verifying_key.to_string() == CiH[i]
            ), (
                "Sanity check failed in prove_range_signatures !"
                + bytes.hex(g.from_string(ai[i], curve=crv).verifying_key.to_string())
                + " ---- "
                + bytes.hex(CiH[i])
            )
    if rang_sig_bool:
        L1, s2, s = generate_ASNL(ai, Ci, CiH, bb)
        if debug:
            verifiy_ASNL(Ci, CiH, L1, s2, s)

        asig = [L1, s2, s]
        rg = [Ci, asig]
    else:
        rg = 1

    C_point = VerifyingKey.from_string(Ci[0], curve=crv).pubkey.point
    for i in range(1, len(Ci)):
        C_point = C_point + VerifyingKey.from_string(Ci[i], curve=crv).pubkey.point

    C = to_32_bytes_number(0)
    for i in range(0, len(Ci)):
        C = add_2_32b(C, Ci[i])

    C_pk = VerifyingKey.from_public_point(C_point, curve=crv)
    if debug:
        x = (
            hash_to_point(to_32_bytes_number(1)).pubkey.point * amount
            + g.from_string(mask, curve=crv).verifying_key.pubkey.point
        )
        assert (
            C_pk.to_string() == VerifyingKey.from_public_point(x, curve=crv).to_string()
        ), (
            "Something went wrong in the genreation of the commitment! "
            + bytes.hex(C_pk.to_string())
            + " should equal "
            + bytes.hex(VerifyingKey.from_public_point(x, curve=crv).to_string())
        )

    return C_pk.to_string(), mask, rg