def verify_commit(receipt, c, hasher=sha256): ec.y(receipt[0], False) # receipt[0] is valid iif its y does exist ec.tuple_from_point(receipt[1]) # verify it is a good point w, R = receipt e = hasher(R[0].to_bytes(32, 'big') + c).digest() e = int_from_hash(e, ec.order) W = ec.pointAdd(R, ec.pointMultiply(e)) return w % ec.order == W[0] % ec.order
def ecssa_verify_raw(m: bytes, ssasig: Tuple[int, int], pub: Tuple[int, int], hasher) -> bool: R_x, s = ssasig[0].to_bytes(32, 'big'), ssasig[1] e = hasher(R_x + m).digest() e = int_from_hash(e, ec.order) if e == 0 or e >= ec.order: # invalid e value return False R = ec.pointAdd(ec.pointMultiply(e, pub), ec.pointMultiply(s)) if R[1] % 2 == 1: # R.y odd return False return R[0] == ssasig[0]
def ecssa_pubkey_recovery_raw(m: bytes, ssasig: Tuple[int, int], hasher=sha256) -> Tuple[int, int]: R_x, s = ssasig R = (R_x, ec.y(R_x, 0)) R_x = R_x.to_bytes(32, 'big') e = hasher(R_x + m).digest() e = int_from_hash(e, ec.order) assert e != 0 and e < ec.order, "invalid e value" e1 = mod_inv(e, ec.order) return ec.pointAdd(ec.pointMultiply(e1, R), ec.pointMultiply(-e1 * s % ec.order))
def det_wallet2(key, r, i): r_bytes = r.to_bytes(32, 'big') i_bytes = i.to_bytes(32, 'big') h_hex = sha256(i_bytes+r_bytes).hexdigest() h_int = int(h_hex, 16) try: prvkey = int_from_prvkey(key) return (prvkey + h_int) % ec.order except: pubkey = ec.tuple_from_point(key) return ec.pointAdd(pubkey, ec.pointMultiply(h_int)) raise ValueError("Invalid key")
s1 = ((h1 + r * p) * mod_inv(k1, ec.order)) % ec.order # if s1 == 0 (extremely unlikely for large ec.order) go back to a different ephemeral key assert s1 != 0 print(" r:", hex(r)) print(" s1:", hex(s1)) print("*** Signature Verification") w = mod_inv(s1, ec.order) u = (h1 * w) % ec.order v = (r * w) % ec.order assert u != 0 assert v != 0 U = ec.pointMultiply(u) V = ec.pointMultiply(v, P) x, y = ec.pointAdd(U, V) print(r == x % ec.order) print("\n*** Malleated Signature") s1m = ec.order - s1 print(" r:", hex(r)) print(" *s1:", hex(s1m)) print("*** Malleated Signature Verification") w = mod_inv(s1m, ec.order) u = (h1 * w) % ec.order v = (r * w) % ec.order assert u != 0 assert v != 0 U = ec.pointMultiply(u) V = ec.pointMultiply(v, P)
def bip32_ckd(xparentkey, index): """Child Key Derivation (CDK) Key derivation is normal if the extended parent key is public or child_index is less than 0x80000000. Key derivation is hardened if the extended parent key is private and child_index is not less than 0x80000000. """ if isinstance(index, int): index = index.to_bytes(4, 'big') elif isinstance(index, bytes) or isinstance(index, bytearray): assert len(index) == 4 else: raise TypeError("a 4 bytes int is required") xparent = b58decode_check(xparentkey) assert len(xparent) == 78, "wrong length for extended parent key" version = xparent[:4] xkey = version # version xkey += (xparent[4] + 1).to_bytes(1, 'big') # (increased) depth if (version in PUBLIC): assert xparent[45] in (2, 3), \ "version/key mismatch in extended parent key" Parent_bytes = xparent[45:] Parent = ec.tuple_from_point(Parent_bytes) xkey += h160(Parent_bytes)[:4] # parent pubkey fingerprint assert index[0] < 0x80, \ "no private/hardened derivation from pubkey" xkey += index # child index parent_chain_code = xparent[13:45] ## normal derivation h = HMAC(parent_chain_code, Parent_bytes + index, sha512).digest() xkey += h[32:] # chain code offset = int.from_bytes(h[:32], 'big') Offset = ec.pointMultiply(offset) Child = ec.pointAdd(Parent, Offset) Child_bytes = ec.bytes_from_point(Child, True) xkey += Child_bytes # public key elif (version in PRIVATE): assert xparent[45] == 0, "version/key mismatch in extended parent key" parent = int.from_bytes(xparent[46:], 'big') Parent = ec.pointMultiply(parent) Parent_bytes = ec.bytes_from_point(Parent, True) xkey += h160(Parent_bytes)[:4] # parent pubkey fingerprint xkey += index # child index parent_chain_code = xparent[13:45] if (index[0] < 0x80): ## normal derivation h = HMAC(parent_chain_code, Parent_bytes + index, sha512).digest() else: ## hardened derivation h = HMAC(parent_chain_code, xparent[45:] + index, sha512).digest() xkey += h[32:] # chain code offset = int.from_bytes(h[:32], 'big') child = (parent + offset) % ec.order child_bytes = b'\x00' + child.to_bytes(32, 'big') xkey += child_bytes # private key else: raise ValueError("invalid extended key version") return b58encode_check(xkey)
assert k1 != 0 K1 = ec.pointMultiply(k1) s1 = (k1-h1*p) % ec.order # if s1 == 0 (extremely unlikely for large ec.order) go back to a different ephemeral key assert s1 != 0 print(" K1[0]:", hex(K1[0])) print(" K1[1]:", hex(K1[1])) print(" s1:", hex(s1)) print("*** Signature Verification") minush1 = -h1 %ec.order V = ec.pointMultiply(minush1, P) V = ec.pointAdd(K1, V) print(V == ec.pointMultiply(s1)) print("\n*** Another message") msg2 = "and Paolo is right to be afraid" print(msg2) print("*** Hash of the message") h_bytes = sha256(msg2.encode()).digest() # hash(msg) must be transformed into an integer modulo ec.order: h2 = int.from_bytes(h_bytes, 'big') % ec.order assert h2 != 0 print(" h2:", hex(h2)) print("\n*** Signature") k2 = k1 #very bad! Never reuse the same ephemeral key!!!
h_int = [] nKeys = 3 r_bytes = r.to_bytes(32, 'big') for i in range(0, nKeys): i_bytes = i.to_bytes(32, 'big') h_hex = sha256(i_bytes+r_bytes).hexdigest() h_int.append(int(h_hex, 16)) p.append((mprvkey + h_int[i]) % ec.order) P = ec.pointMultiply(p[i]) print('prvkey#', i, ':', format(p[i], '#064x')) print('Pubkey#', i, ':', format(P[0], '#064x')) print(' ', format(P[1], '#064x')) # Pubkeys could be calculated without using prvkeys for i in range(0, nKeys): P = ec.pointAdd(mpubkey, ec.pointMultiply(h_int[i])) assert P == ec.pointMultiply(p[i]) def det_wallet2(key, r, i): r_bytes = r.to_bytes(32, 'big') i_bytes = i.to_bytes(32, 'big') h_hex = sha256(i_bytes+r_bytes).hexdigest() h_int = int(h_hex, 16) try: prvkey = int_from_prvkey(key) return (prvkey + h_int) % ec.order except: pubkey = ec.tuple_from_point(key) return ec.pointAdd(pubkey, ec.pointMultiply(h_int)) raise ValueError("Invalid key")