def get_privkey_bignum(self): bn = ssl.EC_KEY_get0_private_key(self.k) if not bn: raise Exception("EC_KEY_get0_private_key failed") nbytes = BN_num_bytes(bn) mb_secret = ctypes.create_string_buffer(nbytes) n = ssl.BN_bn2bin(bn, mb_secret) return base256decode(mb_secret.raw)
def test_shamir_share_private_key(self): ssl_add_system_seeds() k = KEY() k.generate() pkey_bignum = k.get_privkey_bignum() pubkey = k.get_pubkey() numshares = 600 threshold = 100 sharenum_bytes = 2 print "private_key_bignum:", pkey_bignum print "public_key:", hexstr(pubkey) print "address:", BitcoinAddress.from_publickey(pubkey, MAIN) field = ZpField() V = field.value_type ZpPkey = V(pkey_bignum) sharer = SecretSharer(field, ZpRandom(field)) shares = sharer.share(ZpPkey, threshold, [V(i+1) for i in range(numshares)]) # print shares print "Shamir Shares: (%d/%d):" % (threshold, numshares) shares_hex = [hexstr(base256encode(int(pt), sharenum_bytes) + base256encode(int(value), 32)) for pt, value in shares] for share in shares_hex: print share # Try to reconstruct the private key using the hex encoded shares. recombiner = SecretRecombiner(field) for i in range(10): random4_hex = random.sample(shares_hex, threshold) random4_decoded = [decodehexstr(h) for h in random4_hex] random4 = [(V(base256decode(data[:sharenum_bytes])), V(base256decode(data[sharenum_bytes:]))) for data in random4_decoded] recombined_pkey_bignum = recombiner.recombine(random4, V(0)) assert recombined_pkey_bignum == ZpPkey k2 = KEY() k2.set_privkey_bignum(int(recombined_pkey_bignum)) assert k2.get_pubkey() == pubkey print i # With threshold-1 shares this fails for i in range(10): random4_hex = random.sample(shares_hex, threshold-1) random4_decoded = [decodehexstr(h) for h in random4_hex] random4 = [(V(base256decode(data[:sharenum_bytes])), V(base256decode(data[sharenum_bytes:]))) for data in random4_decoded] recombined_pkey_bignum = recombiner.recombine(random4, V(0)) assert recombined_pkey_bignum != ZpPkey
def encode_base58check(content, preserve_leading_zeros=True): """ Encode a bytestring (bid endian) as base58 with checksum. preserve_leading_zeros: argument used for MAIN bitcoin addresses (e.g.ADDRESSVERSION == 0) to preserve base256 leading zeros as base58 zeros ('1'). For example: addrversion=00,hash160=00602005b16851c4f9d0e2c82fa161ac8190e04c will give the bitcoin address: 112z9tWej11X94khKKzofFgWbdhiXLeHPD """ data = content + doublesha256(content)[:4] leading_zeros = None if preserve_leading_zeros: leading_zeros = 0 while data[leading_zeros] == "\x00": leading_zeros += 1 return (base58encode(base256decode(data), leading_zeros=leading_zeros))
def encode_base58check(content, preserve_leading_zeros=True): """ Encode a bytestring (bid endian) as base58 with checksum. preserve_leading_zeros: argument used for MAIN bitcoin addresses (e.g.ADDRESSVERSION == 0) to preserve base256 leading zeros as base58 zeros ('1'). For example: addrversion=00,hash160=00602005b16851c4f9d0e2c82fa161ac8190e04c will give the bitcoin address: 112z9tWej11X94khKKzofFgWbdhiXLeHPD """ data = content + doublesha256(content)[:4] leading_zeros = None if preserve_leading_zeros: leading_zeros = 0 while data[leading_zeros] == "\x00": leading_zeros += 1 return base58encode(base256decode(data), leading_zeros=leading_zeros)
def _deserialize_pushdata_length_and_data(self, op, data, pos): lenlen = {OP_PUSHDATA1:1, OP_PUSHDATA2:2, OP_PUSHDATA4:4}[op] if (len(data) < pos + lenlen): raise MissingDataException("pushdata length size") length = base256decode(data[pos:pos+lenlen][::-1]) return (self._deserialize_pushdata_data(op, length, data, pos + lenlen))