def generate_btc_address(): # secp256k1, not included in stock ecdsa _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L _b = 0x0000000000000000000000000000000000000000000000000000000000000007L _a = 0x0000000000000000000000000000000000000000000000000000000000000000L _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L curve_256 = CurveFp(_p, _a, _b) generator = Point(curve_256, _Gx, _Gy, _r) secret = randrange(1, generator.order()) pubkey = Public_key(generator, generator * secret) step1 = '\x04' + int_to_string(pubkey.point.x()) + \ int_to_string(pubkey.point.y()) step2 = hashlib.sha256(step1).digest() ripehash.update(step2) step4 = '\x30' + ripehash.digest() #3f step5 = hashlib.sha256(step4).digest() step6 = hashlib.sha256(step5).digest() chksum = step6[:4] addr = step4 + chksum addr_58 = b58encode(addr) return ( hex(secret)[2:-1], hexlify(step1), hexlify(addr), addr_58 )
def negative_point(P): return Point(P.curve(), P.x(), -P.y(), P.order())
def _ser_to_python_ecdsa_point(ser: bytes) -> ecdsa.ellipticcurve.Point: x, y = ser_to_point(ser) try: return Point(curve_secp256k1, x, y, CURVE_ORDER) except: raise InvalidECPointException()
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)
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
def main(): parser = argparse.ArgumentParser(description='Threshold Cryptosystem Tool') # RECONSTRUCT KEYS reconstruct_group = parser.add_argument_group(title='Reconstruct Key') reconstruct_group.add_argument( '--file', default=None, type=str, help='Path to comma separated file with secrets.') reconstruct_group.add_argument( '--t', default=None, type=int, help='Number of subshares to reconstruct') # RECONSTRUCT KEYS # ENCRYPT encrypt_group = parser.add_argument_group(title='Encrypt Message') encrypt_group.add_argument( '--pkfile', default=None, help='File containing public key') encrypt_group.add_argument( '--msg', default=None, type=int, help='Message to encrypt') encrypt_group.add_argument( '--outfile', default='./ciphertext.txt', help='File to output message') # ENCRYPT # GENERATE PARAMETERS generate_group = parser.add_argument_group(title='Generate and save threshold parameters') generate_group.add_argument( '--tshares', default=None, type=int, help='Number of reconstructable shares') generate_group.add_argument( '--nshares', default=None, type=int, help='Total number of shares') generate_group.add_argument( '--folder', default='./threshold_data/', help='Folder to save data on') args = parser.parse_args() # Reconstruct Key if args.file and args.t: print('Reconstructed private key: {}'.format(reconstruct(args.file, args.t))) #Encrypt if args.pkfile and args.msg and args.outfile: p = open(args.pkfile).readlines()[0].split(',') p_k = Point(curve_secp256k1, int(p[0]), int(p[1][:-1])) c = th.encrypt(p_k, args.msg) l = '{},{},{}'.format(c[0].x(), c[0].y(), c[1]) open(args.outfile, 'w').write(l) #Generate if args.tshares and args.nshares and args.folder: params = th.generate_threshold_parameters(args.tshares, args.nshares) th.save_params_file(args.tshares, args.nshares, params, args.folder)
def _ser_to_python_ecdsa_point(ser: bytes) -> ecdsa.ellipticcurve.Point: x, y = ser_to_point(ser) return Point(curve_secp256k1, x, y, CURVE_ORDER)
def __init__(self, secret): curve = CurveFp(_p, _a, _b) generator = Point(curve, _Gx, _Gy, _r) self.pubkey = Public_key(generator, generator * secret) self.privkey = Private_key(self.pubkey, secret) self.secret = secret
def naive_multi_exp_ec(gs, es): tmp = Point(None, None, None) for i in range(len(gs)): tmp += es[i] * gs[i] return tmp
def point_to_pubkey_bytes(point: Point): result = bytearray(bytes.fromhex(hex(point.x())[2:])) result.extend(bytearray(bytes.fromhex(hex(point.y())[2:]))) return result
############################################################## # We always provide _a as a positive integer. _p = long_converter(""" ffffffff ffffffff ffffffff fffffffe ffffac73""") _a = 0 _b = 7 _Gx = long_converter(""" 3b4c382c e37aa192 a4019e76 3036f4f5 dd4d7ebb""") _Gy = long_converter(""" 938cf935 318fdced 6bc28286 531733c3 f03c4fee""") _r = long_converter("""01 00000000 00000000 0001b8fa 16dfab9a ca16b6b3""") curve = CurveFp(_p, _a, _b) generator = Point(curve, _Gx, _Gy, _r) SECP160k1 = Curve("SECP160k1", curve, generator, (1, 3, 132, 0, 9), "secp160k1") _p = long_converter(""" ffffffff ffffffff ffffffff ffffffff 7fffffff""") _a = -3 % _p _b = long_converter(""" 1c97befc 54bd7a8b 65acf89f 81d4d4ad c565fa45""") _Gx = long_converter(""" 4a96b568 8ef57328 46646989 68c38bb9 13cbfc82""") _Gy = long_converter(""" 23a62855 3168947d 59dcc912 04235137 7ac5fb32""") _r = long_converter("""01 00000000 00000000 0001f4c8 f927aed3 ca752257""") curve = CurveFp(_p, _a, _b)
You should have received a copy of the GNU General Public License along with CoinParty. If not, see <http://www.gnu.org/licenses/>. """ from ecdsa.ellipticcurve import CurveFp, Point bitcoin_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L """ When secret-sharing hashs (arbitrary 256-bit values), bitcoin_order may not be used, since it is too small to fit each possible hash value. Thus, we use the prime (2^265)-49, which is sufficiently large. Prime derived from http://primes.utm.edu/lists/2small/200bit.html """ hash_order = 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcf hash_modulus = 0x10000000000000000000000000000000000000000000000000000000000000000 """ Bitcoin ECC parameters _p, _a, _b: Description of secp256k1 for the ecdsa module _Gx, Gy: Coordinates of generator (uncompressed form) n: Order of the generator _h: Cofactor c.f.: https://en.bitcoin.it/wiki/Secp256k1 """ _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL _a = 0x0000000000000000000000000000000000000000000000000000000000000000L _b = 0x0000000000000000000000000000000000000000000000000000000000000007L _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L _h = 0x01L bitcoin_curve = CurveFp(_p, _a, _b) G = Point(bitcoin_curve, _Gx, _Gy, n)