def generate_ecdsa_pem(pk): ecPrivateKey = ECPrivateKey() ecPrivateKey['version'] = 1 ecPrivateKey['privateKey'] = ints2octs(i2osp(pk, 32)) ecParam = ECParameters().subtype(implicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatSimple, 0)) # 1.3.132.0.10 ansip256k1(10) ecParam.setComponentByName("namedCurve", _buildOid(1, 3, 132, 0, 10)) print ecParam.prettyPrint() ecPrivateKey.setComponentByName('parameters', ecParam) pub = ecdsa.expand_pub(ecdsa.point_mult(ecdsa.G, pk)) # pb = univ.BitString(long(pub, 16)) ecPrivateKey.setComponentByName('publicKey', long(pub, 16)) print ecPrivateKey.prettyPrint() res = "-----BEGIN EC PRIVATE KEY-----\n" b = base64.b64encode(der_encoder(ecPrivateKey)) n = 64 r = [b[i:i + n] for i in range(0, len(b), n)] for l in r: res += l + "\n" res += "-----END EC PRIVATE KEY-----\n" return res
def pi_verify(pi, c, d, w1, w2, m1, m2, zkp, ka_pub): ntild, h1, h2 = zkp z1, z2, y, e, s1, s2, s3, t1, t2, t3, t4 = pi n, g = ka_pub n2 = n * n n3 = pow(ecdsa.n, 3) if s1 > n3 or t1 > n3: return False minuse = (e * -1) % ecdsa.n u1prim = ecdsa.point_add(ecdsa.point_mult(c, s1), ecdsa.point_mult(w1, minuse)) u2inv = utils.inverse_mod(m1, n2) u2prim = (pow(g, s1, n2) * pow(s2, n, n2) * pow(u2inv, e, n2)) % n2 u3inv = utils.inverse_mod(z1, ntild) u3prim = (pow(h1, s1, ntild) * pow(h2, s3, ntild) * pow(u3inv, e, ntild)) % ntild v1prim = ecdsa.point_add(ecdsa.point_mult(d, t1 + t2), ecdsa.point_mult(y, minuse)) v2prim = ecdsa.point_add( ecdsa.point_add(ecdsa.point_mult(w2, s1), ecdsa.point_mult(d, t2)), ecdsa.point_mult(y, minuse)) v3inv = utils.inverse_mod(m2, n2) v3prim = (pow(g, t1, n2) * pow(t3, n, n2) * pow(v3inv, e, n2)) % n2 v4inv = utils.inverse_mod(z2, ntild) v4prim = (pow(h1, t1, ntild) * pow(h2, t4, ntild) * pow(v4inv, e, ntild)) % ntild h = hashlib.sha256() h.update(ecdsa.expand_pub(c)) h.update(ecdsa.expand_pub(w1)) h.update(ecdsa.expand_pub(d)) h.update(ecdsa.expand_pub(w2)) h.update(str(m1)) h.update(str(m2)) h.update(str(z1)) h.update(ecdsa.expand_pub(u1prim)) h.update(str(u2prim)) h.update(str(u3prim)) h.update(str(z2)) h.update(ecdsa.expand_pub(y)) h.update(ecdsa.expand_pub(v1prim)) h.update(ecdsa.expand_pub(v2prim)) h.update(str(v3prim)) h.update(str(v4prim)) eprime = long(h.hexdigest(), 16) print "\n****************************************" print "Verifying Pi zkp:" print "e", e print "e'", eprime print "****************************************" return e == eprime
def pi_to_pem(pi): z1, z2, y, e, s1, s2, s3, t1, t2, t3, t4 = pi pipem = ECZKPPi() pipem['version'] = 1 pipem['z1'] = z1 pipem['z2'] = z2 pipem['y'] = univ.OctetString(hexValue=ecdsa.expand_pub(y)) print ecdsa.expand_pub(y) pipem['e'] = e pipem['s1'] = s1 pipem['s2'] = s2 pipem['s3'] = s3 pipem['t1'] = t1 pipem['t2'] = t2 pipem['t3'] = t3 pipem['t4'] = t4 hex_dump(pipem)
def pub_to_pub(extended_pub, i): pub, chain = extended_pub if i >= 0x80000000: return None, None else: # Not hardened k = "%x" % chain data = "00%s%08x" % (ecdsa.expand_pub(pub), i) hmac = hashlib.pbkdf2_hmac('sha512', k, data, 100) l = binascii.hexlify(hmac) point = ecdsa.point_mult(ecdsa.G, long(l[:64], 16)) c = long(l[64:], 16) return ecdsa.point_add(point, pub), c
def pi_to_pem2(pi2): z1, z2, z3, y, e, s1, s2, s3, s4, t1, t2, t3, t4, t5, t6, t7 = pi2 pi2pem = ECZKPPiPrim() pi2pem['version'] = 1 pi2pem['z1'] = z1 pi2pem['z2'] = z2 pi2pem['z3'] = z3 pi2pem['y'] = univ.OctetString(hexValue=ecdsa.expand_pub(y)) print ecdsa.expand_pub(y) pi2pem['e'] = e pi2pem['s1'] = s1 pi2pem['s2'] = s2 pi2pem['s3'] = s3 pi2pem['s4'] = s4 pi2pem['t1'] = t1 pi2pem['t2'] = t2 pi2pem['t3'] = t3 pi2pem['t4'] = t4 pi2pem['t5'] = t5 pi2pem['t6'] = t6 pi2pem['t7'] = t7 hex_dump(pi2pem)
def gen_pem(name1, name2): pub1, priv1 = ecdsa.key_gen(ecdsa.G) pub2, priv2 = ecdsa.key_gen(ecdsa.G) pub = ecdsa.point_mult(pub1, priv2) pub = ecdsa.expand_pub(pub) privEncPub, privEncPriv = paillier.gen_key() pairedEncPub, pairedEncPriv = paillier.gen_key() zkp = eczkp.gen_params(1024) generate_tecdsa_pem(priv1, pub, pub2, privEncPriv, pairedEncPub, zkp) generate_tecdsa_pem(priv2, pub, pub1, pairedEncPriv, privEncPub, zkp)
def d_pub(self, i): if i >= pow(2, 31): # Only not hardened raise Exception("Impossible to hardened") k = "%x" % self.chain data = "00%s%08x" % (ecdsa.expand_pub(self.master_pub), i) hmac = hashlib.pbkdf2_hmac('sha256', k, data, 100) point = ecdsa.point_mult(self.master_pub, long(binascii.hexlify(hmac), 16)) data = "%08x" % (i) hmac = hashlib.pbkdf2_hmac('sha256', k, data, 100) c = long(binascii.hexlify(hmac), 16) share = Share(c, self.master, self.secret) share.set_master_pub(point) return share
def d_priv(self, i): k = "%x" % self.chain data = "%08x" % (i) hmac = hashlib.pbkdf2_hmac('sha256', k, data, 100) c = long(binascii.hexlify(hmac), 16) if i >= pow(2, 31): # Hardened data = "00%32x%08x" % (self.secret, i) else: # Not hardened data = "00%s%08x" % (ecdsa.expand_pub(self.master_pub), i) hmac = hashlib.pbkdf2_hmac('sha256', k, data, 100) key = long(binascii.hexlify(hmac), 16) * self.secret point = ecdsa.point_mult(self.master_pub, long(binascii.hexlify(hmac), 16)) share = Share(c, self.master, key) share.set_master_pub(point) return share
def get(pub): p = ecdsa.expand_pub(pub) sha = hashlib.sha256() sha.update(p) ripemd = hashlib.new('ripemd160') ripemd.update(sha.hexdigest()) rip = "00%s" % ripemd.hexdigest() sha = hashlib.sha256() sha.update(rip) sha2 = hashlib.sha256() sha2.update(sha.hexdigest()) checksum = sha2.hexdigest() add = "%s%s" % (rip, checksum[:4]) return "1%s" % encode(long(add, 16))
def priv_to_priv(extended_priv, i): priv, chain = extended_priv if i >= 0x80000000: # Hardened k = "%x" % chain data = "00%32x%08x" % (priv, i) hmac = hashlib.pbkdf2_hmac('sha512', k, data, 100) l = binascii.hexlify(hmac) key = long(l[:64], 16) + priv % ecdsa.n c = long(l[64:], 16) return key, c else: # Not hardened k = "%x" % chain data = "00%s%08x" % (ecdsa.expand_pub(ecdsa.get_pub(priv)), i) hmac = hashlib.pbkdf2_hmac('sha512', k, data, 100) l = binascii.hexlify(hmac) key = long(l[:64], 16) + priv % ecdsa.n c = long(l[64:], 16) return key, c
def pi(c, d, w1, w2, m1, m2, r1, r2, x1, x2, zkp, ka_pub): Ntild, h1, h2 = zkp pkn, g = ka_pub n3 = pow(ecdsa.n, 3) n3ntild = n3 * Ntild alpha = utils.randomnumber(n3) beta = rnd_inv(pkn) gamma = utils.randomnumber(n3ntild) p1 = utils.randomnumber(ecdsa.n * Ntild) delta = utils.randomnumber(n3) mu = rnd_inv(pkn) nu = utils.randomnumber(n3ntild) p2 = utils.randomnumber(ecdsa.n * Ntild) p3 = utils.randomnumber(ecdsa.n) epsilon = utils.randomnumber(ecdsa.n) n2 = pkn * pkn z1 = (pow(h1, x1, Ntild) * pow(h2, p1, Ntild)) % Ntild u1 = ecdsa.point_mult(c, alpha) # POINT u2 = (pow(g, alpha, n2) * pow(beta, pkn, n2)) % n2 u3 = (pow(h1, alpha, Ntild) * pow(h2, gamma, Ntild)) % Ntild z2 = (pow(h1, x2, Ntild) * pow(h2, p2, Ntild)) % Ntild y = ecdsa.point_mult(d, x2 + p3) # POINT v1 = ecdsa.point_mult(d, delta + epsilon) # POINT v2 = ecdsa.point_add(ecdsa.point_mult(w2, alpha), ecdsa.point_mult(d, epsilon)) # POINT v3 = (pow(g, delta, n2) * pow(mu, pkn, n2)) % n2 v4 = (pow(h1, delta, Ntild) * pow(h2, nu, Ntild)) % Ntild h = hashlib.sha256() h.update(ecdsa.expand_pub(c)) h.update(ecdsa.expand_pub(w1)) h.update(ecdsa.expand_pub(d)) h.update(ecdsa.expand_pub(w2)) h.update(str(m1)) h.update(str(m2)) h.update(str(z1)) h.update(ecdsa.expand_pub(u1)) h.update(str(u2)) h.update(str(u3)) h.update(str(z2)) h.update(ecdsa.expand_pub(y)) h.update(ecdsa.expand_pub(v1)) h.update(ecdsa.expand_pub(v2)) h.update(str(v3)) h.update(str(v4)) e = long(h.hexdigest(), 16) s1 = e * x1 + alpha s2 = (pow(r1, e, pkn) * beta) % pkn s3 = e * p1 + gamma t1 = e * x2 + delta t2 = (e * p3 + epsilon) % ecdsa.n t3 = (pow(r2, e, n2) * mu) % n2 t4 = e * p2 + nu return z1, z2, y, e, s1, s2, s3, t1, t2, t3, t4
def pi2_verify(pi2, c, d, w1, w2, m1, m2, m3, m4, zkp, ka_pub, kb_pub): z1, z2, z3, y, e, s1, s2, s3, s4, t1, t2, t3, t4, t5, t6, t7 = pi2 pkn, g = ka_pub pkn2 = pkn * pkn pknprim, gprim = kb_pub pknprim2 = pknprim * pknprim ntild, h1, h2 = zkp minuse = (e * -1) % ecdsa.n u1prim = ecdsa.point_add(ecdsa.point_mult(c, s1), ecdsa.point_mult(w1, minuse)) u2inv = utils.inverse_mod(m1, pknprim2) u2prim = (pow(gprim, s1, pknprim2) * pow(s2, pknprim, pknprim2) * pow(u2inv, e, pknprim2)) % pknprim2 u3inv = utils.inverse_mod(z1, ntild) u3prim = (pow(h1, s1, ntild) * pow(h2, s3, ntild) * pow(u3inv, e, ntild)) % ntild v1prim = ecdsa.point_add(ecdsa.point_mult(d, t1 + t2), ecdsa.point_mult(y, minuse)) v2prim = ecdsa.point_add( ecdsa.point_add(ecdsa.point_mult(w2, s1), ecdsa.point_mult(d, t2)), ecdsa.point_mult(y, minuse)) v3inv = utils.inverse_mod(m2, pkn2) v3prim = (pow(m3, s4, pkn2) * pow(m4, t7, pkn2) * pow(g, ecdsa.n * t5, pkn2) * pow(t3, pkn, pkn2) * pow(v3inv, e, pkn2)) % pkn2 v4inv = utils.inverse_mod(z2, ntild) v4prim = (pow(h1, t1, ntild) * pow(h2, t4, ntild) * pow(v4inv, e, ntild)) % ntild v5inv = utils.inverse_mod(z3, ntild) v5prim = (pow(h1, t5, ntild) * pow(h2, t6, ntild) * pow(v5inv, e, ntild)) % ntild h = hashlib.sha512() h.update(ecdsa.expand_pub(c)) h.update(ecdsa.expand_pub(w1)) h.update(ecdsa.expand_pub(d)) h.update(ecdsa.expand_pub(w2)) h.update(str(m1)) h.update(str(m2)) h.update(str(z1)) h.update(ecdsa.expand_pub(u1prim)) h.update(str(u2prim)) h.update(str(u3prim)) h.update(str(z2)) h.update(str(z3)) h.update(ecdsa.expand_pub(y)) h.update(ecdsa.expand_pub(v1prim)) h.update(ecdsa.expand_pub(v2prim)) h.update(str(v3prim)) h.update(str(v4prim)) h.update(str(v5prim)) eprime = long(h.hexdigest(), 16) print "\n****************************************" print "Verifying Pi' zkp:" print "e", e print "e'", eprime print "****************************************\n" return e == eprime
def pi2(c, d, w1, w2, m1, m2, m3, m4, r1, r2, x1, x2, x3, x4, x5, zkp, ka_pub, kb_pub): pkn, g = ka_pub pkn2 = pkn * pkn pknprim, gprim = kb_pub pknprim2 = pknprim * pknprim ntild, h1, h2 = zkp n3 = pow(ecdsa.n, 3) n5 = pow(ecdsa.n, 5) n6 = pow(ecdsa.n, 6) n7 = pow(ecdsa.n, 7) n8 = pow(ecdsa.n, 8) n3ntild = n3 * ntild nntild = ecdsa.n * ntild if pkn <= n8: return False if pknprim <= n6: return False alpha = utils.randomnumber(n3) beta = rnd_inv(pknprim) gamma = utils.randomnumber(n3ntild) p1 = utils.randomnumber(nntild) delta = utils.randomnumber(n3) mu = rnd_inv(pkn) nu = utils.randomnumber(n3ntild) p2 = utils.randomnumber(nntild) p3 = utils.randomnumber(ecdsa.n) p4 = utils.randomnumber(n5 * ntild) epsilon = utils.randomnumber(ecdsa.n) sigma = utils.randomnumber(n7) tau = utils.randomnumber(n7 * ntild) z1 = (pow(h1, x1, ntild) * pow(h2, p1, ntild)) % ntild u1 = ecdsa.point_mult(c, alpha) u2 = (pow(gprim, alpha, pknprim2) * pow(beta, pknprim, pknprim2)) % pknprim2 u3 = (pow(h1, alpha, ntild) * pow(h2, gamma, ntild)) % ntild z2 = (pow(h1, x2, ntild) * pow(h2, p2, ntild)) % ntild y = ecdsa.point_mult(d, x2 + p3) v1 = ecdsa.point_mult(d, delta + epsilon) v2 = ecdsa.point_add(ecdsa.point_mult(w2, alpha), ecdsa.point_mult(d, epsilon)) v3 = (pow(m3, alpha, pkn2) * pow(m4, delta, pkn2) * pow(g, ecdsa.n * sigma, pkn2) * pow(mu, pkn, pkn2)) % pkn2 v4 = (pow(h1, delta, ntild) * pow(h2, nu, ntild)) % ntild z3 = (pow(h1, x3, ntild) * pow(h2, p4, ntild)) % ntild v5 = (pow(h1, sigma, ntild) * pow(h2, tau, ntild)) % ntild h = hashlib.sha512() h.update(ecdsa.expand_pub(c)) h.update(ecdsa.expand_pub(w1)) h.update(ecdsa.expand_pub(d)) h.update(ecdsa.expand_pub(w2)) h.update(str(m1)) h.update(str(m2)) h.update(str(z1)) h.update(ecdsa.expand_pub(u1)) h.update(str(u2)) h.update(str(u3)) h.update(str(z2)) h.update(str(z3)) h.update(ecdsa.expand_pub(y)) h.update(ecdsa.expand_pub(v1)) h.update(ecdsa.expand_pub(v2)) h.update(str(v3)) h.update(str(v4)) h.update(str(v5)) e = long(h.hexdigest(), 16) s1 = e * x1 + alpha s2 = (pow(r1, e, pknprim) * beta) % pknprim s3 = e * p1 + gamma s4 = e * x1 * x4 + alpha t1 = e * x2 + delta t2 = (e * p3 + epsilon) % ecdsa.n t3 = (pow(r2, e, pkn) * mu) % pkn t4 = e * p2 + nu t5 = e * x3 + sigma t6 = e * p4 + tau t7 = e * x2 * x5 + delta return z1, z2, z3, y, e, s1, s2, s3, s4, t1, t2, t3, t4, t5, t6, t7
def generate_tecdsa_pem(share, pub, pubshare, privEnc, pairedEnc, zkp): tecPrivateKey = ThresholdECPrivateKey() tecPrivateKey['version'] = 1 tecPrivateKey['privateShare'] = ints2octs(i2osp(share, 32)) # privateEnc privateEnc = HEPrivateKey() n, p, q, g, lmbda, mu = privEnc privateEnc['version'] = 1 privateEnc['modulus'] = n privateEnc['prime1'] = p privateEnc['prime2'] = q privateEnc['generator'] = g privateEnc['privateExponent'] = lmbda privateEnc['coefficient'] = mu # hex_dump(privateEnc) tecPrivateKey.setComponentByName('privateEnc', privateEnc) # pairedPublicEnc publicEnc = HEPublicKey() n, g = pairedEnc publicEnc['version'] = 1 publicEnc['modulus'] = n publicEnc['generator'] = g # hex_dump(publicEnc) tecPrivateKey.setComponentByName('pairedPublicEnc', publicEnc) n, h1, h2 = zkp # zkpParameters zkpParameters = ZKPParameter() zkpParameters['modulus'] = n zkpParameters['h1'] = h1 zkpParameters['h2'] = h2 tecPrivateKey.setComponentByName('zkpParameters', zkpParameters) tecPrivateKey.setComponentByName( 'pairedPublicShare', univ.OctetString(hexValue=ecdsa.expand_pub(pubshare))) tecPrivateKey.setComponentByName('publicKey', univ.OctetString(hexValue=pub)) ecParam = ECParameters().subtype(implicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatSimple, 0)) # 1.3.132.0.10 ansip256k1(10) ecParam.setComponentByName("namedCurve", _buildOid(1, 3, 132, 0, 10)) tecPrivateKey.setComponentByName('parameters', ecParam) # print tecPrivateKey.prettyPrint() hex_dump(tecPrivateKey) res = "-----BEGIN THRESHOLD EC PRIVATE KEY-----\n" b = base64.b64encode(der_encoder(tecPrivateKey)) n = 64 r = [b[i:i + n] for i in range(0, len(b), n)] for l in r: res += l + "\n" res += "-----END THRESHOLD EC PRIVATE KEY-----\n" return res
def test(): # p = ecdsa.expand_pub(pub) # print(p) # rec_pub = ecdsa.recover_pub(p) # print(rec_pub == pub) # print(get(pub)) chain = ecdsa.gen_priv() # Shares p1 = ecdsa.gen_priv() pub1 = ecdsa.get_pub(p1) p2 = ecdsa.gen_priv() pub2 = ecdsa.get_pub(p2) p3 = ecdsa.gen_priv() pub3 = ecdsa.get_pub(p3) p4 = ecdsa.gen_priv() pub4 = ecdsa.get_pub(p4) skmas = ecdsa.aggregate(p1, p2, p3, p4) pkmas = ecdsa.get_pub(skmas) print(get(pkmas)) # Compute master pubkey with shares pkmas_shares = ecdsa.point_add( ecdsa.point_add(ecdsa.point_add(pub1, pub2), pub3), pub4) print(get(pkmas_shares)) i = 1 # Pubkey derivation # each one knows: # - chain code # - master pubkey # - i # - own share sha2 = hashlib.sha256() m = "%x%s%x" % (chain, ecdsa.expand_pub(pub), i) sha2.update(m) T = long(sha2.hexdigest(), 16) pki = ecdsa.point_mult(pkmas, T) # print get(pki) # Privkey derivation p11 = p1 * T p21 = p2 p31 = p3 p41 = p4 pkmas1 = ecdsa.get_pub(ecdsa.aggregate(p11, p21, p31, p41)) # print(get(pkmas1)) extended_priv = (skmas, chain) extended_pub = (pkmas, chain) ext_priv1h = priv_to_priv(extended_priv, 0x80000000) ext_priv1 = priv_to_priv(extended_priv, 0x00000001) ext_pub1 = pub_to_pub(extended_pub, 0x00000001) ext_priv2 = priv_to_priv(ext_priv1, 0x00000001) ext_pub2 = pub_to_pub(ext_pub1, 0x00000001) print(get(ecdsa.get_pub(ext_priv1[0]))) print(get(ext_pub1[0])) print(get(ecdsa.get_pub(ext_priv2[0]))) print(get(ext_pub2[0])) print("Multiplicatively") print(get(ecdsa.get_pub(p1 * p2))) print(get(ecdsa.point_mult(pub1, p2)))