# (c) Copyright 2023 by Coinkite Inc. This file is covered by license found in COPYING-CC.
#
# Seed XOR helpers
#
import os, hashlib
from mnemonic import Mnemonic


def numwords_to_len(num_words):
    return (num_words * 8) // 6


def xor(*args):
    # bit-wise xor between all args
    vlen = len(args[0])

    # all have to be same length
    assert all(len(e) == vlen for e in args)
    rv = bytearray(vlen)

    for i in range(vlen):
        for a in args:
            rv[i] ^= a[i]
    return rv


def xor_split(secret, num_parts, deterministic=False):
    vlen = len(secret)
    parts = []

    for i in range(num_parts - 1):
        if deterministic:
            msg = b'Batshitoshi ' + secret + b'%d of %d parts' % (i, num_parts)
            part = hashlib.sha256(msg).digest()[:vlen]
        else:
            part = hashlib.sha256(os.urandom(vlen)).digest()[:vlen]

        parts.append(part)

    parts.append(xor(secret, *parts))

    assert xor(*parts) == secret  # selftest

    return parts


def prepare_test_pairs(num_parts, num_words=24, deterministic=False, mnemonic=None):
    if mnemonic is None:
        seed = os.urandom(numwords_to_len(num_words))
        mnemonic = Mnemonic('english').to_mnemonic(seed)
    else:
        seed = Mnemonic.to_seed(mnemonic=mnemonic)

    parts = xor_split(seed, num_parts=num_parts, deterministic=deterministic)

    return [Mnemonic('english').to_mnemonic(s) for s in parts], mnemonic

# EOF
