aidanaden/shamir-zig
secret sharing (shamir, feldman, pedersen) in zig
71490491b8f1b0741218160b88cf0a87d2a941ce
Simple zig implementation of Shamir's Secret Sharing algorithm.
2 implementations exist:
Uses GF(2^8). Implementation inspired by privy-io/shamir-secret-sharing and hashicorp/vault.
Uses Ristretto255. Implementation inspired by coinbase/kryptology
Includes a CLI app for independent use of shamir secret sharing.
zig fetch --save git+https://github.com/aidanaden/shamir-zig
build.zig
:const shamir = b.dependency("shamir-zig", .{});
exe.root_module.addImport("shamir", shamir.module("shamir"));
nix run github:aidanaden/shamir-zig
brew install aidanaden/tools/shamir
We can generate
shares from a given secret and later reconstruct
the secret from the minimum number of shares (as configured when running generate
).
Note: for algorithms using Ed25519, the secret is hashed via Sha512 and reduced into a value (32-bytes) within the Ed25519 curve. Reduction is required since the secret can only be reconstructed as a value within the Ed25519 curve.
./zig-out/bin/shamir generate --threshold 4 --total 10 --secret mynamejeff
# --- output ---
#
# secret (hex): 6D796E616D656A656666
#
# shares (4/10 required):
# C55F6C84575C6B4BB0B639
# F464701E29B79D09483736
# 34345F1C0918C6DC1A593D
# 3185D736294DAC48D85F8C
# E392144022D14FCB9DF202
# A87636B60C88A103561E29
# 9E1C2F10E1AFAE3E7732BC
# DF3C164FFD60A0B4DB3A91
# 253DC1AFC299E1D63AAFD2
# AF08A0E9F9362F13775FFA
./zig-out/bin/shamir reconstruct -s=34345F1C0918C6DC1A593D,253DC1AFC299E1D63AAFD2,AF08A0E9F9362F13775FFA,C55F6C84575C6B4BB0B639
# --- output ---
# secret (hex): 6D796E616D656A656666
# secret (text): mynamejeff
./zig-out/bin/shamir generate --threshold 4 --total 10 --secret mynamejeff -m s25519
# --- output ---
#
# secret (hashed): 6D33F29E352F4A76FB61C06E6AC84163760FE73CBDEEA718B366DB62EB0EAAA9
# secret (hashed + reduced): 2BEC57FD2D5092059C411411B8058C92750FE73CBDEEA718B366DB62EB0EAA09
#
# shares (4/10 required):
# 13EA9709CC727E0CA9318D88952857DC09C4623D4BECFA80BB4A11BC3590D90F95A112BB916F7310A1096D8BBFD8F2CE8510DB466591B5C30F5D7C6709BD0C0B
# A2B0D0804BC85A78FB823D5F0EAC6D1BEE33B571B8B6CFD092256D335527DE052420E113ECA01ED66548E3B3C7DE9E63CF1B577198F2FE1359F36510C372830C
# 98EAF99A5C2C9DF845C1B60B6BCC98BED71C32D0DD234124F5589ECD705E74010BF0DDB5ABA27E4BBF9244700A382CC37E74B289A8A18A1E5F028635C664730A
# 7478BA4DCF425D2CB1192F91857A47FA82F5C984547BCC0ABD4DB4477232D408F1FD38D7549982CDF097AA20C8C132B5BB4867030D409F2F8655147B64C4880F
# 62E6140919560400B327F7D82FE5079CF797A8B4E6330D84C17DF8FCB16DB50B2FACA3B4EFC36A037FDF5779DB6EC4CB403415FD6EE6CB4A6BA4912634595C04
# 7B5285D171303E01B72F4072A3442196B5106E755A8EAF23ECB1CB5DED882D0927FA83D9626D8397C0F2579857E1456641B9307ABA500D9DF0BEF5A03DBBE402
# 33923A08169BE52AA63056AC910EDE2D4D009B3BACA107708E8EFD63960DBF011CD27EE4CFBA5AD8AF321B0D210A57DD8A8ED40CFC3100316D791BAA72B28F03
# 0FD89DF188499DE2E2C4EA7106F82088B44A02BCEAF1685C2C44443079ED4C0EB450E6CD606CD07B07B9115B1C3183B6DC1BAA8AEC63C5F22F07B4121600D707
# 4E28FAD8EA66FEA1F35BA08C42CEED3B63A8ED732BF6086110142BBDC449EC0BD2B6EB9E56EC92BE4685D1877B6761EEB90F773A0B29A0C062C4053292C6680C
# 19F93B27B20FAE7F7597A70F6623BB6692499CC24A79BF6D8200C38159DB6E08C613014DBCF76E931B80413BB36B8D44324D948CF8A8747B70D49D9585A49803
./zig-out/bin/shamir reconstruct -m s25519 -s=13EA9709CC727E0CA9318D88952857DC09C4623D4BECFA80BB4A11BC3590D90F95A112BB916F7310A1096D8BBFD8F2CE8510DB466591B5C30F5D7C6709BD0C0B,7478BA4DCF425D2CB1192F91857A47FA82F5C984547BCC0ABD4DB4477232D408F1FD38D7549982CDF097AA20C8C132B5BB4867030D409F2F8655147B64C4880F,33923A08169BE52AA63056AC910EDE2D4D009B3BACA107708E8EFD63960DBF011CD27EE4CFBA5AD8AF321B0D210A57DD8A8ED40CFC3100316D791BAA72B28F03,4E28FAD8EA66FEA1F35BA08C42CEED3B63A8ED732BF6086110142BBDC449EC0BD2B6EB9E56EC92BE4685D1877B6761EEB90F773A0B29A0C062C4053292C6680C
# --- output ---
# secret: 2BEC57FD2D5092059C411411B8058C92750FE73CBDEEA718B366DB62EB0EAA09
./zig-out/bin/shamir generate --threshold 4 --total 10 --secret mynamejeff -m f25519
# --- output ---
# secret (hashed): 6D33F29E352F4A76FB61C06E6AC84163760FE73CBDEEA718B366DB62EB0EAAA9
# secret (hashed + reduced): 2BEC57FD2D5092059C411411B8058C92750FE73CBDEEA718B366DB62EB0EAA09
#
# shares (4/10 required):
# 49814F39B575396032A86C3F6EF9F0EBDBC0A88FEC19CAB98A36414097399B0803B3667FAB8A806FFC4B99438D7E11B329E29C3AC62E4917A96EBAD33C4EAB01
# 049667BC415BCABB0619AC12A08B9303331A8A3217B51BFE17EFD30677D16B06790F10EDC8B5E124B1F1CA7BF80C29A7F7AEFE8B77B5E02E669BAAABDDC24605
# 92CD16899DC5FB48314E7512881714B280CEC260E01C43DC9318105DC6E6EB0E507EB0C564C26C724229D68A894F870DC5116F50E68D9B784DBC9A3302F4BD07
# EB6BE224F74F1906383AC8BBD4E182FD459A29EF3EEC1AE606A40877E12704069139983309B233A300F7269BF23822E4FF89BF97E62DFFC908C31BD5F4286205
# ED8F45DDC5B003B56ED684BD38FE7D577AF752EFA17389016073058487C9D8089EA3F6D862F58221F323749C2473C8C4C98A01B7CDB8110FD08CDB6986B44F0F
# F7E224EA86853ACB60A68ECA39862C2D69F23620358E144213E6DBB18CA439087E5387849AE26580445838F9A3459B27AE732EA095F7E6D1A8FDB2C84631600B
# 477E6A586D37E1BE6F7CE83EA87AABF850F909E2B28446659311BF07DBE9C705790F15B3E7F5EFDB3D0130CD733B02EEE19A8CC76DE1A9720914B95F87237F0F
# 5A8C11E5983CB5C91D259CA58EB1827705E83350754BABFA8D0AE7F1B3FC0303808D134C8B66D150FBA1AD081F7D7146BFCF507BDEF4FFA2C774AF229793090B
# 0802CE0B329158BCF5DB3258AB2D25D8CC9637DAA8B9C9E262BEA98556262204CD3BE0D6116E6E9E6EF2644DDE787FC08A81B9440250FB50BB9B2AEFFDAF1801
# 6B3F0CCA128D3315B8D298006E3EDCF9A08DDD3525DA04258DCD20EACD85940FDCAFB5619158459A036EF258327FB1CFC7A3F0E33C5926AA0D9839802D60C609
#
# commitments:
# 6619F19D0BB5D506EB91979E1DC11F4754FFB35CAC987486F8128A36FB67240A
# 680D5DFF0FD0D5AD95EF878E9D5427BCFFD4A38BAD5448768CCCFB3B28F5F902
# B4B1E9FFE8E15C4D786A40792E9A82F7748841CBEC64D55B50BDCB249BC5CC70
# D2E9B85F819DE590B4362B4C8D5462C95EF2DA32CD28D8430CAFAB45FA17E820
./zig-out/bin/shamir verify -m f25519 -s 49814F39B575396032A86C3F6EF9F0EBDBC0A88FEC19CAB98A36414097399B0803B3667FAB8A806FFC4B99438D7E11B329E29C3AC62E4917A96EBAD33C4EAB01 -c=6619F19D0BB5D506EB91979E1DC11F4754FFB35CAC987486F8128A36FB67240A,680D5DFF0FD0D5AD95EF878E9D5427BCFFD4A38BAD5448768CCCFB3B28F5F902,B4B1E9FFE8E15C4D786A40792E9A82F7748841CBEC64D55B50BDCB249BC5CC70,D2E9B85F819DE590B4362B4C8D5462C95EF2DA32CD28D8430CAFAB45FA17E820
# --- output ---
# share validity: true
./zig-out/bin/shamir reconstruct -m f25519 -s=049667BC415BCABB0619AC12A08B9303331A8A3217B51BFE17EFD30677D16B06790F10EDC8B5E124B1F1CA7BF80C29A7F7AEFE8B77B5E02E669BAAABDDC24605,477E6A586D37E1BE6F7CE83EA87AABF850F909E2B28446659311BF07DBE9C705790F15B3E7F5EFDB3D0130CD733B02EEE19A8CC76DE1A9720914B95F87237F0F,6B3F0CCA128D3315B8D298006E3EDCF9A08DDD3525DA04258DCD20EACD85940FDCAFB5619158459A036EF258327FB1CFC7A3F0E33C5926AA0D9839802D60C609,49814F39B575396032A86C3F6EF9F0EBDBC0A88FEC19CAB98A36414097399B0803B3667FAB8A806FFC4B99438D7E11B329E29C3AC62E4917A96EBAD33C4EAB01
# --- output ---
# secret: 2BEC57FD2D5092059C411411B8058C92750FE73CBDEEA718B366DB62EB0EAA09
./zig-out/bin/shamir generate --threshold 4 --total 10 --secret mynamejeff -m p25519
# --- output ---
# secret (hashed): 6D33F29E352F4A76FB61C06E6AC84163760FE73CBDEEA718B366DB62EB0EAAA9
# secret (hashed + reduced): 2BEC57FD2D5092059C411411B8058C92750FE73CBDEEA718B366DB62EB0EAA09
#
# shares (4/10 required):
# 4F68C05ABAF05C8719A63DD4FB956A89535F62A483600B77BF2A6AF23DB84304A342502F83161846C1C0BC27ACF77643B325452BB0227663785C673C35ABED0F2C84B12AA73F387B0A51145A32F97B31E45EDC0168AB4F8D1458A1D58E96C105
# CC49BF6CD19DF7F99BB1D0DF8BBE71D299521C743F2DB0A8C553E8AB7B3E83006EB2B8A2F5996EF40C63040E36AB28ED768A69CDFAFFDC3E18BDF77E25E740036BDA64257A15DB50F03ECE29024292EA261AAFF2B488A2FBC98D0F9C921E7603
# A4871FCCC96F25AA189442680993A92FBCD5712EE19C57196A0C25910F7E3C03D94313D9201A8156AB1666E2AF15740F59E7DCF63B5AEBFFCEDE47BE3D77E205C05CA67302B95F14D03FBA9EBA2137EA4543ADA629F351A7E668B81936286302
# 9375125C44F6BC9D0394D0399E054D8BE5AD969730F0161D30A7EBB96FCECD0CD1D6A39F502B16FA2919B28C12F2C589621D1F0832D1791DC212163CEB7A5C08AE2B065035382A231F6D157F26335AA625487632B5BED2E608F384FA8CAD9305
# F8628F8C5202B305A8D34074F12409360A859510C22F63D7460CC7804D32930DC22B9F7CDE3E8B19DC5E04B3F1B36EE4C267C58AEC34CE6E6FB3DB00874E510A30139F19FD461DBBF6FE12DF04D4C67192FD9F2AD6C469C95F39A55FEB97C009
# F80E4B88E300320D8125E04F77FD13C604E3FF6AD7EFABE81D562FC3B8ABAA0A445346214009220C3172C52FA30DDE43D8D72451F8035160B6E40E464EAD850D45406A2C7924E0AFF59DEB3456BC6CB29DCC0F3BC8F265E5FC983C3CB55F3B0D
# 979A90B0016233C68869A0669DDA77F54A8CBD9CB3832418B73EAFA92519C203862E17117099F859DAC70396F882D74F3E61F9AC10A678B0D79CD7F08F5EB607F5AD016F9E3F9CFF189E88BB3D3038BF1EFD70CA057FD382C7C5BE9E0FF93306
# 2AC74EEFD7FEE98583E2123689A0A7324682C39D68B31C94ED7798476E367E0FB3074A938D628FC8B0F77E72DD98F143210793F942B4E67764AA36481ACFCC034626C13127D7373C6850B4BEA29D91E25423ECF54D24373223D94710B71EB700
# AB39FCE99366998F671E8C39913AF1DBE39FB012973BDFBF8F5A3D297786110C730F4A3A777363016B558439BE94B443814E70F54885F24F899185112704E40F941F85A9B401FBD5260A00173C5380CF2640226A319B3EEF3C4E8BD3B060E60F
# 37F7F7A9D1A655A3F74AFF1A45CDA380A17E3714E86A994F23516341B898A10E3BCB35FE3CC68C114900E73377618BDC19E010E1AC609766667ED3E181660502CC3555C53BD31DDD3F2A3378B7D7B62A81641A1235F80C57CD1943D7C2390D08
#
# commitments:
# BE62A4FDA40E9EE9BDBB7FFF5CC309AB1C3BA96B25DF151566CBF21028E3A952
# 305355D39AE9C1D3048153FC9B46E9D0264B67F18B49F7C47F9D393BF3E67842
# A2D0682D0FB13B0315337C38FB3B6583C7249DCE705A764D2C3B606DBC955D32
# 0CEF43C0C3A7786FA8F3F918DE1BFFA67679003CAC4254E1DA3DCF11DE3A9E2E
./zig-out/bin/shamir verify -m p25519 -s CC49BF6CD19DF7F99BB1D0DF8BBE71D299521C743F2DB0A8C553E8AB7B3E83006EB2B8A2F5996EF40C63040E36AB28ED768A69CDFAFFDC3E18BDF77E25E740036BDA64257A15DB50F03ECE29024292EA261AAFF2B488A2FBC98D0F9C921E7603 -c=BE62A4FDA40E9EE9BDBB7FFF5CC309AB1C3BA96B25DF151566CBF21028E3A952,305355D39AE9C1D3048153FC9B46E9D0264B67F18B49F7C47F9D393BF3E67842,A2D0682D0FB13B0315337C38FB3B6583C7249DCE705A764D2C3B606DBC955D32,0CEF43C0C3A7786FA8F3F918DE1BFFA67679003CAC4254E1DA3DCF11DE3A9E2E
# -- output ---
# share validity: true
./zig-out/bin/shamir reconstruct -m f25519 -s=049667BC415BCABB0619AC12A08B9303331A8A3217B51BFE17EFD30677D16B06790F10EDC8B5E124B1F1CA7BF80C29A7F7AEFE8B77B5E02E669BAAABDDC24605,477E6A586D37E1BE6F7CE83EA87AABF850F909E2B28446659311BF07DBE9C705790F15B3E7F5EFDB3D0130CD733B02EEE19A8CC76DE1A9720914B95F87237F0F,6B3F0CCA128D3315B8D298006E3EDCF9A08DDD3525DA04258DCD20EACD85940FDCAFB5619158459A036EF258327FB1CFC7A3F0E33C5926AA0D9839802D60C609,49814F39B575396032A86C3F6EF9F0EBDBC0A88FEC19CAB98A36414097399B0803B3667FAB8A806FFC4B99438D7E11B329E29C3AC62E4917A96EBAD33C4EAB01
# --- output ---
# secret: 2BEC57FD2D5092059C411411B8058C92750FE73CBDEEA718B366DB62EB0EAA09
test "can split secret into multiple shares" {
var secret = std.ArrayList(u8).init(std.testing.allocator);
defer secret.deinit();
// Hex value of "secret"
try secret.appendSlice(&[_]u8{ 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 });
assert(secret.items.len == 6);
const shares = try generate(secret, 3, 2, std.testing.allocator);
defer {
for (shares.items) |s| {
s.deinit();
}
shares.deinit();
}
assert(shares.items.len == 3);
const first_share = shares.items[0];
assert(first_share.items.len == secret.items.len + 1);
const second_share = shares.items[1];
var thresholds = [2]std.ArrayList(u8){ first_share, second_share };
const reconstructed = try reconstruct(&thresholds, std.testing.allocator);
defer reconstructed.deinit();
assert(std.mem.eql(u8, secret.items, reconstructed.items));
std.debug.print("\nreconstructed (integers): ", .{});
try std.json.stringify(&reconstructed.items, .{ .emit_strings_as_arrays = true }, std.io.getStdErr().writer());
std.debug.print("\nreconstructed (string): ", .{});
try std.json.stringify(&reconstructed.items, .{ .emit_strings_as_arrays = false }, std.io.getStdErr().writer());
}
See more in the tests at shamir.zig, feldman.zig, pedersen.zig
Apache-2.0. See the license file.