Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SEP-0046: Key Sharing Method for Stellar Keys #1601

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

tupui
Copy link

@tupui tupui commented Jan 3, 2025

In the Python SDK we added support for Shamir Secret Sharing as a way to split mnemonics into parts.

Shamir Secret Sharing is standardised here: SLIP-0039

cc @tomerweller @overcat

Let me know if I should extend anything


We added support here:

StellarCN/py-stellar-base#1012

and see also this follow-up

StellarCN/py-stellar-base#1015

Code used to generate the SSS mnemonic phrases
import itertools

import shamir_mnemonic
from stellar_sdk import Keypair
from stellar_sdk.sep.mnemonic import StellarMnemonic


SEP_5_CASES = (
    {
        "mnemonic": "illness spike retreat truth genius clock brain pass fit cave bargain toe",
        "passphrase": "",
        "accounts": (
            (
                "GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RGZGIEKWE4SOOHSUJUJ6",
                "SBGWSG6BTNCKCOB3DIFBGCVMUPQFYPA2G4O34RMTB343OYPXU5DJDVMN",
            ),
            (
                "GBAW5XGWORWVFE2XTJYDTLDHXTY2Q2MO73HYCGB3XMFMQ562Q2W2GJQX",
                "SCEPFFWGAG5P2VX5DHIYK3XEMZYLTYWIPWYEKXFHSK25RVMIUNJ7CTIS",
            ),
            (
                "GAY5PRAHJ2HIYBYCLZXTHID6SPVELOOYH2LBPH3LD4RUMXUW3DOYTLXW",
                "SDAILLEZCSA67DUEP3XUPZJ7NYG7KGVRM46XA7K5QWWUIGADUZCZWTJP",
            ),
            (
                "GAOD5NRAEORFE34G5D4EOSKIJB6V4Z2FGPBCJNQI6MNICVITE6CSYIAE",
                "SBMWLNV75BPI2VB4G27RWOMABVRTSSF7352CCYGVELZDSHCXWCYFKXIX",
            ),
            (
                "GBCUXLFLSL2JE3NWLHAWXQZN6SQC6577YMAU3M3BEMWKYPFWXBSRCWV4",
                "SCPCY3CEHMOP2TADSV2ERNNZBNHBGP4V32VGOORIEV6QJLXD5NMCJUXI",
            ),
            (
                "GBRQY5JFN5UBG5PGOSUOL4M6D7VRMAYU6WW2ZWXBMCKB7GPT3YCBU2XZ",
                "SCK27SFHI3WUDOEMJREV7ZJQG34SCBR6YWCE6OLEXUS2VVYTSNGCRS6X",
            ),
            (
                "GBY27SJVFEWR3DUACNBSMJB6T4ZPR4C7ZXSTHT6GMZUDL23LAM5S2PQX",
                "SDJ4WDPOQAJYR3YIAJOJP3E6E4BMRB7VZ4QAEGCP7EYVDW6NQD3LRJMZ",
            ),
            (
                "GAY7T23Z34DWLSTEAUKVBPHHBUE4E3EMZBAQSLV6ZHS764U3TKUSNJOF",
                "SA3HXJUCE2N27TBIZ5JRBLEBF3TLPQEBINP47E6BTMIWW2RJ5UKR2B3L",
            ),
            (
                "GDJTCF62UUYSAFAVIXHPRBR4AUZV6NYJR75INVDXLLRZLZQ62S44443R",
                "SCD5OSHUUC75MSJG44BAT3HFZL2HZMMQ5M4GPDL7KA6HJHV3FLMUJAME",
            ),
            (
                "GBTVYYDIYWGUQUTKX6ZMLGSZGMTESJYJKJWAATGZGITA25ZB6T5REF44",
                "SCJGVMJ66WAUHQHNLMWDFGY2E72QKSI3XGSBYV6BANDFUFE7VY4XNXXR",
            ),
        ),
    },
    {
        "mnemonic": "resource asthma orphan phone ice canvas fire useful arch jewel impose vague theory cushion top",
        "passphrase": "",
        "accounts": (
            (
                "GAVXVW5MCK7Q66RIBWZZKZEDQTRXWCZUP4DIIFXCCENGW2P6W4OA34RH",
                "SAKS7I2PNDBE5SJSUSU2XLJ7K5XJ3V3K4UDFAHMSBQYPOKE247VHAGDB",
            ),
            (
                "GDFCYVCICATX5YPJUDS22KM2GW5QU2KKSPPPT2IC5AQIU6TP3BZSLR5K",
                "SAZ2H5GLAVWCUWNPQMB6I3OHRI63T2ACUUAWSH7NAGYYPXGIOPLPW3Q4",
            ),
            (
                "GAUA3XK3SGEQFNCBM423WIM5WCZ4CR4ZDPDFCYSFLCTODGGGJMPOHAAE",
                "SDVSSLPL76I33DKAI4LFTOAKCHJNCXUERGPCMVFT655Z4GRLWM6ZZTSC",
            ),
            (
                "GAH3S77QXTAPZ77REY6LGFIJ2XWVXFOKXHCFLA6HQTL3POLVZJDHHUDM",
                "SCH56YSGOBYVBC6DO3ZI2PY62GBVXT4SEJSXJOBQYGC2GCEZSB5PEVBZ",
            ),
            (
                "GCSCZVGV2Y3EQ2RATJ7TE6PVWTW5OH5SMG754AF6W6YM3KJF7RMNPB4Y",
                "SBWBM73VUNBGBMFD4E2BA7Q756AKVEAAVTQH34RYEUFD6X64VYL5KXQ2",
            ),
            (
                "GDKWYAJE3W6PWCXDZNMFNFQSPTF6BUDANE6OVRYMJKBYNGL62VKKCNCC",
                "SAVS4CDQZI6PSA5DPCC42S5WLKYIPKXPCJSFYY4N3VDK25T2XX2BTGVX",
            ),
            (
                "GCDTVB4XDLNX22HI5GUWHBXJFBCPB6JNU6ZON7E57FA3LFURS74CWDJH",
                "SDFC7WZT3GDQVQUQMXN7TC7UWDW5E3GSMFPHUT2TSTQ7RKWTRA4PLBAL",
            ),
            (
                "GBTDPL5S4IOUQHDLCZ7I2UXJ2TEHO6DYIQ3F2P5OOP3IS7JSJI4UMHQJ",
                "SA6UO2FIYC6AS2MSDECLR6F7NKCJTG67F7R4LV2GYB4HCZYXJZRLPOBB",
            ),
            (
                "GD3KWA24OIM7V3MZKDAVSLN3NBHGKVURNJ72ZCTAJSDTF7RIGFXPW5FQ",
                "SBDNHDDICLLMBIDZ2IF2D3LH44OVUGGAVHQVQ6BZQI5IQO6AB6KNJCOV",
            ),
            (
                "GB3C6RRQB3V7EPDXEDJCMTS45LVDLSZQ46PTIGKZUY37DXXEOAKJIWSV",
                "SDHRG2J34MGDAYHMOVKVJC6LX2QZMCTIKRO5I4JQ6BJQ36KVL6QUTT72",
            ),
        ),
    },
    {
        "mnemonic": "bench hurt jump file august wise shallow faculty impulse spring exact slush thunder author capable act festival slice deposit sauce coconut afford frown better",
        "passphrase": "",
        "accounts": (
            (
                "GC3MMSXBWHL6CPOAVERSJITX7BH76YU252WGLUOM5CJX3E7UCYZBTPJQ",
                "SAEWIVK3VLNEJ3WEJRZXQGDAS5NVG2BYSYDFRSH4GKVTS5RXNVED5AX7",
            ),
            (
                "GB3MTYFXPBZBUINVG72XR7AQ6P2I32CYSXWNRKJ2PV5H5C7EAM5YYISO",
                "SBKSABCPDWXDFSZISAVJ5XKVIEWV4M5O3KBRRLSPY3COQI7ZP423FYB4",
            ),
            (
                "GDYF7GIHS2TRGJ5WW4MZ4ELIUIBINRNYPPAWVQBPLAZXC2JRDI4DGAKU",
                "SD5CCQAFRIPB3BWBHQYQ5SC66IB2AVMFNWWPBYGSUXVRZNCIRJ7IHESQ",
            ),
            (
                "GAFLH7DGM3VXFVUID7JUKSGOYG52ZRAQPZHQASVCEQERYC5I4PPJUWBD",
                "SBSGSAIKEF7JYQWQSGXKB4SRHNSKDXTEI33WZDRR6UHYQCQ5I6ZGZQPK",
            ),
            (
                "GAXG3LWEXWCAWUABRO6SMAEUKJXLB5BBX6J2KMHFRIWKAMDJKCFGS3NN",
                "SBIZH53PIRFTPI73JG7QYA3YAINOAT2XMNAUARB3QOWWVZVBAROHGXWM",
            ),
            (
                "GA6RUD4DZ2NEMAQY4VZJ4C6K6VSEYEJITNSLUQKLCFHJ2JOGC5UCGCFQ",
                "SCVM6ZNVRUOP4NMCMMKLTVBEMAF2THIOMHPYSSMPCD2ZU7VDPARQQ6OY",
            ),
            (
                "GCUDW6ZF5SCGCMS3QUTELZ6LSAH6IVVXNRPRLAUNJ2XYLCA7KH7ZCVQS",
                "SBSHUZQNC45IAIRSAHMWJEJ35RY7YNW6SMOEBZHTMMG64NKV7Y52ZEO2",
            ),
            (
                "GBJ646Q524WGBN5X5NOAPIF5VQCR2WZCN6QZIDOSY6VA2PMHJ2X636G4",
                "SC2QO2K2B4EBNBJMBZIKOYSHEX4EZAZNIF4UNLH63AQYV6BE7SMYWC6E",
            ),
            (
                "GDHX4LU6YBSXGYTR7SX2P4ZYZSN24VXNJBVAFOB2GEBKNN3I54IYSRM4",
                "SCGMC5AHAAVB3D4JXQPCORWW37T44XJZUNPEMLRW6DCOEARY3H5MAQST",
            ),
            (
                "GDXOY6HXPIDT2QD352CH7VWX257PHVFR72COWQ74QE3TEV4PK2KCKZX7",
                "SCPA5OX4EYINOPAUEQCPY6TJMYICUS5M7TVXYKWXR3G5ZRAJXY3C37GF",
            ),
        ),
    },
    {
        "mnemonic": "cable spray genius state float twenty onion head street palace net private method loan turn phrase state blanket interest dry amazing dress blast tube",
        "passphrase": "p4ssphr4se",
        "accounts": (
            (
                "GDAHPZ2NSYIIHZXM56Y36SBVTV5QKFIZGYMMBHOU53ETUSWTP62B63EQ",
                "SAFWTGXVS7ELMNCXELFWCFZOPMHUZ5LXNBGUVRCY3FHLFPXK4QPXYP2X",
            ),
            (
                "GDY47CJARRHHL66JH3RJURDYXAMIQ5DMXZLP3TDAUJ6IN2GUOFX4OJOC",
                "SBQPDFUGLMWJYEYXFRM5TQX3AX2BR47WKI4FDS7EJQUSEUUVY72MZPJF",
            ),
            (
                "GCLAQF5H5LGJ2A6ACOMNEHSWYDJ3VKVBUBHDWFGRBEPAVZ56L4D7JJID",
                "SAF2LXRW6FOSVQNC4HHIIDURZL4SCGCG7UEGG23ZQG6Q2DKIGMPZV6BZ",
            ),
            (
                "GBC36J4KG7ZSIQ5UOSJFQNUP4IBRN6LVUFAHQWT2ODEQ7Y3ASWC5ZN3B",
                "SDCCVBIYZDMXOR4VPC3IYMIPODNEDZCS44LDN7B5ZWECIE57N3BTV4GQ",
            ),
            (
                "GA6NHA4KPH5LFYD6LZH35SIX3DU5CWU3GX6GCKPJPPTQCCQPP627E3CB",
                "SA5TRXTO7BG2Z6QTQT3O2LC7A7DLZZ2RBTGUNCTG346PLVSSHXPNDVNT",
            ),
            (
                "GBOWMXTLABFNEWO34UJNSJJNVEF6ESLCNNS36S5SX46UZT2MNYJOLA5L",
                "SDEOED2KPHV355YNOLLDLVQB7HDPQVIGKXCAJMA3HTM4325ZHFZSKKUC",
            ),
            (
                "GBL3F5JUZN3SQKZ7SL4XSXEJI2SNSVGO6WZWNJLG666WOJHNDDLEXTSZ",
                "SDYNO6TLFNV3IM6THLNGUG5FII4ET2H7NH3KCT6OAHIUSHKR4XBEEI6A",
            ),
            (
                "GA5XPPWXL22HFFL5K5CE37CEPUHXYGSP3NNWGM6IK6K4C3EFHZFKSAND",
                "SDXMJXAY45W3WEFWMYEPLPIF4CXAD5ECQ37XKMGY5EKLM472SSRJXCYD",
            ),
            (
                "GDS5I7L7LWFUVSYVAOHXJET2565MGGHJ4VHGVJXIKVKNO5D4JWXIZ3XU",
                "SAIZA26BUP55TDCJ4U7I2MSQEAJDPDSZSBKBPWQTD5OQZQSJAGNN2IQB",
            ),
            (
                "GBOSMFQYKWFDHJWCMCZSMGUMWCZOM4KFMXXS64INDHVCJ2A2JAABCYRR",
                "SDXDYPDNRMGOF25AWYYKPHFAD3M54IT7LCLG7RWTGR3TS32A4HTUXNOS",
            ),
        ),
    },
    {
        "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
        "passphrase": "",
        "accounts": (
            (
                "GB3JDWCQJCWMJ3IILWIGDTQJJC5567PGVEVXSCVPEQOTDN64VJBDQBYX",
                "SBUV3MRWKNS6AYKZ6E6MOUVF2OYMON3MIUASWL3JLY5E3ISDJFELYBRZ",
            ),
            (
                "GDVSYYTUAJ3ACHTPQNSTQBDQ4LDHQCMNY4FCEQH5TJUMSSLWQSTG42MV",
                "SCHDCVCWGAKGIMTORV6K5DYYV3BY4WG3RA4M6MCBGJLHUCWU2MC6DL66",
            ),
            (
                "GBFPWBTN4AXHPWPTQVQBP4KRZ2YVYYOGRMV2PEYL2OBPPJDP7LECEVHR",
                "SAPLVTLUXSDLFRDGCCFLPDZMTCEVMP3ZXTM74EBJCVKZKM34LGQPF7K3",
            ),
            (
                "GCCCOWAKYVFY5M6SYHOW33TSNC7Z5IBRUEU2XQVVT34CIZU7CXZ4OQ4O",
                "SDQYXOP2EAUZP4YOEQ5BUJIQ3RDSP5XV4ZFI6C5Y3QCD5Y63LWPXT7PW",
            ),
            (
                "GCQ3J35MKPKJX7JDXRHC5YTXTULFMCBMZ5IC63EDR66QA3LO7264ZL7Q",
                "SCT7DUHYZD6DRCETT6M73GWKFJI4D56P3SNWNWNJ7ANLJZS6XIFYYXSB",
            ),
            (
                "GDTA7622ZA5PW7F7JL7NOEFGW62M7GW2GY764EQC2TUJ42YJQE2A3QUL",
                "SDTWG5AFDI6GRQNLPWOC7IYS7AKOGMI2GX4OXTBTZHHYPMNZ2PX4ONWU",
            ),
            (
                "GD7A7EACTPTBCYCURD43IEZXGIBCEXNBHN3OFWV2FOX67XKUIGRCTBNU",
                "SDJMWY4KFRS4PTA5WBFVCPS2GKYLXOMCLQSBNEIBG7KRGHNQOM25KMCP",
            ),
            (
                "GAF4AGPVLQXFKEWQV3DZU5YEFU6YP7XJHAEEQH4G3R664MSF77FLLRK3",
                "SDOJH5JRCNGT57QTPTJEQGBEBZJPXE7XUDYDB24VTOPP7PH3ALKHAHFG",
            ),
            (
                "GABTYCZJMCP55SS6I46SR76IHETZDLG4L37MLZRZKQDGBLS5RMP65TSX",
                "SC6N6GYQ2VA4T7CUP2BWGBRT2P6L2HQSZIUNQRHNDLISF6ND7TW4P4ER",
            ),
            (
                "GAKFARYSPI33KUJE7HYLT47DCX2PFWJ77W3LZMRBPSGPGYPMSDBE7W7X",
                "SALJ5LPBTXCFML2CQ7ORP7WJNJOZSVBVRQAAODMVHMUF4P4XXFZB7MKY",
            ),
        ),
    },
)


def mnemonic_to_shamir(mnemonic, passphrase):
    # BIP-39 seed from mnemonic
    seed_raw = StellarMnemonic("english").to_bip39_seed(mnemonic=mnemonic, passphrase=passphrase)

    # Shamir with the BIP-39 seed
    shamir = shamir_mnemonic.generate_mnemonics(
        group_threshold=1,
        groups=[(2, 3)],
        master_secret=seed_raw,
        passphrase=passphrase.encode(),
    )[0]

    return shamir


def consistency_check(mnemonic, shamir_phrases, passphrase, accounts):
    for perms in itertools.permutations(shamir_phrases, 2):
        for idx in range(10):
            reconstructed_kp = Keypair.from_shamir_mnemonic_phrases(mnemonic_phrases=perms, passphrase=passphrase, index=idx)

            kp = Keypair.from_mnemonic_phrase(mnemonic_phrase=mnemonic, passphrase=passphrase, index=idx)
            assert reconstructed_kp.public_key == kp.public_key
            assert reconstructed_kp.secret == kp.secret

            assert reconstructed_kp.public_key == accounts[idx][0]
            assert reconstructed_kp.secret == accounts[idx][1]


for i, case in enumerate(SEP_5_CASES):
    mnemonic, passphrase, accounts = case["mnemonic"], case["passphrase"], case["accounts"]

    shamir_mnemonics = mnemonic_to_shamir(mnemonic=mnemonic, passphrase=passphrase)

    consistency_check(mnemonic=mnemonic, shamir_phrases=shamir_mnemonics, passphrase=passphrase, accounts=accounts)

    print(f"{i+1}:\n{shamir_mnemonics}\n\n")

@overcat
Copy link
Contributor

overcat commented Jan 3, 2025

Great job, I will review it tomorrow.

ecosystem/sep-0005.md Outdated Show resolved Hide resolved
@tupui
Copy link
Author

tupui commented Jan 3, 2025

Putting here as well the code which was used to generate the data (rely on StellarCN/py-stellar-base#1015):

Details
import itertools

import shamir_mnemonic
from stellar_sdk import Keypair
from stellar_sdk.sep.mnemonic import StellarMnemonic


SEP_5_CASES = (
    {
        "mnemonic": "illness spike retreat truth genius clock brain pass fit cave bargain toe",
        "passphrase": "",
        "accounts": (
            (
                "GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RGZGIEKWE4SOOHSUJUJ6",
                "SBGWSG6BTNCKCOB3DIFBGCVMUPQFYPA2G4O34RMTB343OYPXU5DJDVMN",
            ),
            (
                "GBAW5XGWORWVFE2XTJYDTLDHXTY2Q2MO73HYCGB3XMFMQ562Q2W2GJQX",
                "SCEPFFWGAG5P2VX5DHIYK3XEMZYLTYWIPWYEKXFHSK25RVMIUNJ7CTIS",
            ),
            (
                "GAY5PRAHJ2HIYBYCLZXTHID6SPVELOOYH2LBPH3LD4RUMXUW3DOYTLXW",
                "SDAILLEZCSA67DUEP3XUPZJ7NYG7KGVRM46XA7K5QWWUIGADUZCZWTJP",
            ),
            (
                "GAOD5NRAEORFE34G5D4EOSKIJB6V4Z2FGPBCJNQI6MNICVITE6CSYIAE",
                "SBMWLNV75BPI2VB4G27RWOMABVRTSSF7352CCYGVELZDSHCXWCYFKXIX",
            ),
            (
                "GBCUXLFLSL2JE3NWLHAWXQZN6SQC6577YMAU3M3BEMWKYPFWXBSRCWV4",
                "SCPCY3CEHMOP2TADSV2ERNNZBNHBGP4V32VGOORIEV6QJLXD5NMCJUXI",
            ),
            (
                "GBRQY5JFN5UBG5PGOSUOL4M6D7VRMAYU6WW2ZWXBMCKB7GPT3YCBU2XZ",
                "SCK27SFHI3WUDOEMJREV7ZJQG34SCBR6YWCE6OLEXUS2VVYTSNGCRS6X",
            ),
            (
                "GBY27SJVFEWR3DUACNBSMJB6T4ZPR4C7ZXSTHT6GMZUDL23LAM5S2PQX",
                "SDJ4WDPOQAJYR3YIAJOJP3E6E4BMRB7VZ4QAEGCP7EYVDW6NQD3LRJMZ",
            ),
            (
                "GAY7T23Z34DWLSTEAUKVBPHHBUE4E3EMZBAQSLV6ZHS764U3TKUSNJOF",
                "SA3HXJUCE2N27TBIZ5JRBLEBF3TLPQEBINP47E6BTMIWW2RJ5UKR2B3L",
            ),
            (
                "GDJTCF62UUYSAFAVIXHPRBR4AUZV6NYJR75INVDXLLRZLZQ62S44443R",
                "SCD5OSHUUC75MSJG44BAT3HFZL2HZMMQ5M4GPDL7KA6HJHV3FLMUJAME",
            ),
            (
                "GBTVYYDIYWGUQUTKX6ZMLGSZGMTESJYJKJWAATGZGITA25ZB6T5REF44",
                "SCJGVMJ66WAUHQHNLMWDFGY2E72QKSI3XGSBYV6BANDFUFE7VY4XNXXR",
            ),
        ),
    },
    {
        "mnemonic": "resource asthma orphan phone ice canvas fire useful arch jewel impose vague theory cushion top",
        "passphrase": "",
        "accounts": (
            (
                "GAVXVW5MCK7Q66RIBWZZKZEDQTRXWCZUP4DIIFXCCENGW2P6W4OA34RH",
                "SAKS7I2PNDBE5SJSUSU2XLJ7K5XJ3V3K4UDFAHMSBQYPOKE247VHAGDB",
            ),
            (
                "GDFCYVCICATX5YPJUDS22KM2GW5QU2KKSPPPT2IC5AQIU6TP3BZSLR5K",
                "SAZ2H5GLAVWCUWNPQMB6I3OHRI63T2ACUUAWSH7NAGYYPXGIOPLPW3Q4",
            ),
            (
                "GAUA3XK3SGEQFNCBM423WIM5WCZ4CR4ZDPDFCYSFLCTODGGGJMPOHAAE",
                "SDVSSLPL76I33DKAI4LFTOAKCHJNCXUERGPCMVFT655Z4GRLWM6ZZTSC",
            ),
            (
                "GAH3S77QXTAPZ77REY6LGFIJ2XWVXFOKXHCFLA6HQTL3POLVZJDHHUDM",
                "SCH56YSGOBYVBC6DO3ZI2PY62GBVXT4SEJSXJOBQYGC2GCEZSB5PEVBZ",
            ),
            (
                "GCSCZVGV2Y3EQ2RATJ7TE6PVWTW5OH5SMG754AF6W6YM3KJF7RMNPB4Y",
                "SBWBM73VUNBGBMFD4E2BA7Q756AKVEAAVTQH34RYEUFD6X64VYL5KXQ2",
            ),
            (
                "GDKWYAJE3W6PWCXDZNMFNFQSPTF6BUDANE6OVRYMJKBYNGL62VKKCNCC",
                "SAVS4CDQZI6PSA5DPCC42S5WLKYIPKXPCJSFYY4N3VDK25T2XX2BTGVX",
            ),
            (
                "GCDTVB4XDLNX22HI5GUWHBXJFBCPB6JNU6ZON7E57FA3LFURS74CWDJH",
                "SDFC7WZT3GDQVQUQMXN7TC7UWDW5E3GSMFPHUT2TSTQ7RKWTRA4PLBAL",
            ),
            (
                "GBTDPL5S4IOUQHDLCZ7I2UXJ2TEHO6DYIQ3F2P5OOP3IS7JSJI4UMHQJ",
                "SA6UO2FIYC6AS2MSDECLR6F7NKCJTG67F7R4LV2GYB4HCZYXJZRLPOBB",
            ),
            (
                "GD3KWA24OIM7V3MZKDAVSLN3NBHGKVURNJ72ZCTAJSDTF7RIGFXPW5FQ",
                "SBDNHDDICLLMBIDZ2IF2D3LH44OVUGGAVHQVQ6BZQI5IQO6AB6KNJCOV",
            ),
            (
                "GB3C6RRQB3V7EPDXEDJCMTS45LVDLSZQ46PTIGKZUY37DXXEOAKJIWSV",
                "SDHRG2J34MGDAYHMOVKVJC6LX2QZMCTIKRO5I4JQ6BJQ36KVL6QUTT72",
            ),
        ),
    },
    {
        "mnemonic": "bench hurt jump file august wise shallow faculty impulse spring exact slush thunder author capable act festival slice deposit sauce coconut afford frown better",
        "passphrase": "",
        "accounts": (
            (
                "GC3MMSXBWHL6CPOAVERSJITX7BH76YU252WGLUOM5CJX3E7UCYZBTPJQ",
                "SAEWIVK3VLNEJ3WEJRZXQGDAS5NVG2BYSYDFRSH4GKVTS5RXNVED5AX7",
            ),
            (
                "GB3MTYFXPBZBUINVG72XR7AQ6P2I32CYSXWNRKJ2PV5H5C7EAM5YYISO",
                "SBKSABCPDWXDFSZISAVJ5XKVIEWV4M5O3KBRRLSPY3COQI7ZP423FYB4",
            ),
            (
                "GDYF7GIHS2TRGJ5WW4MZ4ELIUIBINRNYPPAWVQBPLAZXC2JRDI4DGAKU",
                "SD5CCQAFRIPB3BWBHQYQ5SC66IB2AVMFNWWPBYGSUXVRZNCIRJ7IHESQ",
            ),
            (
                "GAFLH7DGM3VXFVUID7JUKSGOYG52ZRAQPZHQASVCEQERYC5I4PPJUWBD",
                "SBSGSAIKEF7JYQWQSGXKB4SRHNSKDXTEI33WZDRR6UHYQCQ5I6ZGZQPK",
            ),
            (
                "GAXG3LWEXWCAWUABRO6SMAEUKJXLB5BBX6J2KMHFRIWKAMDJKCFGS3NN",
                "SBIZH53PIRFTPI73JG7QYA3YAINOAT2XMNAUARB3QOWWVZVBAROHGXWM",
            ),
            (
                "GA6RUD4DZ2NEMAQY4VZJ4C6K6VSEYEJITNSLUQKLCFHJ2JOGC5UCGCFQ",
                "SCVM6ZNVRUOP4NMCMMKLTVBEMAF2THIOMHPYSSMPCD2ZU7VDPARQQ6OY",
            ),
            (
                "GCUDW6ZF5SCGCMS3QUTELZ6LSAH6IVVXNRPRLAUNJ2XYLCA7KH7ZCVQS",
                "SBSHUZQNC45IAIRSAHMWJEJ35RY7YNW6SMOEBZHTMMG64NKV7Y52ZEO2",
            ),
            (
                "GBJ646Q524WGBN5X5NOAPIF5VQCR2WZCN6QZIDOSY6VA2PMHJ2X636G4",
                "SC2QO2K2B4EBNBJMBZIKOYSHEX4EZAZNIF4UNLH63AQYV6BE7SMYWC6E",
            ),
            (
                "GDHX4LU6YBSXGYTR7SX2P4ZYZSN24VXNJBVAFOB2GEBKNN3I54IYSRM4",
                "SCGMC5AHAAVB3D4JXQPCORWW37T44XJZUNPEMLRW6DCOEARY3H5MAQST",
            ),
            (
                "GDXOY6HXPIDT2QD352CH7VWX257PHVFR72COWQ74QE3TEV4PK2KCKZX7",
                "SCPA5OX4EYINOPAUEQCPY6TJMYICUS5M7TVXYKWXR3G5ZRAJXY3C37GF",
            ),
        ),
    },
    {
        "mnemonic": "cable spray genius state float twenty onion head street palace net private method loan turn phrase state blanket interest dry amazing dress blast tube",
        "passphrase": "p4ssphr4se",
        "accounts": (
            (
                "GDAHPZ2NSYIIHZXM56Y36SBVTV5QKFIZGYMMBHOU53ETUSWTP62B63EQ",
                "SAFWTGXVS7ELMNCXELFWCFZOPMHUZ5LXNBGUVRCY3FHLFPXK4QPXYP2X",
            ),
            (
                "GDY47CJARRHHL66JH3RJURDYXAMIQ5DMXZLP3TDAUJ6IN2GUOFX4OJOC",
                "SBQPDFUGLMWJYEYXFRM5TQX3AX2BR47WKI4FDS7EJQUSEUUVY72MZPJF",
            ),
            (
                "GCLAQF5H5LGJ2A6ACOMNEHSWYDJ3VKVBUBHDWFGRBEPAVZ56L4D7JJID",
                "SAF2LXRW6FOSVQNC4HHIIDURZL4SCGCG7UEGG23ZQG6Q2DKIGMPZV6BZ",
            ),
            (
                "GBC36J4KG7ZSIQ5UOSJFQNUP4IBRN6LVUFAHQWT2ODEQ7Y3ASWC5ZN3B",
                "SDCCVBIYZDMXOR4VPC3IYMIPODNEDZCS44LDN7B5ZWECIE57N3BTV4GQ",
            ),
            (
                "GA6NHA4KPH5LFYD6LZH35SIX3DU5CWU3GX6GCKPJPPTQCCQPP627E3CB",
                "SA5TRXTO7BG2Z6QTQT3O2LC7A7DLZZ2RBTGUNCTG346PLVSSHXPNDVNT",
            ),
            (
                "GBOWMXTLABFNEWO34UJNSJJNVEF6ESLCNNS36S5SX46UZT2MNYJOLA5L",
                "SDEOED2KPHV355YNOLLDLVQB7HDPQVIGKXCAJMA3HTM4325ZHFZSKKUC",
            ),
            (
                "GBL3F5JUZN3SQKZ7SL4XSXEJI2SNSVGO6WZWNJLG666WOJHNDDLEXTSZ",
                "SDYNO6TLFNV3IM6THLNGUG5FII4ET2H7NH3KCT6OAHIUSHKR4XBEEI6A",
            ),
            (
                "GA5XPPWXL22HFFL5K5CE37CEPUHXYGSP3NNWGM6IK6K4C3EFHZFKSAND",
                "SDXMJXAY45W3WEFWMYEPLPIF4CXAD5ECQ37XKMGY5EKLM472SSRJXCYD",
            ),
            (
                "GDS5I7L7LWFUVSYVAOHXJET2565MGGHJ4VHGVJXIKVKNO5D4JWXIZ3XU",
                "SAIZA26BUP55TDCJ4U7I2MSQEAJDPDSZSBKBPWQTD5OQZQSJAGNN2IQB",
            ),
            (
                "GBOSMFQYKWFDHJWCMCZSMGUMWCZOM4KFMXXS64INDHVCJ2A2JAABCYRR",
                "SDXDYPDNRMGOF25AWYYKPHFAD3M54IT7LCLG7RWTGR3TS32A4HTUXNOS",
            ),
        ),
    },
    {
        "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
        "passphrase": "",
        "accounts": (
            (
                "GB3JDWCQJCWMJ3IILWIGDTQJJC5567PGVEVXSCVPEQOTDN64VJBDQBYX",
                "SBUV3MRWKNS6AYKZ6E6MOUVF2OYMON3MIUASWL3JLY5E3ISDJFELYBRZ",
            ),
            (
                "GDVSYYTUAJ3ACHTPQNSTQBDQ4LDHQCMNY4FCEQH5TJUMSSLWQSTG42MV",
                "SCHDCVCWGAKGIMTORV6K5DYYV3BY4WG3RA4M6MCBGJLHUCWU2MC6DL66",
            ),
            (
                "GBFPWBTN4AXHPWPTQVQBP4KRZ2YVYYOGRMV2PEYL2OBPPJDP7LECEVHR",
                "SAPLVTLUXSDLFRDGCCFLPDZMTCEVMP3ZXTM74EBJCVKZKM34LGQPF7K3",
            ),
            (
                "GCCCOWAKYVFY5M6SYHOW33TSNC7Z5IBRUEU2XQVVT34CIZU7CXZ4OQ4O",
                "SDQYXOP2EAUZP4YOEQ5BUJIQ3RDSP5XV4ZFI6C5Y3QCD5Y63LWPXT7PW",
            ),
            (
                "GCQ3J35MKPKJX7JDXRHC5YTXTULFMCBMZ5IC63EDR66QA3LO7264ZL7Q",
                "SCT7DUHYZD6DRCETT6M73GWKFJI4D56P3SNWNWNJ7ANLJZS6XIFYYXSB",
            ),
            (
                "GDTA7622ZA5PW7F7JL7NOEFGW62M7GW2GY764EQC2TUJ42YJQE2A3QUL",
                "SDTWG5AFDI6GRQNLPWOC7IYS7AKOGMI2GX4OXTBTZHHYPMNZ2PX4ONWU",
            ),
            (
                "GD7A7EACTPTBCYCURD43IEZXGIBCEXNBHN3OFWV2FOX67XKUIGRCTBNU",
                "SDJMWY4KFRS4PTA5WBFVCPS2GKYLXOMCLQSBNEIBG7KRGHNQOM25KMCP",
            ),
            (
                "GAF4AGPVLQXFKEWQV3DZU5YEFU6YP7XJHAEEQH4G3R664MSF77FLLRK3",
                "SDOJH5JRCNGT57QTPTJEQGBEBZJPXE7XUDYDB24VTOPP7PH3ALKHAHFG",
            ),
            (
                "GABTYCZJMCP55SS6I46SR76IHETZDLG4L37MLZRZKQDGBLS5RMP65TSX",
                "SC6N6GYQ2VA4T7CUP2BWGBRT2P6L2HQSZIUNQRHNDLISF6ND7TW4P4ER",
            ),
            (
                "GAKFARYSPI33KUJE7HYLT47DCX2PFWJ77W3LZMRBPSGPGYPMSDBE7W7X",
                "SALJ5LPBTXCFML2CQ7ORP7WJNJOZSVBVRQAAODMVHMUF4P4XXFZB7MKY",
            ),
        ),
    },
)


def mnemonic_to_shamir(mnemonic, passphrase):
    # BIP-39 seed from mnemonic
    seed_raw = StellarMnemonic("english").to_bip39_seed(mnemonic=mnemonic, passphrase=passphrase)

    # Shamir with the BIP-39 seed
    shamir = shamir_mnemonic.generate_mnemonics(
        group_threshold=1,
        groups=[(2, 3)],
        master_secret=seed_raw,
        passphrase=passphrase.encode(),
    )[0]

    return shamir


def consistency_check(mnemonic, shamir_phrases, passphrase, accounts):
    for perms in itertools.permutations(shamir_phrases, 2):
        for idx in range(10):
            reconstructed_kp = Keypair.from_shamir_mnemonic_phrases(mnemonic_phrases=perms, passphrase=passphrase, index=idx)

            kp = Keypair.from_mnemonic_phrase(mnemonic_phrase=mnemonic, passphrase=passphrase, index=idx)
            assert reconstructed_kp.public_key == kp.public_key
            assert reconstructed_kp.secret == kp.secret

            assert reconstructed_kp.public_key == accounts[idx][0]
            assert reconstructed_kp.secret == accounts[idx][1]


for i, case in enumerate(SEP_5_CASES):
    mnemonic, passphrase, accounts = case["mnemonic"], case["passphrase"], case["accounts"]

    shamir_mnemonics = mnemonic_to_shamir(mnemonic=mnemonic, passphrase=passphrase)

    consistency_check(mnemonic=mnemonic, shamir_phrases=shamir_mnemonics, passphrase=passphrase, accounts=accounts)

    print(f"{i+1}:\n{shamir_mnemonics}\n\n")

@overcat
Copy link
Contributor

overcat commented Jan 4, 2025

Hi @tupui, I was wondering if it would be better to add test data for multiple groups? Although it is not widely used, and even Trezor only supports a single group. However, the SLIP 39 specification does include it, and having test data would give someone more confidence if they wanted to implement it.

@tupui
Copy link
Author

tupui commented Jan 4, 2025

Hi @tupui, I was wondering if it would be better to add test data for multiple groups? Although it is not widely used, and even Trezor only supports a single group. However, the SLIP 39 specification does include it, and having test data would give someone more confidence if they wanted to implement it.

I can have a look at it 👍

@tupui
Copy link
Author

tupui commented Jan 7, 2025

@overcat done 😃 Let me know if I should adjust anything.

For the record, here is the small helper I used:

mnemonic = ...
passphrase = ...
seed_raw = StellarMnemonic("english").to_bip39_seed(mnemonic=mnemonic, passphrase=passphrase)
# Shamir with the BIP-39 seed
shamir = shamir_mnemonic.generate_mnemonics(
    group_threshold=2,
    groups=[(2, 3), (1, 1), (2, 3)],
    master_secret=seed_raw,
    passphrase=passphrase.encode(),
)

@overcat
Copy link
Contributor

overcat commented Jan 8, 2025

Hi @tupui,

BIP-0039 seed should be used to derive the multiparts menomonic. The parts are non-deterministic and any derivation
leads to the same set of keys. As recommended for single mnemonic codes, we recommend using 256 bits of
entropy. Which leads to 33 word mnemonic phrases.

I think this is incorrect. Have you noticed that all the test data you generated, regardless of the BIP39 word length, has a SLIP39 word length of 59?

Moreover, there is also such a description in https://trezor.io/learn/a/slip39-faqs:

Can I convert my existing BIP39 wallet into a SLIP39 wallet?
While technically possible, converting a BIP39 wallet to a SLIP39 wallet is not recommended due to several limitations and security concerns. Trezor Suite will not allow you to convert your BIP39 wallet to a SLIP39 wallet.

Here is a correct script for generating test data. Additionally, I suggest adding an entropy field in each test case.

import binascii
import os

import shamir_mnemonic

from stellar_sdk.keypair import Keypair
from stellar_sdk.sep.mnemonic import StellarMnemonic

# entropy = os.urandom(32)
entropy = binascii.unhexlify("00000000000000000000000000000000")  # 128 bits of entropy, Test 5
passphrase = ""
print(f"Entropy: {entropy.hex()}")

mnemonic = StellarMnemonic("english").to_mnemonic(entropy)
print(f"BIP39 Mnemonic: {mnemonic}")

bip39_seed = StellarMnemonic("english").to_bip39_seed(mnemonic=mnemonic, passphrase=passphrase)
print(f"BIP39 Seed: {bip39_seed.hex()}")

print("BIP39 KeyPairs:")
for i in range(3):
    kp = Keypair.from_mnemonic_phrase(mnemonic, passphrase=passphrase, index=i)
    print(f"Index: {i}, Public Key: {kp.public_key}, Secret: {kp.secret}")

mnemonic_phrases = shamir_mnemonic.generate_mnemonics(
    group_threshold=1,
    groups=[(2, 3)],
    master_secret=entropy,
    passphrase=passphrase.encode(),

)[0]
# Note: Due to the presence of the identifier, each generated mnemonic phrase is different, but they can all recover the same seed.
# https://github.com/satoshilabs/slips/blob/master/slip-0039.md#format-of-the-share-mnemonic
print(f"SLIP-0039 Mnemonic phrases: {mnemonic_phrases}")
slip39_seed = shamir_mnemonic.combine_mnemonics(mnemonic_phrases[:2], passphrase=passphrase.encode())
print(f"SLIP-0039 Seed: {slip39_seed.hex()}")

print("SLIP-0039 KeyPairs:")
for i in range(3):
    kp = Keypair.from_shamir_mnemonic_phrases(mnemonic_phrases[:2], passphrase=passphrase, index=i)
    print(f"Index: {i}, Public Key: {kp.public_key}, Secret: {kp.secret}")

@tupui
Copy link
Author

tupui commented Jan 8, 2025

I think this is incorrect. Have you noticed that all the test data you generated, regardless of the BIP39 word length, has a SLIP39 word length of 59?

Yes I noticed. This is because I am using the full BIP39 seed which is more than 256 bits. So we end up at the max which is 59 words. I should rephrase to add "at least".

I went with that route so that we can reuse the current cases. That works in the sense that we can be consistent (see my other script above with the consistency check).

I agree though that using a plain entropy field as you suggest looks better. I can regenerate all the data if we are fine with changing the original test cases (I have seen that these public addresses were reserved to avoid any issues.)

@overcat
Copy link
Contributor

overcat commented Jan 8, 2025

I think this is incorrect. Have you noticed that all the test data you generated, regardless of the BIP39 word length, has a SLIP39 word length of 59?

Yes I noticed. This is because I am using the full BIP39 seed which is more than 256 bits. So we end up at the max which is 59 words. I should rephrase to add "at least".

I went with that route so that we can reuse the current cases. That works in the sense that we can be consistent (see my other script above with the consistency check).

I agree though that using a plain entropy field as you suggest looks better. I can regenerate all the data if we are fine with changing the original test cases (I have seen that these public addresses were reserved to avoid any issues.)

You can derive the plain entropy from the existing mnemonic words, so this should not change the existing test cases.

@tupui
Copy link
Author

tupui commented Jan 8, 2025

I see what you mean 👍 I will do that and also adjust the text to replace the BIP39 with it.

ecosystem/sep-0005.md Outdated Show resolved Hide resolved
@tupui
Copy link
Author

tupui commented Jan 9, 2025

I adjusted for entropy.

Code to reproduce
import itertools

import pprint
import shamir_mnemonic

from stellar_sdk import Keypair
from stellar_sdk.sep.mnemonic import StellarMnemonic


SEP_5_CASES = (
    {
        "mnemonic": "illness spike retreat truth genius clock brain pass fit cave bargain toe",
        "passphrase": "",
        "accounts": (
            (
                "GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RGZGIEKWE4SOOHSUJUJ6",
                "SBGWSG6BTNCKCOB3DIFBGCVMUPQFYPA2G4O34RMTB343OYPXU5DJDVMN",
            ),
            (
                "GBAW5XGWORWVFE2XTJYDTLDHXTY2Q2MO73HYCGB3XMFMQ562Q2W2GJQX",
                "SCEPFFWGAG5P2VX5DHIYK3XEMZYLTYWIPWYEKXFHSK25RVMIUNJ7CTIS",
            ),
            (
                "GAY5PRAHJ2HIYBYCLZXTHID6SPVELOOYH2LBPH3LD4RUMXUW3DOYTLXW",
                "SDAILLEZCSA67DUEP3XUPZJ7NYG7KGVRM46XA7K5QWWUIGADUZCZWTJP",
            ),
            (
                "GAOD5NRAEORFE34G5D4EOSKIJB6V4Z2FGPBCJNQI6MNICVITE6CSYIAE",
                "SBMWLNV75BPI2VB4G27RWOMABVRTSSF7352CCYGVELZDSHCXWCYFKXIX",
            ),
            (
                "GBCUXLFLSL2JE3NWLHAWXQZN6SQC6577YMAU3M3BEMWKYPFWXBSRCWV4",
                "SCPCY3CEHMOP2TADSV2ERNNZBNHBGP4V32VGOORIEV6QJLXD5NMCJUXI",
            ),
            (
                "GBRQY5JFN5UBG5PGOSUOL4M6D7VRMAYU6WW2ZWXBMCKB7GPT3YCBU2XZ",
                "SCK27SFHI3WUDOEMJREV7ZJQG34SCBR6YWCE6OLEXUS2VVYTSNGCRS6X",
            ),
            (
                "GBY27SJVFEWR3DUACNBSMJB6T4ZPR4C7ZXSTHT6GMZUDL23LAM5S2PQX",
                "SDJ4WDPOQAJYR3YIAJOJP3E6E4BMRB7VZ4QAEGCP7EYVDW6NQD3LRJMZ",
            ),
            (
                "GAY7T23Z34DWLSTEAUKVBPHHBUE4E3EMZBAQSLV6ZHS764U3TKUSNJOF",
                "SA3HXJUCE2N27TBIZ5JRBLEBF3TLPQEBINP47E6BTMIWW2RJ5UKR2B3L",
            ),
            (
                "GDJTCF62UUYSAFAVIXHPRBR4AUZV6NYJR75INVDXLLRZLZQ62S44443R",
                "SCD5OSHUUC75MSJG44BAT3HFZL2HZMMQ5M4GPDL7KA6HJHV3FLMUJAME",
            ),
            (
                "GBTVYYDIYWGUQUTKX6ZMLGSZGMTESJYJKJWAATGZGITA25ZB6T5REF44",
                "SCJGVMJ66WAUHQHNLMWDFGY2E72QKSI3XGSBYV6BANDFUFE7VY4XNXXR",
            ),
        ),
    },
    {
        "mnemonic": "resource asthma orphan phone ice canvas fire useful arch jewel impose vague theory cushion top",
        "passphrase": "",
        "accounts": (
            (
                "GAVXVW5MCK7Q66RIBWZZKZEDQTRXWCZUP4DIIFXCCENGW2P6W4OA34RH",
                "SAKS7I2PNDBE5SJSUSU2XLJ7K5XJ3V3K4UDFAHMSBQYPOKE247VHAGDB",
            ),
            (
                "GDFCYVCICATX5YPJUDS22KM2GW5QU2KKSPPPT2IC5AQIU6TP3BZSLR5K",
                "SAZ2H5GLAVWCUWNPQMB6I3OHRI63T2ACUUAWSH7NAGYYPXGIOPLPW3Q4",
            ),
            (
                "GAUA3XK3SGEQFNCBM423WIM5WCZ4CR4ZDPDFCYSFLCTODGGGJMPOHAAE",
                "SDVSSLPL76I33DKAI4LFTOAKCHJNCXUERGPCMVFT655Z4GRLWM6ZZTSC",
            ),
            (
                "GAH3S77QXTAPZ77REY6LGFIJ2XWVXFOKXHCFLA6HQTL3POLVZJDHHUDM",
                "SCH56YSGOBYVBC6DO3ZI2PY62GBVXT4SEJSXJOBQYGC2GCEZSB5PEVBZ",
            ),
            (
                "GCSCZVGV2Y3EQ2RATJ7TE6PVWTW5OH5SMG754AF6W6YM3KJF7RMNPB4Y",
                "SBWBM73VUNBGBMFD4E2BA7Q756AKVEAAVTQH34RYEUFD6X64VYL5KXQ2",
            ),
            (
                "GDKWYAJE3W6PWCXDZNMFNFQSPTF6BUDANE6OVRYMJKBYNGL62VKKCNCC",
                "SAVS4CDQZI6PSA5DPCC42S5WLKYIPKXPCJSFYY4N3VDK25T2XX2BTGVX",
            ),
            (
                "GCDTVB4XDLNX22HI5GUWHBXJFBCPB6JNU6ZON7E57FA3LFURS74CWDJH",
                "SDFC7WZT3GDQVQUQMXN7TC7UWDW5E3GSMFPHUT2TSTQ7RKWTRA4PLBAL",
            ),
            (
                "GBTDPL5S4IOUQHDLCZ7I2UXJ2TEHO6DYIQ3F2P5OOP3IS7JSJI4UMHQJ",
                "SA6UO2FIYC6AS2MSDECLR6F7NKCJTG67F7R4LV2GYB4HCZYXJZRLPOBB",
            ),
            (
                "GD3KWA24OIM7V3MZKDAVSLN3NBHGKVURNJ72ZCTAJSDTF7RIGFXPW5FQ",
                "SBDNHDDICLLMBIDZ2IF2D3LH44OVUGGAVHQVQ6BZQI5IQO6AB6KNJCOV",
            ),
            (
                "GB3C6RRQB3V7EPDXEDJCMTS45LVDLSZQ46PTIGKZUY37DXXEOAKJIWSV",
                "SDHRG2J34MGDAYHMOVKVJC6LX2QZMCTIKRO5I4JQ6BJQ36KVL6QUTT72",
            ),
        ),
    },
    {
        "mnemonic": "bench hurt jump file august wise shallow faculty impulse spring exact slush thunder author capable act festival slice deposit sauce coconut afford frown better",
        "passphrase": "",
        "accounts": (
            (
                "GC3MMSXBWHL6CPOAVERSJITX7BH76YU252WGLUOM5CJX3E7UCYZBTPJQ",
                "SAEWIVK3VLNEJ3WEJRZXQGDAS5NVG2BYSYDFRSH4GKVTS5RXNVED5AX7",
            ),
            (
                "GB3MTYFXPBZBUINVG72XR7AQ6P2I32CYSXWNRKJ2PV5H5C7EAM5YYISO",
                "SBKSABCPDWXDFSZISAVJ5XKVIEWV4M5O3KBRRLSPY3COQI7ZP423FYB4",
            ),
            (
                "GDYF7GIHS2TRGJ5WW4MZ4ELIUIBINRNYPPAWVQBPLAZXC2JRDI4DGAKU",
                "SD5CCQAFRIPB3BWBHQYQ5SC66IB2AVMFNWWPBYGSUXVRZNCIRJ7IHESQ",
            ),
            (
                "GAFLH7DGM3VXFVUID7JUKSGOYG52ZRAQPZHQASVCEQERYC5I4PPJUWBD",
                "SBSGSAIKEF7JYQWQSGXKB4SRHNSKDXTEI33WZDRR6UHYQCQ5I6ZGZQPK",
            ),
            (
                "GAXG3LWEXWCAWUABRO6SMAEUKJXLB5BBX6J2KMHFRIWKAMDJKCFGS3NN",
                "SBIZH53PIRFTPI73JG7QYA3YAINOAT2XMNAUARB3QOWWVZVBAROHGXWM",
            ),
            (
                "GA6RUD4DZ2NEMAQY4VZJ4C6K6VSEYEJITNSLUQKLCFHJ2JOGC5UCGCFQ",
                "SCVM6ZNVRUOP4NMCMMKLTVBEMAF2THIOMHPYSSMPCD2ZU7VDPARQQ6OY",
            ),
            (
                "GCUDW6ZF5SCGCMS3QUTELZ6LSAH6IVVXNRPRLAUNJ2XYLCA7KH7ZCVQS",
                "SBSHUZQNC45IAIRSAHMWJEJ35RY7YNW6SMOEBZHTMMG64NKV7Y52ZEO2",
            ),
            (
                "GBJ646Q524WGBN5X5NOAPIF5VQCR2WZCN6QZIDOSY6VA2PMHJ2X636G4",
                "SC2QO2K2B4EBNBJMBZIKOYSHEX4EZAZNIF4UNLH63AQYV6BE7SMYWC6E",
            ),
            (
                "GDHX4LU6YBSXGYTR7SX2P4ZYZSN24VXNJBVAFOB2GEBKNN3I54IYSRM4",
                "SCGMC5AHAAVB3D4JXQPCORWW37T44XJZUNPEMLRW6DCOEARY3H5MAQST",
            ),
            (
                "GDXOY6HXPIDT2QD352CH7VWX257PHVFR72COWQ74QE3TEV4PK2KCKZX7",
                "SCPA5OX4EYINOPAUEQCPY6TJMYICUS5M7TVXYKWXR3G5ZRAJXY3C37GF",
            ),
        ),
    },
    {
        "mnemonic": "cable spray genius state float twenty onion head street palace net private method loan turn phrase state blanket interest dry amazing dress blast tube",
        "passphrase": "p4ssphr4se",
        "accounts": (
            (
                "GDAHPZ2NSYIIHZXM56Y36SBVTV5QKFIZGYMMBHOU53ETUSWTP62B63EQ",
                "SAFWTGXVS7ELMNCXELFWCFZOPMHUZ5LXNBGUVRCY3FHLFPXK4QPXYP2X",
            ),
            (
                "GDY47CJARRHHL66JH3RJURDYXAMIQ5DMXZLP3TDAUJ6IN2GUOFX4OJOC",
                "SBQPDFUGLMWJYEYXFRM5TQX3AX2BR47WKI4FDS7EJQUSEUUVY72MZPJF",
            ),
            (
                "GCLAQF5H5LGJ2A6ACOMNEHSWYDJ3VKVBUBHDWFGRBEPAVZ56L4D7JJID",
                "SAF2LXRW6FOSVQNC4HHIIDURZL4SCGCG7UEGG23ZQG6Q2DKIGMPZV6BZ",
            ),
            (
                "GBC36J4KG7ZSIQ5UOSJFQNUP4IBRN6LVUFAHQWT2ODEQ7Y3ASWC5ZN3B",
                "SDCCVBIYZDMXOR4VPC3IYMIPODNEDZCS44LDN7B5ZWECIE57N3BTV4GQ",
            ),
            (
                "GA6NHA4KPH5LFYD6LZH35SIX3DU5CWU3GX6GCKPJPPTQCCQPP627E3CB",
                "SA5TRXTO7BG2Z6QTQT3O2LC7A7DLZZ2RBTGUNCTG346PLVSSHXPNDVNT",
            ),
            (
                "GBOWMXTLABFNEWO34UJNSJJNVEF6ESLCNNS36S5SX46UZT2MNYJOLA5L",
                "SDEOED2KPHV355YNOLLDLVQB7HDPQVIGKXCAJMA3HTM4325ZHFZSKKUC",
            ),
            (
                "GBL3F5JUZN3SQKZ7SL4XSXEJI2SNSVGO6WZWNJLG666WOJHNDDLEXTSZ",
                "SDYNO6TLFNV3IM6THLNGUG5FII4ET2H7NH3KCT6OAHIUSHKR4XBEEI6A",
            ),
            (
                "GA5XPPWXL22HFFL5K5CE37CEPUHXYGSP3NNWGM6IK6K4C3EFHZFKSAND",
                "SDXMJXAY45W3WEFWMYEPLPIF4CXAD5ECQ37XKMGY5EKLM472SSRJXCYD",
            ),
            (
                "GDS5I7L7LWFUVSYVAOHXJET2565MGGHJ4VHGVJXIKVKNO5D4JWXIZ3XU",
                "SAIZA26BUP55TDCJ4U7I2MSQEAJDPDSZSBKBPWQTD5OQZQSJAGNN2IQB",
            ),
            (
                "GBOSMFQYKWFDHJWCMCZSMGUMWCZOM4KFMXXS64INDHVCJ2A2JAABCYRR",
                "SDXDYPDNRMGOF25AWYYKPHFAD3M54IT7LCLG7RWTGR3TS32A4HTUXNOS",
            ),
        ),
    },
    {
        "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
        "passphrase": "",
        "accounts": (
            (
                "GB3JDWCQJCWMJ3IILWIGDTQJJC5567PGVEVXSCVPEQOTDN64VJBDQBYX",
                "SBUV3MRWKNS6AYKZ6E6MOUVF2OYMON3MIUASWL3JLY5E3ISDJFELYBRZ",
            ),
            (
                "GDVSYYTUAJ3ACHTPQNSTQBDQ4LDHQCMNY4FCEQH5TJUMSSLWQSTG42MV",
                "SCHDCVCWGAKGIMTORV6K5DYYV3BY4WG3RA4M6MCBGJLHUCWU2MC6DL66",
            ),
            (
                "GBFPWBTN4AXHPWPTQVQBP4KRZ2YVYYOGRMV2PEYL2OBPPJDP7LECEVHR",
                "SAPLVTLUXSDLFRDGCCFLPDZMTCEVMP3ZXTM74EBJCVKZKM34LGQPF7K3",
            ),
            (
                "GCCCOWAKYVFY5M6SYHOW33TSNC7Z5IBRUEU2XQVVT34CIZU7CXZ4OQ4O",
                "SDQYXOP2EAUZP4YOEQ5BUJIQ3RDSP5XV4ZFI6C5Y3QCD5Y63LWPXT7PW",
            ),
            (
                "GCQ3J35MKPKJX7JDXRHC5YTXTULFMCBMZ5IC63EDR66QA3LO7264ZL7Q",
                "SCT7DUHYZD6DRCETT6M73GWKFJI4D56P3SNWNWNJ7ANLJZS6XIFYYXSB",
            ),
            (
                "GDTA7622ZA5PW7F7JL7NOEFGW62M7GW2GY764EQC2TUJ42YJQE2A3QUL",
                "SDTWG5AFDI6GRQNLPWOC7IYS7AKOGMI2GX4OXTBTZHHYPMNZ2PX4ONWU",
            ),
            (
                "GD7A7EACTPTBCYCURD43IEZXGIBCEXNBHN3OFWV2FOX67XKUIGRCTBNU",
                "SDJMWY4KFRS4PTA5WBFVCPS2GKYLXOMCLQSBNEIBG7KRGHNQOM25KMCP",
            ),
            (
                "GAF4AGPVLQXFKEWQV3DZU5YEFU6YP7XJHAEEQH4G3R664MSF77FLLRK3",
                "SDOJH5JRCNGT57QTPTJEQGBEBZJPXE7XUDYDB24VTOPP7PH3ALKHAHFG",
            ),
            (
                "GABTYCZJMCP55SS6I46SR76IHETZDLG4L37MLZRZKQDGBLS5RMP65TSX",
                "SC6N6GYQ2VA4T7CUP2BWGBRT2P6L2HQSZIUNQRHNDLISF6ND7TW4P4ER",
            ),
            (
                "GAKFARYSPI33KUJE7HYLT47DCX2PFWJ77W3LZMRBPSGPGYPMSDBE7W7X",
                "SALJ5LPBTXCFML2CQ7ORP7WJNJOZSVBVRQAAODMVHMUF4P4XXFZB7MKY",
            ),
        ),
    },
)

CHECK_CONSISTENCY = False

def mnemonic_to_shamir(mnemonic, passphrase):
    # Entropy seed from mnemonic
    seed_raw = StellarMnemonic("english").to_entropy(mnemonic)
    print(seed_raw.hex())

    # Shamir with the BIP-39 seed
    if CHECK_CONSISTENCY:
        group_threshold = 1
        groups = [(2, 3)]
    else:
        group_threshold = 2
        groups = [(2, 3), (1, 1), (2, 3)]

    shamir = shamir_mnemonic.generate_mnemonics(
        group_threshold=group_threshold,
        groups=groups,
        master_secret=seed_raw,
        passphrase=passphrase.encode(),
    )

    return shamir


def consistency_check(mnemonic, shamir_phrases, passphrase, accounts):
    for perms in itertools.permutations(shamir_phrases, 2):
        for idx in range(10):
            reconstructed_kp = Keypair.from_shamir_mnemonic_phrases(mnemonic_phrases=perms, passphrase=passphrase, index=idx)

            kp = Keypair.from_mnemonic_phrase(mnemonic_phrase=mnemonic, passphrase=passphrase, index=idx)
            assert reconstructed_kp.public_key == kp.public_key
            assert reconstructed_kp.secret == kp.secret

            assert reconstructed_kp.public_key == accounts[idx][0]
            assert reconstructed_kp.secret == accounts[idx][1]


for i, case in enumerate(SEP_5_CASES):
    mnemonic, passphrase, accounts = case["mnemonic"], case["passphrase"], case["accounts"]

    shamir_mnemonics = mnemonic_to_shamir(mnemonic=mnemonic, passphrase=passphrase)

    if CHECK_CONSISTENCY:
        consistency_check(mnemonic=mnemonic, shamir_phrases=shamir_mnemonics, passphrase=passphrase, accounts=accounts)

    print(f"{i+1}")
    pprint.pprint(shamir_mnemonics)
    print("\n\n")

ecosystem/sep-0005.md Outdated Show resolved Hide resolved
@@ -96,6 +114,25 @@ m/44'/148'/8' GDJTCF62UUYSAFAVIXHPRBR4AUZV6NYJR75INVDXLLRZLZQ62S44443R SCD5OSHUU
m/44'/148'/9' GBTVYYDIYWGUQUTKX6ZMLGSZGMTESJYJKJWAATGZGITA25ZB6T5REF44 SCJGVMJ66WAUHQHNLMWDFGY2E72QKSI3XGSBYV6BANDFUFE7VY4XNXXR
```

Shamir Secret Sharing shares (non-deterministic) - group threshold = 2; groups = [(2, 3), (1, 1), (2, 3)]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Stellar keys of BIP 39 and the Stellar keys of SLIP 39 are different. Are you willing to add it?

Additionally, this part only applies to BIP-39. Can you specify that? For example, m/44'/148' key (BIP39):

m/44'/148' key:

e0eec84fe165cd427cb7bc9b6cfdef0555aa1cb6f9043ff1fe986c3c8ddd22e3

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Stellar keys of BIP 39 and the Stellar keys of SLIP 39 are different. Are you willing to add it?

Sorry I don't understand what you mean.

Copy link
Author

@tupui tupui Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see now (linked to the other PR.) If I start from the entropy and use it directly then yes keys will be different. To get the same keys I need to go with the to_bip39 as I had before. I wanted to have everything being consistent with a single set of Stellar Keys. But if we can't because we say we don't want to use BIP39 as transition then I can make a specific section for SLIP39 as you suggested.

(Would be so much easier to just use the normal mnemonic phrase as a secret for Shamir 😅)

ecosystem/sep-0005.md Outdated Show resolved Hide resolved
ecosystem/sep-0005.md Outdated Show resolved Hide resolved
@tupui
Copy link
Author

tupui commented Jan 10, 2025

Done 😃

Code
import pprint
import shamir_mnemonic

from stellar_sdk import Keypair
from stellar_sdk.sep.mnemonic import StellarMnemonic


SEP_5_CASES = (
    {
        "mnemonic": "illness spike retreat truth genius clock brain pass fit cave bargain toe",
        "passphrase": "",
        "accounts": (
            (
                "GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RGZGIEKWE4SOOHSUJUJ6",
                "SBGWSG6BTNCKCOB3DIFBGCVMUPQFYPA2G4O34RMTB343OYPXU5DJDVMN",
            ),
            (
                "GBAW5XGWORWVFE2XTJYDTLDHXTY2Q2MO73HYCGB3XMFMQ562Q2W2GJQX",
                "SCEPFFWGAG5P2VX5DHIYK3XEMZYLTYWIPWYEKXFHSK25RVMIUNJ7CTIS",
            ),
            (
                "GAY5PRAHJ2HIYBYCLZXTHID6SPVELOOYH2LBPH3LD4RUMXUW3DOYTLXW",
                "SDAILLEZCSA67DUEP3XUPZJ7NYG7KGVRM46XA7K5QWWUIGADUZCZWTJP",
            ),
            (
                "GAOD5NRAEORFE34G5D4EOSKIJB6V4Z2FGPBCJNQI6MNICVITE6CSYIAE",
                "SBMWLNV75BPI2VB4G27RWOMABVRTSSF7352CCYGVELZDSHCXWCYFKXIX",
            ),
            (
                "GBCUXLFLSL2JE3NWLHAWXQZN6SQC6577YMAU3M3BEMWKYPFWXBSRCWV4",
                "SCPCY3CEHMOP2TADSV2ERNNZBNHBGP4V32VGOORIEV6QJLXD5NMCJUXI",
            ),
            (
                "GBRQY5JFN5UBG5PGOSUOL4M6D7VRMAYU6WW2ZWXBMCKB7GPT3YCBU2XZ",
                "SCK27SFHI3WUDOEMJREV7ZJQG34SCBR6YWCE6OLEXUS2VVYTSNGCRS6X",
            ),
            (
                "GBY27SJVFEWR3DUACNBSMJB6T4ZPR4C7ZXSTHT6GMZUDL23LAM5S2PQX",
                "SDJ4WDPOQAJYR3YIAJOJP3E6E4BMRB7VZ4QAEGCP7EYVDW6NQD3LRJMZ",
            ),
            (
                "GAY7T23Z34DWLSTEAUKVBPHHBUE4E3EMZBAQSLV6ZHS764U3TKUSNJOF",
                "SA3HXJUCE2N27TBIZ5JRBLEBF3TLPQEBINP47E6BTMIWW2RJ5UKR2B3L",
            ),
            (
                "GDJTCF62UUYSAFAVIXHPRBR4AUZV6NYJR75INVDXLLRZLZQ62S44443R",
                "SCD5OSHUUC75MSJG44BAT3HFZL2HZMMQ5M4GPDL7KA6HJHV3FLMUJAME",
            ),
            (
                "GBTVYYDIYWGUQUTKX6ZMLGSZGMTESJYJKJWAATGZGITA25ZB6T5REF44",
                "SCJGVMJ66WAUHQHNLMWDFGY2E72QKSI3XGSBYV6BANDFUFE7VY4XNXXR",
            ),
        ),
    },
    {
        "mnemonic": "resource asthma orphan phone ice canvas fire useful arch jewel impose vague theory cushion top",
        "passphrase": "",
        "accounts": (
            (
                "GAVXVW5MCK7Q66RIBWZZKZEDQTRXWCZUP4DIIFXCCENGW2P6W4OA34RH",
                "SAKS7I2PNDBE5SJSUSU2XLJ7K5XJ3V3K4UDFAHMSBQYPOKE247VHAGDB",
            ),
            (
                "GDFCYVCICATX5YPJUDS22KM2GW5QU2KKSPPPT2IC5AQIU6TP3BZSLR5K",
                "SAZ2H5GLAVWCUWNPQMB6I3OHRI63T2ACUUAWSH7NAGYYPXGIOPLPW3Q4",
            ),
            (
                "GAUA3XK3SGEQFNCBM423WIM5WCZ4CR4ZDPDFCYSFLCTODGGGJMPOHAAE",
                "SDVSSLPL76I33DKAI4LFTOAKCHJNCXUERGPCMVFT655Z4GRLWM6ZZTSC",
            ),
            (
                "GAH3S77QXTAPZ77REY6LGFIJ2XWVXFOKXHCFLA6HQTL3POLVZJDHHUDM",
                "SCH56YSGOBYVBC6DO3ZI2PY62GBVXT4SEJSXJOBQYGC2GCEZSB5PEVBZ",
            ),
            (
                "GCSCZVGV2Y3EQ2RATJ7TE6PVWTW5OH5SMG754AF6W6YM3KJF7RMNPB4Y",
                "SBWBM73VUNBGBMFD4E2BA7Q756AKVEAAVTQH34RYEUFD6X64VYL5KXQ2",
            ),
            (
                "GDKWYAJE3W6PWCXDZNMFNFQSPTF6BUDANE6OVRYMJKBYNGL62VKKCNCC",
                "SAVS4CDQZI6PSA5DPCC42S5WLKYIPKXPCJSFYY4N3VDK25T2XX2BTGVX",
            ),
            (
                "GCDTVB4XDLNX22HI5GUWHBXJFBCPB6JNU6ZON7E57FA3LFURS74CWDJH",
                "SDFC7WZT3GDQVQUQMXN7TC7UWDW5E3GSMFPHUT2TSTQ7RKWTRA4PLBAL",
            ),
            (
                "GBTDPL5S4IOUQHDLCZ7I2UXJ2TEHO6DYIQ3F2P5OOP3IS7JSJI4UMHQJ",
                "SA6UO2FIYC6AS2MSDECLR6F7NKCJTG67F7R4LV2GYB4HCZYXJZRLPOBB",
            ),
            (
                "GD3KWA24OIM7V3MZKDAVSLN3NBHGKVURNJ72ZCTAJSDTF7RIGFXPW5FQ",
                "SBDNHDDICLLMBIDZ2IF2D3LH44OVUGGAVHQVQ6BZQI5IQO6AB6KNJCOV",
            ),
            (
                "GB3C6RRQB3V7EPDXEDJCMTS45LVDLSZQ46PTIGKZUY37DXXEOAKJIWSV",
                "SDHRG2J34MGDAYHMOVKVJC6LX2QZMCTIKRO5I4JQ6BJQ36KVL6QUTT72",
            ),
        ),
    },
    {
        "mnemonic": "bench hurt jump file august wise shallow faculty impulse spring exact slush thunder author capable act festival slice deposit sauce coconut afford frown better",
        "passphrase": "",
        "accounts": (
            (
                "GC3MMSXBWHL6CPOAVERSJITX7BH76YU252WGLUOM5CJX3E7UCYZBTPJQ",
                "SAEWIVK3VLNEJ3WEJRZXQGDAS5NVG2BYSYDFRSH4GKVTS5RXNVED5AX7",
            ),
            (
                "GB3MTYFXPBZBUINVG72XR7AQ6P2I32CYSXWNRKJ2PV5H5C7EAM5YYISO",
                "SBKSABCPDWXDFSZISAVJ5XKVIEWV4M5O3KBRRLSPY3COQI7ZP423FYB4",
            ),
            (
                "GDYF7GIHS2TRGJ5WW4MZ4ELIUIBINRNYPPAWVQBPLAZXC2JRDI4DGAKU",
                "SD5CCQAFRIPB3BWBHQYQ5SC66IB2AVMFNWWPBYGSUXVRZNCIRJ7IHESQ",
            ),
            (
                "GAFLH7DGM3VXFVUID7JUKSGOYG52ZRAQPZHQASVCEQERYC5I4PPJUWBD",
                "SBSGSAIKEF7JYQWQSGXKB4SRHNSKDXTEI33WZDRR6UHYQCQ5I6ZGZQPK",
            ),
            (
                "GAXG3LWEXWCAWUABRO6SMAEUKJXLB5BBX6J2KMHFRIWKAMDJKCFGS3NN",
                "SBIZH53PIRFTPI73JG7QYA3YAINOAT2XMNAUARB3QOWWVZVBAROHGXWM",
            ),
            (
                "GA6RUD4DZ2NEMAQY4VZJ4C6K6VSEYEJITNSLUQKLCFHJ2JOGC5UCGCFQ",
                "SCVM6ZNVRUOP4NMCMMKLTVBEMAF2THIOMHPYSSMPCD2ZU7VDPARQQ6OY",
            ),
            (
                "GCUDW6ZF5SCGCMS3QUTELZ6LSAH6IVVXNRPRLAUNJ2XYLCA7KH7ZCVQS",
                "SBSHUZQNC45IAIRSAHMWJEJ35RY7YNW6SMOEBZHTMMG64NKV7Y52ZEO2",
            ),
            (
                "GBJ646Q524WGBN5X5NOAPIF5VQCR2WZCN6QZIDOSY6VA2PMHJ2X636G4",
                "SC2QO2K2B4EBNBJMBZIKOYSHEX4EZAZNIF4UNLH63AQYV6BE7SMYWC6E",
            ),
            (
                "GDHX4LU6YBSXGYTR7SX2P4ZYZSN24VXNJBVAFOB2GEBKNN3I54IYSRM4",
                "SCGMC5AHAAVB3D4JXQPCORWW37T44XJZUNPEMLRW6DCOEARY3H5MAQST",
            ),
            (
                "GDXOY6HXPIDT2QD352CH7VWX257PHVFR72COWQ74QE3TEV4PK2KCKZX7",
                "SCPA5OX4EYINOPAUEQCPY6TJMYICUS5M7TVXYKWXR3G5ZRAJXY3C37GF",
            ),
        ),
    },
    {
        "mnemonic": "cable spray genius state float twenty onion head street palace net private method loan turn phrase state blanket interest dry amazing dress blast tube",
        "passphrase": "p4ssphr4se",
        "accounts": (
            (
                "GDAHPZ2NSYIIHZXM56Y36SBVTV5QKFIZGYMMBHOU53ETUSWTP62B63EQ",
                "SAFWTGXVS7ELMNCXELFWCFZOPMHUZ5LXNBGUVRCY3FHLFPXK4QPXYP2X",
            ),
            (
                "GDY47CJARRHHL66JH3RJURDYXAMIQ5DMXZLP3TDAUJ6IN2GUOFX4OJOC",
                "SBQPDFUGLMWJYEYXFRM5TQX3AX2BR47WKI4FDS7EJQUSEUUVY72MZPJF",
            ),
            (
                "GCLAQF5H5LGJ2A6ACOMNEHSWYDJ3VKVBUBHDWFGRBEPAVZ56L4D7JJID",
                "SAF2LXRW6FOSVQNC4HHIIDURZL4SCGCG7UEGG23ZQG6Q2DKIGMPZV6BZ",
            ),
            (
                "GBC36J4KG7ZSIQ5UOSJFQNUP4IBRN6LVUFAHQWT2ODEQ7Y3ASWC5ZN3B",
                "SDCCVBIYZDMXOR4VPC3IYMIPODNEDZCS44LDN7B5ZWECIE57N3BTV4GQ",
            ),
            (
                "GA6NHA4KPH5LFYD6LZH35SIX3DU5CWU3GX6GCKPJPPTQCCQPP627E3CB",
                "SA5TRXTO7BG2Z6QTQT3O2LC7A7DLZZ2RBTGUNCTG346PLVSSHXPNDVNT",
            ),
            (
                "GBOWMXTLABFNEWO34UJNSJJNVEF6ESLCNNS36S5SX46UZT2MNYJOLA5L",
                "SDEOED2KPHV355YNOLLDLVQB7HDPQVIGKXCAJMA3HTM4325ZHFZSKKUC",
            ),
            (
                "GBL3F5JUZN3SQKZ7SL4XSXEJI2SNSVGO6WZWNJLG666WOJHNDDLEXTSZ",
                "SDYNO6TLFNV3IM6THLNGUG5FII4ET2H7NH3KCT6OAHIUSHKR4XBEEI6A",
            ),
            (
                "GA5XPPWXL22HFFL5K5CE37CEPUHXYGSP3NNWGM6IK6K4C3EFHZFKSAND",
                "SDXMJXAY45W3WEFWMYEPLPIF4CXAD5ECQ37XKMGY5EKLM472SSRJXCYD",
            ),
            (
                "GDS5I7L7LWFUVSYVAOHXJET2565MGGHJ4VHGVJXIKVKNO5D4JWXIZ3XU",
                "SAIZA26BUP55TDCJ4U7I2MSQEAJDPDSZSBKBPWQTD5OQZQSJAGNN2IQB",
            ),
            (
                "GBOSMFQYKWFDHJWCMCZSMGUMWCZOM4KFMXXS64INDHVCJ2A2JAABCYRR",
                "SDXDYPDNRMGOF25AWYYKPHFAD3M54IT7LCLG7RWTGR3TS32A4HTUXNOS",
            ),
        ),
    },
    {
        "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
        "passphrase": "",
        "accounts": (
            (
                "GB3JDWCQJCWMJ3IILWIGDTQJJC5567PGVEVXSCVPEQOTDN64VJBDQBYX",
                "SBUV3MRWKNS6AYKZ6E6MOUVF2OYMON3MIUASWL3JLY5E3ISDJFELYBRZ",
            ),
            (
                "GDVSYYTUAJ3ACHTPQNSTQBDQ4LDHQCMNY4FCEQH5TJUMSSLWQSTG42MV",
                "SCHDCVCWGAKGIMTORV6K5DYYV3BY4WG3RA4M6MCBGJLHUCWU2MC6DL66",
            ),
            (
                "GBFPWBTN4AXHPWPTQVQBP4KRZ2YVYYOGRMV2PEYL2OBPPJDP7LECEVHR",
                "SAPLVTLUXSDLFRDGCCFLPDZMTCEVMP3ZXTM74EBJCVKZKM34LGQPF7K3",
            ),
            (
                "GCCCOWAKYVFY5M6SYHOW33TSNC7Z5IBRUEU2XQVVT34CIZU7CXZ4OQ4O",
                "SDQYXOP2EAUZP4YOEQ5BUJIQ3RDSP5XV4ZFI6C5Y3QCD5Y63LWPXT7PW",
            ),
            (
                "GCQ3J35MKPKJX7JDXRHC5YTXTULFMCBMZ5IC63EDR66QA3LO7264ZL7Q",
                "SCT7DUHYZD6DRCETT6M73GWKFJI4D56P3SNWNWNJ7ANLJZS6XIFYYXSB",
            ),
            (
                "GDTA7622ZA5PW7F7JL7NOEFGW62M7GW2GY764EQC2TUJ42YJQE2A3QUL",
                "SDTWG5AFDI6GRQNLPWOC7IYS7AKOGMI2GX4OXTBTZHHYPMNZ2PX4ONWU",
            ),
            (
                "GD7A7EACTPTBCYCURD43IEZXGIBCEXNBHN3OFWV2FOX67XKUIGRCTBNU",
                "SDJMWY4KFRS4PTA5WBFVCPS2GKYLXOMCLQSBNEIBG7KRGHNQOM25KMCP",
            ),
            (
                "GAF4AGPVLQXFKEWQV3DZU5YEFU6YP7XJHAEEQH4G3R664MSF77FLLRK3",
                "SDOJH5JRCNGT57QTPTJEQGBEBZJPXE7XUDYDB24VTOPP7PH3ALKHAHFG",
            ),
            (
                "GABTYCZJMCP55SS6I46SR76IHETZDLG4L37MLZRZKQDGBLS5RMP65TSX",
                "SC6N6GYQ2VA4T7CUP2BWGBRT2P6L2HQSZIUNQRHNDLISF6ND7TW4P4ER",
            ),
            (
                "GAKFARYSPI33KUJE7HYLT47DCX2PFWJ77W3LZMRBPSGPGYPMSDBE7W7X",
                "SALJ5LPBTXCFML2CQ7ORP7WJNJOZSVBVRQAAODMVHMUF4P4XXFZB7MKY",
            ),
        ),
    },
)


def mnemonic_to_shamir(seed_raw, passphrase):
    # Shamir with the BIP-39 seed
    group_threshold = 2
    groups = [(2, 3), (1, 1), (2, 3)]

    shamir = shamir_mnemonic.generate_mnemonics(
        group_threshold=group_threshold,
        groups=groups,
        master_secret=seed_raw,
        passphrase=passphrase.encode(),
    )

    return shamir


for i, case in enumerate(SEP_5_CASES):
    print(f"{i+1}")

    mnemonic, passphrase, accounts = case["mnemonic"], case["passphrase"], case["accounts"]

    # Entropy seed from mnemonic
    seed_raw = StellarMnemonic("english").to_entropy(mnemonic)
    print(seed_raw.hex())

    shamir_mnemonics = mnemonic_to_shamir(seed_raw=seed_raw, passphrase=passphrase)

    pprint.pprint(shamir_mnemonics)

    perms = [*shamir_mnemonics[0][:2], *shamir_mnemonics[2][:2]]
    for idx in range(10):
        kp = Keypair.from_shamir_mnemonic_phrases(mnemonic_phrases=perms, passphrase=passphrase, index=idx)

        print(f"m/44'/148'/{idx}' {kp.public_key} {kp.secret}")

    print("\n\n")
Run
1
713a3ae074e60e56c6bd0557c4984af1
[['premium penalty acrobat leaf aquatic ivory simple mineral axle party slim '
  'acrobat priest tackle engage ladybug snake literary debris enjoy',
  'premium penalty acrobat lily chest boundary order romp necklace echo detect '
  'adorn blimp ecology guilt emission camera tofu force aircraft',
  'premium penalty acrobat lungs born phrase glad lend actress ladle drove '
  'realize nylon wavy buyer pleasure mandate bumpy ugly sweater'],
 ['premium penalty beard leader angry afraid airline easy alive slim music '
  'painting submit boundary soul fact task valuable speak fancy'],
 ['premium penalty ceramic leaf duke holy usual spider program midst penalty '
  'upgrade very item radar improve romantic leaves pink multiple',
  'premium penalty ceramic lily admit mule decorate adorn club alcohol flash '
  'acrobat standard stay deploy envy level august stilt ruler',
  'premium penalty ceramic lungs acrobat leader buyer item response penalty '
  'crucial party wisdom civil rhythm piece elevator erode adequate acne']]
m/44'/148'/0' GC5RE2NMJU472NN66ENXZS4YK5I6CPYPE4JZ2BIMPWSD7IBRSKKH6QUB SC2E6KW4K4ZXT52KNAWKVPHYHAXQDEBRJW7FOUJUPOMGTKRSZXZH5VTO
m/44'/148'/1' GDMUEO4GKPBZMRS7R3766TC3AXZ7CTTVWJNFJI5MNACBWYF33EQM26FQ SCCGSSYNFUDLKMTBRH7BMGM7AMLBFX6MS4TBOABZT6T73SG7N5LYKMYY
m/44'/148'/2' GBM3QWZCEW4I3NMAQJBTSISDYP3L7HZXCHQ5J2KT4PRE5RBYNNCNLHIT SDJ7TN2DDCRCIX7DYUSBUW6CJIGTTCFXBMNO2IW6RYPLMCFF5X2YX62V
m/44'/148'/3' GDFLHV6UY2A2GFI4BQ4KEPZ5GGEILGF4U3ILQVL3ROXR46XW2E4EMSXJ SBCPEGJUE3AK66A4H7VLIU2W422MWQHA6QOSOELUYNZQMP7CTIQRFXT3
m/44'/148'/4' GDSN6TWIAV256DBMVTKAC7WJ6TYP4IID44KIUNJHR6SRJ6O5O5QHBQFB SDCAR5B3UVAFUGBUW6VYXK47RYYCGPJ4QFC2ERCU4H5DP56IO22IZIU6
m/44'/148'/5' GCYICO73QRKOJRAZ4GOAXMH7JDEX5OPBEYQNAQTW75YR6UUSZ7VET3FO SC326YSVFQCINTT46BTI6JSUNRNB55ZLSUD6K4Z67ZU7HNK226RAWZ37
m/44'/148'/6' GBLDONQAXRAVYIDI7IMK6UGRU6ZA27DZDQEUBOCLTHQMFVAWFLZNDIV5 SAVQD5P52RQEGQ7XJPX5HONKJE34NRJMQQNXVGVDWPMIBMMP7U36Q4QH
m/44'/148'/7' GCSKWTJ4FIAAWA6FLNQJXXLTW6IUQZFMDTZGSJV55ETPL4LJLMASVBXF SADEZZTVW534ZQAH2F3IO574LD6QZCV3FDH6X755A74YQACY34ISEHSY
m/44'/148'/8' GCUM4SVCNRU3J3BWQAICS5O6EUEIGIUUZ476TPXOTTFPVAVKRBHLNSW4 SDJINTL2KKQ3GR4XFKZVODS23EY43HULAQHUAMY44BEQFWMBSN6B57RQ
m/44'/148'/9' GDI42ZQY3DIO2PQJKHAMYCQE526K6QMXQKKLZDBMA3TMJULNVYULGK47 SDMP7WPRX73IUOX4OANSWYO3QS5ZR45J27MLRTLUHX42W4FQQQNKKQIH



2
b781c27351c7024355cf7f0b0efdc7f85e046cf9
[['scroll spew acrobat leaf length mayor cleanup visitor yoga response public '
  'equation beard fortune simple coal prisoner easel guest race recall adapt '
  'critical',
  'scroll spew acrobat lily regular herald ambition knit educate relate salt '
  'dough morning dynamic else network large review usher legend package '
  'penalty picture',
  'scroll spew acrobat lungs vitamins civil sweater ceiling nervous rapids '
  'fiction trouble acne modern scout surprise both early walnut forbid wolf '
  'garbage worthy'],
 ['scroll spew beard leader grief move dive custody admit always vexed emerald '
  'medical debris vanish dish glance payroll shadow building grocery fridge '
  'visitor'],
 ['scroll spew ceramic leaf lift expect reaction diminish dining cricket '
  'enlarge daughter testify machine yield epidemic arena scene science '
  'tendency flexible lyrics genre',
  'scroll spew ceramic lily petition twice cowboy symbolic river criminal '
  'rescue best cards cultural curly debut spray that afraid aspect jewelry '
  'pupal keyboard',
  'scroll spew ceramic lungs smith alcohol network golden dress endless prize '
  'beam activity rumor formal wolf phantom mental walnut ivory material award '
  'cubic']]
m/44'/148'/0' GDSAWDY5G4WNVPSJKBZVGEWCYIJLJLEBRBPT7MC5SBNCIKVLXO3CZRPT SDJTZ2M7PEFR63MQNXSVYHP3XM34ECD2AT4BEHTCTXIUZSKGF7UDNYTR
m/44'/148'/1' GBLNTCU4JPLRTTY4EQN2QOHGZRMWYEZ23SNKQ5OD6RHG3GQJFMHKMTLM SCERLFXDSVXI63D2DN4I3JRRY2EP5R6FXBEEDNN3K3276UPZRTCKOROI
m/44'/148'/2' GDJ3ZAJPBQ6OKYPLBIFZUGTELLDEIML62XGW772WEDQOQ2IZCPCE6XD2 SCTJSPQKGU7MFAQIBL7G7BV53SJWCAGRYF3C2SOI6WN3XCN3TOYN5TMY
m/44'/148'/3' GAWWJ576FFDG2IMWDD7BSR3V6QNMLQ5BHMDVAWU5IFVGDGEEJ4IL3MSP SCU3ITBZGPEOTCUULFIY5BQOR7IIW5V7WAGHWXWMRR62PDXLDP3FOPMV
m/44'/148'/4' GD7OQMNXI2VDXUHKV4N3PU3YQ4LAXI6G37CGWLSGLYA5KDP2XZKHF4TT SBBVQUN7B3OQZ4UKSN6SZ4PSE2YFCKED3NTAYFLWX7PNOCKQG64W6F3W
m/44'/148'/5' GCREIV2Y5YAV5A6KVYQU7G2OJFB3NBYCZ7WXXUKNFXWGNE5VJWOPJLK6 SBDACZKVNXFX7DZY5ZHUXFJDS5L66XOT7DDCDP6WWEOVYEGZC5NGZ6OW
m/44'/148'/6' GBUHXUFGTZNM75MWWLBLQDV2OFAVJTF3BMX4BHMEMRYXWKDMTWBAFXNN SBQMLUR66CJ5XPBVYFTDDJFBQCUPU2YNL54AFZGPZMS3MLHKQHWIW3VX
m/44'/148'/7' GBNRZ557ACSQNIH7G5J2WCIEOEDDEBUQM3RKX544ZTJGJKLAWBYYKAH3 SBYDBB7QETKHNP4P6D42TUZR7Q7ZBBBNRDNAZQ5GA726EDYBEDLAG54M
m/44'/148'/8' GD6JMVP6LHKYJ5YMFEM4W64S3WZ44BLFZTSPUPGR5D7HJSFEYYTJC7IM SB5CETFULTKFS2VUD2QCQTFBPFEPMCD2T6HSFD3BKVRCXZ5RZBBGYA2W
m/44'/148'/9' GBSVOB7K4XDHQ4KVM2RNTIHRNIJNQJXZY7LJ7HPQNB6APGFNB7H43CBM SDNK47MOK6I6MIBO7BWNTGH27D3VFZFLCDC2VLLOZLLQQNMXLX66OZKW



3
150df9e3ab10f3f8f1428d723a6539662e181ec8781355396cec5fc2ce08d760
[['easel thorn acrobat leaf aspect gravity fishing company drove dress actress '
  'survive total screw meaning best petition elder hairy undergo should party '
  'ultimate sled afraid justice upstairs guest browser fridge saver enforce '
  'acid',
  'easel thorn acrobat lily adult trash beam category costume smear aluminum '
  'rebuild permit switch extend relate laden axle airport force unhappy blue '
  'flame angel aviation ambition penalty talent glen location dryer ruler '
  'spend',
  'easel thorn acrobat lungs ajar rich sugar crunch pickup order beyond '
  'geology speak username craft deadline race company pumps trouble deliver '
  'market legend crucial rescue burning flea adorn excuse crazy mansion '
  'physics friendly'],
 ['easel thorn beard leader anatomy burning testify percent that knit firefly '
  'vampire breathe finance heat salt mortgage museum eraser kitchen drink '
  'hamster imply friar umbrella umbrella blanket military paces result mouse '
  'epidemic thorn'],
 ['easel thorn ceramic leaf auction replace earth survive body edge lilac '
  'email verify detailed yelp regular entrance camera weapon educate desktop '
  'window shaped example invasion laser taste wits vitamins knife prune idle '
  'discuss',
  'easel thorn ceramic lily animal railroad vocal peaceful bucket alarm visual '
  'earth episode true acrobat response together fantasy camera sugar holy fact '
  'coastal darkness grownup vegan dwarf remember album leaves cage costume '
  'pile',
  'easel thorn ceramic lungs aide physics rapids clothes pitch average '
  'gasoline receiver company equip branch puny aide educate criminal cargo '
  'coastal cover aspect medical tracks grasp alien involve both roster trouble '
  'hybrid deny']]
m/44'/148'/0' GDU4DGABAZWLFZGULPL5L6G3DTILN4CY2YECXJCPQ5POADE65K4A6CUY SDNYGARXVJLMWYUO22K4YAEPKJBHVESCA75WTOSABVTV2TYND2NSZSPM
m/44'/148'/1' GBGNGTVQWRVEAPXOH56RRWOPQ5VGKEXFSNGGCBZ6HQGHJPRGF7YUHUAX SAWSEVE5SZQB23Q5BLXPRMOKRH664IL623T4NWSXBVBVSWJGEUGVMZQA
m/44'/148'/2' GBNZVUS6FMXJW5SKPX5GHX7H72BFFI7DKQFWF6VE4MPOCWE42JJB355O SDI5MVQMXWAE3VCMQ6PW62NIOMIUX6R2MIDYHJXNYI563PY7VBW4VRFI
m/44'/148'/3' GAIKDCZXIVGBMDZYGOUQ6OVWEWVBJV5RVTT6EFKUFWKNFZYVB6MHCEFZ SAYJYKL7SUL3AMIDP52CGZRLNUSLA5ZSAFJ2LXSKOHJS4JIHY2SCMR6K
m/44'/148'/4' GAK7TNQVH6VA2UIWGHRWXDLZFF7HB5MUYVNAZSCXG4APJINABZLHRCW3 SBGYGIPNZAQ3G6AQFLO3BFA4YE6F67COJ7JRE3NHCYDR2G7EQP5UVCHF
m/44'/148'/5' GCSCLBOK73O655YK42EDETB6MRFPYK3STI2E627B3JPVP6XBLCFNFNOC SDXBOWH3D5Z4VG6RONU4GEG3JG4SEBHVNBVPQBZBCN4C5H4RIK3WSV3P
m/44'/148'/6' GCLDFZ47ZSJ3X2BJ56RGMLWTARMMM2O5EYGIREVOLRDB647BWBZEHFKK SDJ7HPXEBOM6TRNHHW7Z227QUTQJELGZCEMW2Z3EQSTPNP7TDA6KQ4U3
m/44'/148'/7' GB23ZJUW5NIS5AAKCRGZADBU4BCJTOVWCU3CXRVKQYAMDSTA6YWCDCXS SDTHC4GZR3VJU2SJC2TQVI3WSZOXPJFVHJFZV2BK2KQHOQUHC56ZYPGX
m/44'/148'/8' GAPKRA2YYGLMAWMSOS5BDETLKDPARNETFQEZ2HUBJT4KPKGASHHD6WBV SC2NMPSN7MHJJX5MGVYFN5XXVNWSWY4OLT3CWNASFWLZ74LFBAS67CS6
m/44'/148'/9' GCEJISZFNS4FQGAKGQAWOWM67WMFDI62FAO3477UCNUZVCRX7L3FV3RB SCBG6YQXH2ZIWEPLANXRG3OLAUEULA5FO6QTJLWX5VCENSZVCHFPCLEH



4
1ffa5d83ea6593d666b350d6f3e652d598c3063ab51ed4c2e9d6a1d07c8545df
[['stick omit acrobat leaf ancestor born lunar valid extra patrol museum '
  'mortgage check flexible remove lawsuit laundry quick priority tenant cubic '
  'express capacity domestic thank patrol density knit skunk sharp laden '
  'raisin describe',
  'stick omit acrobat lily analysis cards depict mason dance angry emphasis '
  'mayor ultimate dough shelter answer floral float undergo capital scholar '
  'network very mother careful clock slap robin estimate lizard twin upstairs '
  'hunting',
  'stick omit acrobat lungs argue agree vexed amuse retailer inform crucial '
  'shaped capital breathe fluff museum deny class cultural bulb funding '
  'charity submit glance replace hesitate station mild income extra tidy '
  'obesity rocky'],
 ['stick omit beard leader aviation flea resident smell organize ugly angel '
  'violence laden voting upstairs river buyer holy software prospect pupal '
  'gravity physics mailman square medal story treat prisoner unknown kind '
  'famous space'],
 ['stick omit ceramic leaf ajar bulb puny cradle blimp daughter filter raspy '
  'filter humidity calcium charity western climate slap evoke apart hearing '
  'mountain morning premium salon subject privacy rival epidemic river expect '
  'increase',
  'stick omit ceramic lily aquatic repeat pacific news platform capacity '
  'finance problem amount amuse privacy evil improve dismiss railroad survive '
  'gather diploma rich change reject breathe activity lily warmth either slush '
  'dominant depart',
  'stick omit ceramic lungs alive survive undergo climate kind slice findings '
  'loyalty wits climate goat mule wildlife talent easel acid scandal bike '
  'satoshi moisture listen intend involve wrist likely flip process raisin '
  'bundle']]
m/44'/148'/0' GCLBBT6RFBL6GKWCOEPH5RWNBNZNXSDM6WBYQP3QYV5NP6HS3GW2NVRT SAECCVRPXZANUW6YTDHEEKBWGHJYH6NTPHNN3PZY2VYHWCAYVVOKSURO
m/44'/148'/1' GBHS4EKPUFUNI42ZRSBYW3OOFOYFH3XMZRQAGUCU33LTL7OB22BT6AJG SBVFGV3H3Q4RVQWNMHGI27BFO4Z62G4H5I4LRLRXE24SC4JFBSLVGS3V
m/44'/148'/2' GBKMTZUVOLVW4LU5CF3KJNFHGJFF5OXLVXLXGHNSNLLD5XYSAJSZPMQJ SB3R54O465R5FWHGHAQTGXJNLI5KB2EMBX3NS3STKVSAJHLE2IPHVJ7Z
m/44'/148'/3' GDROOKCCNLALPNKI7P4GLW2I4YH7XKIRQOQ2RRZYOW2YV7MFWBIPWHSF SBJIIA77QPPVLJYXGTR4KPXMAQE7VXEXPWDSCFXMV7FUQDLJQ636T5RN
m/44'/148'/4' GBA2BUMVATRU45CF4XBFFURD732TOJ6LYI52GP7UKAKD7CU6B3DTOHNU SB567ZOD3RJXDQJ5E7V7UKCOPRCRKOS5ETZNNWBZ2R52ZHORS4YPZ5YA
m/44'/148'/5' GCORJHF42MCI5GZMN2TJEM5TG6VKKHRVT3EIHE2VWGAAU6PLL7H6XMVL SCQVNOR7ABTKG3OALN5MCEX7NYB5UGCIUTCZU722MWFDPBLGRCFZISXK
m/44'/148'/6' GD326LUPOSLBZTAJ7HW6DFUNJKTQIVAKWF4NMPR7OFT5Z7KRIRFETSSU SATL53TIN6MEYCJJUOCZNEWTI4PLVU3RJTDURGVNWBNLBAZCOE5WM72N
m/44'/148'/7' GDZ2QUEZR2P7GD5YIFHC5KR2UWZQZPM7QGUJD6B7GM6PQZSK5LAOMQMM SDPPPFNANXCLC2LBSX2UZ5Y6IHLHKJIPONEAHREGEOIBQFUOCVCLFLY7
m/44'/148'/8' GCM7GLBSXJ6COKOFXKYKO25JAK2CHPFGGXY45D2ZSQB6IOMUWZOGIGED SDBJKWYKJ4HK66WQFDJ6N5S6N5NH5EHYVTXHLIER55TKBW6W4IYYVLUK
m/44'/148'/9' GADNSELTTAUNBAEXXNKEHZYBM6HMUDJFP57VYZGUF6BDR7NNO6UJJYHO SD2H6SC7GNA6JQYPDE6KKQHB6Q3VNHVK2CLKFFLM6TGKPY3EHGRM6DS5



5
00000000000000000000000000000000
[['edge vexed acrobat leaf breathe black math aspect pumps oral receiver have '
  'result island various weapon cover husband welcome endless',
  'edge vexed acrobat lily ajar camera railroad cinema gross taught prayer '
  'liquid length blue length estimate amazing cover smart grief',
  'edge vexed acrobat lungs check album moisture emphasis system grant testify '
  'physics endorse raisin ladybug oral cubic sunlight very ladybug'],
 ['edge vexed beard leader duke advocate loyalty equation wireless radar slice '
  'express pistol grocery style devote glasses airline example perfect'],
 ['edge vexed ceramic leaf angry bulge cradle angel senior watch reward agency '
  'destroy prune race usual wrist hospital retreat desktop',
  'edge vexed ceramic lily ancestor pregnant library earth escape junior '
  'makeup kidney flexible beaver volume surface writing fangs smug loud',
  'edge vexed ceramic lungs answer hesitate black snapshot slap tracks staff '
  'finger hamster traveler formal aircraft duration patrol merit lyrics']]
m/44'/148'/0' GA5D465BLRTA3U7UOVBFC4B7NBKISL62OSMOEERDAQUDOOHZLAZAFVCM SDVUPCYZPUFIGHDMPWKUVRZV6C72CRX7DT3UKK75C5SHM3IIMMUMJJ4L
m/44'/148'/1' GABB36PFFIJXOJTORX7IJBM3ECNDYUN35ZIE4SOXADDIXADPKVRSGDB7 SBVVZWVIP5FL5XRB6DK6MN567SZ4CHJNXCPYWCEWOMMJ5DHAM5HC4B3I
m/44'/148'/2' GB4YPCN7MXUDYHFPQW5FRPUX6AYEXG6LQO537L2367PTQPYQ3VMLPETZ SCIUU473TFAMPA2INXHIHLGMTSBNQ3BRXGETOGWMOKYDWNFE5LARKN7X
m/44'/148'/3' GDX2EUQQQBTFRZZUGWECF5UMXRAHQ5KWVGW6U7HKEKXAQHBH4T4MQJAG SB24IVJVT34UAR337BQLJ4IIGOFJ7EODATKOWI2NMUL74XZITMVLPJZ5
m/44'/148'/4' GDJQHGSVRBFLDXMCN6LPF23SVJHYNZIOH2XC4RQYI2CTY4YFM4VD4QB5 SB6ALSO7TDROHXLQYEE6HLMDPK5QK7YTRRO6OLQYHOBLPAHO7QGCCR2T
m/44'/148'/5' GAW6PQVK22D4HMYVU3QEO4LMR4736QBQ2MTWCBOAIINP6IKXN4IYY4BW SDXTH6HSOMCEHJBPYTV5VZGLVSLVIKCCD3BKAUSX35EVRLNNLAT527QP
m/44'/148'/6' GDURBDQZ73EAAQ3ZGXS2A6X3VJJDXV7PFMBTS3DKIROBE7UETXUCTWI6 SAILOQQI4INX77ZYBAMSHAIVZRIHQX47Q7GQ4RDQ7XW4YI4B7ZWWXCGU
m/44'/148'/7' GD37CHASVMM3VKFGK7WGG3KSNST3Z2Y4Y5HJODXAUPN7C5V4DI64QA5R SCXCCWLX43UDGKDOFMO3UXDOXUFJ3KVHXXUEX2RRULI55PFUQZJ72YEP
m/44'/148'/8' GAG6Z3FYOGWIB5D5MFG5XDKWYH63PBZTAQHIQQWKQNBETWXMQ7LC7AJZ SB777RSMY5AJUKDDQRTNHWKSYQS75XZIOYICIPLE5R6NZ2VONS7V5LTI
m/44'/148'/9' GBAMYLBYFYUBJ6N7HZFFFWJ5U7H2BJDH7UFOCQU2XDQPKGCIEK5PATFK SAXMTDP4GFC7PCQZNPXMGYEMO4SWPUQRBSGE5R2WYWTCW3QJAKYHZA6F

Copy link
Contributor

@overcat overcat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Your test cases have all been verified as correct. Now we need to wait for someone with write access to the repository to review it.

@leighmcculloch
Copy link
Member

leighmcculloch commented Jan 14, 2025

This is fantastic @tupui. Thanks for reviewing as well @overcat.

Because SEP-5 is final, the intent is it won't change. SEP-5 is an old and very stable SEP that wallets can say they support already in full. Expanding it is not ideal because that statement a wallet makes that it "supports SEP-5" changes.

Can the new text be moved into a new SEP? The new SEP can reference SEP-5, and operate as an extension.

@tupui
Copy link
Author

tupui commented Jan 14, 2025

Thanks @leighmcculloch 🙇

Great, I am happy to do this! Looking at e.g. SEP-44 being an extension of SEP-41, I can use that model to do the same here. SEP-45.

@tupui tupui changed the title Add Shamir Secret Sharing to SEP-0005 SEP-0046: Key Sharing Method for Stellar Keys Jan 15, 2025
@tupui
Copy link
Author

tupui commented Jan 15, 2025

I updated the PR. Please let me know what you think 😃

Also feel free to add your names.

ecosystem/sep-0046.md Outdated Show resolved Hide resolved
Copy link
Contributor

@overcat overcat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it looks great; I just added a little suggestion.

The parts are non-deterministic and any derivation leads to the same set of keys. As recommended for single
mnemonic codes, we recommend using 256 bits of entropy. Which leads to 33 word mnemonic phrases.

While BIP-0039 can be derived from the entropy, it is not compatible with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's great to point that out. 👍

SLIP-0039 as noted in the standard. This means that BIP-0039 derived addresses
are different from SLIP-0039 derived addresses.

## Design Rationale
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to explain the reasons for choosing SLIP-39 here; in my opinion, Alternatives considered include: is a bit redundant.

SLIP-39 was chosen as the base standard because:

1. Industry adoption and testing
2. Hardware wallet support
3. ...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rephrased a bit. Please feel free to add some suggestions.

ecosystem/sep-0046.md Outdated Show resolved Hide resolved
@overcat
Copy link
Contributor

overcat commented Jan 15, 2025

Also feel free to add your names.

Hi @tupui, if you'd like to add me as a co-author, you can add: Jun Luo <@overcat>.

@leighmcculloch leighmcculloch self-requested a review January 15, 2025 03:35
ecosystem/sep-0046.md Outdated Show resolved Hide resolved
@kwantam
Copy link

kwantam commented Jan 16, 2025

Probably a naive question: skimming through the proposed text for SEP-0046, it seems to me like it's not much more than a pointer to SLIP-0039. If that's a correct statement, what is the goal of publishing this as a SEP?

@tupui
Copy link
Author

tupui commented Jan 16, 2025

Probably a naive question: skimming through the proposed text for SEP-0046, it seems to me like it's not much more than a pointer to SLIP-0039. If that's a correct statement, what is the goal of publishing this as a SEP?

Correct, this is why it started as being in the text of SEP-005. But being frozen we needed to move that to its own SEP. The point here is to endorse it and encourage wallets to implement the feature. Having some Stellar specific test cases would help towards that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants