def to_addr(self, pubhex): # pubhex is really privhex key = bytes.fromhex(pubhex) assert len(key) == 32, '{}: incorrect privkey length'.format(len(key)) from nacl.bindings import crypto_scalarmult_base p2 = crypto_scalarmult_base(self.zhash256(key, 1)) from .protocol import _b58chk_encode ver_bytes = g.proto.addr_fmt_to_ver_bytes('zcash_z') ret = _b58chk_encode(ver_bytes + self.zhash256(key, 0) + p2) return CoinAddr(ret)
def to_addr(self,pubhex): # pubhex is really privhex key = bytes.fromhex(pubhex) assert len(key) == 32,'{}: incorrect privkey length'.format(len(key)) from nacl.bindings import crypto_scalarmult_base p2 = crypto_scalarmult_base(self.zhash256(key,1)) from mmgen.protocol import _b58chk_encode ret = _b58chk_encode(g.proto.addr_ver_num['zcash_z'][0] + (self.zhash256(key,0)+p2).hex()) assert len(ret) == self.addr_width,'Invalid Zcash z-address length' return CoinAddr(ret)
def to_addr(self, pubhex): # pubhex is really privhex key = bytes.fromhex(pubhex) assert len(key) == 32, '{}: incorrect privkey length'.format(len(key)) from nacl.bindings import crypto_scalarmult_base p2 = crypto_scalarmult_base(self.zhash256(key, 1)) from mmgen.protocol import _b58chk_encode ret = _b58chk_encode(g.proto.addr_ver_num['zcash_z'][0] + (self.zhash256(key, 0) + p2).hex()) assert len(ret) == self.addr_width, 'Invalid Zcash z-address length' return CoinAddr(ret)
def x25519_scalarmult_base(scalar: ECScalar) -> ECPoint: """Scalar multiplication of the ED25519 base point with `scalar` The base point according to the Curve25519 paper is :math:`P = 9`. This function is commonly used to generate a public key (point) from a private scalar. :param scalar: Scalar (integer) `n`, in byte representation (:class:`ECScalar`) :returns: Point on curve, commonly interpreted as public key (if `n` is the private key) """ return ECPoint(crypto_scalarmult_base(scalar))
def to_addr(self, pubhex): # pubhex is really privhex key = pubhex.decode('hex') assert len(key) == 32, '{}: incorrect privkey length'.format(len(key)) if g.platform == 'win': ydie(1, 'Zcash z-addresses not supported on Windows platform') from nacl.bindings import crypto_scalarmult_base p2 = crypto_scalarmult_base(self.zhash256(key, 1)) from mmgen.protocol import _b58chk_encode ret = _b58chk_encode(g.proto.addr_ver_num['zcash_z'][0] + hexlify(self.zhash256(key, 0) + p2)) assert len(ret) == self.addr_width, 'Invalid Zcash z-address length' return CoinAddr(ret)
def __init__(self, private_key=None, public_key=None): if not private_key: private_key = os.urandom(ASYM_KEY_SIZE_BYTE) elif isinstance(private_key, str): private_key = decode_key(private_key) private_key_length = len(private_key) if private_key_length != ASYM_KEY_SIZE_BYTE: raise ValueError('(decoded) private key has wrong length: {} != {}'.format(private_key_length, ASYM_KEY_SIZE_BYTE)) if not public_key: public_key = crypto_scalarmult_base(private_key) self.private_key = private_key self.public_key = public_key
def test_c25519(rep=100, payload_size=1024 * 10): r = 5 from .SphinxParamsC25519 import Group_C25519 group = Group_C25519() params = SphinxParams(group=group, body_len=payload_size, assoc_len=4) # Monkey patch to use AES-CTR params.lioness_enc = params.xor_rho params.lioness_dec = params.xor_rho pki = {} pkiPriv = {} pkiPub = {} for i in range(10): nid = pack("b", i) x = params.group.gensecret() y = crypto_scalarmult_base(x) pkiPriv[nid] = pki_entry(nid, x, y) pkiPub[nid] = pki_entry(nid, None, y) # The simplest path selection algorithm and message packaging use_nodes = rand_subset(pkiPub.keys(), r) nodes_routing = list(map(Nenc, use_nodes)) node_keys = [pkiPub[n].y for n in use_nodes] print() assoc = [b"XXXX"] * len(nodes_routing) import time t0 = time.time() for _ in range(rep): header, delta = create_forward_message(params, nodes_routing, node_keys, b"dest", b"this is a test", assoc) t1 = time.time() print("Time per mix encoding: %.2fms" % ((t1 - t0) * 1000.0 / rep)) T_package = (t1 - t0) / rep from .SphinxNode import sphinx_process import time t0 = time.time() for _ in range(rep): x = pkiPriv[use_nodes[0]].x sphinx_process(params, x, header, delta, b"XXXX") t1 = time.time() print("Time per mix processing: %.2fms" % ((t1 - t0) * 1000.0 / rep)) T_process = (t1 - t0) / rep return T_package, T_process
def test_scalarmult(): x, xpub = secret_scalar() assert len(x) == 32 y, ypub = secret_scalar() # the Curve25519 base point (generator) base = unhexlify(b"09" + b"00" * 31) bx1 = c.crypto_scalarmult_base(x) bx2 = c.crypto_scalarmult(x, base) assert tohex(bx1) == tohex(bx2) assert tohex(bx1) == tohex(xpub) xby = c.crypto_scalarmult(x, c.crypto_scalarmult_base(y)) ybx = c.crypto_scalarmult(y, c.crypto_scalarmult_base(x)) assert tohex(xby) == tohex(ybx) z = unhexlify(b"10" * 32) bz1 = c.crypto_scalarmult_base(z) assert tohex(bz1) == ("781faab908430150daccdd6f9d6c5086" "e34f73a93ebbaa271765e5036edfc519") bz2 = c.crypto_scalarmult(z, base) assert tohex(bz1) == tohex(bz2)
def profile_ultrix_c25519(rep=100, payload_size=1024 * 10): r = 5 from .SphinxParamsC25519 import Group_C25519 from .UltrixNode import ultrix_process group = Group_C25519() params = SphinxParams(group=group, header_len = 32+50, body_len=payload_size, assoc_len=4) pkiPriv = {} pkiPub = {} for i in range(10): nid = pack("b", i) x = params.group.gensecret() y = crypto_scalarmult_base(x) pkiPriv[nid] = pki_entry(nid, x, y) pkiPub[nid] = pki_entry(nid, None, y) # The simplest path selection algorithm and message packaging use_nodes = rand_subset(pkiPub.keys(), r) nodes_routing = list(map(Nenc, use_nodes)) node_keys = [pkiPub[n].y for n in use_nodes] assoc = [b"XXXX"] * len(nodes_routing) import time ta = time.time() t0 = time.time() for _ in range(rep): header, delta = create_forward_message(params, nodes_routing, node_keys, b"dest", b"this is a test", assoc) t1 = time.time() print("Time per mix encoding: %.2fms" % ((t1-t0)*1000.0/rep)) t0 = time.time() for _ in range(rep): x = pkiPriv[use_nodes[0]].x ultrix_process(params, x, header, delta, b"XXXX") t1 = time.time() print("Time per mix processing: %.2fms" % ((t1-t0)*1000.0/rep)) tb = time.time() print("Total (for %d repeats): %.2fms" % (rep, (tb-ta)*1000.0))
def generate_serval_keys(name): node_hash = HexEncoder.decode(nacl.hash.sha256(name.encode("utf-8"))) sign_pk, sign_sk = crypto_sign_seed_keypair(node_hash) box_sk = crypto_sign_ed25519_sk_to_curve25519(sign_sk) box_pk = crypto_scalarmult_base(box_sk) rhiz_pk = HexEncoder.decode(nacl.hash.sha256(("rhizome"+name).encode("utf-8"))) keys = { "sign_pk": HexEncoder.encode(sign_pk).decode("ascii").upper(), "box_sk": HexEncoder.encode( box_sk).decode("ascii").upper(), "sign_sk": HexEncoder.encode(sign_sk).decode("ascii").upper(), "box_pk": HexEncoder.encode( box_pk).decode("ascii").upper(), "sid": HexEncoder.encode( box_pk).decode("ascii").upper(), "rhiz_pk": HexEncoder.encode(rhiz_pk).decode("ascii").upper(), } return keys
def _put_key(pubkeyb64, eph_secret, file_key): """This method encrypts file key using X25519 and returns X25519 line argument list. Args: pubkeyb64: target base64url-encode X25519 public key. eph_secret: 32-bytes ephemeral secret. file_key: file key to encrypt using X25519. Returns: X25519 line argument list. It raises ValueError whether some issue is detected. """ # compute ephemeral public key try: eph_pub_key = crypto_scalarmult_base(eph_secret) except NaclRuntimeError: raise ValueError('Libsodium prevented all-zeros X25519 output.') # decode static public key static_pub_key = encoding._decode(pubkeyb64) # compute shared key try: shared_key = crypto_scalarmult(eph_secret, static_pub_key) except NaclRuntimeError: raise ValueError('Libsodium prevented all-zeros X25519 output.') # compute key encryption key kek = HKDF(algorithm=hashes.SHA256(), length=32, salt=eph_pub_key + static_pub_key, info=b'age-tool.com X25519', backend=default_backend()).derive(shared_key) # encrypt file key enc_file_key = symencrypt._encrypt_key(kek, file_key) # build and return X25519 line argument list argl = [encoding._encode(eph_pub_key), encoding._encode(enc_file_key)] return argl
def test_box_seed_keypair_random(): seed = c.randombytes(c.crypto_box_SEEDBYTES) pk, sk = c.crypto_box_seed_keypair(seed) ppk = c.crypto_scalarmult_base(sk) assert pk == ppk
def crypto_box_keypair_not_random(self, sk): if len(sk) != self.crypto_box_SECRETKEYBYTES: raise ValueError("Invalid secret key length") return bindings.crypto_scalarmult_base(sk), sk
def generate_key(): private_key = os.urandom(32) public_key = crypto_scalarmult_base(private_key) return b64encode(private_key).decode('utf-8'), b64encode( public_key).decode('utf-8')
def expon_base(self, exp): base = crypto_scalarmult_base(exp[0]) for f in exp[1:]: base = crypto_scalarmult(f, base) return base
def test_c25519_hemi(rep=1, payload_size=1024): r = 5 from .SphinxParamsC25519 import Group_C25519 group = Group_C25519() params = SphinxParams(group=group, body_len=payload_size, assoc_len=4) # Monkey patch to use AES-CTR params.lioness_enc = params.xor_rho params.lioness_dec = params.xor_rho pki = {} pkiPriv = {} pkiPub = {} for i in range(10): nid = pack("b", i) # Nenc(params, bytes([i])) x = params.group.gensecret() y = crypto_scalarmult_base(x) pkiPriv[nid] = pki_entry(nid, x, y) pkiPub[nid] = pki_entry(nid, None, y) # The simplest path selection algorithm and message packaging use_nodes = rand_subset(pkiPub.keys(), r) nodes_routing = list(map(Nenc, use_nodes)) node_keys = [pkiPub[n].y for n in use_nodes] assoc = [b"XXXX"] * len(nodes_routing) header, delta = create_forward_message(params, nodes_routing, node_keys, b"dest", b"this is a test", assoc) from .SphinxNode import sphinx_process from binascii import hexlify x = pkiPriv[use_nodes[0]].x i = 0 while True: assert pkiPriv[use_nodes[i]].x == x assert pkiPriv[use_nodes[i]].y == node_keys[i] alpha, beta, gamma = header (_, B, (header, delta), mac_key) = sphinx_process(params, x, header, delta, b"XXXX") routing = PFdecode(params, B) assert i == 4 or B == nodes_routing[i + 1] i += 1 if routing[0] == Relay_flag: addr = routing[1] assert addr == use_nodes[i] x = pkiPriv[addr].x elif routing[0] == Dest_flag: assert len(routing) == 1 dec_dest, dec_msg = receive_forward(params, mac_key, delta) assert dec_dest == b"dest" assert dec_msg == b"this is a test" break else: print("Error") assert False break
def expon_base(self, exp): assert len(exp) > 0 base = crypto_scalarmult_base(_expand32(exp[0])) for f in exp[1:]: base = crypto_scalarmult(_expand32(f), base) return base